掌握了基本图形的画法后,我们可以开始尝试让这些基本图形变成动态的,就像一种桌面,有很多个小球,相互碰撞并改变小球颜色的动态效果。
要达到这种效果,首先要把这个大问题分解成若干个小问题:
1、先让一个小球在屏幕中运动到边界时能弹回;
2、两个小球同时运动时,除了到达边界弹回,还要两个小球相碰撞时弹回并改变颜色;
3、更多小球同时运动。
1、单球运动
单球运动,就是移动画出来的画空心圆,也就是只要改变圆心就可以实现,但是在画下一个圆之前要把上一次画的圆给清除掉。画完后,接着要判断圆心到边界的距离与半径的大小关系,确定下一次的运动方向。
单球运动函数
//单个球运动,碰到边界改变运动方向
//dir为运动方向的参数
u8 LCD_Drawball(u16 *x,u16 *y,u16 r ,u16 color,u16 dir)
{
u16 flag_x = 0,flag_y = 0;
LCD_DrawCircle(*x,*y,r,WHITE);//清除上次的圆
switch(dir) //选择运动方向
{
case 0:
flag_x=0;flag_y=0;
break;
case 1:
flag_x=0;flag_y=1;
break;
case 2:
flag_x=1;flag_y=0;
break;
case 3:
flag_x=1;flag_y=1;
break;
}
if(flag_y==0)
(*y)++; //移动圆心
else if(flag_y==1)
(*y)--; //移动圆心
if(flag_x==0)
(*x)++; //移动圆心
else if(flag_x==1)
(*x)--; //移动圆心
LCD_DrawCircle(*x,*y,r,color);//画出移动后的圆
if((*y)-r<=0) //判断边界
flag_y = 0; //确定下次的运动方向
if((*y)+r >=320) //判断边界
flag_y = 1; //确定下次的运动方向
if((*x)-r<=0) //判断边界
flag_x = 0; //确定下次的运动方向
if((*x)+r >=240) //判断边界
flag_x = 1; //确定下次的运动方向
if((flag_x==0)&(flag_y==0))dir=0;
if((flag_x==0)&(flag_y==1))dir=1;
if((flag_x==1)&(flag_y==0))dir=2;
if((flag_x==1)&(flag_y==1))dir=3;
return dir; //返回下一次的运动方向
}
主函数
#include "stm32f4xx.h"
#include "core_cm4.h"
#include "ili9341.h"
#include "lcd.h"
int main()
{
u16 x1=30,y1=30,r1=20,dir1=0,color1=RED;
ILI9341_Init(); //ILI9341初始化
while(1)
{
dir1=LCD_Drawball(&x1,&y1,r1,color1,dir1);
}
}
2、双球运动
双球运动要在单球运动的基础上,再加上双球碰撞的判断函数。可以计算两个圆心的距离和两个圆的半径的大小关系,判断是否相碰撞,如果碰撞就对调运动方向,再改变颜色。
判断两球碰撞函数
//如果两个球碰撞,改变运动方向,颜色
void IfTwoBallCrash(u16 x1,u16 y1,u16 r1,u16 *color1,u16 *dir1,u16 x2,u16 y2,u16 r2,u16 *color2,u16 *dir2)
{
u16 temp;
if((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)<=((r1+r2)*(r1+r2)))
{
temp=(*dir1);
(*dir1)=(*dir2);
(*dir2)=temp;
(*color1)+=5000;
(*color2)+=5000;
}
}
由于要改变原有的数据,所以函数的传参要为指针类型。
主函数
#include "stm32f4xx.h"
#include "core_cm4.h"
#include "ili9341.h"
#include "lcd.h"
int main()
{
u16 x1=30,y1=30,r1=20,dir1=0,color1=RED;
u16 x2=100,y2=30,r2=20,dir2=1,color2=IRON_GRAY;
ILI9341_Init(); //ILI9341初始化
while(1)
{
dir1=LCD_Drawball(&x1,&y1,r1,color1,dir1);
dir2=LCD_Drawball(&x2,&y2,r2,color2,dir2);
IfTwoBallCrash(x1,y1,r1,&color1,&dir1,x2,y2,r2,&color2,&dir2);
}
}
```**3、多球运动**
多球运动同样可以通过调用以上两个函数实现,这里就不再进行分析了。