本文主要是介绍不稳定版的python俄罗斯方块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
基于Python2.7,Linux下运行异常
有普通俄罗斯方块的功能以及历史最高分、暂停、重玩功能
本来是在另一台电脑上的,那台电脑不能连接u盘,故本版本是对着稳定版的代码抄的,可能哪里抄错了一些,所以存在bug.
# coding=utf-8
from Tkinter import *
from random import *
try:import cPickle as pickle
except ImportError:import pickle
import threading
from time import sleep
import os#幕布类
class Curtain(object):def __init__(self, canvas):self.row = 20self.col = 10self.back = list()self.gridBack = list()for i in range(0, self.row):self.back.insert(i, list())self.gridBack.insert(i, list())for i in range(0, self.row):for j in range(0,self.col):self.back[i].insert(j, 0)self.gridBack[i].insert(j, canvas.create_rectangle(30 * j, 30 * i, 30 * (j+1), 30 * (i+1)))#方块类
class Brick(object):def __init__(self):self.speed = 1 #下落速度self.shape = 0self.curRow = 0self.curCol = 0self.down = False#生成一个新方块def getNewBrick(self, brickConfig):self.curBrickNum = randint(0, len(brickConfig)-1)self.shape = 0self.currBrick = brickConfig[self.curBrickNum][self.shape]self.curCol = 0self.curRow = 0self.down = False'''工具类:1.读写配置文件的形状、分数历史记录信息2.控制程序暂停、继续、重玩3.判断方块是否抵达边界4.检测方块生成位置上是否有被占用的格子
'''
class Tool(object):def __init__(self):self.curr_dir = os.path.dirname(os.path.realpath(__file__)) #取得当前目录的路径self.ifPause = Falseself.ifRestart = False#暂停def pause(self):self.ifPause = True#继续def continu(self):self.ifPause = False#重玩def restart(self):self.ifRestart = True#判断是否抵达边界,左移则aspect传1,右移传3,下移传4def checkIfArriveBorder(self, aspect, brick, back):flag = Trueif aspect == 4: #下,没到下界返回Truefor i in range(0, 3):for j in range(0, 3):if brick.currBrick[i][j] != 0 and (brick.curRow + i >= back.row or back.back[brick.curRow + i][brick.curCol + j] !=0):flag = Falsebrick.down = Truebreakelif aspect == 3: #右for i in range(0, 3):for j in range(0, 3):if brick.currBrick[j][i] != 0 and (brick.curCol + i >= back.col or back.back[brick.curRow + i][brick.curCol + j] !=0):flag = Falsebreakelif aspect == 2: #上,判断变形操作是否会越界if brick.curCol < 0:brick.curCol = 0if brick.curCol + 2 >= back.col:brick.curCol = back.col - 3if brick.curRow + 2 >= back.row:brick.curRow = brick.curRow - 3elif aspect == 1:for i in range(0, 3):for j in range(0, 3):if brick.currBrick[i][j] != 0 and(brick.curCol + i < 0 or back.back[brick.curRow + j][brick.curCol + i] != 0):flag = Falsebreakelse:print '未知错误,aspect值=',aspect#从文件中读取历史最高分def getMaxGrade(self):f = open(self.curr_dir + '/grade.txt', 'rb')grade = pickle.load(f) # 反序列化历史最高分的信息f.close()return grade#向文件中写入新的历史最高分def updateHistoryGradeMax(self, newMax):f = open(self.curr_dir + '/grade.txt', 'wb')f.seek(0)f.truncate()pickle.dump(newMax, f)f.close()#从配置文件中读取方块的形状并返回读取的值def getBrickFromConfig(self):_configFile = open(self.curr_dir + '/config.txt', 'rb')brick = pickle.load(_configFile)_configFile.close()return brick#检测方块生成位置上是否有被占用的格子,有则返回True,并检查顶层格子是否有方块,有则游戏结束def checkIfBeenUse(self, back, brick):flag = Falsefor i in range(0,3):for j in range(0,3):if back.back[i][j] == 1 and brick.currBrick[i][j] == 1:flag = Truebreakif flag:breakfor i in range(0, back.col):if back.back[0][i] == 1:flag = Truebreakreturn flag
class Main(object):#实例化类和图形相关的组件def _init__(self):self.start = Trueself.tool = Tool()self.root = Tk()self.HistoryScorceMax = self.tool.getMaxGrade()self.currGrade = 0self.brickConfig = self.tool.getBrickFromConfig()self.ifRestart = Falseself.root.title = ('俄罗斯方块v0.1')self.root.minsize(400, 600)self.frame = Frame(self.root, width=400, height = 600)self.frame.place(x=0, y=0)self.label = Label(self.root,text='历史最高分')self.historyGradeLabel = Label(self.root,text=self.HistoryScorceMax) #显示历史最高分self.label1 = Label(self.root,text='当前分数')self.gameInfo = Label(self.root,text='游戏开始',fg='red',font=('times',12,'bold'))self.currentGradeLabel = Label(self.root, text=self.currGrade)self.button1 = Button(text='暂停', command=self.tool.pause)self.button2 = Button(text='继续', command=self.tool.continu)self.button3 = Button(text='重玩', command=self.tool.restart)self.canvas = Canvas(self.frame, width=300, heigh=600)self.button1.place(x=350, y=0)self.button2.place(x=350, y=40)self.button3.place(x=350, y=80)self.label.place(x=304, y=120)self.historyGradeLabel.place(x=369, y=120)self.currentGradeLabel.place(x=357, y=160)self.gameInfo.place(x=304, y=200)self.label1.place(x=304, y=160)self.back = Curtain(self.canvas)self.brick = Brick()self.canvas.pack()#清屏并重新开始def cleanAndRestart(self):for i in range(0, self.back.row): #重置位置信息和颜色for j in range(0, self.back.col):self.back.back[i][j] = 0self.canvas.itemconfig(self.back.gridBack[i][j],fill="white")self.brick.getNewBrick(self.brickConfig) #重置方块self.currGrade = 0 #重置分数self.currentGradeLabel.config(text=self.currGrade)self.tool.ifRestart = Falseself.gameInfo.config(text="游戏开始")#更新当前分数并对比历史最高分,若超过历史最高分刷新历史最高分并写入文件存储def updateAndCheckGrade(self):self.currGrade += 1self.currentGradeLabel.config(text=self.currGrade)if self.currGrade > self.HistoryScorceMax:self.HistoryScorceMax = self.currGradeself.historyGradeLabel.config(text=self.HistoryScorceMax)self.tool.updateHistoryGradeMax(self.HistoryScorceMax)#检查是否有需要消除的行def checkIfNeedRemove(self):for i in range(0, self.back.row):tag1 = Truefor j in range(0, self.back.col):if self.back.back[i][j] == 0:tag1 = Falsebreakif tag1 == True:self.updateAndCheckGrade()for m in xrange(i - 1, 0, -1):for n in range(0, self.back.col):self.back.back[m+1][n] = self.back.back[m][n]#更新back表中的位置信息def updateBackInfo(self):for i in range(0, self.back.row):for j in range(0, self.back.col):if self.back.back[i][j] == 1:self.canvas.itemconfig(self.back.gridBack[i][j], fill="red")elif self.back.back[i][j] == 0:self.canvas.itemconfig(self.back.gridBack[i][j], fill="white")for i in range(0, len(self.brick.currBrick)):for j in range(0, len(self.brick.currBrick[i])):if self.brick.currBrick[i][j] == 1:self.canvas.itemconfig(self.back.gridBack[self.brick.curRow+i][self.brick.curCol+j], fill="red")#判断方块是否已经运动到达底部if self.brick.down:for i in range(0, len(self.brick.currBrick)):for j in range(0, len(self.brick.currBrick[i])):if self.brick.currBrick[i][j] != 0:self.back.back[self.brick.curRow+i][self.brick.curCol+j] = self.brick.currBrick[i][j]#检查整行是否需要消除self.checkIfNeedRemove()#获得下一个方块self.brick.getNewBrick(self.brickConfig)#处理键盘事件def onKeyBoardEvent(self, event):#未开始,不必监听键盘输入if self.start == False:returnif self.tool.ifPause: #暂停时不监听键盘操作return#记录原来的值midCurCol = self.brick.curColmidCurRow = self.brick.curRowmidShape = self.brick.shapedirection = 0midBrick = self.brick.currBrickif event.keycode == 37:# 左移self.brick.curCol -= 1direction = 1elif event.keycode == 38:# 变化方块的形状self.brick.shape += 1direction = 2if self.brick.shape >= 4:self.brick.shape = 0self.brick.currBrick = self.brickConfig[self.brick.curBrickNum][self.brick.shape]elif event.keycode == 39:direction = 3# 右移self.brick.curCol += 1elif event.keycode == 40:direction = 4# 下移self.brick.curRow += 1if self.tool.checkIfArriveBorder(direction,self.brick,self.back):self.brick.curCol = midCurColself.brick.curRow = midCurRowself.brick.shape = midShapeself.brick.currBrick = midBrickself.updateBackInfo()return True#方块向下移动的线程run方法def brickDown(self):while True:if self.start == False:print("线程退出")break;if self.tool.ifRestart:print '开始重玩'self.cleanAndRestart()while self.tool.ifPause:if self.tool.ifRestart:self.cleanAndRestart() #暂停时点击重玩按钮,进入重玩流程self.tool.ifPause = Falsebreakif self.tool.checkIfBeenUse(self.back,self.brick):print('格子被占用,游戏结束')self.gameInfo.config(text="游戏结束")while True:if self.tool.ifRestart:self.cleanAndRestart()self.tool.ifPause = Falsebreakelse:tempRow = self.brick.curRowself.brick.curRow += 1if self.tool.checkIfArriveBorder(4, self.brick, self.back) == False:self.brick.curRow = tempRowself.updateBackInfo()sleep(self.brick.speed)def __init__(self):self._init__()self.brick.getNewBrick(self.brickConfig)self.downThread = threading.Thread(target=self.brickDown, args=())self.downThread.start()#监听键盘事件self.root.bind("<KeyPress>", self.onKeyBoardEvent)self.root.mainloop()self.start = False
main = Main()
这篇关于不稳定版的python俄罗斯方块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!