目录

  • 一、最终效果展示
  • 二、静态小球的初始化显示
  • 三、小球的运动与反弹
  • 四、小球运动的规范化
  • 五、鼠标的吸引力
  • 六、鼠标的击打斥力
  • 七、鼠标的扰动力

一、最终效果展示

效果图如下:

二、静态小球的初始化显示

代码如下:

#include<stdio.h>
#include<string.h>
#include<graphics.h>
#include<time.h>
#include<math.h>#define WIDTH 1024 //屏幕的宽
#define HEIGHT 768 //屏幕的高
#define NUM_MOVERS 800 //小球的数量//定义小球结构
struct Mover
{COLORREF color;//颜色float x,y;//坐标float vX,vY;//速度float radius;//半径
};//定义全局变量
struct Mover movers[NUM_MOVERS];//小球数组
void startup()
{//设置随机种子srand((unsigned int)time(NULL));//初始化小球数组for(int i=0;i<NUM_MOVERS;i++){movers[i].color=RGB(rand()%256,rand()%256,rand()%256);movers[i].x=rand()%WIDTH;movers[i].y=rand()%HEIGHT;movers[i].vX=float(cos(float(i)))*(rand()%34);movers[i].vY=float(sin(float(i)))*(rand()%34);movers[i].radius=(rand()%34)/15.0;}initgraph(WIDTH,HEIGHT);BeginBatchDraw();
}void show()
{int i;clearrectangle(0,0,WIDTH-1,HEIGHT-1);//清除画面中的全部矩形区域for(i=0;i<NUM_MOVERS;i++){//画小球setcolor(movers[i].color);setfillstyle(movers[i].color);fillcircle(int(movers[i].x+0.5),int(movers[i].y+0.5),int(movers[i].radius+0.5));}FlushBatchDraw();Sleep(2);
}void updateWithoutInput()
{}void updateWithInput()
{}void gameover()
{EndBatchDraw();closegraph();
}int main()
{startup();//数据的初始化while(1){show();//显示画面updateWithoutInput();//与用户输入无关的更新updateWithInput();//与用户输入有关的更新}gameover();//游戏结束,进行后续处理return 0;
}

效果图如下:

三、小球的运动与反弹

代码如下:

#include<stdio.h>
#include<string.h>
#include<graphics.h>
#include<time.h>
#include<math.h>#define WIDTH 1024 //屏幕的宽
#define HEIGHT 768 //屏幕的高
#define NUM_MOVERS 800 //小球的数量//定义小球结构
struct Mover
{COLORREF color;//颜色float x,y;//坐标float vX,vY;//速度float radius;//半径
};//定义全局变量
struct Mover movers[NUM_MOVERS];//小球数组
void startup()
{//设置随机种子srand((unsigned int)time(NULL));//初始化小球数组for(int i=0;i<NUM_MOVERS;i++){movers[i].color=RGB(rand()%256,rand()%256,rand()%256);movers[i].x=rand()%WIDTH;movers[i].y=rand()%HEIGHT;movers[i].vX=float(cos(float(i)))*(rand()%34);movers[i].vY=float(sin(float(i)))*(rand()%34);movers[i].radius=(rand()%34)/15.0;}initgraph(WIDTH,HEIGHT);BeginBatchDraw();
}void show()
{int i;clearrectangle(0,0,WIDTH-1,HEIGHT-1);//清除画面中的全部矩形区域for(i=0;i<NUM_MOVERS;i++){//画小球setcolor(movers[i].color);setfillstyle(movers[i].color);fillcircle(int(movers[i].x+0.5),int(movers[i].y+0.5),int(movers[i].radius+0.5));}FlushBatchDraw();Sleep(2);
}void updateWithoutInput()
{int i;float x,y,vX,vY;float nextX,nextY;for(i=0;i<NUM_MOVERS;i++){float x = movers[i].x;//当前小球的坐标float y = movers[i].y;float vX = movers[i].vX;//当前小球的速度float vY = movers[i].vY;//根据“位置+速度”更新小球的坐标nextX=x +vX;nextY=y+vY;//如果小球超过上、下、左、右4个边界,将位置设为边界处,速度反向if(nextX>WIDTH){nextX=WIDTH;vX=-1*vX;}else if(nextX<0){nextX=0;vX=-1*vX;}if(nextY>HEIGHT){nextY=HEIGHT;vY=-1*vY;}else if(nextY<0){nextY=0;vY=-1*vY;}//更新小球位置movers[i].vX=vX;movers[i].vY=vY;movers[i].x=nextX;movers[i].y=nextY;}
}void updateWithInput()
{}void gameover()
{EndBatchDraw();closegraph();
}int main()
{startup();//数据的初始化while(1){show();//显示画面updateWithoutInput();//与用户输入无关的更新updateWithInput();//与用户输入有关的更新}gameover();//游戏结束,进行后续处理return 0;
}

效果图如下:

四、小球运动的规范化

加入阻尼,模拟真实世界中运动物体受摩檫力逐渐变慢的效果,为了避免小球绝对静止,
当小球速度过小时 使其速度增加,修改小球的半径,速度越大则半径越大。

代码如下:

#include<stdio.h>
#include<string.h>
#include<graphics.h>
#include<time.h>
#include<math.h>#define WIDTH 1024 //屏幕的宽
#define HEIGHT 768 //屏幕的高
#define NUM_MOVERS 800 //小球的数量
#define FRICTION 0.96f//摩檫力、阻尼系数//定义小球结构
struct Mover
{COLORREF color;//颜色float x,y;//坐标float vX,vY;//速度float radius;//半径
};//定义全局变量
struct Mover movers[NUM_MOVERS];//小球数组
void startup()
{//设置随机种子srand((unsigned int)time(NULL));//初始化小球数组for(int i=0;i<NUM_MOVERS;i++){movers[i].color=RGB(rand()%256,rand()%256,rand()%256);movers[i].x=rand()%WIDTH;movers[i].y=rand()%HEIGHT;movers[i].vX=float(cos(float(i)))*(rand()%34);movers[i].vY=float(sin(float(i)))*(rand()%34);movers[i].radius=(rand()%34)/15.0;}initgraph(WIDTH,HEIGHT);BeginBatchDraw();
}void show()
{int i;clearrectangle(0,0,WIDTH-1,HEIGHT-1);//清除画面中的全部矩形区域for(i=0;i<NUM_MOVERS;i++){//画小球setcolor(movers[i].color);setfillstyle(movers[i].color);fillcircle(int(movers[i].x+0.5),int(movers[i].y+0.5),int(movers[i].radius+0.5));}FlushBatchDraw();Sleep(2);
}void updateWithoutInput()
{int i;float x,y,vX,vY;float nextX,nextY;float avgVX,avgVY,avgV,sc;for(i=0;i<NUM_MOVERS;i++){float x = movers[i].x;//当前小球的坐标float y = movers[i].y;float vX = movers[i].vX;//当前小球的速度float vY = movers[i].vY;//小球运动有一个阻尼(摩擦力),速度逐渐减小vX=vX*FRICTION;vY=vY*FRICTION;//速度的绝对值avgVX=abs(vX);avgVY=abs(vY);//两个方向速度的平均avgV=(avgVX+avgVY)*0.5f;//因为有上面阻尼的作用,如果速度过小,乘以一个0~3的随机数,//会以比较大的概率让速度变大if(avgVX<0.1)vX=vX*float(rand())/RAND_MAX*3;if(avgVY<0.1)vY=vY*float(rand())/RAND_MAX*3;//小球的半径在0.4~3.5之间,速度越大,半径越大sc=avgV*0.45f;sc=max(min(sc,3.5f),0.4f);movers[i].radius=sc;//根据“位置+速度”更新小球的坐标nextX=x +vX;nextY=y+vY;//如果小球超过上、下、左、右4个边界,将位置设为边界处,速度反向if(nextX>WIDTH){nextX=WIDTH;vX=-1*vX;}else if(nextX<0){nextX=0;vX=-1*vX;}if(nextY>HEIGHT){nextY=HEIGHT;vY=-1*vY;}else if(nextY<0){nextY=0;vY=-1*vY;}//更新小球位置movers[i].vX=vX;movers[i].vY=vY;movers[i].x=nextX;movers[i].y=nextY;}
}void updateWithInput()
{}void gameover()
{EndBatchDraw();closegraph();
}int main()
{startup();//数据的初始化while(1){show();//显示画面updateWithoutInput();//与用户输入无关的更新updateWithInput();//与用户输入有关的更新}gameover();//游戏结束,进行后续处理return 0;
}

效果图如下:

五、鼠标的吸引力

增加鼠标对一定范围内小球的吸引力,小球距离鼠标越近,吸引力越大。

代码如下:

#include<stdio.h>
#include<string.h>
#include<graphics.h>
#include<time.h>
#include<math.h>#define WIDTH 1024 //屏幕的宽
#define HEIGHT 768 //屏幕的高
#define NUM_MOVERS 800 //小球的数量
#define FRICTION 0.96f//摩檫力、阻尼系数//定义小球结构
struct Mover
{COLORREF color;//颜色float x,y;//坐标float vX,vY;//速度float radius;//半径
};//定义全局变量
struct Mover movers[NUM_MOVERS];//小球数组
int mouseX,mouseY;//当前鼠标坐标
void startup()
{//设置随机种子srand((unsigned int)time(NULL));//初始化小球数组for(int i=0;i<NUM_MOVERS;i++){movers[i].color=RGB(rand()%256,rand()%256,rand()%256);movers[i].x=rand()%WIDTH;movers[i].y=rand()%HEIGHT;movers[i].vX=float(cos(float(i)))*(rand()%34);movers[i].vY=float(sin(float(i)))*(rand()%34);movers[i].radius=(rand()%34)/15.0;}//初始化当前鼠标在画布中心mouseX=WIDTH/2;mouseY=HEIGHT/2;initgraph(WIDTH,HEIGHT);BeginBatchDraw();
}void show()
{int i;clearrectangle(0,0,WIDTH-1,HEIGHT-1);//清除画面中的全部矩形区域for(i=0;i<NUM_MOVERS;i++){//画小球setcolor(movers[i].color);setfillstyle(movers[i].color);fillcircle(int(movers[i].x+0.5),int(movers[i].y+0.5),int(movers[i].radius+0.5));}FlushBatchDraw();Sleep(2);
}void updateWithoutInput()
{int i;float x,y,vX,vY;float nextX,nextY;float avgVX,avgVY,avgV,sc;//阻尼float toDist=WIDTH*0.36;//吸引距离,若小球与鼠标的距离在此范围内则会受向内的引力float d;//当前小球和鼠标位置的距离float dX,dY;//计算小球当前位置的差  for(i=0;i<NUM_MOVERS;i++){x = movers[i].x;//当前小球的坐标y = movers[i].y;vX = movers[i].vX;//当前小球的速度vY = movers[i].vY;dX=x-mouseX;//计算小球当前位置的差  dY=y-mouseY;d=sqrt(dX*dX+dY*dY);//当前小球和鼠标位置的距离//下面将dX,dY归一化,仅反映方向,和距离无关if(d!=0){dX=dX/d;dY=dY/d;}else{dX=0;dY=0;}//小球距离鼠标<toDist,再次范围内小球会受到鼠标的吸引if(d<toDist){//吸引力引起的加速度幅度,小球距离鼠标越近引起的加速度越大float toAcc=(1-(d/toDist))*WIDTH*0.0014f;//由dX,dY归一化方向信息,加速度幅度值为toAcc,得到新的小球高度vX=vX-dX*toAcc;vY=vY-dY*toAcc;}//小球运动有一个阻尼(摩擦力),速度逐渐减小vX=vX*FRICTION;vY=vY*FRICTION;//速度的绝对值avgVX=abs(vX);avgVY=abs(vY);//两个方向速度的平均avgV=(avgVX+avgVY)*0.5f;//因为有上面阻尼的作用,如果速度过小,乘以一个0~3的随机数,//会以比较大的概率让速度变大if(avgVX<0.1)vX=vX*float(rand())/RAND_MAX*3;if(avgVY<0.1)vY=vY*float(rand())/RAND_MAX*3;//小球的半径在0.4~3.5之间,速度越大,半径越大sc=avgV*0.45f;sc=max(min(sc,3.5f),0.4f);movers[i].radius=sc;//根据“位置+速度”更新小球的坐标nextX=x +vX;nextY=y+vY;//如果小球超过上、下、左、右4个边界,将位置设为边界处,速度反向if(nextX>WIDTH){nextX=WIDTH;vX=-1*vX;}else if(nextX<0){nextX=0;vX=-1*vX;}if(nextY>HEIGHT){nextY=HEIGHT;vY=-1*vY;}else if(nextY<0){nextY=0;vY=-1*vY;}//更新小球位置movers[i].vX=vX;movers[i].vY=vY;movers[i].x=nextX;movers[i].y=nextY;}
}void updateWithInput()
{MOUSEMSG m;//定义鼠标消息while(MouseHit())//检测当前是否有鼠标消息{m=GetMouseMsg();//如果鼠标移动,更新当前鼠标坐标变量if(m.uMsg==WM_MOUSEMOVE)//如果鼠标移动,更新当前鼠标坐标变量{mouseX=m.x;mouseY=m.y;}}
}void gameover()
{EndBatchDraw();closegraph();
}int main()
{startup();//数据的初始化while(1){show();//显示画面updateWithoutInput();//与用户输入无关的更新updateWithInput();//与用户输入有关的更新}gameover();//游戏结束,进行后续处理return 0;
}

效果图如下:

六、鼠标的击打斥力

当鼠标左键按下时会对一定范围内的小球产生击打斥力,
类似于往池塘中扔一个石头,距离越近影响越大。

代码如下:

#include<stdio.h>
#include<string.h>
#include<graphics.h>
#include<time.h>
#include<math.h>#define WIDTH 1024 //屏幕的宽
#define HEIGHT 768 //屏幕的高
#define NUM_MOVERS 800 //小球的数量
#define FRICTION 0.96f//摩檫力、阻尼系数//定义小球结构
struct Mover
{COLORREF color;//颜色float x,y;//坐标float vX,vY;//速度float radius;//半径
};//定义全局变量
struct Mover movers[NUM_MOVERS];//小球数组
int mouseX,mouseY;//当前鼠标坐标
int isMouseDown;//鼠标左键是否按下
void startup()
{//设置随机种子srand((unsigned int)time(NULL));//初始化小球数组for(int i=0;i<NUM_MOVERS;i++){movers[i].color=RGB(rand()%256,rand()%256,rand()%256);movers[i].x=rand()%WIDTH;movers[i].y=rand()%HEIGHT;movers[i].vX=float(cos(float(i)))*(rand()%34);movers[i].vY=float(sin(float(i)))*(rand()%34);movers[i].radius=(rand()%34)/15.0;}//初始化当前鼠标在画布中心mouseX=WIDTH/2;mouseY=HEIGHT/2;isMouseDown=0;//初始鼠标未按下initgraph(WIDTH,HEIGHT);BeginBatchDraw();
}void show()
{int i;clearrectangle(0,0,WIDTH-1,HEIGHT-1);//清除画面中的全部矩形区域for(i=0;i<NUM_MOVERS;i++){//画小球setcolor(movers[i].color);setfillstyle(movers[i].color);fillcircle(int(movers[i].x+0.5),int(movers[i].y+0.5),int(movers[i].radius+0.5));}FlushBatchDraw();Sleep(2);
}void updateWithoutInput()
{int i;float x,y,vX,vY;float nextX,nextY;float avgVX,avgVY,avgV,sc;//阻尼float toDist=WIDTH*0.36;//吸引距离,若小球与鼠标的距离在此范围内则会受向内的引力float blowDist=WIDTH*0.25;//击打距离,小球与鼠标的距离在次范围内会受到向外的斥力float stirDist=WIDTH*0.125;//扰动距离,小球距离鼠标在此范围内会受到鼠标的扰动float d;//当前小球和鼠标位置的距离float dX,dY;//计算小球当前位置的差 for(i=0;i<NUM_MOVERS;i++){x = movers[i].x;//当前小球的坐标y = movers[i].y;vX = movers[i].vX;//当前小球的速度vY = movers[i].vY;dX=x-mouseX;//计算小球当前位置的差  dY=y-mouseY;d=sqrt(dX*dX+dY*dY);//当前小球和鼠标位置的距离//下面将dX,dY归一化,仅反映方向,和距离无关if(d!=0){dX=dX/d;dY=dY/d;}else{dX=0;dY=0;}//小球距离鼠标<toDist,再次范围内小球会受到鼠标的吸引if(d<toDist){//吸引力引起的加速度幅度,小球距离鼠标越近引起的加速度越大//但吸引力的值明显比上面斥力的值小很多float toAcc=(1-(d/toDist))*WIDTH*0.0014f;//由dX,dY归一化方向信息,加速度幅度值为toAcc,得到新的小球高度vX=vX-dX*toAcc;vY=vY-dY*toAcc;}//当鼠标左键按下,并且小球距离鼠标<blowDist(在击打范围内)时会受到向外的斥力if(isMouseDown&&d<blowDist){//击打力引起的加速度幅度,这个公式表示小球距离鼠标越近击打斥力引起的加速度越大float blowAcc=(1-(d/blowDist))*10;//由上面得到的dX,dY归一化方向信息,上面的加速度幅度值为blowAcc,得到新的小球速度//float(rand())/RAND_MAX产生0~1的随机数//0.5f-float(rand())/RAND_MAX产生-0.5~0.5的随机数,加入一些扰动vX=vX+dX*blowAcc+0.5f-float(rand())/RAND_MAX;vY=vY+dY*blowAcc+0.5f-float(rand())/RAND_MAX;}//小球运动有一个阻尼(摩擦力),速度逐渐减小vX=vX*FRICTION;vY=vY*FRICTION;//速度的绝对值avgVX=abs(vX);avgVY=abs(vY);//两个方向速度的平均avgV=(avgVX+avgVY)*0.5f;//因为有上面阻尼的作用,如果速度过小,乘以一个0~3的随机数,//会以比较大的概率让速度变大if(avgVX<0.1)vX=vX*float(rand())/RAND_MAX*3;if(avgVY<0.1)vY=vY*float(rand())/RAND_MAX*3;//小球的半径在0.4~3.5之间,速度越大,半径越大sc=avgV*0.45f;sc=max(min(sc,3.5f),0.4f);movers[i].radius=sc;//根据“位置+速度”更新小球的坐标nextX=x +vX;nextY=y+vY;//如果小球超过上、下、左、右4个边界,将位置设为边界处,速度反向if(nextX>WIDTH){nextX=WIDTH;vX=-1*vX;}else if(nextX<0){nextX=0;vX=-1*vX;}if(nextY>HEIGHT){nextY=HEIGHT;vY=-1*vY;}else if(nextY<0){nextY=0;vY=-1*vY;}//更新小球位置movers[i].vX=vX;movers[i].vY=vY;movers[i].x=nextX;movers[i].y=nextY;}
}void updateWithInput()
{MOUSEMSG m;//定义鼠标消息while(MouseHit())//检测当前是否有鼠标消息{m=GetMouseMsg();//如果鼠标移动,更新当前鼠标坐标变量if(m.uMsg==WM_MOUSEMOVE)//如果鼠标移动,更新当前鼠标坐标变量{mouseX=m.x;mouseY=m.y;}else if(m.uMsg==WM_LBUTTONDOWN)//鼠标左键按下isMouseDown=1;else if(m.uMsg==WM_LBUTTONUP)//鼠标左键抬起isMouseDown=0;}
}void gameover()
{EndBatchDraw();closegraph();
}int main()
{startup();//数据的初始化while(1){show();//显示画面updateWithoutInput();//与用户输入无关的更新updateWithInput();//与用户输入有关的更新}gameover();//游戏结束,进行后续处理return 0;
}

效果图如下:

七、鼠标的扰动力

实现鼠标移动时对粒子的扰动力,类似于在水面上拿树枝搅动,搅动的越快扰动越大。

代码如下:

#include<stdio.h>
#include<string.h>
#include<graphics.h>
#include<time.h>
#include<math.h>#define WIDTH 1024 //屏幕的宽
#define HEIGHT 768 //屏幕的高
#define NUM_MOVERS 800 //小球的数量
#define FRICTION 0.96f//摩檫力、阻尼系数//定义小球结构
struct Mover
{COLORREF color;//颜色float x,y;//坐标float vX,vY;//速度float radius;//半径
};//定义全局变量
struct Mover movers[NUM_MOVERS];//小球数组
int mouseX,mouseY;//当前鼠标坐标
int prevMouseX,prevMouseY;//上次鼠标坐标
int mouseVX,mouseVY;//鼠标的速度
int isMouseDown;//鼠标左键是否按下
void startup()
{//设置随机种子srand((unsigned int)time(NULL));//初始化小球数组for(int i=0;i<NUM_MOVERS;i++){movers[i].color=RGB(rand()%256,rand()%256,rand()%256);movers[i].x=rand()%WIDTH;movers[i].y=rand()%HEIGHT;movers[i].vX=float(cos(float(i)))*(rand()%34);movers[i].vY=float(sin(float(i)))*(rand()%34);movers[i].radius=(rand()%34)/15.0;}//初始化当前鼠标在画布中心mouseX=WIDTH/2;mouseY=HEIGHT/2;isMouseDown=0;//初始鼠标未按下initgraph(WIDTH,HEIGHT);BeginBatchDraw();
}void show()
{int i;clearrectangle(0,0,WIDTH-1,HEIGHT-1);//清除画面中的全部矩形区域for(i=0;i<NUM_MOVERS;i++){//画小球setcolor(movers[i].color);setfillstyle(movers[i].color);fillcircle(int(movers[i].x+0.5),int(movers[i].y+0.5),int(movers[i].radius+0.5));}FlushBatchDraw();Sleep(2);
}void updateWithoutInput()
{int i;float x,y,vX,vY;float nextX,nextY;float avgVX,avgVY,avgV,sc;//阻尼float toDist=WIDTH*0.36;//吸引距离,若小球与鼠标的距离在此范围内则会受向内的引力float blowDist=WIDTH*0.25;//击打距离,小球与鼠标的距离在次范围内会受到向外的斥力float stirDist=WIDTH*0.125;//扰动距离,小球距离鼠标在此范围内会受到鼠标的扰动float d;//当前小球和鼠标位置的距离float dX,dY;//计算小球当前位置的差 //前后两次运行间鼠标移动的距离,即鼠标的速度mouseVX=mouseX-prevMouseX;mouseVY=mouseY-prevMouseY;//为记录这次鼠标的坐标,更新上次鼠标坐标变量prevMouseX=mouseX;prevMouseY=mouseY;for(i=0;i<NUM_MOVERS;i++){x = movers[i].x;//当前小球的坐标y = movers[i].y;vX = movers[i].vX;//当前小球的速度vY = movers[i].vY;dX=x-mouseX;//计算小球当前位置的差  dY=y-mouseY;d=sqrt(dX*dX+dY*dY);//当前小球和鼠标位置的距离//下面将dX,dY归一化,仅反映方向,和距离无关if(d!=0){dX=dX/d;dY=dY/d;}else{dX=0;dY=0;}//小球距离鼠标<toDist,再次范围内小球会受到鼠标的吸引if(d<toDist){//吸引力引起的加速度幅度,小球距离鼠标越近引起的加速度越大//但吸引力的值明显比上面斥力的值小很多float toAcc=(1-(d/toDist))*WIDTH*0.0014f;//由dX,dY归一化方向信息,加速度幅度值为toAcc,得到新的小球高度vX=vX-dX*toAcc;vY=vY-dY*toAcc;}//当鼠标左键按下,并且小球距离鼠标<blowDist(在击打范围内)时会受到向外的斥力if(isMouseDown&&d<blowDist){//击打力引起的加速度幅度,这个公式表示小球距离鼠标越近击打斥力引起的加速度越大float blowAcc=(1-(d/blowDist))*10;//由上面得到的dX,dY归一化方向信息,上面的加速度幅度值为blowAcc,得到新的小球速度//float(rand())/RAND_MAX产生0~1的随机数//0.5f-float(rand())/RAND_MAX产生-0.5~0.5的随机数,加入一些扰动vX=vX+dX*blowAcc+0.5f-float(rand())/RAND_MAX;vY=vY+dY*blowAcc+0.5f-float(rand())/RAND_MAX;}//若小球距离鼠标<stirDist,在此范围内小球会受到鼠标的扰动if(d<stirDist){//扰动力引起的加速度幅度,小球距离鼠标越近引起的加速度越大,扰动力的值更小float mAcc=(1-(d/stirDist))*WIDTH*0.00026f;//鼠标速度越大,引起的扰动力越大vX=vX+mouseVX*mAcc;vY=vY+mouseVY*mAcc;}//小球运动有一个阻尼(摩擦力),速度逐渐减小vX=vX*FRICTION;vY=vY*FRICTION;//速度的绝对值avgVX=abs(vX);avgVY=abs(vY);//两个方向速度的平均avgV=(avgVX+avgVY)*0.5f;//因为有上面阻尼的作用,如果速度过小,乘以一个0~3的随机数,//会以比较大的概率让速度变大if(avgVX<0.1)vX=vX*float(rand())/RAND_MAX*3;if(avgVY<0.1)vY=vY*float(rand())/RAND_MAX*3;//小球的半径在0.4~3.5之间,速度越大,半径越大sc=avgV*0.45f;sc=max(min(sc,3.5f),0.4f);movers[i].radius=sc;//根据“位置+速度”更新小球的坐标nextX=x +vX;nextY=y+vY;//如果小球超过上、下、左、右4个边界,将位置设为边界处,速度反向if(nextX>WIDTH){nextX=WIDTH;vX=-1*vX;}else if(nextX<0){nextX=0;vX=-1*vX;}if(nextY>HEIGHT){nextY=HEIGHT;vY=-1*vY;}else if(nextY<0){nextY=0;vY=-1*vY;}//更新小球位置movers[i].vX=vX;movers[i].vY=vY;movers[i].x=nextX;movers[i].y=nextY;}
}void updateWithInput()
{MOUSEMSG m;//定义鼠标消息while(MouseHit())//检测当前是否有鼠标消息{m=GetMouseMsg();//如果鼠标移动,更新当前鼠标坐标变量if(m.uMsg==WM_MOUSEMOVE)//如果鼠标移动,更新当前鼠标坐标变量{mouseX=m.x;mouseY=m.y;}else if(m.uMsg==WM_LBUTTONDOWN)//鼠标左键按下isMouseDown=1;else if(m.uMsg==WM_LBUTTONUP)//鼠标左键抬起isMouseDown=0;}
}void gameover()
{EndBatchDraw();closegraph();
}int main()
{startup();//数据的初始化while(1){show();//显示画面updateWithoutInput();//与用户输入无关的更新updateWithInput();//与用户输入有关的更新}gameover();//游戏结束,进行后续处理return 0;
}

效果图如下:

项目: 互动粒子仿真相关推荐

  1. C语言结构体练习-互动粒子仿真

    线下的C语言课,教完结构体的知识后,为了加深同学们对结构体知识的理解,带领大家一起实现了一个酷炫的互动粒子仿真小程序: 假设有15个粒子小球,要记录他们的速度.坐标,可以用数组实现: float ba ...

  2. 华锐互动虚拟仿真实训室 3D动物解剖

      随着畜牧业的兴起,兽医专业需求越来越大,从家禽到牲畜.当涉及到繁殖.解剖和手术时,它需要专业指导或亲自操作.技术人员的培训需要时间.空间和设施.如何节约成本.减少开支.提高教学质量,一直是各大畜牧 ...

  3. “跟童老师学编程”专栏目录

    最开始写这个专栏,来自于2017年的一篇回答: 对于一个大一计科新生,有什么代码行数在 500~1000 的程序(C 语言)可以试着写来练手? 2017年写了一本C语言游戏开发的实践教材: 童晶:做游 ...

  4. 做游戏,学编程(C语言)教材《C语言课程设计与游戏开发实践教程》出版了...

    经过半年多的写作.修改.校样.印制,我们的实践教材<C语言课程设计与游戏开发实践教程>终于出版了.这本书可以看成是"做游戏,学编程(C语言)专栏"的详细版本,以下为书中 ...

  5. 计算机仿真模拟在装配,模拟仿真企业_灵图互动信誉优良

    模拟仿真企业,灵图互动信誉优良,数字孪生:结合真实产线数据的三维数字同步孪生,实现对产线数据的完整还原. 模拟仿真企业, 本实验主要介绍AVL BOOST软件,并让学生掌握该软件的基本使用方法,以及基 ...

  6. 无人驾驶8: 粒子滤波定位(优达学城项目)

    优达学城无人车定位的项目实现: 粒子滤波算法流程图 粒子滤波的伪代码: step1:初始化 理论上说,当粒子数量足够多时,能准确地呈现贝叶斯后验分布,如果粒子太少,可能漏掉准确位置,粒子数量太多,会拖 ...

  7. 项目六 PLC与RobotStudio联合仿真激光切割工作站——系统联调

    一.任务描述 将PLC程序和RobotStudio模型进行系统联调,实现激光切割工作站的基本逻辑控制. 二.系统联调 1. RobotStudio端准备 添加通讯插件,如任务一描述的方法,构建相关与P ...

  8. 【项目实战】Python实现用PSO粒子群优化算法对KMeans聚类模型进行优化项目实战

    说明:这是一个机器学习实战项目(附带数据+代码+文档+代码讲解),如需数据+代码+文档+代码讲解可以直接到文章最后获取. 1.项目背景 粒子群优化算法(Particle Swarm optimizat ...

  9. NeuroFluid: 流体仿真的人工智能新范式

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 内容来自上海交通大学人工智能研究院 AI TIME&上海交通大学首期专场活动,我们邀请了上海交通大学人工智能研究院助理教授王韫博 ...

最新文章

  1. Windows下Qt程序打包
  2. 基于 SpringBoot 的仿豆瓣平台【源码分享】
  3. linux blkid命令 查看块设备文件系统类型、LABEL、UUID信息 简介
  4. UOJ #35. 后缀排序 后缀数组 模板
  5. WSDL中文版——详解
  6. java jcheckbox事件_JAVA事件-----JCheckBox和JRadioButton事件响应
  7. WPF Template模版之DataTemplate与ControlTemplate的关系和应用【二】
  8. hpunix下11gRac的安装
  9. illegal multibyte sequence python3
  10. maya材质sheen_maya怎样做耐磨金属质感?
  11. Java刺客信条回复生命,刺客信条英灵殿怎么回血 生命值恢复方法介绍
  12. AT649 自由研究
  13. 光纤非线性效应对光OFDM信号的影响研究
  14. linux下gcc/g++命令
  15. Nginx源码包软件安装步骤
  16. 地图编辑器开发(四)
  17. python交互式培训网站对比(风变编程、指尖编程、扇贝编程)
  18. 为什么计算机能读懂 1 和 0 ?
  19. 2021-2027全球与中国低代码业务流程管理软件市场现状及未来发展趋势
  20. 【Android面试题】准备、hr面试问题总结

热门文章

  1. DRF——路由控制器
  2. tnsname.ora
  3. java 泛型小小的测试题
  4. 随机取6位数字或字母方法
  5. 做人,你想过这四个致命的问题吗
  6. 基于python的打印进度条、计算用时
  7. 简单的MongoDB实践
  8. android智能刷新smart,Android横向智能刷新框架-SmartRefreshHorizontal
  9. java.lang.ClassNotFoundException: org/apache/xerces/parsers/SAXParser
  10. C++ Primer 5th笔记(chap 15 OOP)抽象基类