| 
 【项目背景】  
- 随着科技的发展,教育和娱乐领域越来越注重互动性和学习体验的结合。微型智能弹球游戏项目旨在通过 UNIHIKER_K10 硬件平台和 GamePad for micro:bit V4.0 手柄,为用户打造一个既具有教育意义又充满乐趣的互动游戏。这款游戏不仅能够锻炼玩家的反应速度和手眼协调能力,还能通过编程和硬件操作的结合,增加对 STEM(科学、技术、工程和数学)领域的兴趣和理解。
 - UNIHIKER_K10 是一款集成了显示屏、多种传感器和可编程接口的微型计算机,非常适合用于教育和娱乐项目。它支持多种编程语言和库,使得开发者能够轻松地实现复杂的功能。GamePad for micro:bit V4.0 手柄则为游戏提供了直观的控制方式,通过物理操作增强了游戏的互动性。
 
 
  
【项目硬件】UNIHIKER_K10 和 GamePad for micro:bit V4.0 手柄,实现交互式游戏。 
 
  
 
  
 
  
 
 
 
【程序设计】 
			
			
			- 
 - #include "unihiker_k10.h"
 - Music        music;
 - // 创建对象
 - UNIHIKER_K10 k10;
 - uint8_t screen_dir = 2;
 - int speed=0;
 - // 定义屏幕宽度和高度
 - #define SCREEN_WIDTH 240
 - #define SCREEN_HEIGHT 320
 - uint8_t score = 0;
 - // 游戏对象定义
 - #define BALL_SIZE 20
 - struct GameObject {
 -     int x;
 -     int y;
 -     int width;
 -     int height;
 -     int dx;
 -     int dy;
 - } ball, paddle;
 - 
 - // 初始化游戏对象
 - void initGameObjects() {
 -     ball.x = SCREEN_WIDTH / 2;
 -     ball.y = SCREEN_HEIGHT / 2;
 -     ball.width = BALL_SIZE;
 -     ball.height = BALL_SIZE;
 -     ball.dx = 2;
 -     ball.dy = 2;
 - 
 -     paddle.x = SCREEN_WIDTH / 2 - 20;
 -     paddle.y = SCREEN_HEIGHT - 30;
 -     paddle.width = 80;
 -     paddle.height = 20;
 -     paddle.dx = 0;
 - }
 - 
 - // 绘制游戏对象
 - void drawGameObjects() {
 -     //k10.canvas->canvasClear();
 -     k10.canvas->canvasCircle(ball.x, ball.y, BALL_SIZE, 0x000000, 0xFF0000, true);
 -     k10.canvas->canvasRectangle(paddle.x, paddle.y, paddle.width, paddle.height, 0x000000, 0x00FF00, true);
 -     k10.canvas->updateCanvas();
 - }
 - // LED 灯显示分数
 - void LEDshow(){
 -   switch (score) {
 -     case 0:
 -       k10.rgb->write(-1,  0x000000); 
 -       break;
 -     case 1:
 -       k10.rgb->write(-1, 0x000000); 
 -       k10.rgb->write( 2, 0x0000FF);
 -       
 -       break;
 -     case 2:
 -       k10.rgb->write(-1, 0x000000); 
 -       k10.rgb->write( 1, 0x0000FF);
 -       break;
 -     case 3:
 -       k10.rgb->write(-1, 0x000000);
 -       k10.rgb->write( 1, 0x0000FF);
 -       k10.rgb->write( 2, 0x0000FF);
 -       break;
 -     case 4:
 -       k10.rgb->write(-1, 0x000000);
 -       k10.rgb->write( 0, 0x0000FF);
 -       break;
 -     case 5:
 -       k10.rgb->write(-1, 0x000000);
 -       k10.rgb->write( 0, 0x0000FF);
 -       k10.rgb->write( 2, 0x0000FF);
 -       break;
 -     case 6:
 -       k10.rgb->write(-1, 0x000000);
 -       k10.rgb->write( 0, 0x0000FF);
 -       k10.rgb->write( 1, 0x0000FF);
 -       break;
 -     case 7:
 -       k10.rgb->write( 0, 0x0000FF);
 -       k10.rgb->write( 1, 0x0000FF);
 -       k10.rgb->write( 2, 0x0000FF);
 -       break;
 -     // 可以继续添加case 5, 6, 7...
 -     default:
 -       k10.rgb->setRangeColor(0, 2, 0x000000); // 默认所有灯灭
 -   }
 - }
 - // 更新游戏逻辑
 - void updateGame() {
 -     // 更新球的位置
 -     ball.x += ball.dx;
 -     ball.y += ball.dy;
 - 
 -     // 检测球是否碰到左右边界
 -     if (ball.x <= BALL_SIZE/2 || ball.x >= SCREEN_WIDTH - BALL_SIZE/2) {
 -         ball.dx = -ball.dx;
 -     }
 -     // 检测球是否碰到顶部边界
 -     if (ball.y <= BALL_SIZE/2) {
 -         ball.dy = -ball.dy;
 -     }
 -     // 检测球是否碰到挡板
 -     if (ball.x >= paddle.x && ball.x <= paddle.x + paddle.width &&
 -         ball.y +ball.height/2>= paddle.y  && ball.y <= paddle.y + paddle.height) {
 -         ball.dy = -ball.dy;
 -         score++;
 -         LEDshow();
 -         //music.playTone(262, 1000);
 -     }
 -     // 检测球是否掉出底部
 -     if (ball.y > SCREEN_HEIGHT - BALL_SIZE) {
 -         // 重置球的位置
 -         ball.x = SCREEN_WIDTH / 2;
 -         ball.y = SCREEN_HEIGHT / 2;
 -         k10.canvas->canvasClear();
 -               k10.canvas->updateCanvas();
 -     }
 - 
 -     // 绘制更新后的游戏对象
 -     drawGameObjects();
 - }
 - 
 - // 处理用户输入
 - void handleInput() {
 -     if (analogRead(P1) < 1000) {
 -         paddle.x -= 5;
 -     } else if (analogRead(P1) > 3000) {
 -         paddle.x += 5;
 -     } else if((k10.buttonA->isPressed())){
 -       speed=speed+100;
 -     } else if((k10.buttonB->isPressed())){
 -       speed=speed-100;
 -       if(speed<0){
 -         speed=0;
 -       }
 -     }
 - 
 -     // 确保挡板不会超出屏幕
 -     if (paddle.x < 0) {
 -         paddle.x = 0;
 -     } else if (paddle.x > SCREEN_WIDTH - paddle.width) {
 -         paddle.x = SCREEN_WIDTH - paddle.width;
 -     }
 - }
 - 
 - void setup() {
 -     k10.begin();
 -     k10.initScreen(screen_dir);
 -     k10.creatCanvas();
 -     k10.setScreenBackground(0x000000);
 -     Serial.begin(9600);
 -     initGameObjects();
 -     drawGameObjects();
 - }
 - 
 - void loop() {
 -     handleInput();
 -     updateGame();
 -     delay(speed); // 控制游戏速度
 - }
 
  复制代码 【程序解析】包含头文件  
- #include "unihiker_k10.h":包含用于控制 UNIHIKER_K10 硬件平台的库。
 
 
 声明全局变量和对象  
- Music music;:声明一个音乐对象。
 - UNIHIKER_K10 k10;:声明一个 UNIHIKER_K10 类型的对象,用于与硬件进行交互。
 - uint8_t screen_dir = 2;:定义屏幕方向变量,并初始化为 2。
 - int speed = 0;:定义一个速度变量,用于控制游戏循环的速度。
 
 
 定义屏幕尺寸  
- #define SCREEN_WIDTH 240 和 #define SCREEN_HEIGHT 320:定义屏幕的宽度和高度。
 
 
 定义分数和游戏对象结构  
- uint8_t score = 0;:定义一个变量来存储玩家的分数。
 - struct GameObject { ... } ball, paddle;:定义一个结构体来存储游戏对象(球和挡板)的属性,包括位置、尺寸和移动速度。
 
 
 初始化游戏对象  
- void initGameObjects() {...}:初始化球和挡板的位置、尺寸和移动速度。
 
 
 绘制游戏对象  
- void drawGameObjects() {...}:在屏幕上绘制球和挡板的当前位置。
 
 
 LED 显示分数  
- void LEDshow() {...}:根据当前分数,通过 LED 灯显示分数。
 
 
 更新游戏逻辑  
- void updateGame() {...}:更新球的位置,检测碰撞,更新分数,并重新绘制游戏对象。
 
 
 处理用户输入  
- void handleInput() {...}:处理来自手柄的输入,调整挡板的位置和游戏速度。
 
 
 设置初始化函数  
- void setup() {...}:在程序开始时调用,用于初始化硬件设置和游戏对象。
 
 
 主循环函数  
- void loop() {...}:程序的主循环,不断调用 handleInput() 和 updateGame() 函数,以及控制循环速度的 delay(speed)。
 
 
 游戏逻辑细节  
- 球的移动和边界检测:在 updateGame() 函数中,球的位置会根据其速度更新,并且会检测是否与屏幕的边界发生碰撞,如果是,则反转相应的移动方向。
 - 挡板的控制:在 handleInput() 函数中,通过读取手柄的模拟输入来控制挡板的水平移动,并确保挡板不会移出屏幕范围。
 - 得分和LED显示:当球与挡板碰撞时,分数增加,并通过 LEDshow() 函数更新 LED 灯的二进制显示。
 
 
 程序执行流程  
- 程序首先在 setup() 函数中进行初始化。
 - 然后进入 loop() 函数,不断循环执行用户输入处理和游戏逻辑更新。
 - 游戏状态的每次更新都会在屏幕上重新绘制游戏对象,并根据需要更新 LED 灯的显示。
 
 
  
 【演示视频】 
 
 
 |