日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

项目: 互动粒子仿真

發(fā)布時間:2025/3/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 项目: 互动粒子仿真 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 一、最終效果展示
  • 二、靜態(tài)小球的初始化顯示
  • 三、小球的運動與反彈
  • 四、小球運動的規(guī)范化
  • 五、鼠標的吸引力
  • 六、鼠標的擊打斥力
  • 七、鼠標的擾動力

一、最終效果展示

效果圖如下:

二、靜態(tài)小球的初始化顯示

代碼如下:

#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 //小球的數(shù)量//定義小球結(jié)構(gòu) struct Mover {COLORREF color;//顏色float x,y;//坐標float vX,vY;//速度float radius;//半徑 };//定義全局變量 struct Mover movers[NUM_MOVERS];//小球數(shù)組 void startup() {//設置隨機種子srand((unsigned int)time(NULL));//初始化小球數(shù)組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);//清除畫面中的全部矩形區(qū)域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();//數(shù)據(jù)的初始化while(1){show();//顯示畫面updateWithoutInput();//與用戶輸入無關(guān)的更新updateWithInput();//與用戶輸入有關(guān)的更新}gameover();//游戲結(jié)束,進行后續(xù)處理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 //小球的數(shù)量//定義小球結(jié)構(gòu) struct Mover {COLORREF color;//顏色float x,y;//坐標float vX,vY;//速度float radius;//半徑 };//定義全局變量 struct Mover movers[NUM_MOVERS];//小球數(shù)組 void startup() {//設置隨機種子srand((unsigned int)time(NULL));//初始化小球數(shù)組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);//清除畫面中的全部矩形區(qū)域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;//根據(jù)“位置+速度”更新小球的坐標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();//數(shù)據(jù)的初始化while(1){show();//顯示畫面updateWithoutInput();//與用戶輸入無關(guān)的更新updateWithInput();//與用戶輸入有關(guān)的更新}gameover();//游戲結(jié)束,進行后續(xù)處理return 0; }

效果圖如下:

四、小球運動的規(guī)范化

加入阻尼,模擬真實世界中運動物體受摩檫力逐漸變慢的效果,為了避免小球絕對靜止, 當小球速度過小時 使其速度增加,修改小球的半徑,速度越大則半徑越大。

代碼如下:

#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 //小球的數(shù)量 #define FRICTION 0.96f//摩檫力、阻尼系數(shù)//定義小球結(jié)構(gòu) struct Mover {COLORREF color;//顏色float x,y;//坐標float vX,vY;//速度float radius;//半徑 };//定義全局變量 struct Mover movers[NUM_MOVERS];//小球數(shù)組 void startup() {//設置隨機種子srand((unsigned int)time(NULL));//初始化小球數(shù)組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);//清除畫面中的全部矩形區(qū)域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的隨機數(shù),//會以比較大的概率讓速度變大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;//根據(jù)“位置+速度”更新小球的坐標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();//數(shù)據(jù)的初始化while(1){show();//顯示畫面updateWithoutInput();//與用戶輸入無關(guān)的更新updateWithInput();//與用戶輸入有關(guān)的更新}gameover();//游戲結(jié)束,進行后續(xù)處理return 0; }

效果圖如下:

五、鼠標的吸引力

增加鼠標對一定范圍內(nèi)小球的吸引力,小球距離鼠標越近,吸引力越大。

代碼如下:

#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 //小球的數(shù)量 #define FRICTION 0.96f//摩檫力、阻尼系數(shù)//定義小球結(jié)構(gòu) struct Mover {COLORREF color;//顏色float x,y;//坐標float vX,vY;//速度float radius;//半徑 };//定義全局變量 struct Mover movers[NUM_MOVERS];//小球數(shù)組 int mouseX,mouseY;//當前鼠標坐標 void startup() {//設置隨機種子srand((unsigned int)time(NULL));//初始化小球數(shù)組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);//清除畫面中的全部矩形區(qū)域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;//吸引距離,若小球與鼠標的距離在此范圍內(nèi)則會受向內(nèi)的引力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歸一化,僅反映方向,和距離無關(guān)if(d!=0){dX=dX/d;dY=dY/d;}else{dX=0;dY=0;}//小球距離鼠標<toDist,再次范圍內(nèi)小球會受到鼠標的吸引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的隨機數(shù),//會以比較大的概率讓速度變大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;//根據(jù)“位置+速度”更新小球的坐標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();//數(shù)據(jù)的初始化while(1){show();//顯示畫面updateWithoutInput();//與用戶輸入無關(guān)的更新updateWithInput();//與用戶輸入有關(guān)的更新}gameover();//游戲結(jié)束,進行后續(xù)處理return 0; }

效果圖如下:

六、鼠標的擊打斥力

當鼠標左鍵按下時會對一定范圍內(nèi)的小球產(chǎn)生擊打斥力, 類似于往池塘中扔一個石頭,距離越近影響越大。

代碼如下:

#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 //小球的數(shù)量 #define FRICTION 0.96f//摩檫力、阻尼系數(shù)//定義小球結(jié)構(gòu) struct Mover {COLORREF color;//顏色float x,y;//坐標float vX,vY;//速度float radius;//半徑 };//定義全局變量 struct Mover movers[NUM_MOVERS];//小球數(shù)組 int mouseX,mouseY;//當前鼠標坐標 int isMouseDown;//鼠標左鍵是否按下 void startup() {//設置隨機種子srand((unsigned int)time(NULL));//初始化小球數(shù)組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);//清除畫面中的全部矩形區(qū)域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;//吸引距離,若小球與鼠標的距離在此范圍內(nèi)則會受向內(nèi)的引力float blowDist=WIDTH*0.25;//擊打距離,小球與鼠標的距離在次范圍內(nèi)會受到向外的斥力float stirDist=WIDTH*0.125;//擾動距離,小球距離鼠標在此范圍內(nèi)會受到鼠標的擾動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歸一化,僅反映方向,和距離無關(guān)if(d!=0){dX=dX/d;dY=dY/d;}else{dX=0;dY=0;}//小球距離鼠標<toDist,再次范圍內(nèi)小球會受到鼠標的吸引if(d<toDist){//吸引力引起的加速度幅度,小球距離鼠標越近引起的加速度越大//但吸引力的值明顯比上面斥力的值小很多float toAcc=(1-(d/toDist))*WIDTH*0.0014f;//由dX,dY歸一化方向信息,加速度幅度值為toAcc,得到新的小球高度vX=vX-dX*toAcc;vY=vY-dY*toAcc;}//當鼠標左鍵按下,并且小球距離鼠標<blowDist(在擊打范圍內(nèi))時會受到向外的斥力if(isMouseDown&&d<blowDist){//擊打力引起的加速度幅度,這個公式表示小球距離鼠標越近擊打斥力引起的加速度越大float blowAcc=(1-(d/blowDist))*10;//由上面得到的dX,dY歸一化方向信息,上面的加速度幅度值為blowAcc,得到新的小球速度//float(rand())/RAND_MAX產(chǎn)生0~1的隨機數(shù)//0.5f-float(rand())/RAND_MAX產(chǎn)生-0.5~0.5的隨機數(shù),加入一些擾動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的隨機數(shù),//會以比較大的概率讓速度變大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;//根據(jù)“位置+速度”更新小球的坐標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();//數(shù)據(jù)的初始化while(1){show();//顯示畫面updateWithoutInput();//與用戶輸入無關(guān)的更新updateWithInput();//與用戶輸入有關(guān)的更新}gameover();//游戲結(jié)束,進行后續(xù)處理return 0; }

效果圖如下:

七、鼠標的擾動力

實現(xiàn)鼠標移動時對粒子的擾動力,類似于在水面上拿樹枝攪動,攪動的越快擾動越大。

代碼如下:

#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 //小球的數(shù)量 #define FRICTION 0.96f//摩檫力、阻尼系數(shù)//定義小球結(jié)構(gòu) struct Mover {COLORREF color;//顏色float x,y;//坐標float vX,vY;//速度float radius;//半徑 };//定義全局變量 struct Mover movers[NUM_MOVERS];//小球數(shù)組 int mouseX,mouseY;//當前鼠標坐標 int prevMouseX,prevMouseY;//上次鼠標坐標 int mouseVX,mouseVY;//鼠標的速度 int isMouseDown;//鼠標左鍵是否按下 void startup() {//設置隨機種子srand((unsigned int)time(NULL));//初始化小球數(shù)組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);//清除畫面中的全部矩形區(qū)域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;//吸引距離,若小球與鼠標的距離在此范圍內(nèi)則會受向內(nèi)的引力float blowDist=WIDTH*0.25;//擊打距離,小球與鼠標的距離在次范圍內(nèi)會受到向外的斥力float stirDist=WIDTH*0.125;//擾動距離,小球距離鼠標在此范圍內(nèi)會受到鼠標的擾動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歸一化,僅反映方向,和距離無關(guān)if(d!=0){dX=dX/d;dY=dY/d;}else{dX=0;dY=0;}//小球距離鼠標<toDist,再次范圍內(nèi)小球會受到鼠標的吸引if(d<toDist){//吸引力引起的加速度幅度,小球距離鼠標越近引起的加速度越大//但吸引力的值明顯比上面斥力的值小很多float toAcc=(1-(d/toDist))*WIDTH*0.0014f;//由dX,dY歸一化方向信息,加速度幅度值為toAcc,得到新的小球高度vX=vX-dX*toAcc;vY=vY-dY*toAcc;}//當鼠標左鍵按下,并且小球距離鼠標<blowDist(在擊打范圍內(nèi))時會受到向外的斥力if(isMouseDown&&d<blowDist){//擊打力引起的加速度幅度,這個公式表示小球距離鼠標越近擊打斥力引起的加速度越大float blowAcc=(1-(d/blowDist))*10;//由上面得到的dX,dY歸一化方向信息,上面的加速度幅度值為blowAcc,得到新的小球速度//float(rand())/RAND_MAX產(chǎn)生0~1的隨機數(shù)//0.5f-float(rand())/RAND_MAX產(chǎn)生-0.5~0.5的隨機數(shù),加入一些擾動vX=vX+dX*blowAcc+0.5f-float(rand())/RAND_MAX;vY=vY+dY*blowAcc+0.5f-float(rand())/RAND_MAX;}//若小球距離鼠標<stirDist,在此范圍內(nèi)小球會受到鼠標的擾動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的隨機數(shù),//會以比較大的概率讓速度變大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;//根據(jù)“位置+速度”更新小球的坐標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();//數(shù)據(jù)的初始化while(1){show();//顯示畫面updateWithoutInput();//與用戶輸入無關(guān)的更新updateWithInput();//與用戶輸入有關(guān)的更新}gameover();//游戲結(jié)束,進行后續(xù)處理return 0; }

效果圖如下:

總結(jié)

以上是生活随笔為你收集整理的项目: 互动粒子仿真的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: av美国| 一区二区不卡在线 | 国产三级三级三级三级三级 | 亚洲欧美色图在线 | 天天做天天摸天天爽天天爱 | 国产在线视频你懂得 | 亚洲乱码视频 | 色一情 | 黑人精品一区二区 | 制服丝袜成人动漫 | 依人久久| 黑人毛片网站 | 色戒在线免费 | 美女的隐私免费看 | 精品国产乱码久久久久久蜜臀 | 日韩特黄| 国内福利视频 | 日本一区二区三区免费看 | 中文字幕日韩视频 | 欧美午夜在线 | 男人天堂v | 玩偶游戏在线观看免费 | 国产精久久一区二区三区 | 桃色视频网 | 男生脱女生衣服 | 日本加勒比中文字幕 | 国产精品福利在线播放 | 黄色av网址大全 | 中国女人内谢69xxxxⅹ视频 | 国产美女无遮挡永久免费观看 | 国产一区二区三区乱码 | 神马三级我不卡 | 日韩欧美网 | 大吊一区二区三区 | 97免费在线观看视频 | 国产99免费| 欧美视频一区二区三区四区在线观看 | 超级变态重口av番号 | 国产精品乱码一区二区 | 国产精品视频专区 | 国产又粗又猛又爽又黄91精品 | 污视频在线观看网站 | 极品美女av | 天天爽网站 | 亚洲av区无码字幕中文色 | 亚洲日本一区二区 | 久艹av| 九色蝌蚪9l视频蝌蚪9l视频 | 海角社区id | 久爱视频在线观看 | 九九久久综合 | 亚洲中文字幕在线观看 | 麻豆福利视频 | 亚洲国产精品久久久久婷婷老年 | 亚洲欧洲国产视频 | 一区二区在线视频免费观看 | 偷拍欧美亚洲 | 国产精品伦一区 | 谁有毛片网址 | 秋霞一区二区三区 | 国产又粗又猛又爽又黄的视频一 | 免费大黄网站 | 少女情窦初开的第4集在线观看 | 男人天堂成人网 | 欧美97 | 国产精品无码粉嫩小泬 | 农村村妇真实偷人视频 | 欧美专区 日韩专区 | 性欧美一区 | 婷婷综合五月 | 一级视频黄色 | 成人毛片18女人毛片免费 | 亚洲av无码乱码国产麻豆 | 久久久久黄色 | 亚洲精品久久久久久久蜜桃 | 人人九九 | www.久久久久 | 日韩淫片| 中文字幕第一区综合 | 暖暖视频日本 | 免费爱爱视频 | 午夜视频在线观看国产 | 日韩欧美中文字幕在线播放 | 在线免费av网 | 精品国产一区二区三区在线观看 | 精产国品一二三产区m553麻豆 | 性色在线视频 | 日日舔夜夜摸 | 五月天av网站 | 欧美自拍偷拍 | 国产.com| 噜噜狠狠狠狠综合久久 | 亚洲精品乱码久久久久久蜜桃91 | 日本综合久久 | 中文字字幕一区二区三区四区五区 | 男女偷爱性视频刺激 | www超碰在线| 亚洲人人精品 | 久久久久久久久久综合 |