由于学习的过程中,大部分学习过了,过段时间会忘记,所以下面我学习了杨丰盛老师的地图系统中的一些重点,和难点,都统一给分析下来,好以后回头看,一目了然,希望看到我文章的人,也有一些的帮助,在描述的过程中,如果有错误,请提出,我会在最快的时间内给予改正,谢谢!
废话就不多说了,先贴整体代码出来,看给予大家浏览,不懂后面有分析
#include "HelloMap.h"
USING_NS_CC;
#define MAPTILDSIZE 33 //经常使用的参数
typedef enum _CONTROLTAG //枚举菜单按钮
{
TAG_UP=100,TAG_DOWN,TAG_LEFT,TAG_RIGHT,TAG_FIRE
}CONTROLTAG;
CCScene* HelloMap::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
HelloMap *layer = HelloMap::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloMap::init()
{
//
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
_mapTild = CCTMXTiledMap::create("map.tmx");
_mapTild->setPosition(CCPointZero);
this->addChild(_mapTild);
_SpriteNPC = CCSprite::create("SpinningPeas.png");
_SpriteNPC->setPosition(ccp(MAPTILDSIZE/2,MAPTILDSIZE/2));
_mapTild->addChild(_SpriteNPC);
CCMenuItemFont* upMenuItem = CCMenuItemFont::create("UP",this,menu_selector(HelloMap::menuCallback));
CCMenuItemFont* downMenuItem = CCMenuItemFont::create("DOWN",this,menu_selector(HelloMap::menuCallback));
CCMenuItemFont* leftMenuItem = CCMenuItemFont::create("LEFT",this,menu_selector(HelloMap::menuCallback));
CCMenuItemFont* rightMenuItem = CCMenuItemFont::create("RIGHT",this,menu_selector(HelloMap::menuCallback));
CCMenuItemFont* fireMenuItem = CCMenuItemFont::create("FIRE",this,menu_selector(HelloMap::menuCallback));
CCMenu* Menu = CCMenu::create(upMenuItem,downMenuItem,leftMenuItem,rightMenuItem,fireMenuItem,NULL);
Menu->setPosition(CCPointZero);
this->addChild(Menu);
upMenuItem->setPosition(ccp(screenSize.width/2,screenSize.height-30));
downMenuItem->setPosition(ccp(screenSize.width/2,30));
leftMenuItem->setPosition(ccp(50,screenSize.height/2));
rightMenuItem->setPosition(ccp(screenSize.width-50,screenSize.height/2));
fireMenuItem->setPosition(ccp(50,screenSize.height-30));
upMenuItem->setTag(TAG_UP);
downMenuItem->setTag(TAG_DOWN);
leftMenuItem->setTag(TAG_LEFT);
rightMenuItem->setTag(TAG_RIGHT);
fireMenuItem->setTag(TAG_FIRE);
return true;
}
void HelloMap::menuCallback(CCObject* pSender)
{
CCMenuItem *item = (CCMenuItem*) pSender;
int tag = item->getTag();
CCPoint spriteCurPos =ccp((int)(_SpriteNPC->getPositionX()/MAPTILDSIZE),_mapTild->getMapSize().height-1-(int)(_SpriteNPC->getPositionY()/MAPTILDSIZE)) ; //获取精灵所在格子的位置
CCPoint spriteNextPos =spriteCurPos;//精灵移动下一个位置
CCTMXLayer *ly = _mapTild->layerNamed("layer2"); //读取地图的层
int gID = 0; //用于存放GID
switch (tag)
{
case TAG_UP:
spriteNextPos.y -=1;//精灵下一个精灵的位置
if(spriteNextPos.y<=0)return;
gID = ly->tileGIDAt(spriteNextPos);//获取地图的GID
if(gID)return;
if (_mapTild->getContentSize().height+_mapTild->getPositionY()>320+MAPTILDSIZE)//地图的总高度+地图的Y轴是否大于屏幕的大小,
{
if(_SpriteNPC->getPositionY()+_mapTild->getPositionY()>160){ //判断精灵是否去到屏幕Y轴的中心点 ,如果是,地图跟着移动,如果不是,精灵移动
_mapTild->setPosition(ccp(_mapTild->getPositionX(),_mapTild->getPositionY()-MAPTILDSIZE));
}
_SpriteNPC ->setPosition(ccp(_SpriteNPC->getPositionX(),_SpriteNPC->getPositionY()+MAPTILDSIZE));
}else if(_SpriteNPC->getPositionY()<_mapTild->getContentSize().height-MAPTILDSIZE){//
_SpriteNPC ->setPosition(ccp(_SpriteNPC->getPositionX(),_SpriteNPC->getPositionY()+MAPTILDSIZE));
}
break;
case TAG_DOWN:
spriteNextPos.y+= 1;
if(spriteNextPos.y>_mapTild->getMapSize().height-1)return;
gID = ly->tileGIDAt(spriteNextPos);
if(gID)return;
if(_mapTild->getPositionY()<0) //如果地图的Y轴小于0就执行,精灵跟地图一起移动,否则精灵移动
{
if(_SpriteNPC->getPositionY()+_mapTild->getPositionY()<160){
_mapTild->setPosition(ccp(_mapTild->getPositionX(),_mapTild->getPositionY()+MAPTILDSIZE));
}
_SpriteNPC ->setPosition(ccp(_SpriteNPC->getPositionX(),_SpriteNPC->getPositionY()-MAPTILDSIZE));
}else if(_SpriteNPC->getPositionY()>MAPTILDSIZE){//如果精灵的Y轴大于一个位置的大小,则执行精灵移动
_SpriteNPC ->setPosition(ccp(_SpriteNPC->getPositionX(),_SpriteNPC->getPositionY()-MAPTILDSIZE));
}
break;
case TAG_LEFT:
spriteNextPos.x-=1;
if(spriteNextPos.x<=0)return;
gID = ly->tileGIDAt(spriteNextPos);
if(gID)return;
if(_mapTild->getPositionX()<0){
if(_SpriteNPC->getPositionX()+_mapTild->getPositionX()<240){
_mapTild->setPosition(ccp(_mapTild->getPositionX()+MAPTILDSIZE,_mapTild->getPositionY()));
}
_SpriteNPC->setPosition(ccp(_SpriteNPC->getPositionX()-MAPTILDSIZE,_SpriteNPC->getPositionY()));
}else if(_SpriteNPC->getPositionX()>MAPTILDSIZE){
_SpriteNPC->setPosition(ccp(_SpriteNPC->getPositionX()-MAPTILDSIZE,_SpriteNPC->getPositionY()));
}
break;
case TAG_RIGHT:
spriteNextPos.x+=1;
if(spriteNextPos.x>_mapTild->getMapSize().width-1)return;
gID = ly->tileGIDAt(spriteNextPos);
if(gID)return;
if(_mapTild->getContentSize().width+_mapTild->getPositionX()>480+MAPTILDSIZE/2){
if(_SpriteNPC->getPositionX()+_mapTild->getPositionX()>240){
_mapTild->setPosition(ccp(_mapTild->getPositionX()-MAPTILDSIZE,_mapTild->getPositionY()));
}
_SpriteNPC ->setPosition(ccp(_SpriteNPC->getPositionX()+MAPTILDSIZE,_SpriteNPC->getPositionY()));
}else if(_SpriteNPC->getPositionX()<_mapTild->getContentSize().width-MAPTILDSIZE){
_SpriteNPC ->setPosition(ccp(_SpriteNPC->getPositionX()+MAPTILDSIZE,_SpriteNPC->getPositionY()));
}
break;
case TAG_FIRE:
ly->setTileGID(46,spriteCurPos);
default:
break;
}
}
创建精灵,这个我想不用多说吧,
_SpriteNPC = CCSprite::create("SpinningPeas.png");
_SpriteNPC->setPosition(ccp(MAPTILDSIZE/2,MAPTILDSIZE/2));
_mapTild->addChild(_SpriteNPC);
载入地图
_mapTild = CCTMXTiledMap::create("map.tmx");
_mapTild->setPosition(CCPointZero);
this->addChild(_mapTild);
创建菜单按钮 设置菜单按钮的位置,设置菜单按钮标签
CCMenuItemFont* upMenuItem = CCMenuItemFont::create("UP",this,menu_selector(HelloMap::menuCallback));
CCMenuItemFont* downMenuItem = CCMenuItemFont::create("DOWN",this,menu_selector(HelloMap::menuCallback));
CCMenuItemFont* leftMenuItem = CCMenuItemFont::create("LEFT",this,menu_selector(HelloMap::menuCallback));
CCMenuItemFont* rightMenuItem = CCMenuItemFont::create("RIGHT",this,menu_selector(HelloMap::menuCallback));
CCMenuItemFont* fireMenuItem = CCMenuItemFont::create("FIRE",this,menu_selector(HelloMap::menuCallback));
CCMenu* Menu = CCMenu::create(upMenuItem,downMenuItem,leftMenuItem,rightMenuItem,fireMenuItem,NULL);
Menu->setPosition(CCPointZero);
this->addChild(Menu);
upMenuItem->setPosition(ccp(screenSize.width/2,screenSize.height-30));
downMenuItem->setPosition(ccp(screenSize.width/2,30));
leftMenuItem->setPosition(ccp(50,screenSize.height/2));
rightMenuItem->setPosition(ccp(screenSize.width-50,screenSize.height/2));
fireMenuItem->setPosition(ccp(50,screenSize.height-30));
upMenuItem->setTag(TAG_UP);
downMenuItem->setTag(TAG_DOWN);
leftMenuItem->setTag(TAG_LEFT);
rightMenuItem->setTag(TAG_RIGHT);
fireMenuItem->setTag(TAG_FIRE);
其中菜单按钮中的响应事件,需要设置,这里我给大家剖析按钮所发生的事件是什么原理,这里我只列举一个 向上的按钮,
首先,我们要让精灵在屏幕上移动,我们可以移动几个像素,这个可以设置, 这里我采用移动32像素,
_SpriteNPC ->setPosition(ccp(_SpriteNPC->getPositionX(),_SpriteNPC->getPositionY()+MAPTILDSIZE));
如果有一张地图大于屏幕的尺寸,这里我们如何让精灵在地图上移动呢,这时候我们应该要想到精灵向前移动,地图向后移动这样就可以达到一个错位的效果,相当于精灵向前移动
_mapTild->setPosition(ccp(_mapTild->getPositionX(),_mapTild->getPositionY()-MAPTILDSIZE));
看懂没? 不懂,就慢慢思考吧, 当然地图层不可以一直向下移动,也有一个临界点,就是地图层 与屏幕层重合的时候,就停止移动
这时候就有一个条件了
_mapTild->getContentSize().height+_mapTild->getPositionY()>320 中文意思
地图总高度+地图Y轴的坐标(向下移动,坐标为负的) 大于320 还不懂?请思考
_mapTild->getContentSize().height+_mapTild->getPositionY()-320>0 ,这懂了吧?
地图向下移动了,但是精灵这时候向上移动的时候,不可能无止境的向上移动,这时候精灵移动也是有限制的,同样是重合线为终止线
if(_SpriteNPC->getPositionY()<_mapTild->getContentSize().height-MAPTILDSIZE)
精灵Y轴的坐标小于地图层的高度(320)减去一个单元图片像素
完成了? 没有完成,因为我们的主角不是在屏幕的中间,这游戏怎么玩?
if(_SpriteNPC->getPositionY()+_mapTild->getPositionY()>160){ //判断精灵是否去到屏幕Y轴的中心点 ,如果是,地图跟着移动,如果不是,精灵移动
_mapTild->setPosition(ccp(_mapTild->getPositionX(),_mapTild->getPositionY()-MAPTILDSIZE));
}
_SpriteNPC ->setPosition(ccp(_SpriteNPC->getPositionX(),_SpriteNPC->getPositionY()+MAPTILDSIZE));
精灵的Y轴+地图的Y轴大于160 地图移动,否则精灵移动 ,
给精灵设置障碍物
CCTMXLayer *ly = _mapTild->layerNamed("layer2"); //读取地图障碍物的层
这时候我们要判断精灵的下一步是否有障碍物
CCPoint spriteCurPos =ccp((int)(_SpriteNPC->getPositionX()/MAPTILDSIZE),_mapTild->getMapSize().height-1-(int)(_SpriteNPC->getPositionY()/MAPTILDSIZE)) ; //获取精灵所在格子的位置
CCPoint spriteNextPos =spriteCurPos;//精灵移动下一个位置
在精灵的按钮事件上添加
spriteNextPos.y -=1;//精灵下一个精灵的位置
if(spriteNextPos.y<=0)return;
gID = ly->tileGIDAt(spriteNextPos);//获取地图的GID
if(gID)return;
好了,就总结到这里.下期再见!