游戏开发引擎Cocos2dx碰撞检测原理与英雄要打死怪物之游戏开发《赵云要格斗》7Word格式.docx
《游戏开发引擎Cocos2dx碰撞检测原理与英雄要打死怪物之游戏开发《赵云要格斗》7Word格式.docx》由会员分享,可在线阅读,更多相关《游戏开发引擎Cocos2dx碰撞检测原理与英雄要打死怪物之游戏开发《赵云要格斗》7Word格式.docx(6页珍藏版)》请在冰豆网上搜索。
![游戏开发引擎Cocos2dx碰撞检测原理与英雄要打死怪物之游戏开发《赵云要格斗》7Word格式.docx](https://file1.bdocx.com/fileroot1/2023-2/2/58894da9-168c-44bb-bfdd-feeda68560c9/58894da9-168c-44bb-bfdd-feeda68560c91.gif)
1.矩形1在矩形2左方,两者无碰撞
成立条件:
x1+w1*0.5<
x2-w2*0.5
2.矩形1在矩形2右方,两者无碰撞
:
x1-w1*0.5>
x2+w2*0.5
3.矩形1在矩形2下方,两者无碰撞
y1+h1*0.5<
y2-h2*0.5
4.矩形1在矩形2上方,两者无碰撞
y1-h1*0.5>
y2+h2*0.5
上面四种就是所有的不碰撞的情况了,然后我们弄个判断,依次检测上面四种情形,一旦发现有一种情况成立,就返回无碰撞,如果四种情况都不成立,那恭喜你了,碰撞成功了!
二、自定义碰撞检测函数
碰撞检测对于精灵类可以用
sprite1->
boundingBox().intersectsRect(sprite1->
boundingBox());
只不过我这个游戏中的英雄和怪物都是自己定义的类,所以直接调用上面的函数就出点儿问题,所以自己就把前面碰撞检测的原理写了个函数,可以直接调用了,不用管你是什么对像。
首先,在用到碰撞检测的地方#include"
HelloWorldScene.h"
定义函数
//矩形碰撞检测bool
isRectCollision
(CCRect
rect1,
CCRect
rect2);
然后在其实现函数里HelloWorldScene.cpp里:
///碰撞检测bool
HelloWorld:
:
rect2){float
x1
=
rect1.origin.x;
//矩形1中心点的横坐标float
y1
rect1.origin.y;
//矩形1中心点的纵坐标float
w1
rect1.size.width;
//矩形1的宽度float
h1
rect1.size.height;
//矩形1的高度float
x2
rect2.origin.x;
float
y2
rect2.origin.y;
w2
rect2.size.width;
h2
rect2.size.height;
if
(x1+w1*0.5<
x2-w2*0.5)
return
false;
//矩形1在矩形2左方,两者无碰撞else
if
(x1-w1*0.5>
x2+w2*0.5)return
//矩形1在矩形2右方,两者无碰撞else
(y1+h1*0.5<
y2-h2*0.5)return
//矩形1在矩形2下方,两者无碰撞else
(y1-h1*0.5>
y2+h2*0.5)return
//矩形1在矩形2上方,两者无碰撞return
true;
}
这个代码的原理就是我们上面所讲的东西,很简单吧!
三、英雄要打死怪物
现在我们要调用二中的函数,我们先来看看英雄和怪物的碰撞范围吧
(我把背景弄透明了,实际是这样的)
所以,这里要注意下。
这里就是要小心,最好不要把整个图片的宽度和高度都包含进去;
碰撞检测的一个简单流程:
然后就是实现了啦~
voidHelloWorld:
update(floatdelta)函数中添加
好了,这里得来讲讲怪物受伤死亡动画了了。
接着上一篇讲的Monster.h增加函数
//受伤动画
void
HurtAnimation(const
char
*name_each,const
unsigned
int
num,bool
run_directon);
//受伤动画结束
HurtEnd();
//判断是否在受伤动画
bool
IsHurt;
//死亡动画
DeadAnimation(const
//死亡动画结束
DeadEnd();
//判断是否死亡
Isdead;
//怪物死亡闪烁结束
BlinkEnd();
然后在实现函数Monster.cpp
Monster:
run_directon)
{
if(IsHurt||Isdead)
return;
//受伤优先
if(IsRunning||IsAttack)
m_MonsterSprite->
stopAllActions();
//当前精灵停止所有动画
//恢复精灵原来的初始化贴图
this->
removeChild(m_MonsterSprite,TRUE);
//把原来的精灵删除掉
m_MonsterSprite=CCSprite:
create(Monster_name);
//恢复精灵原来的贴图样子
setFlipX(MonsterDirecton);
addChild(m_MonsterSprite);
IsRunning=false;
IsAttack=false;
}
CCAnimation*
animation
CCAnimation:
create();
for(
i=1;
i<
=num;
i++)
szName[100]
{0};
sprintf(szName,"
%s%d.png"
name_each,i);
animation->
addSpriteFrameWithFileName(szName);
//加载动画的帧
setDelayPerUnit(2.8f/14.0f);
setRestoreOriginalFrame(true);
setLoops
(1);
//动画循环1次
//将动画包装成一个动作
CCAnimate*
act=CCAnimate:
create(animation);
//创建回调动作,受伤动画结束调用HurtEnd()
CCCallFunc*
callFunc=CCCallFunc:
create(this,callfunc_selector(Monster:
HurtEnd));
//创建连续动作
CCActionInterval*
hurtackact=CCSequence:
create(act,callFunc,NULL);
runAction(hurtackact);
IsHurt=true;
HurtEnd()
IsHurt=false;
Monster_xue->
setCurrentProgress(Monster_xue->
getCurrentProgress()-10);
if(Monster_xue->
getCurrentProgress()==0)
//播放怪物死亡动画
DeadAnimation("
monster_dead"
2,MonsterDirecton);
Isdead=true;
//创建回调动作,死亡结束后调用deadact()
DeadEnd));
deadact=CCSequence:
runAction(deadact);
DeadEnd()
//恢复死亡的样子
create("
monster_dead2.png"
);
//存在血条
if(Monster_xue!
=NULL)
if(MonsterDirecton)//因为怪物中心不在图片中心,所以只能根据怪物的脸朝向,设置血条的横坐标
setPosition(ccp(m_MonsterSprite->
getPositionX()+60,
getPositionY()));
//设置在怪物上头
else
getPositionX()-60,
//怪物闪两下再死亡
CCBlink*
blinkact=CCBlink:
create(3,6);
//3是持续时间,6是闪的次数
//创建回调动作,闪烁结束后调用BlinkEnd()
BlinkEnd));
create(blinkact,callFunc,NULL);
//闪烁结束
BlinkEnd()
removeAllChildren();
//把怪物和血条都删除掉;
怪物死亡的一个过程,在每次受伤掉血后,立马检测当前血量,如果血量为0,马上播放死亡动画,接着再播放闪烁动画,然后就可以把怪物删除掉了啦~~就这么简单。
效果:
1、怪物在巡逻,这时攻击没有检测到碰撞
2、英雄在攻击,检测到碰撞,怪物受伤并掉血
3、怪物血量为0,怪物死亡,并播放闪烁动画
四、思路总结
这里碰撞检测我是反其它道而行,把所有不碰撞的可能都列出来,其它的不就是碰撞的了么?
然后再来自己编程,另一方面,怪物就是受伤、死亡的动画,以及闪烁,这些都是很基础的,基本上都是相同的函数,只要用一次你就会了。
就是这里要记得这是按顺序的动作,要记得这点就行了。