欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python俄罗斯方块课程设计(教你python如何写俄罗斯方块)

程序员文章站 2024-03-27 14:35:16
环境python3.7,pyqt5,pyinstaller进行打包成exe文件。效果代码import sys, randomfrom pyqt5.qtwidgets import qmainwindo...

环境

python3.7,pyqt5,pyinstaller进行打包成exe文件。

效果

python俄罗斯方块课程设计(教你python如何写俄罗斯方块)
python俄罗斯方块课程设计(教你python如何写俄罗斯方块)
python俄罗斯方块课程设计(教你python如何写俄罗斯方块)

代码

import sys, random
from pyqt5.qtwidgets import qmainwindow, qframe, qdesktopwidget, qapplication
from pyqt5.qtcore import qt, qbasictimer, pyqtsignal
from pyqt5.qtgui import qpainter, qcolor

class tetris(qmainwindow):
    def __init__(self):
        super().__init__()

        self.initui()

    def initui(self):
        self.tboard = board(self)
        self.setcentralwidget(self.tboard)

        self.statusbar = self.statusbar()
        self.tboard.msg2statusbar[str].connect(self.statusbar.showmessage)

        self.tboard.start()

        self.resize(180, 380)
        self.center()
        self.setwindowtitle('tetris')
        self.show()

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


class board(qframe):
    msg2statusbar = 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
        self.clearboard()

    def shapeat(self, x, y):
        return self.board[(y * board.boardwidth) + x]

    def setshapeat(self, x, y, shape):
        self.board[(y * board.boardwidth) + x] = shape

    def squarewidth(self):
        return self.contentsrect().width() // board.boardwidth

    def squareheight(self):
        return self.contentsrect().height() // board.boardheight

    def start(self):

        if self.ispaused:
            return

        self.isstarted = true
        self.iswaitingafterline = false
        self.numlinesremoved = 0
        self.clearboard()

        self.msg2statusbar.emit(str(self.numlinesremoved))

        self.newpiece()
        self.timer.start(board.speed, self)

    def pause(self):

        if not self.isstarted:
            return

        self.ispaused = not self.ispaused

        if self.ispaused:
            self.timer.stop()
            self.msg2statusbar.emit("paused")

        else:
            self.timer.start(board.speed, self)
            self.msg2statusbar.emit(str(self.numlinesremoved))

        self.update()

    def paintevent(self, event):

        painter = qpainter(self)
        rect = self.contentsrect()

        boardtop = rect.bottom() - board.boardheight * self.squareheight()

        for i in range(board.boardheight):
            for j in range(board.boardwidth):
                shape = self.shapeat(j, board.boardheight - i - 1)

                if shape != tetrominoe.noshape:
                    self.drawsquare(painter,
                                    rect.left() + j * self.squarewidth(),
                                    boardtop + i * self.squareheight(), shape)

        if self.curpiece.shape() != tetrominoe.noshape:

            for i in range(4):
                x = self.curx + self.curpiece.x(i)
                y = self.cury - self.curpiece.y(i)
                self.drawsquare(painter, rect.left() + x * self.squarewidth(),
                                boardtop + (board.boardheight - y - 1) * self.squareheight(),
                                self.curpiece.shape())

    def keypressevent(self, event):

        if not self.isstarted or self.curpiece.shape() == tetrominoe.noshape:
            super(board, 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(board, self).keypressevent(event)

    def timerevent(self, event):

        if event.timerid() == self.timer.timerid():

            if self.iswaitingafterline:
                self.iswaitingafterline = false
                self.newpiece()
            else:
                self.onelinedown()

        else:
            super(board, self).timerevent(event)

    def clearboard(self):

        for i in range(board.boardheight * board.boardwidth):
            self.board.append(tetrominoe.noshape)

    def dropdown(self):

        newy = self.cury

        while newy > 0:

            if not self.trymove(self.curpiece, self.curx, newy - 1):
                break

            newy -= 1

        self.piecedropped()

    def onelinedown(self):

        if not self.trymove(self.curpiece, self.curx, self.cury - 1):
            self.piecedropped()

    def piecedropped(self):

        for i in range(4):
            x = self.curx + self.curpiece.x(i)
            y = self.cury - self.curpiece.y(i)
            self.setshapeat(x, y, self.curpiece.shape())

        self.removefulllines()

        if not self.iswaitingafterline:
            self.newpiece()

    def removefulllines(self):

        numfulllines = 0
        rowstoremove = []

        for i in range(board.boardheight):

            n = 0
            for j in range(board.boardwidth):
                if not self.shapeat(j, i) == tetrominoe.noshape:
                    n = n + 1

            if n == 10:
                rowstoremove.append(i)

        rowstoremove.reverse()

        for m in rowstoremove:

            for k in range(m, board.boardheight):
                for l in range(board.boardwidth):
                    self.setshapeat(l, k, self.shapeat(l, k + 1))

        numfulllines = numfulllines + len(rowstoremove)

        if numfulllines > 0:
            self.numlinesremoved = self.numlinesremoved + numfulllines
            self.msg2statusbar.emit(str(self.numlinesremoved))

            self.iswaitingafterline = true
            self.curpiece.setshape(tetrominoe.noshape)
            self.update()

    def newpiece(self):

        self.curpiece = shape()
        self.curpiece.setrandomshape()
        self.curx = board.boardwidth // 2 + 1
        self.cury = board.boardheight - 1 + self.curpiece.miny()

        if not self.trymove(self.curpiece, self.curx, self.cury):
            self.curpiece.setshape(tetrominoe.noshape)
            self.timer.stop()
            self.isstarted = false
            self.msg2statusbar.emit("game over")

    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 >= board.boardwidth or y < 0 or y >= board.boardheight:
                return false

            if self.shapeat(x, y) != tetrominoe.noshape:
                return false

        self.curpiece = newpiece
        self.curx = newx
        self.cury = newy
        self.update()

        return true

    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)


class tetrominoe(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 = tetrominoe.noshape

        self.setshape(tetrominoe.noshape)

    def shape(self):
        return self.pieceshape

    def setshape(self, shape):

        table = shape.coordstable[shape]

        for i in range(4):
            for j in range(2):
                self.coords[i][j] = table[i][j]

        self.pieceshape = shape

    def setrandomshape(self):
        self.setshape(random.randint(1, 7))

    def x(self, index):
        return self.coords[index][0]

    def y(self, index):
        return self.coords[index][1]

    def setx(self, index, x):
        self.coords[index][0] = x

    def sety(self, index, y):
        self.coords[index][1] = y

    def minx(self):

        m = self.coords[0][0]
        for i in range(4):
            m = min(m, self.coords[i][0])

        return m

    def maxx(self):

        m = self.coords[0][0]
        for i in range(4):
            m = max(m, self.coords[i][0])

        return m

    def miny(self):

        m = self.coords[0][1]
        for i in range(4):
            m = min(m, self.coords[i][1])

        return m

    def maxy(self):

        m = self.coords[0][1]
        for i in range(4):
            m = max(m, self.coords[i][1])

        return m

    def rotateleft(self):

        if self.pieceshape == tetrominoe.squareshape:
            return self

        result = shape()
        result.pieceshape = self.pieceshape

        for i in range(4):
            result.setx(i, self.y(i))
            result.sety(i, -self.x(i))

        return result

    def rotateright(self):

        if self.pieceshape == tetrominoe.squareshape:
            return self

        result = shape()
        result.pieceshape = self.pieceshape

        for i in range(4):
            result.setx(i, -self.y(i))
            result.sety(i, self.x(i))

        return result


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