用Python實現童年的回憶:俄羅斯方塊!別說還挺好玩

在那個電子產品比較匱乏的年代,小遊戲機html


仍是爲數很少的遊戲類電子產品,對小孩子更是有着不可抗拒的魔力,在當時若是哪一個小孩買了一個小遊戲機,大夥必定迅速圍上去...網絡

俄羅斯方塊做爲其中一款小遊戲,儘管規則簡單、只有黑白雙色,但其對當時遊戲玩家的影響絲絕不亞於 LOL、農藥、吃雞對如今遊戲玩家的影響,下面咱們來看一下如何用 Python 實現俄羅斯方塊這款小遊戲。app

規則

由小方塊組成的不一樣形狀的板塊陸續從屏幕上方落下來,玩家經過調整板塊的位置和方向,使它們在屏幕底部拼出完整的一條或幾條。這些完整的橫條會隨即消失,給新落下來的板塊騰出空間,與此同時,玩家獲得分數獎勵。沒有被消除掉的方塊不斷堆積起來,一旦堆到屏幕頂端,玩家便告輸,遊戲結束。 --- 百度百科dom

環境

  • 操做系統:Windows
  • Python 版本:3.6
  • 涉及模塊:sys、random、PyQt5

實現

首先安裝第三方模塊 PyQt5,使用 pip install PyQt5 便可。學習

➢ 遊戲主界面url

實現代碼spa

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
class MainBoard(QFrame):
    msg = pyqtSignal(str)
    BoardWidth = 10
    BoardHeight = 22
    Speed = 300
    def __init__(self, parent):
        super().__init__(parent)
        self.initBoard()
    def initBoard(self):
        self.timer = QBasicTimer()
        self.isWaitingAfterLine = False
        self.curX = 0
        self.curY = 0
        self.numLinesRemoved = 0
        self.board = []
        self.setFocusPolicy(Qt.StrongFocus)
        self.isStarted = False
        self.isPaused = False

效果圖以下操作系統

➢ 小板塊插件

定義小版塊的形狀3d

class ShapeForm(object):
    NoShape = 0
    ZShape = 1
    SShape = 2
    LineShape = 3
    TShape = 4
    SquareShape = 5
    LShape = 6
    MirroredLShape = 7

class Shape(object):
    coordsTable = (
        ((0, 0),     (0, 0),     (0, 0),     (0, 0)),
        ((0, -1),    (0, 0),     (-1, 0),    (-1, 1)),
        ((0, -1),    (0, 0),     (1, 0),     (1, 1)),
        ((0, -1),    (0, 0),     (0, 1),     (0, 2)),
        ((-1, 0),    (0, 0),     (1, 0),     (0, 1)),
        ((0, 0),     (1, 0),     (0, 1),     (1, 1)),
        ((-1, -1),   (0, -1),    (0, 0),     (0, 1)),
        ((1, -1),    (0, -1),    (0, 0),     (0, 1))
    )

    def __init__(self):
        self.coords = [[0,0] for i in range(4)]
        self.pieceShape = ShapeForm.NoShape
        self.setShape(ShapeForm.NoShape)

畫出圖形

def drawSquare(self, painter, x, y, shape):
    colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
                  0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00]
    color = QColor(colorTable[shape])
    painter.fillRect(x + 1, y + 1, self.squareWidth() - 2,
        self.squareHeight() - 2, color)
    painter.setPen(color.lighter())
    painter.drawLine(x, y + self.squareHeight() - 1, x, y)
    painter.drawLine(x, y, x + self.squareWidth() - 1, y)
    painter.setPen(color.darker())
    painter.drawLine(x + 1, y + self.squareHeight() - 1,
        x + self.squareWidth() - 1, y + self.squareHeight() - 1)
    painter.drawLine(x + self.squareWidth() - 1,
        y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)

效果圖以下

➢ 按鍵事件

def keyPressEvent(self, event):
        if not self.isStarted or self.curPiece.shape() == ShapeForm.NoShape:
            super(MainBoard, self).keyPressEvent(event)
            return
        key = event.key()
        if key == Qt.Key_P:
            self.pause()
            return
        if self.isPaused:
            return
        elif key == Qt.Key_Left:
            self.tryMove(self.curPiece, self.curX - 1, self.curY)
        elif key == Qt.Key_Right:
            self.tryMove(self.curPiece, self.curX + 1, self.curY)
        elif key == Qt.Key_Down:
            self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY)
        elif key == Qt.Key_Up:
            self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY)
        elif key == Qt.Key_Space:
            self.dropDown()
        elif key == Qt.Key_D:
            self.oneLineDown()
        else:
            super(MainBoard, self).keyPressEvent(event)

    def tryMove(self, newPiece, newX, newY):
        for i in range(4):
            x = newX + newPiece.x(i)
            y = newY - newPiece.y(i)
            if x < 0 or x >= MainBoard.BoardWidth or y < 0 or y >= MainBoard.BoardHeight:
                return False
            if self.shapeAt(x, y) != ShapeForm.NoShape:
                return False
        self.curPiece = newPiece
        self.curX = newX
        self.curY = newY
        self.update()
        return True

➢ 計時器事件

def timerEvent(self, event):
    if event.timerId() == self.timer.timerId():
        if self.isWaitingAfterLine:
            self.isWaitingAfterLine = False
            self.newPiece()
        else:
            self.oneLineDown()
    else:
        super(MainBoard, self).timerEvent(event)

➢ 開始和暫停

def start(self):
        if self.isPaused:
            return
        self.isStarted = True
        self.isWaitingAfterLine = False
        self.numLinesRemoved = 0
        self.clearBoard()
        self.msg.emit(str(self.numLinesRemoved))
        self.newPiece()
        self.timer.start(MainBoard.Speed, self)

    def pause(self):
        if not self.isStarted:
            return
        self.isPaused = not self.isPaused
        if self.isPaused:
            self.timer.stop()
            self.msg.emit("paused")
        else:
            self.timer.start(MainBoard.Speed, self)
            self.msg.emit(str(self.numLinesRemoved))
        self.update()

➢ 遊戲類及初始化

class Tetris(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.tboard = MainBoard(self)
        self.setCentralWidget(self.tboard)
        self.statusbar = self.statusBar()
        self.tboard.msg[str].connect(self.statusbar.showMessage)
        self.tboard.start()
        self.resize(300, 500)
        self.center()
        self.setWindowTitle('俄羅斯方塊')
        self.show()

    def center(self):
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2,
            (screen.height()-size.height())/2)

啓動

if __name__ == '__main__':
    app = QApplication([])
    tetris = Tetris()
    sys.exit(app.exec_())

最終效果

打包

爲了方便運行,咱們將 Python 文件打成 exe 文件,用到的插件爲 pyinstaller。

首先,安裝 pyinstaller,使用 pip install pyinstaller 便可。 安裝完成後,在文件目錄

打開命令窗口,在命令窗口執行命令 pyinstaller --onefile --nowindowed --icon="C:\Users\LE\Desktop\tetris\tetris.ico" tetris.py 便可。執行完成後,咱們到 dist 目錄下


便可找到生成的 exe 文件。

本文的文字及圖片來源於網絡,僅供學習、交流使用,不具備任何商業用途,若有問題請及時聯繫咱們以做處理想要獲取更多Python學習資料能夠加QQ:2955637827私聊或加Q羣630390733你們一塊兒來學習討論吧!

相關文章
相關標籤/搜索