假期来了,如其玩CS堕落,不如自己写一个小游戏玩一玩!这三天很卖力地在敲代码,到现在有点成绩了,发个临时版本上来。
http://home.xxsyzx.com/upfiles/killall.zip (Windows Only) 游戏很简单,开枪杀死所有的对手即可。
5月1日:大致地设计了一个C++游戏的结构,用了大量的类继承和多态,简直把++的特性发挥到极致。之前我是如此厌恶C++的面向对象编程,最近突然感觉到有点用途了!!大体地建造了一个物理运动系统,有加速度、重力、动量以及各种量的矢量合成与运算。
5月2日:弄了一天碰撞检测算法,请教了好几位朋友同学,还花了好几个小时上网看资料,最终还是没有满意的解决方案。挑灯夜战,最后把这个问题解决了才睡觉。。。临时的解决方法是:
1、对于子弹这类可以看成质点的物体,把运动轨迹当成直线来处理。在平面上,给每个对象都画一个矩形(颜色可以一致,如果是可以看作同一类碰撞的话),然后从子弹的开始处往目的地模拟画线,当遇到一个不同颜色的点时,则碰撞发生了,而且也得到了碰撞位置。这种方法的速度很快,而且仅是画直线和重画位置改变了的矩形而已,属于线性的时间复杂度。
2、对于人与障碍物的碰撞,要看成矩形和矩形之间的碰撞。假设矩形运动速度在一定限度内的话,可以在运动的每一瞬间检测是否和另一个矩形发生相交。如果相交了,则说明发生碰撞。同时计算碰撞所在的面,并修正碰撞物体的位置,恢复到碰撞之前的状态。
对于a和b两个矩形,判断是否发生碰撞:
if (b.x1> a.x2 || b.y1 > a.y2 || b.x2 < a.x1 || b.y2 < a.y1){
return false; //没有发生碰撞
}
//Handle intersection problem! //发生了碰撞!
int dy1 = abs(a.y1-b.y2), dy2=abs(a.y2-b.y1);
int dx1 = abs(a.x1-b.x2), dx2=abs(a.x2-b.x1);
int dh = min(dy1, dy2), dw = min(dx1, dx2);
//看看是调整左右位置还是调整上下位置。取最小改动的那一个。
if(dh < dw){ //adjust y
if(dy1
this->handleCollision(DIR_TOP, o);
o->handleCollision(DIR_BOTTOM, this);
}else{ //collid the top of o
this->position.y = b.y1 – a.y2 + a.y1 + 1;
this->handleCollision(DIR_BOTTOM, o);
o->handleCollision(DIR_TOP, this);
}
}else { //adjust x
if(dx1
this->handleCollision(DIR_LEFT, o);
o->handleCollision(DIR_RIGHT, this);
}else{ //collid the left of o
this->position.x = b.x1 – a.x2 + a.x1 -1;
this->handleCollision(DIR_RIGHT, o);
o->handleCollision(DIR_LEFT, this);
}
}
这种方法比较典型,我相信很多游戏也这么解决碰撞问题。
但是一个很明显的缺点就是,复杂度会随着矩形数量的增加而非线性增加!!!很容易证明复杂度是n^2的,如果地图上有5000个对象,在1秒时间里也不可能完成检测。这样玩家不用玩游戏了,看幻灯片算了。
我用了某些3D游戏里用的方法来解决这个问题,把地图分为m*n个区域,记录下在任意一个区域内的物体,如果物体存在于多个区域上,那么在多个区域进行标记。这样检测在某个位置的碰撞,只需要把在那个位置的物体拿出来进行检测即可。用空间换回了时间!速度很快,真的很有效果!!
5月3日:实现了动画效果,地图随着人物移动而滚动。花了一个下午,做好了一个可以玩的小游戏。因为还没有实现AI功能,所以电脑控制的人物不能走动了!
下载试试吧!
顾着下载,差点忘记SF!
喜欢这样的小游戏。但是,大哥,下次能写个可爱河蟹,不那么血腥暴力的游戏么……
我给的链接下载不了吗?
下得了
之前没有全屏在一些电脑上居然会很卡。。。特别是XP,还有鼠标的问题。
现在改为全屏后,这些问题估计都能解决了吧!
正常情况,游戏一直是60FPS的或者更高。否则就应该是显卡问题。我本机运行的时候CPU才占用10%
做的还可以啊!!! ^_^!
貌似 子弹没有惯性!! 点到哪打到哪!!
在同学帮助下,终于弄明白怎么玩了。⊙﹏⊙
试下小虾的作品
哈哈
狂赞..
to Kiming,有什么好方法解决这个问题呢?
如果子弹有惯性,是不是可以无限远了? 还是只能到达屏幕边沿的位置?
如果是可以穿墙的哇 O(∩_∩)O 貌似都快成外挂了
在屏幕的边缘!!
办法还没有^_^!
我在google reader看到的feed只有标题和第一句话,所以不知道这个帖子是关于上次的那个问题的解答的。
哦,其实不算是解答呢,我只是换了一种方法来达到同样的效果。
但是我仍然很想解决那个难题。我看网上很少有人研究这个?搜出来的都是简单的矩形相交检查,没多大意义。
呵呵,代码我看得云里雾里的……
PHP刚开始学,感到前景“险恶”,就不再前行了,呵呵。
这个。。。有几行代码显示不正常,少了尖括号,不知道是不是ckeditor的错。。。
感觉还不错哈 赞!
看了你的博客,犀利啊。颇受激励
好吧。。碰触。。有次做了个类弹幕的游戏我拿数个圆形填满物体算碰撞的,感觉矩形对于旋转物体计算很麻烦,圆形的话只要知道圆心就行,再者屏幕一次要出现5000个单位,这个么。。。什么BT游戏啊,那次做弹幕想试下VB效率同时计算1000架飞机我键盘按得都泪流满面了,哎,某只菜鸟看后有感~