cocos creator 碰撞超级玛丽怎么实现碰撞的

[原]cocos2d-x游戏开发系列教程-超级玛丽09-怪物激活与移动 - 推酷
[原]cocos2d-x游戏开发系列教程-超级玛丽09-怪物激活与移动
在游戏中,很多怪物本身是会移动的,这里主要有蘑菇怪,乌龟等。
说起怪物的移动,首先在游戏里先要考虑怪物的抽象和设计。
在CMMonster.h中,有个类CMMonsterBasic,这个类抽象了所有的怪物,具体的怪物都是它的派生类,比如CMMonsterMushrooms蘑菇怪。
CMMonsterBasic继承自CCNode和CMSender,所以怪物都是渲染对象,并且有消息发送功能。
怪物基本类的接口:
virtual bool init(CCPoint ptMonsterPos,CMMario *pMario,CMGameMap *pGameMap,CMReceiver *pReceiver); 初始化
virtual bool OnCollisionMario() = 0;& 与马里奥相撞处理
virtual void Dead(enMonsterDeadType DeadType); 怪物死亡
virtual bool OnCallPerFrame(float fT);& 帧刷新定时调用
void MonsterTurn(); 怪物转向,比如蘑菇怪遇到阻挡它的墙时,它会转向
怪物类的基本数据
CMMario&& &&& &&& &&& &*m_pM&& 马里奥对象
CMGameMap&& &&& &&& &*m_pGameM 地图对象
enMoveDirection&& &&& & m_MoveD& 移动方向
bool&& &&& &&& &&& & m_bIsA&&&&&&&&&&&&& 是否激活
float&& &&& &&& &&& & m_fDropSpeedP&&&& 掉落加速度
bool&& &&& &&& &&& & m_bIsT&& 是否相撞
怪物的创建:
当游戏开始时,根据tmx地图中的标记,创建怪物对象并放置到响应位置,具体代码在CMGameMap的init函数中
创建完怪物之后,将其加入到数组中,这些怪物刚刚创建时候,都是不激活的,也就是不会动的
怪物的激活和移动:
触发怪物的激活的原理在于判断怪物是不是已经进入视图,如果没有进入视图,那么怪物不需要动。但是判断是否进入视图还是很麻烦的,所以在马里奥程序里,是用马里奥和怪物的距离,来触发怪物的激活的。
怪物的激活和移动都是在virtual bool OnCallPerFrame(float fT); 函数中,这个函数是CMGameMap的帧更新函数调用过来的,也就是说每次帧更新,每个怪物都会响应这个函数。在这个函数里,负责激活和移动,以及判断怪物和马里奥的碰撞。
下面我们以蘑菇怪的帧更新函数来学习怪物帧更新处理。
bool CMMonsterMushrooms::OnCallPerFrame( float fT )
//是否激活
if (m_bIsActivation==true)
//移动与碰撞
if (m_MoveDirection == enMoveLeft)
//用怪物左方的2个瓦片来判断移动碰撞
CCSprite* pTileSpriteLeftTop = m_pGameMap-&TileMapLayerPosToTileSprite(ccp(getPositionX(),getPositionY()+getContentSize().height));
CCSprite* pTileSpriteLeftMid = m_pGameMap-&TileMapLayerPosToTileSprite(ccp(getPositionX(),getPositionY()+getContentSize().height/2));
if (pTileSpriteLeftTop!=NULL || pTileSpriteLeftMid!=NULL)
m_MoveDirection = enMoveR
setPositionX(getPositionX()-1);
else if(m_MoveDirection == enMoveRight)
//用怪物右方的2个瓦片来判断移动碰撞
CCSprite* pTileSpriteRightTop = m_pGameMap-&TileMapLayerPosToTileSprite(ccp(getPositionX()+getContentSize().width,getPositionY()+getContentSize().height));
CCSprite* pTileSpriteRightMid = m_pGameMap-&TileMapLayerPosToTileSprite(ccp(getPositionX()+getContentSize().width,getPositionY()+getContentSize().height/2));
if (pTileSpriteRightTop!=NULL || pTileSpriteRightMid!=NULL)
m_MoveDirection = enMoveL
setPositionX(getPositionX()+1);
//用怪物下方的三个瓦片来判断掉落碰撞
CCSprite* pTileSpriteBottomMid = m_pGameMap-&TileMapLayerPosToTileSprite(ccp(getPositionX()+boundingBox().size.width/2,getPositionY()));
CCSprite* pTileSpriteBottomLeft = m_pGameMap-&TileMapLayerPosToTileSprite(ccp(getPositionX()+COLLISION_POS_ADJUSTMENT,getPositionY()));
CCSprite* pTileSpriteBottomRight = m_pGameMap-&TileMapLayerPosToTileSprite(ccp(getPositionX()+boundingBox().size.width-COLLISION_POS_ADJUSTMENT,getPositionY()));
if (pTileSpriteBottomLeft!=NULL || pTileSpriteBottomMid!=NULL || pTileSpriteBottomRight!=NULL)
//掉落速度归零
m_fDropSpeedPlus = 0;
setPositionY(getPositionY()-m_fDropSpeedPlus);
//掉落加速度
m_fDropSpeedPlus += DROP_SPEED_PLUS;
return (CMMonsterBasic::OnCallPerFrame(fT)||OnCollisionMario());
} while (false);
CCLog(&fun CMMonsterMushrooms::OnCallPerFrame Error!&);
首先判断是否激活了,如果激活了那么则判断它的移动,它不需要按键驱动,按照时间移动它即可,遇到障碍物则返回。如果蘑菇怪在天上,则自然降落。
最后调用基类的定时刷新函数和马里奥的冲突函数。基类的定时刷新函数做什么呢
bool CMMonsterBasic::OnCallPerFrame(float fT)
//判断当怪物离开地图则发消息删除自己
if (getPositionX()&0 || getPositionY()&0)
TCmd_Remove_Monster* pData = new TCmd_Remove_M
pData-&pMonster =
SendMsg(enMsgMonsterDisappear,pData,sizeof(pData));
//需要删除自己
CC_BREAK_IF(m_pMario==NULL);
//判断马里奥与当前怪物的距离,用以激活。
if (abs(m_pMario-&getPositionX() - getPositionX())&MONSTER_ACTIVE_DISTANCE)
m_bIsActivation =
//不需要删除自己
} while (false);
CCLog(&fun CMMonsterBasic::OnCallPerFrame Error!&);
基类的函数主要要做的事情是:
1)如果怪物离开地图,则自杀。自杀是通过发送消息给地图类,让地图类杀掉本对象
2)如果怪物与马里奥的距离小于某个值,则激活,激活的意思就是这个怪物开始运动了
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致&>&&>&&>&&>&cocos2dx 超级玛丽 demo 源码
cocos2dx 超级玛丽 demo 源码
上传大小:5.97MB
cocos2dx 的超级玛丽源码,压缩档有win32工程,未加入android工程,大家可自己做,很方便
综合评分:4.5(44位用户评分)
收藏((6))
所需积分:3
下载次数:205
审核通过送C币
创建者:redwolfchao
创建者:ch
创建者:doomlord
课程推荐相关知识库
上传者其他资源上传者专辑
移动开发热门标签
VIP会员动态
android服务器底层网络模块的设计方法
所需积分:0
剩余积分:720
您当前C币:0
可兑换下载积分:0
兑换下载分:
兑换失败,您当前C币不够,请先充值C币
消耗C币:0
你当前的下载分为234。
cocos2dx 超级玛丽 demo 源码
会员到期时间:
剩余下载次数:
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励20下载分
被举报人:
jiangfan65
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:2740人阅读
cocos2d-x(75)
背景在上一篇博客中,我们提到CMGameScene,但是CMGameScene只是个框架,实际担任游戏逻辑的是CMGameMap类,这个博文就来了解下CMGameMap头文件class CMGameMap : public cocos2d::CCTMXTiledMap ,public CMReceiver
protected:
enTagMario = 998,
//通过这个Tag查找Mario
protected:
CCArray *m_pArrayI
//金币数组
CCArray *m_pArrayM
//怪物数组
CCArray *m_pArrayB
//砖块数组
float m_fMapM
//地图偏移量
float m_fDropSpeedP
//掉落速度
float m_fJumpS
//跳跃速度
bool m_bIsLeftKeyD
//左键是否按下
bool m_bIsRightKeyD
//右键是否按下
bool m_bIsJumpKeyD
//跳跃键是否按下
bool m_bIsHeroD
//是否死亡
static CMGameMap* CreateGameMap(const char* pFileName);
// 返回地图指定位置上的图块
CCSprite* TileMapLayerPosToTileSprite(CCPoint TileMapLayerPos);
//通过地图块坐标返回地图块类型
enumTileType TileMapPosToTileType(CCPoint HeroPos,float fMapMove);
//地图块坐标转换为地图层坐标
TileMapPosToTileMapLayerPos(CCPoint TileMapPos);
//地图层坐标转换为世界坐标
TileMapLayerPosToWorldPos(CCPoint TileMapLayerPos,float m_fMapMove);
//地图层坐标转换为地图块坐标
TileMapLayerPosToTileMapPos(CCPoint TileMapLayerPos);
//返回地图偏移量
GetMapMove();
virtual void OnCallPerFrame(float dt);
protected:
virtual bool Init();
//Mario碰撞
void MarioMove(float fT);
void HitBlock(CCPoint TileMapLayerPos);
//删除砖块
void DeleteBlock();
//消息处理
protected:
virtual void OnMsgReceive( int enMsg,void* pData,int nSize );
void OnSubMsgItemRemove(void *pData ,int nSize); //[道具移除]消息处理
void OnSubMsgMarioLevelUp();
//[马里奥长大]消息处理
void OnSubMsgMonsterDisappear(void *pData,int nSize);//[怪物消失]消息处理
void OnSubMsgStamp(void *pData,int nSize);
//[被马里奥踩踏]消息处理
void OnSubMsgBlockBoxHitted(void *pData,int nSize); // [砖块被顶]消息处理
void OnSubMsgMarioBeHurt();
//马里奥被伤害的消息处理
};从头文件上CMGameMap是从CCTMXTileMap派生,CCTMXTileMap是cocos2dx中的一个瓦片地图类,会有别的博文对这个类进行详细解释,目前我们知道它是CCNode的子类即可。这个类作为容纳游戏逻辑的类,里面有很多的成员:m_pArrayItems:& 道具,是指在地图上显示的金币等道具m_pArrayMonsters:怪物m_pArrayBlocks:砖头m_fMapMove: 在这个游戏里,地图比窗口大,窗口只能显示地图的一部分,这个值表示窗口原点和地图原点的偏移m_fDropSpeedPlus: 马里奥掉落速度m_fJumpSpeed:跳跃速度m_bIsLeftKeyDown:左键是否按下m_bisRightKeyDown:右键是否按下m_bIsJumpKeyDown:跳跃是否按下以上三个标记,用于连续操作m_bIsHeroDead:&& 马里奥是否死亡CreateGameMap:创建地图TileMapLayerPosToTileSprite(CCPoint TileMapLayerPos):根据位置获得精灵TileMapPosToTileType(CCPoint, float fMapMove):根据位置获得精灵类型TileMapPosToTileMapLayerPos(CCPoint tileMapPos):根据地图坐标,获取砖块坐标TileMapLayerPosToWorldPos:通过砖块坐标转化成世界坐标,也就是cocos2d的坐标TileMapLayerPosToTileMapPos:将图层坐标转化成地图块坐标GetMapMove:获取地图偏移OnCallPerFrame:被CMGameScene调用的函数,进行逻辑处理,每一帧刷新都会调用该函数Init:初始化MarioMove:马里奥移动时,判断游戏逻辑HitBlock:撞砖块DeleteBlock:删除砖块OnMsgReceive:接收到地图中的精灵发过来的消息OnSubMsg系列函数:对响应的精灵发过来的消息进行处理CreateGameMap该函数是本类第一个被调用的函数,详细内容如下:CMGameMap* CMGameMap::CreateGameMap(const char* pFileName)
CMGameMap* pPlayer = new CMGameM
if (pPlayer && pPlayer-&initWithTMXFile(pFileName))
pPlayer-&Init();
pPlayer-&autorelease();
} while (false);
CCLog(&Fun CMGameMap::CreateGameMap Error!&);
return NULL;
}这个函数调用了initWithTMXFile函数,这个函数是初始化瓦片地图的函数,在别的博客里详细解释Initinit函数负责初始化地图中所有的精灵,各就各位,准备游戏bool CMGameMap::Init()
//初始化成员变量
m_fMapMove = 0;
m_fDropSpeedPlus = 0;
m_fJumpSpeed = 0;
m_bIsLeftKeyDown =
m_bIsRightKeyDown =
m_bIsJumpKeyDown =
m_bIsHeroDead =
//初始化游戏对象数组
m_pArrayItems = CCArray::create();
m_pArrayItems-&retain();
m_pArrayMonsters = CCArray::create();
m_pArrayMonsters-&retain();
m_pArrayBlocks = CCArray::create();
m_pArrayBlocks-&retain();
//初始化Mario
CMMario* pMario = CMMario::CreateHero(this);
CC_BREAK_IF(pMario==NULL);
pMario-&setPosition(TileMapPosToTileMapLayerPos(ccp(2,11)));
addChild(pMario,enZOrderFront,enTagMario);
//pMario-&SetStatus(enMarioStatusBig);
//隐藏原落坑判断层
CCTMXLayer* pTrapLayer = layerNamed(&trap&);
CC_BREAK_IF(pTrapLayer==NULL);
pTrapLayer-&setVisible(false);
//初始化显示金币
CCTMXLayer* pCoinLayer = layerNamed(&coin&);
CC_BREAK_IF(pCoinLayer==NULL);
pCoinLayer-&setVisible(false);
//获得地图的瓦片数量
int nMapHorizontalTileNum = pCoinLayer-&boundingBox().size.width/getTileSize().
int nMapVerticalTileNum = pCoinLayer-&boundingBox().size.height/getTileSize().
//遍历每片瓦片,寻找金币,建立并加入金币集合
for (int i = 0;i&nMapHorizontalTileNi++)
for (int j = 0;j&nMapVerticalTileNj++)
if (TileMapPosToTileType(ccp(i,j),m_fMapMove)==enTileTypeCoin)
//将瓦片地图坐标转换为瓦片地图层坐标
CCPoint CoinTileMapLayerPos = TileMapPosToTileMapLayerPos(ccp(i,j));
CMItemCoin* pCoin = CMItemCoin::CreateItemIcon(CoinTileMapLayerPos,getTileSize(),pMario,this);
if (pCoin==NULL)
CCLog(&Coin init Error!&);
pCoin-&setPosition(CoinTileMapLayerPos);
pCoin-&setAnchorPoint(ccp(0,0));
m_pArrayItems-&addObject(pCoin);
addChild(pCoin);
//初始化怪物显示
CCTMXObjectGroup* pObjectLayer = objectGroupNamed(&objects&);
CC_BREAK_IF(pObjectLayer==NULL);
CCArray *ObjectArray = pObjectLayer-&getObjects();
CCDictionary *pDic = NULL;
for (unsigned int i = 0; i & ObjectArray-&count(); i++)
pDic = (CCDictionary *)ObjectArray-&objectAtIndex(i);
int PosX = ((CCString*)pDic-&objectForKey(&x&))-&intValue();
int PosY = ((CCString*)pDic-&objectForKey(&y&))-&intValue();
PosY -= this-&getTileSize().
CCPoint TileXY = ccp(PosX, PosY);
CCString *strName = (CCString*)pDic-&objectForKey(&name&);
CCString *strType = (CCString*)pDic-&objectForKey(&type&);
// 进行怪物的初始化,先根据名字来判断是不是enemy,再细分enemy类型
if (strName-&m_sString == &enemy&)
if (strType-&m_sString == &mushroom&)
CMMonsterMushrooms *pMonster = CMMonsterMushrooms::CreateMonsterMushrooms(TileXY,pMario,this,this);
if (pMonster==NULL)
CCLog(&pMonster==NULL!&);
pMonster-&setPosition(ccp(TileXY.x,TileXY.y));
pMonster-&setAnchorPoint(ccp(0,0));
m_pArrayMonsters-&addObject(pMonster);
addChild(pMonster,enZOrderFront);
if (strType-&m_sString == &tortoise&)
CMMonsterTortoise *pMonster = CMMonsterTortoise::CreateMonsterTortoise(TileXY,pMario,this,this);
if (pMonster==NULL)
CCLog(&pMonster==NULL!&);
pMonster-&setPosition(ccp(TileXY.x,TileXY.y));
pMonster-&setAnchorPoint(ccp(0,0));
m_pArrayMonsters-&addObject(pMonster);
addChild(pMonster,enZOrderFront);
if (strType-&m_sString == &flower&)
CMMonsterFlower *pMonster = CMMonsterFlower::CreateMonsterFlower(TileXY,pMario,this,this);
if (pMonster==NULL)
CCLog(&pMonster==NULL!&);
pMonster-&setPosition(ccp(TileXY.x,TileXY.y));
pMonster-&setAnchorPoint(ccp(0,0));
m_pArrayMonsters-&addObject(pMonster);
addChild(pMonster,enZOrderFront);
//初始化砖块显示
CCTMXLayer* pBlockLayer = layerNamed(&block&);
CC_BREAK_IF(pBlockLayer==NULL);
pBlockLayer-&setVisible(false);
//获得地图的瓦片数量
int nMapHorizontalTileNum = pCoinLayer-&boundingBox().size.width/getTileSize().
int nMapVerticalTileNum = pCoinLayer-&boundingBox().size.height/getTileSize().
//遍历每片瓦片,寻找瓦片,建立并加入瓦片集合
for (int i = 0;i&nMapHorizontalTileNi++)
for (int j = 0;j&nMapVerticalTileNj++)
if (TileMapPosToTileType(ccp(i,j),m_fMapMove)==enTileTypeBlock)
//解析得到当前砖块的属性
int GID = pBlockLayer-&tileGIDAt(ccp(i,j));
CCDictionary *pDic = propertiesForGID(GID);
CC_BREAK_IF(pDic==NULL);
CCString *strBlockType = (CCString*)pDic-&objectForKey(&blockType&);
if (strBlockType==NULL)
int nBlockType = strBlockType-&intValue();
//将瓦片地图坐标转换为瓦片地图层坐标
CCPoint BlockTileMapLayerPos = TileMapPosToTileMapLayerPos(ccp(i,j));
CMItemBlock* pBlock = CMItemBlock::CreateItemBlock(BlockTileMapLayerPos,getTileSize(),pMario,this,(enumBlockType)nBlockType);
if (pBlock==NULL)
CCLog(&Block init Error!&);
pBlock-&setPosition(BlockTileMapLayerPos);
pBlock-&setAnchorPoint(ccp(0,0));
m_pArrayBlocks-&addObject(pBlock);
addChild(pBlock);
} while (false);
CCLog(&Fun CMGameMap::Init Error!&);
}这里很多精灵是从TMX地图中获得的,因此如果需要进一步学习马里奥的话,需要先了解TMX地图了。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4406271次
积分:60202
积分:60202
排名:第32名
原创:1323篇
转载:70篇
译文:34篇
评论:5724条
难度:初级
类型:技术教程
难度:初级
类型:技术教程
难度:初级
类型:技术教程
文章:80篇
阅读:272573
文章:24篇
阅读:35368
文章:180篇
阅读:251450
文章:35篇
阅读:77821
文章:50篇
阅读:183243
文章:60篇
阅读:262758
文章:44篇
阅读:623210
文章:202篇
阅读:1478098
文章:90篇
阅读:408356
文章:70篇
阅读:542434
文章:27篇
阅读:106525
(1)(1)(1)(2)(20)(20)(3)(1)(1)(1)(1)(3)(136)(26)(98)(58)(12)(9)(14)(18)(58)(295)(1)(21)(1)(2)(2)(2)(2)(5)(5)(7)(4)(4)(63)(12)(13)(7)(12)(5)(4)(5)(7)(1)(84)(56)(1)(17)(3)(3)(2)(8)(4)(5)(4)(4)(1)(3)(4)(5)(5)(4)(2)(22)(33)(20)(20)(3)(3)(9)(2)(4)(5)(10)(2)(5)(1)(9)(20)(6)(10)(64)}

我要回帖

更多关于 cocos2dx spine 碰撞 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信