我正在尝试使我的 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;
}
}
}
我尝试更改三元运算符中的条件,但没有任何作用。
尝试以下方法
if ((x + radius > window_width ) || (x - radius < 0)){...}
if ((y + radius > window_height) || (y - radius < 0)){...}
如你所见,我修改了主要条件。将
<=
更改为 <
,因为您不希望它位于边界上,您希望球弹起,几乎不碰它。
我还删除了每个条件中的
&& xDirectionPositive
部分,它是多余的。您只需切换具体情况即可。
据我所知,唯一可能导致球不弹跳的事情是你处理方向不正确(
xDirectionPositive
或&& yDirectionPositive
)。