博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2d-x游戏开发系列教程-超级玛丽09-怪物激活与移动
阅读量:4710 次
发布时间:2019-06-10

本文共 3729 字,大约阅读时间需要 12 分钟。

在游戏中,很多怪物本身是会移动的,这里主要有蘑菇怪,乌龟等。

说起怪物的移动,首先在游戏里先要考虑怪物的抽象和设计。

在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_pMario;   马里奥对象

CMGameMap            *m_pGameMap; 地图对象

enMoveDirection         m_MoveDirection;  移动方向

bool                 m_bIsActivation;              是否激活

float                 m_fDropSpeedPlus;     掉落加速度

bool                 m_bIsTouched;   是否相撞

怪物的创建:

当游戏开始时,根据tmx地图中的标记,创建怪物对象并放置到响应位置,具体代码在CMGameMap的init函数中

创建完怪物之后,将其加入到数组中,这些怪物刚刚创建时候,都是不激活的,也就是不会动的

怪物的激活和移动:

触发怪物的激活的原理在于判断怪物是不是已经进入视图,如果没有进入视图,那么怪物不需要动。但是判断是否进入视图还是很麻烦的,所以在马里奥程序里,是用马里奥和怪物的距离,来触发怪物的激活的。

怪物的激活和移动都是在virtual bool OnCallPerFrame(float fT); 函数中,这个函数是CMGameMap的帧更新函数调用过来的,也就是说每次帧更新,每个怪物都会响应这个函数。在这个函数里,负责激活和移动,以及判断怪物和马里奥的碰撞。

下面我们以蘑菇怪的帧更新函数来学习怪物帧更新处理。

bool CMMonsterMushrooms::OnCallPerFrame( float fT ){	do 	{		//是否激活		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 = enMoveRight;				}				else				{					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 = enMoveLeft;				}				else				{					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;			}			else			{				setPositionY(getPositionY()-m_fDropSpeedPlus);				//掉落加速度				m_fDropSpeedPlus += DROP_SPEED_PLUS;			}		}				return (CMMonsterBasic::OnCallPerFrame(fT)||OnCollisionMario());	} while (false);		CCLog("fun CMMonsterMushrooms::OnCallPerFrame Error!");	return false;}
首先判断是否激活了,如果激活了那么则判断它的移动,它不需要按键驱动,按照时间移动它即可,遇到障碍物则返回。如果蘑菇怪在天上,则自然降落。

最后调用基类的定时刷新函数和马里奥的冲突函数。基类的定时刷新函数做什么呢

bool CMMonsterBasic::OnCallPerFrame(float fT){	do 	{		//判断当怪物离开地图则发消息删除自己		if (getPositionX()<0 || getPositionY()<0)		{			TCmd_Remove_Monster* pData = new TCmd_Remove_Monster;			pData->pMonster = this;			SendMsg(enMsgMonsterDisappear,pData,sizeof(pData));			return true;//需要删除自己		}		CC_BREAK_IF(m_pMario==NULL);		//判断马里奥与当前怪物的距离,用以激活。		if (abs(m_pMario->getPositionX() - getPositionX())
基类的函数主要要做的事情是:

1)如果怪物离开地图,则自杀。自杀是通过发送消息给地图类,让地图类杀掉本对象

2)如果怪物与马里奥的距离小于某个值,则激活,激活的意思就是这个怪物开始运动了

转载于:https://www.cnblogs.com/new0801/p/6177206.html

你可能感兴趣的文章
Process使用
查看>>
Win7旗舰版一直显示检查更新的问题
查看>>
@AspectJ 语法概要
查看>>
pre 标签的使用注意事项
查看>>
textarea取设值及动态求字符长度问题
查看>>
Http StatuCode说明
查看>>
doctype 的各种声明
查看>>
删除学生信息
查看>>
PAT 1074 宇宙无敌加法器 (20 分)
查看>>
spring AOP理解和相关术语
查看>>
jenkins配置构建执行状态
查看>>
Git克隆与更新代码
查看>>
ABP开发框架前后端开发系列---(15)ABP框架的服务端和客户端缓存的使用
查看>>
免密登录
查看>>
jjs 产生undefined的情况
查看>>
拼图数字游戏
查看>>
PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [4] 首页 APP 接口开发方案 ③ 定时读取缓存方式...
查看>>
xml
查看>>
python上下文管理器
查看>>
总结了一些MySQL优化方面的技巧
查看>>