cocos2d-x游戏开发系列教程-超级玛丽07-CMGameMap
背景
在上一篇博客中,我们提到CMGameScene,但是CMGameScene只是个框架,实际担任游戏逻辑的是CMGameMap类,这个博文就来了解下CMGameMap
头文件
class CMGameMap : public cocos2d::CCTMXTiledMap ,public CMReceiver
{
protected:
enum
{
enTagMario = 998, //通过这个Tag查找Mario
};
protected:
CCArray *m_pArrayItems; //金币数组
CCArray *m_pArrayMonsters; //怪物数组
CCArray *m_pArrayBlocks; //砖块数组 float m_fMapMove; //地图偏移量
float m_fDropSpeedPlus; //掉落速度
float m_fJumpSpeed; //跳跃速度 bool m_bIsLeftKeyDown; //左键是否按下
bool m_bIsRightKeyDown; //右键是否按下
bool m_bIsJumpKeyDown; //跳跃键是否按下
bool m_bIsHeroDead; //是否死亡
public:
static CMGameMap* CreateGameMap(const char* pFileName); // 返回地图指定位置上的图块
CCSprite* TileMapLayerPosToTileSprite(CCPoint TileMapLayerPos);
//通过地图块坐标返回地图块类型
enumTileType TileMapPosToTileType(CCPoint HeroPos,float fMapMove);
//地图块坐标转换为地图层坐标
CCPoint TileMapPosToTileMapLayerPos(CCPoint TileMapPos);
//地图层坐标转换为世界坐标
CCPoint TileMapLayerPosToWorldPos(CCPoint TileMapLayerPos,float m_fMapMove);
//地图层坐标转换为地图块坐标
CCPoint TileMapLayerPosToTileMapPos(CCPoint TileMapLayerPos);
//返回地图偏移量
float GetMapMove();
virtual void OnCallPerFrame(float dt);
protected:
virtual bool Init(); void onExit(); //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)
{
do
{
CMGameMap* pPlayer = new CMGameMap;
if (pPlayer && pPlayer->initWithTMXFile(pFileName))
{
pPlayer->Init();
pPlayer->autorelease();
return pPlayer;
}
delete pPlayer;
} while (false);
CCLog("Fun CMGameMap::CreateGameMap Error!");
return NULL;
}
这个函数调用了initWithTMXFile函数,这个函数是初始化瓦片地图的函数,在别的博客里详细解释
Init
init函数负责初始化地图中所有的精灵,各就各位,准备游戏
bool CMGameMap::Init()
{
do
{
//初始化成员变量
m_fMapMove = 0;
m_fDropSpeedPlus = 0;
m_fJumpSpeed = 0;
m_bIsLeftKeyDown = false;
m_bIsRightKeyDown = false;
m_bIsJumpKeyDown = false;
m_bIsHeroDead = false; //初始化游戏对象数组
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().width;
int nMapVerticalTileNum = pCoinLayer->boundingBox().size.height/getTileSize().height;
//遍历每片瓦片,寻找金币,建立并加入金币集合
for (int i = 0;i<nMapHorizontalTileNum;i++)
{
for (int j = 0;j<nMapVerticalTileNum;j++)
{
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().height;
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().width;
// int nMapVerticalTileNum = pCoinLayer->boundingBox().size.height/getTileSize().height;
//遍历每片瓦片,寻找瓦片,建立并加入瓦片集合
for (int i = 0;i<nMapHorizontalTileNum;i++)
{
for (int j = 0;j<nMapVerticalTileNum;j++)
{
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)
{
continue;
}
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);
}
}
} return true;
} while (false);
CCLog("Fun CMGameMap::Init Error!");
return false;
}
这里很多精灵是从TMX地图中获得的,因此如果需要进一步学习马里奥的话,需要先了解TMX地图了。
cocos2d-x游戏开发系列教程-超级玛丽07-CMGameMap的更多相关文章
- cocos2d-x游戏开发系列教程-超级玛丽07-CMGameMap(三)-按键处理
在地图初始化好了之后,就开始移动马里奥吧,我在windows下,是使用键盘来移动马里奥的 w是跳,d是前进,a是后退,那么在程序里是怎么来获取这个按键的呢? 普通的windows程序,在按键之后,会有 ...
- cocos2d-x游戏开发系列教程-超级玛丽10-怪物与马里奥冲突检测
在超级玛丽游戏中,马里奥在移动,怪物也在移动,当他们遇见时,需要判断是马里奥身亡还是怪物身亡. 这个判断的代码在怪物类的检测函数实现中. 比如蘑菇怪的冲突检测函数: bool CMMonsterMus ...
- cocos2d-x游戏开发系列教程-超级玛丽06-CMGameScene
背景 在CMMenuScene中,当用户点击开始游戏时,导演让场景进入到CMGameScene 头文件 class CMGameScene : public cocos2d::CCLayer,publ ...
- cocos2d-x游戏开发系列教程-超级玛丽08-消息机制
在超级玛丽游戏里,地图类CMGameMap负责所有的程序逻辑,它包含了背景地图,包含了游戏元素精灵,当游戏中的精灵之间发生碰撞时,比如马里奥撞上砖头这种事情发生时,马里奥对象本身不知道怎么处理这个逻辑 ...
- cocos2d-x游戏开发系列教程-超级玛丽05-CMMenuScene
代码下载链接 http://download.csdn.net/detail/yincheng01/6864893 解压密码:c.itcast.cn 背景 上一篇博文提到appDelegate,在该类 ...
- cocos2d-x游戏开发系列教程-超级玛丽09-怪物激活与移动
在游戏中,很多怪物本身是会移动的,这里主要有蘑菇怪,乌龟等. 说起怪物的移动,首先在游戏里先要考虑怪物的抽象和设计. 在CMMonster.h中,有个类CMMonsterBasic,这个类抽象了所有的 ...
- cocos2d-x游戏开发系列教程-超级玛丽07-CMGameMap(五)-地图卷动
马里奥在平移的过程中,涉及到地图的卷动问题. 在这个游戏里,地图比窗口大,窗口只是显示了地图的一部分,因此马里奥在移动的时候,移动到一定位置之后要卷动地图,否则马里奥移动到窗口右边之后......那结 ...
- cocos2d-x游戏开发系列教程-超级玛丽04-AppDelegate
代码下载链接 http://download.csdn.net/detail/yincheng01/6864893 解压密码:c.itcast.cn 背景 上一篇博文提到在CCApplication: ...
- cocos2d-x游戏开发系列教程-超级玛丽02-代码结构
代码下载链接 http://download.csdn.net/detail/yincheng01/6864893 解压密码:c.itcast.cn 前景回顾 上一篇博文提到超级马里奥的游戏效果,大家 ...
随机推荐
- uva 10026 Shoemaker's Problem(排序)
题目连接:10026 Shoemaker's Problem 题目大意:有一个鞋匠接了n双要修的鞋子, 修每双鞋需要d天,每推迟一天修将亏损val元,问按什么样的顺序修鞋可以保证损失最少,如果有多种情 ...
- 【转】sqlserver数据库之间的表的复制
以下以数据库t1和test为例. 1.复制表结构及资料 select * into 数据库名.dbo.表名 from 源表(全部数据) 如:select * into t1.dbo.YS1 ...
- IWebBrowser隐藏滚动条
刚才在项目里看到一个IWebBrowser2,竟然需要通过MoveWindow的方式把滚动条遮挡,如果要缩小IWebBrowser2控件的显示大小呢?这种方法至少我用不习惯,起码也得从源头解决这样的问 ...
- PHP学习笔记7-JSON数据操作
JSON,全称是JavaScript Object Notation.它是基于JavaScript编程语言ECMA-262 3rd Edition-December 1999标准的一种轻量级的数据交换 ...
- GCD 之 同步 异步 并发
1. dispatch_async(dispatch_get_global_queue(, ), ^{ // 处理耗时操作的代码块... //通知主线程刷新 dispatch_async(dispat ...
- (Problem 41)Pandigital prime
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly o ...
- 高质量程序设计指南C/C++语言——内存管理
• free()和delete只是把指针所指的内容给释放掉,并没有把指针本身删掉.指针被free()或delete以后其地址仍然不变(不等于NULL),只是该地址对应的内存是垃圾——p成了野指针.如果 ...
- [转]IOS 学习笔记(8) 滚动视图(UIScrollView)的使用方法
下面介绍pageControl结合ScrollView实现连续滑动翻页的效果,ScrollView我们在应用开发中经常用到,以g这种翻页效果还是很好看的,如下图所示: 通过这个例子,我们重点学习UIS ...
- Ajax 生成流文件下载 以及复选框的实现
JQuery的ajax函数的返回类型只有xml.text.json.html等类型,没有“流”类型,所以我们要实现ajax下载,不能够使用相应的ajax函数进行文件下载.但可以用js生成一个form, ...
- Qt socket中怎么传结构体?
直接发送和接收结构体,例如:struct A {...};struct A objectA; 发送的时候: tcpSocket->write((char *)&objectA, size ...