失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【Python游戏】用Python实现一个2048小游戏 | 附带源码

【Python游戏】用Python实现一个2048小游戏 | 附带源码

时间:2022-05-11 20:56:26

相关推荐

【Python游戏】用Python实现一个2048小游戏 | 附带源码

导语

感觉好几天没和大家一起写小游戏玩了,今天恰巧有空。这次我们来用Python做个2048小游戏吧。废话不多说,上才艺

相关文件

公众号:Python日志

可以关注小编公众号,会不定时的发布一下Python小技巧,还有很多资源可以免费领取哟!!

源码领取:加Python学习交流群:773162165可以领取哟

开发环境

Python版本:3.6.4

相关模块:

pygame模块;

以及一些Python自带的模块。

环境搭建

安装Python并添加到环境变量,pip安装需要的相关模块即可。

原理介绍

“使用方向键移动方块,两个数字相同的方块撞在一起后,将会合并为一个数字是原来两倍的新方块。游戏的时候尽可能多地合并这些数字方块就行了。”

大概了解了游戏规则之后,我们就可以开始写这个游戏啦~首先,进行一下游戏初始化操作并播放一首自己喜欢的游戏背景音乐:

# 游戏初始化pygame.init()screen = pygame.display.set_mode(cfg.SCREENSIZE)pygame.display.set_caption('2048 公众号:Python日志 Python学习交流群:773162165')# 播放背景音乐pygame.mixer.music.load(cfg.BGMPATH)pygame.mixer.music.play(-1)

接着,我们来定义一个2048游戏类,里面主要负责实现2048的各种游戏规则:

'''2048游戏'''class Game2048(object):def __init__(self, matrix_size=(4, 4), max_score_filepath=None, **kwargs):# matrix_size: (num_rows, num_cols)self.matrix_size = matrix_size# 游戏最高分保存路径self.max_score_filepath = max_score_filepath# 初始化self.initialize()

具体而言,我们先用一个二维的列表来保存当前的游戏状态:

self.game_matrix = [['null' for _ in range(self.matrix_size[1])] for _ in range(self.matrix_size[0])]

其中null表示当前的块里没有数字。否则,对应的位置则用当前的数字表示。很显然地,2048小游戏的当前游戏状态是可以用一个4*4的列表表示的:

游戏一开始,我们需要在这个二维列表里随机地选择两个位置生成数字(即2或者4):

'''在新的位置随机生成数字'''def randomGenerateNumber(self):empty_pos = []for i in range(self.matrix_size[0]):for j in range(self.matrix_size[1]):if self.game_matrix[i][j] == 'null': empty_pos.append([i, j])i, j = random.choice(empty_pos)self.game_matrix[i][j] = 2 if random.random() > 0.1 else 4self.randomGenerateNumber()self.randomGenerateNumber()

然后,当玩家按下方向键(↑↓←→)时,这个二维列表要根据玩家的操作指令进行更新,主要分为两个部分:

移动所有的数字块并进行必要的合并和记分;

随机地在一个还没有数字的位置上生成一个数字。

具体而言,代码实现如下:

'''更新游戏状态'''def update(self):game_matrix_before = copy.deepcopy(self.game_matrix)self.move()if game_matrix_before != self.game_matrix: self.randomGenerateNumber()

其中,移动所有的数字并进行必要的合并的代码实现如下:

'''根据指定的方向, 移动所有数字块'''def move(self):# 提取非空数字def extract(array):array_new = []for item in array:if item != 'null': array_new.append(item)return array_new# 合并非空数字def merge(array):score = 0if len(array) < 2: return array, scorefor i in range(len(array)-1):if array[i] == 'null':breakif array[i] == array[i+1]:array[i] *= 2array.pop(i+1)array.append('null')score += array[i]return extract(array), score# 不需要移动的话直接returnif self.move_direction is None: return# 向上if self.move_direction == 'up':for j in range(self.matrix_size[1]):col = []for i in range(self.matrix_size[0]):col.append(self.game_matrix[i][j])col = extract(col)col.reverse()col, score = merge(col)self.score += scorecol.reverse()col = col + ['null',] * (self.matrix_size[0] - len(col))for i in range(self.matrix_size[0]):self.game_matrix[i][j] = col[i]# 向下elif self.move_direction == 'down':for j in range(self.matrix_size[1]):col = []for i in range(self.matrix_size[0]):col.append(self.game_matrix[i][j])col = extract(col)col, score = merge(col)self.score += scorecol = ['null',] * (self.matrix_size[0] - len(col)) + colfor i in range(self.matrix_size[0]):self.game_matrix[i][j] = col[i]# 向左elif self.move_direction == 'left':for idx, row in enumerate(copy.deepcopy(self.game_matrix)):row = extract(row)row.reverse()row, score = merge(row)self.score += scorerow.reverse()row = row + ['null',] * (self.matrix_size[1] - len(row))self.game_matrix[idx] = row# 向右elif self.move_direction == 'right':for idx, row in enumerate(copy.deepcopy(self.game_matrix)):row = extract(row)row, score = merge(row)self.score += scorerow = ['null',] * (self.matrix_size[1] - len(row)) + rowself.game_matrix[idx] = rowself.move_direction = None

懒得动脑子了(反正就4*4那么大T_T),所以直接遍历了这个二维列表以实现我们想要的所有操作了。最后,我们再写个函数以根据当前的游戏状态来判断游戏是否结束就ok啦:

'''游戏是否结束'''@propertydef isgameover(self):for i in range(self.matrix_size[0]):for j in range(self.matrix_size[1]):if self.game_matrix[i][j] == 'null': return Falseif (i == self.matrix_size[0] - 1) and (j == self.matrix_size[1] - 1):continueelif (i == self.matrix_size[0] - 1):if (self.game_matrix[i][j] == self.game_matrix[i][j+1]):return Falseelif (j == self.matrix_size[1] - 1):if (self.game_matrix[i][j] == self.game_matrix[i+1][j]):return Falseelse:if (self.game_matrix[i][j] == self.game_matrix[i+1][j]) or (self.game_matrix[i][j] == self.game_matrix[i][j+1]):return Falsereturn True

其实很简单,如果二维列表被数字填满,且数字不能再进行合并的话,这局游戏就结束了,否则,游戏就没有结束。

定义完2048游戏类,我们的游戏基本上算是写完了。只需要在游戏主循环里根据用户操作来更新当前的游戏状态并将游戏里所有必要的元素显示在屏幕上就ok啦:

# 游戏主循环clock = pygame.time.Clock()is_running = Truewhile is_running:screen.fill(pygame.Color(cfg.BG_COLOR))# --按键检测for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()elif event.type == pygame.KEYDOWN:if event.key in [pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT]:game_2048.setDirection({pygame.K_UP: 'up', pygame.K_DOWN: 'down', pygame.K_LEFT: 'left', pygame.K_RIGHT: 'right'}[event.key])# --更新游戏状态game_2048.update()if game_2048.isgameover:game_2048.saveMaxScore()is_running = False# --将必要的游戏元素画到屏幕上drawGameMatrix(screen, game_2048.game_matrix, cfg)start_x, start_y = drawScore(screen, game_2048.score, game_2048.max_score, cfg)drawGameIntro(screen, start_x, start_y, cfg)# --屏幕更新pygame.display.update()clock.tick(cfg.FPS)return endInterface(screen, cfg)

最后的效果大概是这样的:

玩这个我还是一个菜鸡,嘿嘿~

大家要是有啥不懂的或者有啥疑问的话,可以在下面评论哟,当然别忘了一键三连关注一下小编啦!

如果觉得《【Python游戏】用Python实现一个2048小游戏 | 附带源码》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。