2048游戏的Python实现
概述:
2048是一款流行的单人益智游戏,玩家通过滑动数字瓷砖来合并相同的数字,目标是合成2048这个数字。本文将介绍如何使用Python和Pygame库实现2048游戏的基本功能,包括游戏逻辑、界面绘制和用户交互。
主要功能:
- 游戏界面:游戏界面由一个4x4的网格组成,每个格子可以显示不同的数字。游戏开始时,随机生成两个瓷砖,分别为2或4。
- 用户输入:玩家可以通过键盘的方向键(上、下、左、右)来控制瓷砖的移动和合并。
- 瓷砖合并:当两个相同的数字瓷砖碰撞时,它们会合并成一个新的瓷砖,数字会加倍。
- 胜利条件:当玩家成功合成2048时,游戏会显示胜利信息。
- 游戏重置:玩家可以通过按空格键重置游戏,开始新一轮。
代码结构:
- 颜色设置:定义了不同数字对应的颜色,以便在界面上进行美观的显示。
- 绘制函数:包括
draw_grid
和draw_tile
函数,用于绘制游戏网格和瓷砖。 - 移动逻辑:实现了瓷砖的移动和合并逻辑,包括
move_left
、move_right
、move_up
和move_down
函数。 - 游戏循环:包含主菜单和游戏循环,处理用户输入并更新游戏状态。
运行环境:
- Python 3.x
- Pygame库(可通过
pip install pygame
安装)
总结:
这个2048游戏的Python实现是一个很好的练手项目,适合初学者学习游戏开发的基本概念。通过这个项目,开发者可以掌握如何处理用户输入、绘制图形界面以及实现简单的游戏逻辑。可以根据需要进一步扩展功能,例如添加分数记录、游戏结束提示、音效等。
import pygame
import random
import sys
# 初始化pygame
pygame.init()
# 设置屏幕大小
screen_width = 400
screen_height = 400
screen = pygame.display.set_mode((screen_width, screen_height))
# 设置颜色
background_color = (187, 173, 160)
tile_colors = {
0: (205, 193, 180),
2: (238, 228, 218),
4: (237, 224, 200),
8: (242, 177, 121),
16: (246, 149, 72),
32: (245, 124, 36),
64: (246, 94, 51),
128: (237, 207, 114),
256: (237, 204, 97),
512: (237, 200, 80),
1024: (237, 197, 63),
2048: (237, 194, 46),
}
# 设置字体
font = pygame.font.Font(None, 32)
# 游戏变量
grid_size = 4
tiles = [[0] * grid_size for _ in range(grid_size)]
def draw_grid():
for x in range(1, grid_size):
pygame.draw.line(screen, (105, 104, 104), (x * (screen_width // grid_size), 0), (x * (screen_width // grid_size), screen_height))
for y in range(1, grid_size):
pygame.draw.line(screen, (105, 104, 104), (0, y * (screen_height // grid_size)), (screen_width, y * (screen_height // grid_size)))
def draw_tile(value, x, y):
size = screen_width // grid_size
start_x = x * size
start_y = y * size
color = tile_colors.get(value, tile_colors[0]) # 使用get方法提供默认颜色
pygame.draw.rect(screen, color, (start_x + 5, start_y + 5, size - 10, size - 10))
if value:
text_surface = font.render(str(value), True, (255, 255, 255))
text_rect = text_surface.get_rect(center=(start_x + size // 2, start_y + size // 2))
screen.blit(text_surface, text_rect)
def draw_board():
screen.fill(background_color)
draw_grid()
for x in range(grid_size):
for y in range(grid_size):
draw_tile(tiles[x][y], x, y)
def add_new_tile():
available_positions = [(x, y) for x in range(grid_size) for y in range(grid_size) if tiles[x][y] == 0]
if available_positions:
x, y = random.choice(available_positions)
tiles[x][y] = random.choice([2, 4])
def move_left():
for y in range(grid_size):
new_line = [tiles[x][y] for x in range(grid_size) if tiles[x][y] != 0]
new_line = [value for value in new_line if value != 0]
new_line += [0] * (grid_size - len(new_line))
for x in range(grid_size - 1, 0, -1):
if new_line[x] == new_line[x - 1]:
new_line[x] = new_line[x] + new_line[x - 1]
new_line[x - 1] = 0
new_line = [value for value in new_line if value != 0]
new_line += [0] * (grid_size - len(new_line))
for x in range(grid_size):
tiles[x][y] = new_line[x]
def move_right():
for y in range(grid_size):
new_line = [tiles[x][y] for x in range(grid_size) if tiles[x][y] != 0]
new_line = [value for value in new_line if value != 0]
new_line += [0] * (grid_size - len(new_line))
for x in range(0, grid_size - 1):
if new_line[x] == new_line[x + 1]:
new_line[x] = new_line[x] + new_line[x + 1]
new_line[x + 1] = 0
new_line = [value for value in new_line if value != 0]
new_line += [0] * (grid_size - len(new_line))
for x in range(grid_size):
tiles[x][y] = new_line[x]
def move_up():
for x in range(grid_size):
new_line = [tiles[x][y] for y in range(grid_size) if tiles[x][y] != 0]
new_line = [value for value in new_line if value != 0]
new_line += [0] * (grid_size - len(new_line))
for y in range(grid_size - 1, 0, -1):
if new_line[y] == new_line[y - 1]:
new_line[y] = new_line[y] + new_line[y - 1]
new_line[y - 1] = 0
new_line = [value for value in new_line if value != 0]
new_line += [0] * (grid_size - len(new_line))
for y in range(grid_size):
tiles[x][y] = new_line[y]
def move_down():
for x in range(grid_size):
new_line = [tiles[x][y] for y in range(grid_size) if tiles[x][y] != 0]
new_line = [value for value in new_line if value != 0]
new_line += [0] * (grid_size - len(new_line))
for y in range(0, grid_size - 1):
if new_line[y] == new_line[y + 1]:
new_line[y] = new_line[y] + new_line[y + 1]
new_line[y + 1] = 0
new_line = [value for value in new_line if value != 0]
new_line += [0] * (grid_size - len(new_line))
for y in range(grid_size):
tiles[x][y] = new_line[y]
def check_for_winner():
for x in range(grid_size):
for y in range(grid_size):
if tiles[x][y] == 2048:
return True
return False
def main_menu():
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
for i in range(grid_size):
for j in range(grid_size):
tiles[i][j] = 0
add_new_tile()
add_new_tile()
elif event.key == pygame.K_ESCAPE:
running = False
screen.fill((0, 0, 0))
text_surface = font.render('Press SPACE to start', True, (255, 255, 255))
text_rect = text_surface.get_rect(center=(screen_width // 2, screen_height // 2))
screen.blit(text_surface, text_rect)
pygame.display.flip()
return
def game_loop():
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
move_left()
add_new_tile()
elif event.key == pygame.K_RIGHT:
move_right()
add_new_tile()
elif event.key == pygame.K_UP:
move_up()
add_new_tile()
elif event.key == pygame.K_DOWN:
move_down()
add_new_tile()
elif event.key == pygame.K_ESCAPE:
running = False
if check_for_winner():
running = False
game_message = "You win!"
print(game_message)
draw_board()
pygame.display.flip()
return
main_menu()
game_loop()
pygame.quit()
sys.exit()