Python PyQt5俄羅斯方塊
源代碼:https://github.com/limingnihao/tetris/tree/master/python
使用python做一個簡單的游戲糙箍,感覺可以練習(xí)一下基本語法蝶溶。下面介紹一下如何使用Python PtQt5制作一個俄羅斯方塊丛晌。
先設(shè)計一下基本的流程,分別介紹每個流程所需要開發(fā)的代碼:
開始
設(shè)置一個定時任務(wù)携丁,循環(huán)畫背景,當(dāng)前方塊、下一個方塊佛吓。
生產(chǎn)出當(dāng)前方塊和下一個方塊。
使用QBasicTimer開啟一個timer垂攘,設(shè)置時間間隔维雇,則會根據(jù)時間間隔回調(diào)timerEvent
方法。
self.timer = QBasicTimer()
self.timer.start(1000, self)
def timerEvent(self, event):
if event.timerId() == self.timer.timerId():
self.downHandler()
else:
super(QWidget, self).timerEvent(event)
方塊生產(chǎn)
首先我們要定義方塊和背景的構(gòu)建晒他。
背景:采用二維數(shù)組的方式構(gòu)建背景吱型,有方塊的地方則為非0,沒有方塊的地方則為0陨仅,然后循環(huán)這個二維數(shù)組進畫圖津滞。
方塊:采用一個四維數(shù)組7 * 4 * 4 * 4铝侵,第一維是7個形狀(長條形狀、方塊形狀)触徐,第二維是每個形狀有4個方向咪鲜,三四維度一起看做一個4*4的二維數(shù)組,存儲方塊的具體數(shù)據(jù)撞鹉。有方塊的地方則為非0疟丙,沒有方塊的地方則為0,然后循環(huán)這個二維數(shù)組可以畫出形狀鸟雏。
鍵盤監(jiān)聽
監(jiān)聽鍵盤的上下左右
def keyPressEvent(self, event):
key = event.key()
if key == Qt.Key_Left:
self.leftHandler()
elif key == Qt.Key_Right:
self.rightHandler()
elif key == Qt.Key_Down:
self.downHandler()
elif key == Qt.Key_Up:
self.upHandler()
elif key == Qt.Key_P:
self.startHandler()
elif key == Qt.Key_Space:
self.downoverHandler()
判斷是否可以移動
當(dāng)進行左右移動隆敢,或變形時,需要判斷是否可以移動崔慧,主要是根據(jù)背景的是否有非0的數(shù)據(jù)而不能進行操作拂蝎。需要結(jié)合背景當(dāng)前的數(shù)據(jù)、當(dāng)前形狀的坐標(biāo)和數(shù)據(jù)進行判斷惶室。
- 判斷x軸數(shù)據(jù)是否越界温自。
- 判斷y軸數(shù)據(jù)是否越界。
- 判斷方塊數(shù)據(jù)是否和背景數(shù)據(jù)發(fā)生重合皇钞。
def isChange(self, shapeData, x, y):
for i in range(0, len(shapeData)):
for j in range(0, len(shapeData[i])):
if(shapeData[i][j] == 1):
if (x + j) < 0 :
return False
if (x + j) >= self.width:
return False
if (y + i) >= self.height:
return False
if(self.data[y + i][x + j] > 0):
return False
return True
落地處理
當(dāng)不能在移動的時候悼泌,說明方塊需要落地,主要處理削行夹界、和產(chǎn)生下一個方塊馆里。
消除行,循環(huán)背景數(shù)據(jù)可柿,當(dāng)發(fā)現(xiàn)數(shù)組有一行數(shù)據(jù)全為非0鸠踪,則需要將上面的數(shù)據(jù)copy過來:
def scoreShape(self):
total = 0
for i in range(0, len(self.data)):
count = 0
for j in range(0, len(self.data[i])):
if self.data[i][j] > 0 :
count += 1
if count == len(self.data[i]):
total += 1
for k in range(i, 1, -1):
self.data[k] = self.data[k - 1]
return total
產(chǎn)生下一個方塊,如果需要展示下一個方塊复斥,則copy數(shù)據(jù)即可营密。
def productShape(self):
if self.nextShape:
self.currentShape = self.factory.next(self.nextShape.color, self.nextShape.data, self.blockSize, self.blockOffset)
else:
self.currentShape = self.factory.product(self.blockSize, self.blockOffset)
self.nextShape = self.factory.product(self.blockSize, 0)
self.nextShape.offsetX = (self.backWidth + 2) * self.blockSize
self.nextShape.offsetY = 2 * self.blockSize
self.nextShape.border = 0xaaaaaa