内容正文:
项目十二 制作2048小游戏
Contents
了解游戏规则
了解设计思路
掌握游戏实现
游戏介绍
PART 01
《2048》 [1] 是一款比较流行的数字游戏,最早于2014年3月20日发行。原版2048首先在GitHub上发布,原作者是Gabriele Cirulli,后被移植到各个平台。这款游戏是基于《1024》和《小3传奇》的玩法开发而成的新型数字游戏。
2014年Gabriele Cirulli利用周末的时间写2048这个游戏的程序,仅仅只是好玩而已。他想用一种不同的视觉展现效果和更快速的动画来创造属于自己的游戏版本。
每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。不断的叠加最终拼凑出2048这个数字就算成功。
游戏背景
4
游戏规则 1
游戏开始时方格内会出现 1 个为“2” 的数字
玩家只需要 上 下 左 右 其中一个方向移动出现的数字
数字向滑动的方向靠拢
随机出现一个新的数字 “2” 或 “4”
游戏规则
5
游戏规则 2
相同的数字相撞时会叠加靠拢(例如 2 和 2 相撞靠拢会叠加为 4)
不断的叠加碰撞,最终拼凑出 2048 为成功
游戏规则
6
游戏规则 3
如果 上 下 左 右 四个方向均不可移动(棋盘填满数字)挑战失败,Game Over!
如果出现数字 2048 挑战成功, WINNER!(这里以 128 为例)
游戏规则
7
设计思路
PART 02
背景棋盘
2048 的棋盘是一个 4 * 4 的网格
网格内置数字
头部左侧添加分数统计
头部右侧添加操作指示
设计思路
9
数字矩阵 – 右移
相同数字叠加计算 (2 + 2 = 4)
出现新的数字 “2” 或 “4”
所得分数累加计算
设计思路
10
数字矩阵 – 左移
相同数字叠加计算 (2 + 2 = 4)
出现新的数字 “2” 或 “4”
所得分数累加计算
设计思路
11
数字矩阵 – 上移
相同数字叠加计算 (2 + 2 = 4)
出现新的数字 “2” 或 “4”
所得分数累加计算
设计思路
12
数字矩阵 – 下移
相同数字叠加计算 (2 + 2 = 4)
出现新的数字 “2” 或 “4”
所得分数累加计算
设计思路
13
胜利条件
当出现 2048 这个数字则游戏胜利并结束游戏, WINNER!(这里以 128 为例)
失败条件
四个方向均不可移动(棋盘填满数字),Game Over!
设计思路
14
源码分析
PART 03
Pygame最初是由Pete Shinner编写的,该项目于2000年10月启动,六个月后,pygame版本1.0发布。
pygame是一个利用SDL(Simple DirectMedia Layer)写就的游戏库。SDL 是一个用于控制多媒体的跨平台C库,与DirectX相当,它已被用于数百种商业和开源游戏。
Pete Shinner对Python和SDL两个项目的简洁与优雅印象深刻,他决定将Python和SDL结合起来,组建一个真正利用Python的项目,目标是让做简单的事情变得容易,让困难的事情变简单。
Pygame
16
加载游戏中所需的模块:这个是标准的东西
资源处理类:定义一些类来处理最基本的资源,这些资源将加载图像和声音,以及连接和断开网络,加载保存游戏文件以及用户可能拥有的任何其他资源。
游戏对象类:定义游戏对象的类。
任何其他游戏功能:定义其他必要的功能,例如记分板。
初始化游戏:包括pygame对象本身,背景,游戏对象(初始化类的实例)以及可能想要添加的任何其他一些代码。
主循环:将任何输入处理(即,观察用户按键/鼠标按钮),更新游戏对象的代码,最后更新屏幕。
游戏代码的组成部分
17
# 绘制游戏界面,第一个参数是屏幕,第二个参数颜色
# 第三个参数rect大小,第四个默认参数
def drawSurface(cls, screen, matrix, score):
# 设置游戏界面的颜色字体
pygame.draw.rect(screen, (255, 255, 255), Title_Rect)
font1 = pygame.font.SysFont('simsun', 48)
font2 = pygame.font.SysFont(None, 32)
# font.render第一个参数是文本内容,第二个参数是否抗锯齿,第三个参数字体颜色
screen.blit(font1.render('Score:', True, (255, 127, 0)), (20, 25))
screen.blit(font1.render('%s' % score, True, (255, 127, 0)), (170, 25))
screen.blit(font2.render('up', True, (255, 127, 0)), (360, 20))
screen.blit(font2.render('left down right', True, (255, 127, 0)), (300, 50))
a, b = matrix.shape
# 按照行列画方块
for i in range(a):
for j in range(b):
cls.drawBlock(screen, i, j, Block_Color[matrix[i][j]], matrix[i][j])
背景网格
源码分析
代码缩进 4个空格
正文缩进1.27厘米
18
while True:
# 定义事件
for event in pygame.event.get():
# 退出事件
if event.type == pygame.QUIT:
pygame.quit()
sys.exit(0)
#按下按键
elif event.type == pygame.KEYDOWN:
if (event.key == K_RIGHT) or (event.key == K_LEFT) or (event.key == K_UP) or (event.key == K_DOWN):
# 创建各种动作类的对象,上下左右以及其他
actionObject = GameInit.keyDownPressed(event.key, matrix)
matrix, score = actionObject.handleData() #处理数据,获得新矩阵与分数
currentscore += score
GameInit.drawSurface(screen, matrix, currentscore)
if matrix.min() != 0 or matrix.max() == 16:
GameInit.gameOver(matrix) #游戏结束
else:
pass
pygame.display.update()
按键监听
源码分析
代码缩进 4个空格
正文缩进1.27厘米
19
#左移,继承基础类的属性和方法,提供一种处理数据的方法,handleData()
class LeftAction(UpdateNew):
# 继承自父类的属性进行初始化。而且是用父类的初始化方法来初始化继承的属性。
def __init__(self, matrix):
super(LeftAction, self).__init__(matrix)
def handleData(self):
matrix = self.matrix.copy() # 获得一份矩阵的复制
newmatrix = self.toSequence(matrix)
return newmatrix, self.score
# 上移,同左移+转置
class UpAction(UpdateNew):
def __init__(self, matrix):
super(UpAction, self).__init__(matrix)
def handleData(self):
matrix = self.matrix.copy().T # 转置
newmatrix = self.toSequence(matrix)
return newmatrix.T, self.score
移动事件
源码分析
代码缩进 4个空格
正文缩进1.27厘米
20
# 去除矩阵中每一行前面与中间的0元素,获得矩阵中0元素位置
# 合并元素后返回添加一个2或4元素后的矩阵
def toSequence(self, matrix):
lastmatrix = matrix.copy()
m, n = matrix.shape # 获得矩阵的行,列
# 对于m行,去除前面和中间的0后合并
for i in range(m):
newList = self.removeZero(list(matrix[i]))
matrix[i] = newList
# 添加所有0元素的行列号
for k in range(Size - 1, Size - newList.count(0) - 1, -1): # 添加所有有0的行号列号
self.zerolist.append((i, k))
# 矩阵中有最小值0且移动后的矩阵不同,才可以添加0位置处添加随机数
if matrix.min() == 0 and (matrix != lastmatrix).any():
GameInit.initData(matrix, self.zerolist)
return matrix
数字矩阵合并
源码分析
代码缩进 4个空格
正文缩进1.27厘米
21
def gameOver(matrix):
if matrix.max() != 2048:
print('您获得了胜利,游戏结束')
return True
else:
testmatrix = matrix.copy()
a, b = testmatrix.shape
for i in range(a):
for j in range(b - 1):
if testmatrix[i][j] == testmatrix[i][j + 1]: # 如果每行存在相邻两个数相同,则游戏没有结束
print('游戏没有结束')
return False
for i in range(b):
for j in range(a - 1):
if testmatrix[j][i] == testmatrix[j + 1][i]:
print('游戏没有结束')
return False
print('游戏结束')
return True
结束条件
源码分析
代码缩进 4个空格
正文缩进1.27厘米
22
谢谢观看
$$