掌握了基本圖形的畫法后,我們可以開始嘗試讓這些基本圖形變成動(dòng)態(tài)的,就像一種桌面,有很多個(gè)小球,相互碰撞并改變小球顏色的動(dòng)態(tài)效果。
要達(dá)到這種效果,首先要把這個(gè)大問題分解成若干個(gè)小問題:
1、先讓一個(gè)小球在屏幕中運(yùn)動(dòng)到邊界時(shí)能彈回;
2、兩個(gè)小球同時(shí)運(yùn)動(dòng)時(shí),除了到達(dá)邊界彈回,還要兩個(gè)小球相碰撞時(shí)彈回并改變顏色;
3、更多小球同時(shí)運(yùn)動(dòng)。
1、單球運(yùn)動(dòng)
單球運(yùn)動(dòng),就是移動(dòng)畫出來的畫空心圓,也就是只要改變圓心就可以實(shí)現(xiàn),但是在畫下一個(gè)圓之前要把上一次畫的圓給清除掉。畫完后,接著要判斷圓心到邊界的距離與半徑的大小關(guān)系,確定下一次的運(yùn)動(dòng)方向。
單球運(yùn)動(dòng)函數(shù)
//單個(gè)球運(yùn)動(dòng),碰到邊界改變運(yùn)動(dòng)方向
//dir為運(yùn)動(dòng)方向的參數(shù)
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) //選擇運(yùn)動(dòng)方向
{
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)++; //移動(dòng)圓心
else if(flag_y==1)
(*y)--; //移動(dòng)圓心
if(flag_x==0)
(*x)++; //移動(dòng)圓心
else if(flag_x==1)
(*x)--; //移動(dòng)圓心
LCD_DrawCircle(*x,*y,r,color);//畫出移動(dòng)后的圓
if((*y)-r<=0) //判斷邊界
flag_y = 0; //確定下次的運(yùn)動(dòng)方向
if((*y)+r >=320) //判斷邊界
flag_y = 1; //確定下次的運(yùn)動(dòng)方向
if((*x)-r<=0) //判斷邊界
flag_x = 0; //確定下次的運(yùn)動(dòng)方向
if((*x)+r >=240) //判斷邊界
flag_x = 1; //確定下次的運(yùn)動(dòng)方向
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; //返回下一次的運(yùn)動(dòng)方向
}
主函數(shù)
#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、雙球運(yùn)動(dòng)
雙球運(yùn)動(dòng)要在單球運(yùn)動(dòng)的基礎(chǔ)上,再加上雙球碰撞的判斷函數(shù)??梢杂?jì)算兩個(gè)圓心的距離和兩個(gè)圓的半徑的大小關(guān)系,判斷是否相碰撞,如果碰撞就對調(diào)運(yùn)動(dòng)方向,再改變顏色。
判斷兩球碰撞函數(shù)
//如果兩個(gè)球碰撞,改變運(yùn)動(dòng)方向,顏色
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;
}
}
由于要改變原有的數(shù)據(jù),所以函數(shù)的傳參要為指針類型。
主函數(shù)
#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、多球運(yùn)動(dòng)**
多球運(yùn)動(dòng)同樣可以通過調(diào)用以上兩個(gè)函數(shù)實(shí)現(xiàn),這里就不再進(jìn)行分析了。
電子發(fā)燒友App












評(píng)論