C++多小球非对心弹性碰撞(HGE引擎)
生活随笔
收集整理的這篇文章主要介紹了
C++多小球非对心弹性碰撞(HGE引擎)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
程序是一個月前完成的,之前一直沒正兒八經的來整理下這個程序,感覺比較簡單,不過即使簡單的東西也要跟大家分享下。
源碼下載:http://download.csdn.net/detail/y85171642/7209727開篇
開始上代碼之前我先說下我為啥寫的這個程序,大三的時候學習C#接觸過GDI+而發現原來做圖形界面的程序也可以這么簡單。之后便開始用GDI+做起動畫、游戲等,其中便有一個模擬多小球碰撞的,在CSDN上有分享過( http://pan.baidu.com/s/1qWjTkmS?),不過現在回頭想想那個程序還是存在很多問題的,比如:沒考慮非對心碰撞問題,或者說是球體斜碰問題,幀率低問題,碰撞檢測精度不夠導致小球粘連問題(使用的是球體像素整型)。說到這里想必使用過GDI+的同學都會有一個想法就是GDI+用來做游戲效率確實不行。于是呢轉戰C++,正好自己的畢設要寫一個C++ 2D游戲,所以在寫游戲項目之余,便花費一天時間寫了這個模擬球體“彈性斜碰”程序。至于為什么要花這么長時間,是因為大多數時間我都花在了這個“斜碰”問題上,這也是我要寫這篇博客的主要原因,網上關于小球彈性斜碰的程序確實很少。不信可以百度下。上代碼
模擬小球碰撞嘛,所以小球的實體類是必須的(Ball.h) #pragma once #include <math.h> #include "hge.h" class CBall { public:CBall();CBall(float _x,float _y,float _speedX ,float _speedY,float _radius ,DWORD _color,float _density = 1.0f);~CBall(){}; public:bool IsCollision(CBall *ball,float dt); //碰撞檢測void CollisionWith(CBall *ball); //彈性正碰void CollisionWith2(CBall *ball); //彈性斜碰void SwapColor(CBall *ball); //好玩點,加個交換顏色void MoveNext(float dt,float _width,float _height);//由于程序不大,方便起見所有就都public了 public:float x; //x軸坐標float y; //y軸坐標float speed_x; //x軸方向速度float speed_y; //x軸方向速度float radius; //球體半徑float density; //密度float weight; //質量DWORD color; //混合顏色 }; 從Ball的類成員定義中可以看出來,球體的大概屬性基本包括全面了,不過多了個Color這個屬性是用來設置球體顏色的,因為圖片素材是純白實心圓,在使用color顏色進行頂點著色時候可直接設置獲得該顏色的圓。 下面依次說下各個成員方法的作用,部分有代碼。 (1)構造方法CBall(float_x,float_y,float...?,float_density?=1.0f);對成員變量初始化,需要注意,密度默認是1.0f,而質量通過體積和密度的計算求得?!厩蝮w質量 m=ρ*v , v = 4/3*π*r^3】。 (2)碰撞檢測,返回當前對象時候與參數ball發生碰撞,dt是一幀的時間。 bool CBall::IsCollision(CBall *ball,float dt) {//計算的是下一刻的位置,以免發生粘連float disX = (this->x+this->speed_x*dt)-(ball->x+ball->speed_x*dt);float disY = (this->y+this->speed_y*dt)-(ball->y+ball->speed_y*dt);float dis = sqrt(disX*disX+disY*disY);//判斷下一刻是否 發生碰撞if(dis < this->radius+ball->radius)return true;return false; } (3)彈性正碰?voidCBall::CollisionWith(CBall?*ball)根據動能定理和動量守恒定律得出公式 ? ??//彈性正碰撞公式 //v1' = [ (m1-m2)*v1 + 2*m2*v2 ] / (m1+m2) //v2' = [ (m2-m1)*v2 + 2*m1*v1 ] / (m1+m2) 碰撞后,兩小球的速度,方向,會發生改變。 (4)彈性斜碰,文章的主角,由于計算比較復雜所以需要用到向量(Vector)。 void CBall::CollisionWith2(CBall *ball) {//參考資料://http://www.cnblogs.com/kenkofox/archive/2011/09/06/2168944.html//http://tina0152.blog.163.com/blog/static/119447958200910229109326///球心點float x1 = this->x ;float y1 = this->y ;float x2 = ball->x ;float y2 = ball->y ;//碰撞處切平面向量t,及其法向量shgeVector s(x2-x1, y2-y1);s.Normalize();//標準化矢量hgeVector t(x2-x1, y2-y1);t.Rotate(3.1415926f/2);t.Normalize();//速度向量hgeVector v1(this->speed_x,this->speed_y);hgeVector v2(ball->speed_x,ball->speed_y);//先算v1(v1x, v1y)在s和t軸的投影值,分別設為v1s和v1t//再算v2(v2x, v2y)在s和t軸的投影值,分別設為v2s和v2t:float v1s = v1.Dot(&s);float v1t = v1.Dot(&t);float v2s = v2.Dot(&s);float v2t = v2.Dot(&t);//轉換后于s向量上的彈性正碰撞。質量不等//彈性正碰撞公式//v1' = [ (m1-m2)*v1 + 2*m2*v2 ] / (m1+m2)//v2' = [ (m2-m1)*v2 + 2*m1*v1 ] / (m1+m2)float m1 = this->weight;float m2 = ball->weight;float temp_v1s = ((m1-m2)*v1s + 2*m2*v2s )/ (m1+m2);v2s = ((m2-m1)*v2s + 2*m1*v1s )/ (m1+m2);v1s = temp_v1s;//首先求出v1t和v2t在t軸的向量v1t'和v2t'(將數值變為向量)//再求出v1s'和v2s'在s軸的向量v1s'和v2s'(將數值變為向量)hgeVector v1tVector = t*v1t;hgeVector v1sVector = s*v1s;hgeVector v2tVector = t*v2t;hgeVector v2sVector = s*v2s;//新速度矢量hgeVector v1_new = v1tVector+v1sVector;hgeVector v2_new = v2tVector+v2sVector;//劃分成x,y方向分量速度this->speed_x = v1_new.x;this->speed_y = v1_new.y;ball->speed_x = v2_new.x;ball->speed_y = v2_new.y; } (5)交換顏色,發生碰撞后的兩個小球進行顏色交換,純屬娛樂。 void?CBall::SwapColor(CBall?*ball) (6)小球移動,參數 _width,_height分別是窗口的寬高,因為這個方法內包含邊界碰撞的檢測和反彈。 void CBall::MoveNext(float dt,float _width,float _height) {float moveX = speed_x*dt;float moveY = speed_y*dt;//x方向邊界if (x+moveX<radius||x+moveX>_width-radius)speed_x = -speed_x;//Y方向邊界if(y+moveY<radius||y+moveY>_height-radius)speed_y = -speed_y;x+=speed_x*dt;y+=speed_y*dt; }?
主函數,使用HGE引擎,看源文件吧這里不詳細說了。 (HGE是一個小型的2D游戲引擎,基于DirectX8,相關學習資料下載:http://pan.baidu.com/s/1dDtdd2h)結束語
大四快畢業了,現在才發現大學期間學的確實太少,玩的太多(DotAer哈哈),好多感慨,都化成兩個字“時間”。回想起當初剛上大一的時候,拿著書本照著上面一字不差的敲著C程序代碼,直到程序運行出來還不能理解程序是怎么個原理,怎么實現的,不過還好“時間”告訴了我。從大一學的枯燥的只能用來ACM的C/C++到大二終于見到圖形界面卻又笨拙而不適合圖形界面開發的Java再到大三時讓圖形界面開發簡單至極卻又低效無法滿足游戲開發的C#到最后又回到了最初那個高效而復雜的讓人抓狂的C++,就這樣走完了大學四年。同學現在有不少出去工作了的,不過給我的感覺就是大家好像都是一知半解,拿著剛好養活自己的工資,在不斷地學習著,不過期待同學們都能找到自己滿意的工作,也希望自己找工作能順利。寫這篇文章是還在考慮要不要參加藍橋杯的決賽,畢竟我都大四了,而且最近的事情會好多。不好意思思路有點斷篇。言歸正傳,畢設在做一個“仿《保衛蘿卜》塔防游戲”,框架基本上搭建差不多了,還有部分需要完善的地方,在此先發個不完整版,http://pan.baidu.com/s/1dDEbK4L,框架僅供參考。畢竟我是菜鳥級的,很多東西都一知半解,所以程序有什么不妥的地方還望不吝提出。先謝謝了! 程序源碼下載:http://download.csdn.net/detail/y85171642/7209727轉載于:https://www.cnblogs.com/yinlong1991/p/3710247.html
總結
以上是生活随笔為你收集整理的C++多小球非对心弹性碰撞(HGE引擎)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 仅IE6中链接A的href为javasc
- 下一篇: 【HDOJ】1239 Calling E