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文件。
效果
代码
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_())