[python]代码库# -*- coding: utf-8 -*-
from Tkinter import *
import random
from tkMessageBox import askquestion
# 尚需改进,有待提高
# 各种方块的表示,与参考方块的相对位置
shapedic = {1: ((0, 0), (1, 0), (0, -1), (1, -1)), # 正方形
2: ((0, 0), (0, -1), (0, -2), (0, 1)), # 长条
3: ((0, 0), (0, -1), (1, 0), (1, 1)), # 之字型
4: ((0, 0), (0, -1), (-1, 0), (-1, 1)), # 反之字型
5: ((0, 0), (1, 0), (-1, 0), (-1, -1)), # L型
6: ((0, 0), (1, 0), (-1, 0), (1, -1)), # 反L型
7: ((0, 0), (1, 0), (-1, 0), (0, -1)) # T型
}
# 旋转函数,顺时针旋转90度,相对于参考方块
change_dic = {(0, 0): (0, 0), (0, 1): (-1, 0), (-1, 0): (0, -1), (0, -1): (1, 0), (1, 0): (0, 1),
(1, -1): (1, 1), (1, 1): (-1, 1), (-1, 1): (-1, -1), (-1, -1): (1, -1),
(2, 0): (0, 2), (0, 2): (-2, 0), (-2, 0): (0, -2), (0, -2): (2, 0)}
# 随机颜色
colorDict = {
0: '#CCC0B4',
1: '#EEE4DA',
2: '#EDE0C8',
3: '#F2B179',
4: '#EC8D54',
5: '#F67C5F',
6: '#EA5937',
7: '#804000',
8: '#F1D04B',
9: '#E4C02A',
10: '#EE7600',
11: '#D5A500',
12: '#E4C02A',
13: '#804000',
14: '#EA5937',
15: '#EE7600',
16: '#776E65',
17: '#776E65',
18: '#FFFFFF',
19: 'yellow',
20: 'blue',
21: 'lightblue',
22: 'red'
}
# 俄罗斯方块
class Game_Russia:
def __init__(self):
# 每个方块的大小
self.width = 20
# 方块数目,长和宽
self.row = 28
self.column = 19
# #初始化
# self.scores=0
# self.all_square={}#坐标系网格中个位置方块的存在性
# self.head_square=[]#参考方块绝对位置
# self.new_square=[]#移动方块相对位置
# self.direction=-1#方块初始方向
# #规定界限
# #i表示第i列,0在左边
# #j表示第j行,零在上面
# for j in range(-4,self.row):
# for i in range(self.column):
# self.all_square[i,j]=0
# #划界,开口向上
# for j in range(self.row+1):
# self.all_square[19,j]=1
# self.all_square[-1,j]=1
# for i in range(-1,self.column+1):
# self.all_square[i,28]=1
"""
用来debug
for j in range(self.row+1):
for i in range(-1,self.column+1):
print self.all_square[i,j],
"""
self.window = Tk()
self.window.geometry()
self.window.maxsize(400, 610)
self.window.minsize(400, 610)
self.window.title(u"俄罗斯方块")
self.frame1 = Frame(self.window, bg="white", relief=GROOVE, borderwidth=5)
self.frame2 = Frame(self.window, bg="white", relief=RAISED, borderwidth=2, height=40,
width=570)
self.canvas = Canvas(self.frame1, bg='purple', width=400, height=570)
self.score_label = Label(self.frame2, text="Score: 0")
self.frame1.pack()
self.frame2.pack(fill=BOTH)
self.score_label.pack(side=LEFT)
self.canvas.pack(fill=BOTH)
self.draw_wall()
self.initial()
self.get_new_square()
self.draw_new_square()
self.play()
self.window.mainloop()
"=== View Part ==="
# 边界
def draw_wall(self):
self.canvas.create_line(5, 5, 385, 5, fill='blue', width=1)
self.canvas.create_line(385, 5, 385, 565, fill='blue', width=1)
self.canvas.create_line(5, 5, 5, 565, fill='blue', width=1)
self.canvas.create_line(5, 565, 385, 565, fill='blue', width=1)
# 得分
def draw_score(self):
self.get_score()
self.score_label.config(self.score_label, text="Score: " + str(self.scores))
# 画下面所有不动的方块
def draw_square(self):
color = colorDict[random.randint(0, len(colorDict) - 1)]
for j in range(self.row):
self.canvas.delete("line" + str(j))
for i in range(self.column):
if self.all_square[i, j]:
self.canvas.create_rectangle(5 + i * self.width,
5 + j * self.width, 5 + (i + 1) * self.width,
5 + (j + 1) * self.width, fill=color, tags="line" + str(j))
# 画移动的方块
def draw_new_square(self):
self.canvas.delete("new")
self.head_square[1] += 1
color = colorDict[random.randint(0, len(colorDict) - 1)]
for i in range(4):
self.canvas.create_rectangle(5 + (self.head_square[0] + self.new_square[i][0]) * self.width,
5 + (self.head_square[1] + self.new_square[i][1]) * self.width,
5 + (self.head_square[0] + self.new_square[i][0] + 1) * self.width,
5 + (self.head_square[1] + 1 + self.new_square[i][1]) * self.width, fill=color,
tags="new")
"=== Model Part ==="
def initial(self):
# 初始化
self.scores = 0
self.all_square = {} # 坐标系网格中个位置方块的存在性
self.head_square = [] # 参考方块绝对位置
self.new_square = [] # 移动方块相对位置
self.direction = -1 # 方块初始方向
# 规定界限
# i表示第i列,0在左边
# j表示第j行,零在上面
for j in range(-4, self.row):
for i in range(self.column):
self.all_square[i, j] = 0
# 划界,开口向上
for j in range(self.row + 1):
self.all_square[19, j] = 1
self.all_square[-1, j] = 1
for i in range(-1, self.column + 1):
self.all_square[i, 28] = 1
def is_dead(self):
# 判断死亡与否,最上方中间四个方块
for i in {8, 9, 10, 11}:
if self.all_square[i, 0]:
return True
else:
return False
def get_new_square(self):
# 获得新的方块,初始位置均为(9,-2)
self.new = random.randrange(1, 8) # 随机方块
# 主方块(参考方块)的位置
self.direction = random.randrange(4)
self.head_square = [9, -2]
self.new_square = list(shapedic[self.new])
for i in range(self.direction):
self.change()
def delete_one_line(self, j):
# 得分后删除整行
for t in range(j, 2, -1):
for i in range(self.column):
self.all_square[i, t] = self.all_square[i, t - 1]
for i in range(self.column):
self.all_square[i, 0] = 0
def get_score(self):
for j in range(self.row):
for i in range(self.column):
# 判断某行是否全满
if not self.all_square[i, j]:
break
else:
self.scores += 10
self.delete_one_line(j)
# 移动方块停止
def get_seated(self):
self.all_square[tuple(self.head_square)] = 1
for i in range(4):
self.all_square[self.head_square[0] + self.new_square[i][0],
self.head_square[1] + self.new_square[i][1]] = 1
# 方块是否到了最底端
def is_seated(self):
for i in range(4):
if self.all_square[self.head_square[0] + self.new_square[i][0],
self.head_square[1] + self.new_square[i][1] + 1]:
return True
return False
"=== Control Part ==="
# 改变方块朝向
# 通过旋转改变,主方块不动
def change(self):
if self.new > 1:
for i in range(4):
if self.all_square[self.head_square[0] + change_dic[self.new_square[i]][0], self.head_square[1] +
change_dic[self.new_square[i]][1]]:
return
else:
for i in range(4):
self.new_square[i] = change_dic[self.new_square[i]]
else:
return
# 右移
def right_move(self):
# 先判断是否可以移动
for i in range(4):
if self.all_square[self.head_square[0] + self.new_square[i][0] - 1,
self.head_square[1] + self.new_square[i][1]]:
return True
self.head_square[0] -= 1
# 左移
def left_move(self):
for i in range(4):
if self.all_square[self.head_square[0] + self.new_square[i][0] + 1,
self.head_square[1] + self.new_square[i][1]]:
return True
self.head_square[0] += 1
# 向下加速
def down_quicker(self):
while (not self.is_seated()):
self.draw_new_square()
self.canvas.after(50)
self.canvas.update()
# 方向键控制
def move(self, event):
if event.keycode == 39:
self.left_move()
elif event.keycode == 38:
self.change()
elif event.keycode == 37:
self.right_move()
elif event.keycode == 40:
self.down_quicker()
else:
pass
# 开始游戏
def play(self):
self.canvas.bind('', self.move)
self.canvas.focus_set()
while True:
if self.is_dead():
self.gameover()
break
if self.is_seated():
self.get_seated()
self.get_new_square()
self.draw_score()
self.draw_square()
self.draw_new_square()
else:
self.draw_new_square()
self.canvas.after(500)
self.canvas.update()
# 游戏结束
def gameover(self):
if askquestion("LOSE", u"你输了!\n重新开始吗?") == 'yes':
return self.restart()
else:
return self.window.destroy()
# 重新开始
def restart(self):
self.initial()
self.draw_square()
self.get_new_square()
self.draw_new_square()
self.play()
# 主程序
if __name__ == "__main__":
Game_Russia()