下面依次说下各个成员方法的作用,部分有代码。 (1)构造方法CBall(float _x,float _y,float ... ,float _density = 1.0f);对成员变量初始化,需要注意,密度默认是1.0f,而质量通过体积和密度的计算求得。【球体质量 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)弹性正碰 void CBall::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,及其法向量s hgeVector 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,框架仅供参考。毕竟我是菜鸟级的,很多东西都一知半解,所以程序有什么不妥的地方还望不吝提出。先谢谢了!