375| 0
|
基于掌控板的——2048——小游戏 |
本帖最后由 mmm530531 于 2025-5-1 19:06 编辑 一、项目简介 2048 是一款广受欢迎的数字合并游戏,通过不断合并相同数字来获得更大的数字。本次项目使用掌控板来实现这一经典游戏,结合掌控板的硬件特性,为游戏带来独特的交互体验。 二、硬件准备 1. 掌控板:作为游戏运行的核心硬件,它集成了丰富的传感器和接口,方便实现游戏的各种功能。 2. USB 数据线:用于连接掌控板和电脑,以便烧录代码。 三、软件准备 1. mpython:选择一款适合的编程环境,用于编写和烧录游戏代码。 四、代码实现 1. 游戏初始化: from mpython import * import random # 初始化 OLED 对象 oled = OLED() # 初始化游戏板 board = [[0] * 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[j] == 0: empty_cells.append((i, j)) if empty_cells: row, col = random.choice(empty_cells) board[row][col] = 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[j] != 0: num_str = str(board[j]) x = j * 24 + (24 - font_width * len(num_str)) // 2 y = i * 16 + (16 - font_width) // 2 color = color_map.get(board[j], (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 = [num for num in row if num != 0] i = 0 while i < len(new_row) - 1: if new_row == new_row[i + 1]: # 更新分数 score += new_row * 2 new_row *= 2 del new_row[i + 1] i += 1 new_row.extend([0] * (4 - len(new_row))) for j in range(4): row[j] = new_row[j] 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[j] == 0: return False if i > 0 and board[j] == board[i - 1][j]: return False if j > 0 and board[j] == board[j - 1]: return False return True 6. 重置游戏:当游戏结束后,按下特定按键可重置游戏。 def reset_game(): """重置游戏状态""" global board, score board = [[0] * 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 创客社区的分享顺利! ![]() ![]() |
4.75 KB, 下载次数: 63
© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed