cocos2d-x 45度斜地图的应用

原文地址:http://blog.csdn.net/dingxiaowei2013/article/details/11894879


前言:

我们在做经典的格斗类的游戏的时候,场景常常用的是45°斜地图来创建的。下面我就来实现一个简单的Demo来展现一下斜地图的使用。

功能实现:

1.倾斜地图的加载;

2.点击地图居中;

3.主角只能在一定的范围内移动;

4.鼠标点击屏幕,主角移动一格,如果连续点击则主句不断的移动;

代码实现:

图层要设置z轴属性,方便可以隐藏主角:
在图层的属性中加上 cc_vertexz -400
如果前面的图层那就设置为automatic

在AppDelegate添加代码:

  1. //深度测试,方便实现遮盖效果
  2. CCDirector::sharedDirector()->setDepthTest(true);
  3. //Opengl渲染设置,如果地图有背景图层的话就需要加这句
  4. CCDirector::sharedDirector()->setProjection(kCCDirectorProjection2D);

Player类:

  1. #ifndef___5tilemap__Player__
  2. #define___5tilemap__Player__
  3. #include<iostream>
  4. #include"cocos2d.h"
  5. usingnamespacecocos2d;
  6. classPlayer:publicCCSprite
  7. {
  8. public:
  9. staticPlayer*create();
  10. virtualboolinitPlayer();
  11. voidupdateVertextZ(CCPointtilePos,CCTMXTiledMap*tileMap);
  12. };
  13. #endif/*defined(___5tilemap__Player__)*/

  1. #include"Player.h"
  2. staticPlayer*s;
  3. Player*Player::create()
  4. {
  5. s=newPlayer();
  6. if(s&&s->initPlayer()){
  7. s->autorelease();
  8. returns;
  9. }
  10. else
  11. {
  12. deletes;
  13. s=NULL;
  14. returnNULL;
  15. }
  16. }
  17. boolPlayer::initPlayer()
  18. {
  19. if(!CCSprite::initWithFile("ninja.png")){
  20. returnfalse;
  21. }
  22. returntrue;
  23. }
  24. voidPlayer::updateVertextZ(cocos2d::CCPointtilePos,cocos2d::CCTMXTiledMap*tileMap)
  25. {
  26. floatlowestZ=-(tileMap->getMapSize().width+tileMap->getMapSize().height);
  27. floatcurrentZ=tilePos.x+tilePos.y;
  28. this->setVertexZ(lowestZ+currentZ-1);
  29. }


HelloWorld.h:

  1. #ifndef__HELLOWORLD_SCENE_H__
  2. #define__HELLOWORLD_SCENE_H__
  3. #include"cocos2d.h"
  4. #include"Player.h"
  5. usingnamespacecocos2d;
  6. typedefenum{
  7. MoveDirectionNone=0,
  8. MoveDirectionUpperLeft,
  9. MoveDirectionLowerLeft,
  10. MoveDirectionUpperRight,
  11. MoveDirectionLowerRight,
  12. MAX_MoveDirections
  13. }EMoveDirection;
  14. classHelloWorld:publiccocos2d::CCLayer
  15. {
  16. public:
  17. //Method'init'incocos2d-xreturnsbool,insteadof'id'incocos2d-iphone(anobjectpointer)
  18. virtualboolinit();
  19. //there'sno'id'incpp,sowerecommendtoreturntheclassinstancepointer
  20. staticcocos2d::CCScene*scene();
  21. CREATE_FUNC(HelloWorld);
  22. virtualvoidccTouchesBegan(CCSet*pTouches,CCEvent*pEvent);
  23. CCPointlocationFromTouches(CCSet*touches);
  24. Player*player;
  25. CCPointplayableAreaMin,playableAreaMax;
  26. //获取瓷砖块的坐标
  27. CCPointtilePosFromLocation(CCPointlocation,CCTMXTiledMap*tilemap);
  28. //图层居中
  29. voidcenterTileMapOnTileCoord(CCPointtilePos,CCTMXTiledMap*tileMap);
  30. virtualvoidccTouchesEnded(CCSet*pTouches,CCEvent*pEvent);
  31. CCPointscreenCenter;
  32. CCTMXTiledMap*tileMap;
  33. CCRectupperLeft,lowerLeft,upperRight,lowerRight;
  34. CCPointmoveOffsets[MAX_MoveDirections];
  35. EMoveDirectioncurrentMoveDirection;
  36. voidupdate(floatdelta);
  37. CCPointensureTilePosIsWithinBounds(CCPointtilePos);
  38. };
  39. #endif//__HELLOWORLD_SCENE_H__

HelloWorldScene.cpp

  1. #include"HelloWorldScene.h"
  2. #include"SimpleAudioEngine.h"
  3. #include"Player.h"
  4. usingnamespacecocos2d;
  5. usingnamespaceCocosDenshion;
  6. CCScene*HelloWorld::scene()
  7. {
  8. //'scene'isanautoreleaseobject
  9. CCScene*scene=CCScene::create();
  10. //'layer'isanautoreleaseobject
  11. HelloWorld*layer=HelloWorld::create();
  12. //addlayerasachildtoscene
  13. scene->addChild(layer);
  14. //returnthescene
  15. returnscene;
  16. }
  17. //on"init"youneedtoinitializeyourinstance
  18. boolHelloWorld::init()
  19. {
  20. //1.superinitfirst
  21. if(!CCLayer::init())
  22. {
  23. returnfalse;
  24. }
  25. CCSizesize=CCDirector::sharedDirector()->getWinSize();
  26. //添加一个地图
  27. CCTMXTiledMap*tileMap=CCTMXTiledMap::create("huohuo.tmx");
  28. //CCTMXTiledMap*tileMap=CCTMXTiledMap::create("isometric.tmx");
  29. //tileMap->setAnchorPoint(CCPointMake(size.width/2,size.height/2));
  30. //tileMap->setPosition(CCPointMake(size.width/2,size.height/2));
  31. CCSizes=tileMap->getContentSize();
  32. CCLog("width:%f",-s.width/2);
  33. tileMap->setPosition(ccp(-s.width/2,0));
  34. this->addChild(tileMap,-1,1);
  35. this->setTouchEnabled(true);
  36. this->tileMap=tileMap;
  37. //添加主角精灵
  38. player=Player::create();
  39. player->setPosition(CCPointMake(size.width/2,size.height/2));
  40. player->setAnchorPoint(ccp(0.3f,0.1));
  41. this->addChild(player);
  42. constintborderSize=10;
  43. playableAreaMin=CCPointMake(borderSize,borderSize);
  44. playableAreaMax=CCPointMake(tileMap->getMapSize().width-1-borderSize,tileMap->getMapSize().height-1-borderSize);
  45. screenCenter=CCPointMake(size.width/2,size.height/2);
  46. upperLeft=CCRectMake(0,screenCenter.y,screenCenter.x,screenCenter.y);
  47. lowerLeft=CCRectMake(0,0,screenCenter.x,screenCenter.y);
  48. upperRight=CCRectMake(screenCenter.x,screenCenter.y,screenCenter.x,screenCenter.y);
  49. lowerRight=CCRectMake(screenCenter.x,0,screenCenter.x,screenCenter.y);
  50. moveOffsets[MoveDirectionNone]=CCPointZero;
  51. moveOffsets[MoveDirectionUpperLeft]=CCPointMake(-1,0);
  52. moveOffsets[MoveDirectionLowerLeft]=CCPointMake(0,1);
  53. moveOffsets[MoveDirectionUpperRight]=CCPointMake(0,-1);
  54. moveOffsets[MoveDirectionLowerRight]=CCPointMake(1,0);
  55. currentMoveDirection=MoveDirectionNone;
  56. //通过预约的更新方法来检查角色的移动
  57. this->scheduleUpdate();
  58. returntrue;
  59. }
  60. //返回点击的坐标点
  61. CCPointHelloWorld::locationFromTouches(cocos2d::CCSet*touches)
  62. {
  63. CCTouch*touch=(CCTouch*)touches->anyObject();
  64. returntouch->getLocation();
  65. }
  66. voidHelloWorld::ccTouchesBegan(cocos2d::CCSet*pTouches,cocos2d::CCEvent*pEvent)
  67. {
  68. //CCNode*node=this->getChildByTag(1);
  69. //CCTMXTiledMap*tileMap=(CCTMXTiledMap*)node;
  70. //CCPointtouchLocation=this->locationFromTouches(pTouches);
  71. //CCPointtilepos=this->tilePosFromLocation(touchLocation,tileMap);
  72. //CCLog("%f,%f",tilepos.x,tilepos.y);
  73. //
  74. //this->centerTileMapOnTileCoord(tilepos,tileMap);
  75. //
  76. //player->updateVertextZ(tilepos,tileMap);
  77. CCTouch*touch=(CCTouch*)pTouches->anyObject();
  78. CCPointtouchLocation=touch->getLocation();
  79. if(upperLeft.containsPoint(touchLocation)){
  80. currentMoveDirection=MoveDirectionUpperLeft;
  81. }
  82. elseif(lowerLeft.containsPoint(touchLocation))
  83. {
  84. currentMoveDirection=MoveDirectionLowerLeft;
  85. }
  86. elseif(upperRight.containsPoint(touchLocation))
  87. {
  88. currentMoveDirection=MoveDirectionUpperRight;
  89. }
  90. elseif(lowerRight.containsPoint(touchLocation))
  91. {
  92. currentMoveDirection=MoveDirectionLowerRight;
  93. }
  94. }
  95. //获取瓷砖块的坐标
  96. CCPointHelloWorld::tilePosFromLocation(cocos2d::CCPointlocation,cocos2d::CCTMXTiledMap*tilemap)
  97. {
  98. CCPointpos=ccpSub(location,tilemap->getPosition());
  99. floathalfMapWidth=tilemap->getMapSize().width*0.5f;
  100. floatmapHeight=tilemap->getMapSize().height;
  101. floattileWidth=tilemap->getTileSize().width;
  102. floattileHeight=tilemap->getTileSize().height;
  103. CCPointtilePasDiv=ccp(pos.x/tileWidth,pos.y/tileHeight);
  104. floatinverseTileY=mapHeight-tilePasDiv.y;
  105. floatposX=(int)(inverseTileY+tilePasDiv.x-halfMapWidth);
  106. floatposY=(int)(inverseTileY-tilePasDiv.x+halfMapWidth);
  107. //posX=MAX(0,posX);
  108. //posX=MIN(tilemap->getMapSize().width-1,posX);
  109. //posY=MAX(0,posY);
  110. //posY=MIN(tilemap->getMapSize().height-1,posY);
  111. posX=MAX(playableAreaMin.x,posX);
  112. posX=MIN(playableAreaMax.x,posX);
  113. posY=MAX(playableAreaMin.y,posY);
  114. posY=MIN(playableAreaMax.y,posY);
  115. pos=CCPointMake(posX,posY);
  116. returnpos;
  117. }
  118. //将地图居中
  119. voidHelloWorld::centerTileMapOnTileCoord(cocos2d::CCPointtilePos,cocos2d::CCTMXTiledMap*tileMap)
  120. {
  121. //获取屏幕大小和屏幕中心点
  122. CCSizesize=CCDirector::sharedDirector()->getWinSize();
  123. CCPointscreenCenter=CCPointMake(size.width/2,size.height/2);
  124. //获取地板层
  125. CCTMXLayer*layer=tileMap->layerNamed("Ground");
  126. //CCTMXLayer*layer=tileMap->layerNamed("GroundLayer1");
  127. //仅仅在内部使用;瓷砖的Y坐标减去1
  128. tilePos.y-=1;
  129. //获取瓷砖块坐标
  130. CCPointscrollPosition=layer->positionAt(tilePos);
  131. //考虑到地图移动的情况,我将像素坐标信息乘以-1,从而得到负值
  132. scrollPosition=ccpMult(scrollPosition,-1);
  133. //为屏幕中央坐标添加位移值
  134. scrollPosition=ccpAdd(scrollPosition,screenCenter);
  135. CCMoveTo*move=CCMoveTo::create(.2f,scrollPosition);
  136. tileMap->stopAllActions();
  137. tileMap->runAction(move);
  138. }
  139. voidHelloWorld::update(floatdelta)
  140. {
  141. if(tileMap->numberOfRunningActions()==0){
  142. if(currentMoveDirection!=MoveDirectionNone){
  143. CCPointtilePos=this->tilePosFromLocation(screenCenter,tileMap);
  144. CCPointoffset=moveOffsets[currentMoveDirection];
  145. tilePos=CCPointMake(tilePos.x+offset.x,tilePos.y+offset.y);
  146. tilePos=this->ensureTilePosIsWithinBounds(tilePos);
  147. this->centerTileMapOnTileCoord(tilePos,tileMap);
  148. }
  149. }
  150. //连续不断的修改角色的vertexz的值
  151. CCPointtilePos=this->tilePosFromLocation(tilePos,tileMap);
  152. player->updateVertextZ(tilePos,tileMap);
  153. }
  154. CCPointHelloWorld::ensureTilePosIsWithinBounds(CCPointtilePos)
  155. {
  156. tilePos.x=MAX(playableAreaMin.x,tilePos.x);
  157. tilePos.x=MIN(playableAreaMax.x,tilePos.x);
  158. tilePos.y=MAX(playableAreaMin.y,tilePos.y);
  159. tilePos.y=MIN(playableAreaMax.y,tilePos.y);
  160. returntilePos;
  161. }
  162. voidHelloWorld::ccTouchesEnded(cocos2d::CCSet*pTouches,cocos2d::CCEvent*pEvent)
  163. {
  164. currentMoveDirection=MoveDirectionNone;
  165. }


实现效果:



源码下载:

http://download.csdn.net/detail/s10141303/6302839

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值