原文地址:http://blog.csdn.net/dingxiaowei2013/article/details/11894879
前言:
我们在做经典的格斗类的游戏的时候,场景常常用的是45°斜地图来创建的。下面我就来实现一个简单的Demo来展现一下斜地图的使用。
功能实现:
1.倾斜地图的加载;
2.点击地图居中;
3.主角只能在一定的范围内移动;
4.鼠标点击屏幕,主角移动一格,如果连续点击则主句不断的移动;
代码实现:
图层要设置z轴属性,方便可以隐藏主角:
在图层的属性中加上 cc_vertexz -400
如果前面的图层那就设置为automatic
在AppDelegate添加代码:
- //深度测试,方便实现遮盖效果
- CCDirector::sharedDirector()->setDepthTest(true);
- //Opengl渲染设置,如果地图有背景图层的话就需要加这句
- CCDirector::sharedDirector()->setProjection(kCCDirectorProjection2D);
Player类:
- #ifndef___5tilemap__Player__
- #define___5tilemap__Player__
- #include<iostream>
- #include"cocos2d.h"
- usingnamespacecocos2d;
- classPlayer:publicCCSprite
- {
- public:
- staticPlayer*create();
- virtualboolinitPlayer();
- voidupdateVertextZ(CCPointtilePos,CCTMXTiledMap*tileMap);
- };
- #endif/*defined(___5tilemap__Player__)*/
- #include"Player.h"
- staticPlayer*s;
- Player*Player::create()
- {
- s=newPlayer();
- if(s&&s->initPlayer()){
- s->autorelease();
- returns;
- }
- else
- {
- deletes;
- s=NULL;
- returnNULL;
- }
- }
- boolPlayer::initPlayer()
- {
- if(!CCSprite::initWithFile("ninja.png")){
- returnfalse;
- }
- returntrue;
- }
- voidPlayer::updateVertextZ(cocos2d::CCPointtilePos,cocos2d::CCTMXTiledMap*tileMap)
- {
- floatlowestZ=-(tileMap->getMapSize().width+tileMap->getMapSize().height);
- floatcurrentZ=tilePos.x+tilePos.y;
- this->setVertexZ(lowestZ+currentZ-1);
- }
HelloWorld.h:
- #ifndef__HELLOWORLD_SCENE_H__
- #define__HELLOWORLD_SCENE_H__
- #include"cocos2d.h"
- #include"Player.h"
- usingnamespacecocos2d;
- typedefenum{
- MoveDirectionNone=0,
- MoveDirectionUpperLeft,
- MoveDirectionLowerLeft,
- MoveDirectionUpperRight,
- MoveDirectionLowerRight,
- MAX_MoveDirections
- }EMoveDirection;
- classHelloWorld:publiccocos2d::CCLayer
- {
- public:
- //Method'init'incocos2d-xreturnsbool,insteadof'id'incocos2d-iphone(anobjectpointer)
- virtualboolinit();
- //there'sno'id'incpp,sowerecommendtoreturntheclassinstancepointer
- staticcocos2d::CCScene*scene();
- CREATE_FUNC(HelloWorld);
- virtualvoidccTouchesBegan(CCSet*pTouches,CCEvent*pEvent);
- CCPointlocationFromTouches(CCSet*touches);
- Player*player;
- CCPointplayableAreaMin,playableAreaMax;
- //获取瓷砖块的坐标
- CCPointtilePosFromLocation(CCPointlocation,CCTMXTiledMap*tilemap);
- //图层居中
- voidcenterTileMapOnTileCoord(CCPointtilePos,CCTMXTiledMap*tileMap);
- virtualvoidccTouchesEnded(CCSet*pTouches,CCEvent*pEvent);
- CCPointscreenCenter;
- CCTMXTiledMap*tileMap;
- CCRectupperLeft,lowerLeft,upperRight,lowerRight;
- CCPointmoveOffsets[MAX_MoveDirections];
- EMoveDirectioncurrentMoveDirection;
- voidupdate(floatdelta);
- CCPointensureTilePosIsWithinBounds(CCPointtilePos);
- };
- #endif//__HELLOWORLD_SCENE_H__
- #include"HelloWorldScene.h"
- #include"SimpleAudioEngine.h"
- #include"Player.h"
- usingnamespacecocos2d;
- usingnamespaceCocosDenshion;
- CCScene*HelloWorld::scene()
- {
- //'scene'isanautoreleaseobject
- CCScene*scene=CCScene::create();
- //'layer'isanautoreleaseobject
- HelloWorld*layer=HelloWorld::create();
- //addlayerasachildtoscene
- scene->addChild(layer);
- //returnthescene
- returnscene;
- }
- //on"init"youneedtoinitializeyourinstance
- boolHelloWorld::init()
- {
- //1.superinitfirst
- if(!CCLayer::init())
- {
- returnfalse;
- }
- CCSizesize=CCDirector::sharedDirector()->getWinSize();
- //添加一个地图
- CCTMXTiledMap*tileMap=CCTMXTiledMap::create("huohuo.tmx");
- //CCTMXTiledMap*tileMap=CCTMXTiledMap::create("isometric.tmx");
- //tileMap->setAnchorPoint(CCPointMake(size.width/2,size.height/2));
- //tileMap->setPosition(CCPointMake(size.width/2,size.height/2));
- CCSizes=tileMap->getContentSize();
- CCLog("width:%f",-s.width/2);
- tileMap->setPosition(ccp(-s.width/2,0));
- this->addChild(tileMap,-1,1);
- this->setTouchEnabled(true);
- this->tileMap=tileMap;
- //添加主角精灵
- player=Player::create();
- player->setPosition(CCPointMake(size.width/2,size.height/2));
- player->setAnchorPoint(ccp(0.3f,0.1));
- this->addChild(player);
- constintborderSize=10;
- playableAreaMin=CCPointMake(borderSize,borderSize);
- playableAreaMax=CCPointMake(tileMap->getMapSize().width-1-borderSize,tileMap->getMapSize().height-1-borderSize);
- screenCenter=CCPointMake(size.width/2,size.height/2);
- upperLeft=CCRectMake(0,screenCenter.y,screenCenter.x,screenCenter.y);
- lowerLeft=CCRectMake(0,0,screenCenter.x,screenCenter.y);
- upperRight=CCRectMake(screenCenter.x,screenCenter.y,screenCenter.x,screenCenter.y);
- lowerRight=CCRectMake(screenCenter.x,0,screenCenter.x,screenCenter.y);
- moveOffsets[MoveDirectionNone]=CCPointZero;
- moveOffsets[MoveDirectionUpperLeft]=CCPointMake(-1,0);
- moveOffsets[MoveDirectionLowerLeft]=CCPointMake(0,1);
- moveOffsets[MoveDirectionUpperRight]=CCPointMake(0,-1);
- moveOffsets[MoveDirectionLowerRight]=CCPointMake(1,0);
- currentMoveDirection=MoveDirectionNone;
- //通过预约的更新方法来检查角色的移动
- this->scheduleUpdate();
- returntrue;
- }
- //返回点击的坐标点
- CCPointHelloWorld::locationFromTouches(cocos2d::CCSet*touches)
- {
- CCTouch*touch=(CCTouch*)touches->anyObject();
- returntouch->getLocation();
- }
- voidHelloWorld::ccTouchesBegan(cocos2d::CCSet*pTouches,cocos2d::CCEvent*pEvent)
- {
- //CCNode*node=this->getChildByTag(1);
- //CCTMXTiledMap*tileMap=(CCTMXTiledMap*)node;
- //CCPointtouchLocation=this->locationFromTouches(pTouches);
- //CCPointtilepos=this->tilePosFromLocation(touchLocation,tileMap);
- //CCLog("%f,%f",tilepos.x,tilepos.y);
- //
- //this->centerTileMapOnTileCoord(tilepos,tileMap);
- //
- //player->updateVertextZ(tilepos,tileMap);
- CCTouch*touch=(CCTouch*)pTouches->anyObject();
- CCPointtouchLocation=touch->getLocation();
- if(upperLeft.containsPoint(touchLocation)){
- currentMoveDirection=MoveDirectionUpperLeft;
- }
- elseif(lowerLeft.containsPoint(touchLocation))
- {
- currentMoveDirection=MoveDirectionLowerLeft;
- }
- elseif(upperRight.containsPoint(touchLocation))
- {
- currentMoveDirection=MoveDirectionUpperRight;
- }
- elseif(lowerRight.containsPoint(touchLocation))
- {
- currentMoveDirection=MoveDirectionLowerRight;
- }
- }
- //获取瓷砖块的坐标
- CCPointHelloWorld::tilePosFromLocation(cocos2d::CCPointlocation,cocos2d::CCTMXTiledMap*tilemap)
- {
- CCPointpos=ccpSub(location,tilemap->getPosition());
- floathalfMapWidth=tilemap->getMapSize().width*0.5f;
- floatmapHeight=tilemap->getMapSize().height;
- floattileWidth=tilemap->getTileSize().width;
- floattileHeight=tilemap->getTileSize().height;
- CCPointtilePasDiv=ccp(pos.x/tileWidth,pos.y/tileHeight);
- floatinverseTileY=mapHeight-tilePasDiv.y;
- floatposX=(int)(inverseTileY+tilePasDiv.x-halfMapWidth);
- floatposY=(int)(inverseTileY-tilePasDiv.x+halfMapWidth);
- //posX=MAX(0,posX);
- //posX=MIN(tilemap->getMapSize().width-1,posX);
- //posY=MAX(0,posY);
- //posY=MIN(tilemap->getMapSize().height-1,posY);
- posX=MAX(playableAreaMin.x,posX);
- posX=MIN(playableAreaMax.x,posX);
- posY=MAX(playableAreaMin.y,posY);
- posY=MIN(playableAreaMax.y,posY);
- pos=CCPointMake(posX,posY);
- returnpos;
- }
- //将地图居中
- voidHelloWorld::centerTileMapOnTileCoord(cocos2d::CCPointtilePos,cocos2d::CCTMXTiledMap*tileMap)
- {
- //获取屏幕大小和屏幕中心点
- CCSizesize=CCDirector::sharedDirector()->getWinSize();
- CCPointscreenCenter=CCPointMake(size.width/2,size.height/2);
- //获取地板层
- CCTMXLayer*layer=tileMap->layerNamed("Ground");
- //CCTMXLayer*layer=tileMap->layerNamed("GroundLayer1");
- //仅仅在内部使用;瓷砖的Y坐标减去1
- tilePos.y-=1;
- //获取瓷砖块坐标
- CCPointscrollPosition=layer->positionAt(tilePos);
- //考虑到地图移动的情况,我将像素坐标信息乘以-1,从而得到负值
- scrollPosition=ccpMult(scrollPosition,-1);
- //为屏幕中央坐标添加位移值
- scrollPosition=ccpAdd(scrollPosition,screenCenter);
- CCMoveTo*move=CCMoveTo::create(.2f,scrollPosition);
- tileMap->stopAllActions();
- tileMap->runAction(move);
- }
- voidHelloWorld::update(floatdelta)
- {
- if(tileMap->numberOfRunningActions()==0){
- if(currentMoveDirection!=MoveDirectionNone){
- CCPointtilePos=this->tilePosFromLocation(screenCenter,tileMap);
- CCPointoffset=moveOffsets[currentMoveDirection];
- tilePos=CCPointMake(tilePos.x+offset.x,tilePos.y+offset.y);
- tilePos=this->ensureTilePosIsWithinBounds(tilePos);
- this->centerTileMapOnTileCoord(tilePos,tileMap);
- }
- }
- //连续不断的修改角色的vertexz的值
- CCPointtilePos=this->tilePosFromLocation(tilePos,tileMap);
- player->updateVertextZ(tilePos,tileMap);
- }
- CCPointHelloWorld::ensureTilePosIsWithinBounds(CCPointtilePos)
- {
- tilePos.x=MAX(playableAreaMin.x,tilePos.x);
- tilePos.x=MIN(playableAreaMax.x,tilePos.x);
- tilePos.y=MAX(playableAreaMin.y,tilePos.y);
- tilePos.y=MIN(playableAreaMax.y,tilePos.y);
- returntilePos;
- }
- voidHelloWorld::ccTouchesEnded(cocos2d::CCSet*pTouches,cocos2d::CCEvent*pEvent)
- {
- currentMoveDirection=MoveDirectionNone;
- }
实现效果: