基于掌控板的——2048——小游戏
本帖最后由 mmm530531 于 2025-5-1 19:06 编辑一、项目简介
2048 是一款广受欢迎的数字合并游戏,通过不断合并相同数字来获得更大的数字。本次项目使用掌控板来实现这一经典游戏,结合掌控板的硬件特性,为游戏带来独特的交互体验。
二、硬件准备
1. 掌控板:作为游戏运行的核心硬件,它集成了丰富的传感器和接口,方便实现游戏的各种功能。
2. USB 数据线:用于连接掌控板和电脑,以便烧录代码。
三、软件准备
1. mpython:选择一款适合的编程环境,用于编写和烧录游戏代码。
四、代码实现
1. 游戏初始化:
from mpython import *
import random
# 初始化 OLED 对象
oled = OLED()
# 初始化游戏板
board = [ * 4 for _ in range(4)]
# 定义颜色映射
color_map = {
2: (255, 255, 255),
4: (255, 255, 0),
8: (255, 165, 0),
16: (255, 0, 0),
32: (0, 255, 0),
64: (0, 0, 255),
128: (255, 255, 128),
256: (255, 128, 255),
512: (128, 255, 255),
1024: (255, 128, 0),
2048: (0, 255, 255)
}
# 初始化分数和最高分
score = 0
high_score = 0
2. 添加新数字:在空白位置随机添加数字 2 或 4。
def add_new_tile():
"""在空白位置添加新的数字 2 或 4"""
empty_cells = []
for i in range(4):
for j in range(4):
if board == 0:
empty_cells.append((i, j))
if empty_cells:
row, col = random.choice(empty_cells)
board = 2 if random.random() < 0.9 else 4
3. 绘制游戏板:在 OLED 屏幕上绘制游戏板和数字,并显示当前得分和最高得分。
def draw_board():
"""在 OLED 上绘制游戏板"""
oled.fill(0)
draw_grid()
# 绘制游戏区数字
for i in range(4):
for j in range(4):
if board != 0:
num_str = str(board)
x = j * 24 + (24 - font_width * len(num_str)) // 2
y = i * 16 + (16 - font_width) // 2
color = color_map.get(board, (255, 255, 255))
# 假设使用 RGB565 颜色编码转换
r, g, b = color
rgb565 = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
oled.text(num_str, x, y, rgb565)
# 绘制右侧得分区域
oled.text("Score:", 100, 10)
oled.text("%d" % score, 100, 20)
oled.text("High Score:", 100, 35)
oled.text("%d" % high_score, 100, 45)
oled.show()
4. 移动和合并数字:根据不同方向移动游戏板上的数字,并合并相同数字。
def merge_left():
"""向左合并数字"""
global score
for row in board:
new_row =
i = 0
while i < len(new_row) - 1:
if new_row == new_row:
# 更新分数
score += new_row * 2
new_row *= 2
del new_row
i += 1
new_row.extend( * (4 - len(new_row)))
for j in range(4):
row = new_row
def rotate_board():
"""顺时针旋转游戏板"""
global board
board = list(map(list, zip(*board[::-1])))
def move(direction):
"""根据方向移动和合并数字"""
if direction == 'left':
merge_left()
elif direction == 'up':
rotate_board()
merge_left()
rotate_board()
rotate_board()
rotate_board()
elif direction == 'right':
rotate_board()
rotate_board()
merge_left()
rotate_board()
rotate_board()
elif direction == 'down':
rotate_board()
rotate_board()
rotate_board()
merge_left()
rotate_board()
5. 检查游戏是否结束:判断游戏是否结束,当没有空白位置且相邻数字不能合并时,游戏结束。
def is_game_over():
"""检查游戏是否结束"""
for i in range(4):
for j in range(4):
if board == 0:
return False
if i > 0 and board == board:
return False
if j > 0 and board == board:
return False
return True
6. 重置游戏:当游戏结束后,按下特定按键可重置游戏。
def reset_game():
"""重置游戏状态"""
global board, score
board = [ * 4 for _ in range(4)]
score = 0
add_new_tile()
add_new_tile()
draw_board()
7. 游戏主循环:监听按键和加速度计事件,实现游戏的交互和逻辑。
# 初始化游戏
add_new_tile()
add_new_tile()
draw_board()
while True:
if button_a.value() == 0:
move('left')
add_new_tile()
draw_board()
elif button_b.value() == 0:
move('right')
add_new_tile()
draw_board()
elif accelerometer.get_x() > 0.5:
move('down')
add_new_tile()
draw_board()
elif accelerometer.get_x() < -0.5:
move('up')
add_new_tile()
draw_board()
if is_game_over():
# 检查是否打破最高分
if score > high_score:
high_score = score
oled.fill(0)
oled.text("Game Over!", 5, 5)
oled.text("Final Score:", 5, 20)
oled.text(str(score), 5 + len("Final Score:") * font_width, 20)
oled.text("High Score:", 5, 35)
oled.text(str(high_score), 5 + len("High Score:") * font_width, 35)
oled.show()
# 等待按键按下以重置游戏
while True:
if button_a.value() == 0 or button_b.value() == 0:
reset_game()
break
五、制作过程中的问题与解决
在制作过程中,遇到了一些问题。比如在 OLED 显示时,出现了 TypeError 和 NameError 等错误。 1. TypeError: can not convert tuple to int:这是因为在 OLED 显示颜色时,传入了元组形式的颜色值,而 oled.text 函数可能只接受单个整数值。通过将颜色元组转换为 RGB565 颜色编码的单个整数值解决了该问题。 2. NameError:在游戏结束界面部分,由于未正确定义或引用变量(如 font_width)导致报错。通过将 font_width 定义为全局变量,确保了在需要使用的地方都能正确访问。
六、总结
通过这次在掌控板上制作 2048 小游戏,深入了解了掌控板的编程和硬件特性。在解决各种问题的过程中,也提高了自己的编程能力和调试技巧。希望我的分享能对大家有所帮助,也期待大家在这个基础上进行更多的创新和改进。 希望以上内容对你有所帮助,祝你在 dfrobot 创客社区的分享顺利!
页:
[1]