C 球弹跳实验室

问题描述 投票:0回答:1

我正在尝试使我的 C 代码与 MSP-EXP432P4111 微控制器及其 BoosterPack 配合使用,以便球可以在屏幕上弹来弹去,从屏幕的墙壁和角落弹起,屏幕尺寸为 128 x 128 像素。目前,球将飞入角落,但不会反弹,我将失去球权。我该如何解决这个问题,使其不断弹跳?

#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <ti/grlib/grlib.h>
#include "LcdDriver/Crystalfontz128x128_ST7735.h"
#include <stdio.h>
#include <stdbool.h>

//*****************************************************************************
Graphics_Context g_sContext;
volatile uint32_t flag; //global flag
volatile uint32_t window_height;
volatile uint32_t window_width;
volatile int32_t x; // x position
volatile int32_t y; // y position
volatile int32_t vx; // x velocity
volatile int32_t vy; // y velocity
const int32_t radius = 3;
volatile uint32_t hits; // # of wall hits
volatile uint32_t hitCounter; //used to reset velocity
int32_t oldx;  // Variable to store the previous x position
int32_t oldy;  // Variable to store the previous y position
volatile bool xDirectionPositive;  // Flag indicating the direction of x movement
volatile bool yDirectionPositive;  // Flag indicating the direction of y movement
volatile uint32_t flag;  // Flag variable

void SysTick_Handler(void){
   flag = 1;
}

//*****************************************************************************
void LCD_init(){
//add LCD related codes in here
    Crystalfontz128x128_Init(); //initializes display
    Crystalfontz128x128_SetOrientation(LCD_ORIENTATION_UP); //set default screen orientation
    Graphics_initContext(&g_sContext, &g_sCrystalfontz128x128, &g_sCrystalfontz128x128_funcs);
    Graphics_setForegroundColor(&g_sContext, GRAPHICS_COLOR_RED);
    Graphics_setBackgroundColor(&g_sContext, GRAPHICS_COLOR_WHITE);
    GrContextFontSet(&g_sContext, &g_sFontFixed6x8);
    Graphics_clearDisplay(&g_sContext);
}

//*****************************************************************************
void erase(int32_t x, int32_t y, int32_t radius){
// draw over old with background color to erase it
    Graphics_setForegroundColor(&g_sContext, GRAPHICS_COLOR_WHITE);
    Graphics_drawCircle(&g_sContext, x, y , radius);
    //restore foreground color setting
    Graphics_setForegroundColor(&g_sContext, GRAPHICS_COLOR_RED);
}

//*****************************************************************************
void draw(int32_t x, int32_t y, int32_t radius){
// draw circle with default foreground color
    Graphics_drawCircle(&g_sContext , x, y , radius);
}

//*****************************************************************************

 int main(void) {
     SysTick_enableModule();
     x = 64;
     y = 64;
     vx = 1;
     vy = -1;
     hits = 0;
     hitCounter = 0;
     window_height = 127;
     window_width = 127;
     oldx = x;
     oldy = y;
     xDirectionPositive = true;
     yDirectionPositive = true;

     WDT_A_holdTimer();

     LCD_init();
     SysTick_setPeriod(30000);
     SysTick_enableInterrupt();

     // ... (existing code)

     while (1)
     {
         if (flag == 1)
         {
             erase(oldx, oldy, radius); // Erase the old circle at its previous position

             // Update ball position
             oldx = x;  // Save the current x as the old x
             oldy = y;  // Save the current y as the old y

             // Check if the ball is hitting the left or right wall
             if ((x + radius >= window_width && xDirectionPositive) || (x - radius <= 0 && !xDirectionPositive))
             {
                 xDirectionPositive = !xDirectionPositive;  // Toggle the x-direction flag
                 vx = (xDirectionPositive) ? 1 : -1;  // Reset velocity based on x direction flag

                 // Increase the magnitude of the x-velocity up to a maximum of 15
                 if (vx < 0)
                 {
                     vx = (-vx) < 15 ? (-vx) + 1 : 15;
                 }
                 else
                 {
                     vx = vx < 15 ? vx + 1 : 15;
                 }

                 hits++; // Increment hits counter when the ball hits the wall
             }

             // Check if the ball is hitting the top or bottom wall
             if ((y + radius >= window_height && yDirectionPositive) || (y - radius <= 0 && !yDirectionPositive))
             {
                 yDirectionPositive = !yDirectionPositive;  // Toggle the y-direction flag
                 vy = (yDirectionPositive) ? 1 : -1;  // Reset velocity based on y direction flag

                 // Increase the magnitude of the y-velocity up to a maximum of 15
                 if (vy < 0)
                 {
                     vy = (-vy) < 15 ? (-vy) + 1 : 15;
                 }
                 else
                 {
                     vy = vy < 15 ? vy + 1 : 15;
                 }

                 hits++; // Increment hits counter when the ball hits the wall
             }

             // Check if 50 hits are reached to reset velocities
             if (hits >= 50)
             {
                 hits = 0; // Reset hits counter
                 hitCounter++;

                 // Reset velocities to have magnitude 1 while maintaining the current direction
                 if (hitCounter % 2 == 0)
                 {
                     vx = (xDirectionPositive) ? 1 : -1;  // Reset based on x direction flag
                     vy = (yDirectionPositive) ? 1 : -1;  // Reset based on y direction flag
                 }
             }

             x += vx; // Update x based on velocity
             y += vy; // Update y based on velocity

             draw(x, y, radius); // Draw the new circle at its updated position

             flag = 0;
         }
     }
   }

我尝试更改三元运算符中的条件,但没有任何作用。

c microcontroller
1个回答
0
投票

尝试以下方法

if ((x + radius > window_width ) || (x - radius < 0)){...}
if ((y + radius > window_height) || (y - radius < 0)){...}

如你所见,我修改了主要条件。将

<=
更改为
<
,因为您不希望它位于边界上,您希望球弹起,几乎不碰它。

我还删除了每个条件中的

&& xDirectionPositive
部分,它是多余的。您只需切换具体情况即可。

据我所知,唯一可能导致球不弹跳的事情是你处理方向不正确(

xDirectionPositive
&& yDirectionPositive
)。

© www.soinside.com 2019 - 2024. All rights reserved.