用Python实现童年的回忆:俄罗斯方块!别说还挺好玩
在那个电子产品比较匮乏的年代,小游戏机
还是为数不多的游戏类电子产品,对小孩子更是有着不可抗拒的魔力,在当时如果哪个小孩买了一个小游戏机,大伙一定迅速围上去...
俄罗斯方块作为其中一款小游戏,尽管规则简单、只有黑白双色,但其对当时游戏玩家的影响丝毫不亚于 LOL、农药、吃鸡对现在游戏玩家的影响,下面我们来看一下如何用 Python 实现俄罗斯方块这款小游戏。
规则
由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。 --- 百度百科
环境
- 操作系统:Windows
- Python 版本:3.6
- 涉及模块:sys、random、PyQt5
实现
首先安装第三方模块 PyQt5,使用 pip install PyQt5
即可。
➢ 游戏主界面
实现代码
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
效果图如下
➢ 小板块
定义小版块的形状
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大家一起来学习讨论吧!
用Python实现童年的回忆:俄罗斯方块!别说还挺好玩的更多相关文章
- 用Python实现童年小游戏贪吃蛇
贪吃蛇作为一款经典小游戏,早在 1976 年就面世了,我最早接触它还是在家长的诺基亚手机中.
- Python 之父撰文回忆:为什么要创造 pgen 解析器?
花下猫语: 近日,Python 之父在 Medium 上开通了博客,并发布了一篇关于 PEG 解析器的文章(参见我翻的 全文译文).据我所知,他有自己的博客,为什么还会跑去 Medium 上写文呢?好 ...
- 用Python实现童年的21款小游戏,有你玩过的吗?(不要错过哦)
Python为什么能这么火热,Python相对于其他语言来说比较简单,即使是零基础的普通人也能很快的掌握,在其他方面比如,处于灰色界的爬虫,要VIP的视频,小说,歌,没有爬虫解决不了的:数据挖掘及分析 ...
- 吴裕雄--天生自然python学习笔记:python 用pygame模块开发俄罗斯方块游戏
俄罗斯方块游戏 多年前,游戏机中最流行的游戏就是“俄罗斯方块”了.时至今日,虽然网络 游戏日新月异 ,但“俄罗斯方块”这款小游戏仍在许多人心中 占有一席之地.本例中, 我们将亲手设计一个简单的俄罗斯方 ...
- POJ 3348 Cows | 凸包——童年的回忆(误)
想当年--还是邱神给我讲的凸包来着-- #include <cstdio> #include <cstring> #include <cmath> #include ...
- HTML5 canvas制作童年的回忆大风车
今天看到一篇CSS3写的大风车http://www.cnblogs.com/yaojaa/archive/2013/01/30/2882521.html,感觉CSS3太神奇了,这在以前用CSS是想都不 ...
- 如果Python对于磁盘没有写入权限,还会运行吗?
Python如果对于磁盘没有写入权限,那么编译成功的字节码文件就只会存储在内存当中,而不会写入到磁盘,每次运行Python都会重新编译,然后运行.
- python的全局变量玩法还挺特别的
global g_arr def add(): #global g_arr g_arr = [] g_arr.append(1) add() print g_arr #你将收获一个NameError错 ...
- python蟒蛇绘制的代码以及目前还不知道怎么用的RGB颜色对照表
#PythonDraw.py import turtle#引入海龟库 turtle.setup(650,350,200,200)#确定窗口大小,长650,高350,确定窗口位置,距离电脑左上角200, ...
随机推荐
- api-hook,更轻量的接口测试工具
前言 在网站的开发过程中,接口联调和测试是至关重要的一环,其直接影响产品的核心价值,而目前也有许多技术方案和工具加持,让我们的开发测试工作更加便捷.接口作为数据传输的重要载体,数据格式和内容具有多样性 ...
- Spring简介以及配置信息
Spring框架是一种轻量级的.一站式的企业级开发解决方案 框架(framework):是一组设计思想.规范.API的精心组合,专门用来解决某一层次或领域的问题 轻量级(lightweight): ...
- yii2.0 关于 ActiveForm 中 checkboxList 的使用
在视图中创建复选框,列出复选框内的内容其中$id 为 列出在复选框中的数组 //$ids:所有要显示的checkbox(Array)<?=$form->field($model, 'id' ...
- IB卡开启EIPOIB做虚拟化桥接使用
步骤1:开启EiPOIB 编辑默认"no"为"yes" /etc/infiniband/openib.conf E_IPOIB_LOAD=yes 步骤2:重启h ...
- Apache Beam,批处理和流式处理的融合!
1. 概述 在本教程中,我们将介绍 Apache Beam 并探讨其基本概念. 我们将首先演示使用 Apache Beam 的用例和好处,然后介绍基本概念和术语.之后,我们将通过一个简单的例子来说明 ...
- CentOS创建管理LVM分区(挂载新分区)
来源: CentOS 8.0 创建管理LVM分区(挂载新分区) https://www.iwmyx.cn/centos80cjgllvmfa.html 1.查看可用磁盘 fdisk -l 2.新盘(/ ...
- C#数据结构-二叉树-顺序存储结构
什么是二叉树:每个树的节点只有两个子树的树形结构. 为什么使用顺序存储结构:使用数组存放满二叉树的各结点非常方便,可以根据一个结点的索引号很容易地推算出它的双亲.孩子.兄弟等结点的编号,从而对这些结点 ...
- 第15.47节、PyQt显示部件:QGraphicsView图形视图和QGraphicsScene图形场景简介及应用案例
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 Designer中的Graphics V ...
- Python中import模块时报SyntaxError: (unicode error)utf-8 codec can not decode 错误的解决办法
老猿有个通过UE编辑(其他文本编辑器一样有类似问题)的bmi.py文件,在Python Idle环境打开文件执行时没有问题,但import时报错: SyntaxError: (unicode erro ...
- Python类知识学习时的部分问题
Python的富比较方法__eq__和__ne__之间的关联关系分析 Python的富比较方法__le__.ge__之间的关联关系分析 Python的富比较方法__lt.__gt__之间的关联关系分析 ...