Python游戏开发,pygame模块,Python实现2048小游戏(pygame 2048)

网友投稿 310 2022-06-19


前言:

这次给大家做个2048小游戏吧。废话不多说,让我们愉快地开始吧~

开发工具

Python版本: 3.6.4

相关模块:

pygame模块;

以及一些Python自带的模块。

环境搭建

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

原理简介

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

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

# 游戏初始化

pygame.init()

screen = pygame.display.set_mode(cfg.SCREENSIZE)

pygame.display.set_caption('2048 —— 微信公众号:Charles的皮卡丘')

# 播放背景音乐

pygame.mixer.music.load(cfg.BGMPATH)

pygame.mixer.music.play(-1, 30)

接着,我们来定义一个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 4

self.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 = 0

if len(array) < 2: return array, score

for i in range(len(array)-1):

if array[i] == 'null':

break

if array[i] == array[i+1]:

array[i] *= 2

array.pop(i+1)

array.append('null')

score += array[i]

return extract(array), score

# 不需要移动的话直接return

if 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 += score

col.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 += score

col = ['null',] * (self.matrix_size[0] - len(col)) + col

for 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 += score

row.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 += score

row = ['null',] * (self.matrix_size[1] - len(row)) + row

self.game_matrix[idx] = row

self.move_direction = None

直接遍历了这个二维列表以实现我们想要的所有操作了。最后,我们再写个函数以根据当前的游戏状态来判断游戏是否结束就ok啦:

'''游戏是否结束'''

@property

def 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 False

if (i == self.matrix_size[0] - 1) and (j == self.matrix_size[1] - 1):

continue

elif (i == self.matrix_size[0] - 1):

if (self.game_matrix[i][j] == self.game_matrix[i][j+1]):

return False

elif (j == self.matrix_size[1] - 1):

if (self.game_matrix[i][j] == self.game_matrix[i+1][j]):

return False

else:

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 False

return True

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

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

# 游戏主循环

clock = pygame.time.Clock()

is_running = True

while 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)


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python爬虫能当副业吗?到了哪个层次能接单?解析能挣钱的方式(python爬虫兼职月入)
下一篇:VS2019下载地址和安装(vs2019在线安装下载的位置)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~