大多橫板游戲主角的移動都是有背景一起在移動的,不單單是主角在動。當主角的位置離地圖的左端距離小於屏幕寬度的一半或者主角離地圖最右端的距離小於屏幕寬度的一半時,觸屏之后就人物在移動,背景沒有動,當主角位於這端中間的位置時,觸屏之后主角移動的同時,背景也在往主角反方向移動,一旦當主角移動到兩端的內邊界時,背景就停止移動,只主角移動。
這段代碼放到這里做個備份,不是最終版,而且也不是性能最高的解決辦法,
當主角走到兩端時,背景偶爾會走多了出線黑邊,
功能:每次點擊屏幕之后,主角停止當前的動作,走到觸屏的那個點然后停下來。
1 // 2 // GameLayer.h 3 // PlayerActionTest 4 // 5 // Created by 嘉定 on 12-12-25. 6 // 7 // 8 9 #ifndef __PlayerActionTest__GameLayer__ 10 #define __PlayerActionTest__GameLayer__ 11 12 #include "cocos2d.h" 13 #include "Player.h" 14 #include "RangeLayer.h" 15 #include "TouchMoveHandle.h" 16 17 USING_NS_CC; 18 19 class GameLayer : public cocos2d::CCLayer 20 { 21 public: 22 23 GameLayer(); 24 25 26 CCLayer *container; 27 28 CCSprite *backBg; 29 CCSprite *frontBg; 30 31 Player *player; 32 CCLayer *bg; 33 34 void showBg(); 35 void showPlayer(); 36 37 38 virtual void onEnter(); 39 virtual void registerWithTouchDispatcher(); 40 virtual void ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent); 41 virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event); 42 virtual void ccTouchEnded(CCTouch* touch, CCEvent* event); 43 // virtual void ccTouchCancelled(CCTouch* touch, CCEvent* event); 44 // virtual void ccTouchMoved(CCTouch* touch, CCEvent* event); 45 46 47 CREATE_FUNC(GameLayer); 48 49 private: 50 CCPoint selfTargetPos;//相對於GameLayer這個容器的本地坐標 51 52 TouchMoveHandle *currentMoveHandle; 53 54 }; 55 56 #endif /* defined(__PlayerActionTest__GameLayer__) */
1 // 2 // GameLayer.cpp 3 // PlayerActionTest 4 // 5 // Created by 嘉定 on 12-12-25. 6 // 7 // 8 9 #include "GameLayer.h" 10 #include "TouchMoveHandle.h" 11 12 GameLayer::GameLayer() 13 { 14 15 } 16 17 void GameLayer::showPlayer() 18 { 19 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 20 21 //npc 22 Player *npc = Player::create(); 23 npc->setScale(1.5); 24 npc->setPosition(ccp(850,75)); 25 npc->playAction(Player::state_idle); 26 container->addChild(npc); 27 28 29 //標出原點 30 player = Player::create(); 31 player->setScale(1.5); 32 player->setPosition(ccp(winSize.width/2,95)); 33 player->playAction(Player::state_idle); 34 container->addChild(player); 35 36 37 } 38 39 void GameLayer::onEnter() 40 { 41 CCLayer::onEnter(); 42 } 43 44 void GameLayer::registerWithTouchDispatcher() 45 { 46 CCDirector* pDirector = CCDirector::sharedDirector(); 47 pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true); 48 } 49 50 bool GameLayer::ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event) 51 { 52 // CCLog("ccTouchBegan"); 53 //Gamelayer的寬度一直都是1136,而不會因為內部添加了frontBG而寬度增加 54 55 //全局坐標換算成GameLayer內部坐標系 56 selfTargetPos = ccp(touch->getLocation().x + abs(container->getPositionX()),touch->getLocation().y); 57 58 if(currentMoveHandle) 59 { 60 currentMoveHandle->destroy(); 61 currentMoveHandle->release(); 62 currentMoveHandle = NULL; 63 } 64 currentMoveHandle = TouchMoveHandle::create(); 65 currentMoveHandle->retain(); 66 currentMoveHandle->handle(player,backBg,frontBg,container,selfTargetPos); 67 68 return true; 69 } 70 71 void GameLayer::ccTouchEnded(cocos2d::CCTouch *touch, cocos2d::CCEvent *event) 72 { 73 // CCLog("ccTouchEnded"); 74 } 75 76 //void GameLayer::ccTouchCancelled(cocos2d::CCTouch *touch, cocos2d::CCEvent *event) 77 //{ 78 // CCLog("ccTouchCancelled"); 79 // 80 //} 81 82 void GameLayer::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent) 83 { 84 // CCLog("ccTouchesEnded"); 85 86 87 // CCSetIterator it = pTouches->begin(); 88 // CCTouch *touch = (CCTouch*)(*it); 89 // CCPoint location = touch->getLocation(); 90 // player->runTo(location); 91 // 92 } 93 94 //void GameLayer::ccTouchMoved(cocos2d::CCTouch *touch, cocos2d::CCEvent *event) 95 //{ 96 // 97 //} 98 99 void GameLayer::showBg() 100 { 101 setTouchEnabled(true); 102 103 container = CCLayer::create(); 104 105 106 107 108 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 109 frontBg = CCSprite::create("map/zhongjing.png"); 110 CCSize mapSize = frontBg->getContentSize(); 111 float mapScale = winSize.height / mapSize.height; 112 frontBg->setAnchorPoint(CCPointZero); 113 frontBg->setPosition(CCPointZero); 114 115 frontBg->setScale(mapScale); 116 117 backBg = CCSprite::create("map/beijing.png"); 118 CCSize backMapSize = backBg->getContentSize(); 119 backBg->setAnchorPoint(CCPointZero); 120 backBg->setScale(mapScale); 121 backBg->setPosition(ccp(0,winSize.height - (backMapSize.height * mapScale))); 122 123 addChild(backBg); 124 addChild(container); 125 container->addChild(frontBg); 126 127 RangeLayer *range = RangeLayer::create(); 128 CCSize size = CCSizeMake(frontBg->getContentSize().width * frontBg->getScale(), winSize.height); 129 range->setContentSize(size); 130 range->setLinePox(winSize.width/2, frontBg->getContentSize().width*frontBg->getScale()- winSize.width/2); 131 container->addChild(range); 132 }
1 // 2 // TouchMoveHandle.h 3 // PlayerActionTest 4 // 5 // Created by 嘉定 on 13-1-3. 6 // 7 // 此類負責地圖點擊移動的執行 8 // 主要處理人物和背景的移動,都是橫向移動,不包含y方向上的移動。 9 10 #ifndef __PlayerActionTest__TouchMoveHandle__ 11 #define __PlayerActionTest__TouchMoveHandle__ 12 13 #include "cocos2d.h" 14 #include "Player.h" 15 16 USING_NS_CC; 17 18 class TouchMoveHandle : public CCObject 19 { 20 public: 21 22 TouchMoveHandle(); 23 virtual ~TouchMoveHandle(); 24 25 typedef enum 26 { 27 leftToCenter = 1, 28 centerToLeft = 2, 29 rightToCenter = 3, 30 centerToRight = 4, 31 behaviorUnKnow = 5 32 }PlayerCrossBehavior; 33 34 void handle(Player *_player, CCSprite *_backBg,CCSprite *_centerBg,CCLayer *_container,CCPoint touchPoint); 35 36 37 virtual bool init(); 38 39 PlayerCrossBehavior moveBehavior; 40 41 void destroy(); 42 43 44 CREATE_FUNC(TouchMoveHandle); 45 46 private: 47 48 float winWidth; 49 Player *player; 50 CCSprite *backBg; 51 CCSprite *centerBg; 52 CCLayer *container; 53 54 55 float backBgWidth; 56 float centerBgWidth; 57 58 CCPoint targetPoint; 59 //左側判斷移動邊界 60 float leftSideX; 61 //右側判斷移動邊界 62 float rightSideX; 63 64 CCPoint getCrossSidePoint1(); 65 66 void moveContainer1(CCPoint target); 67 void playerCrollSideLineHandler(); 68 }; 69 70 #endif /* defined(__PlayerActionTest__TouchMoveHandle__) */
1 // 2 // TouchMoveHandle.cpp 3 // PlayerActionTest 4 // 5 // Created by 嘉定 on 13-1-3. 6 // 7 // 8 9 #include "TouchMoveHandle.h" 10 11 12 TouchMoveHandle::TouchMoveHandle(): 13 winWidth(0), 14 player(NULL), 15 backBg(NULL), 16 centerBg(NULL), 17 backBgWidth(0), 18 centerBgWidth(0), 19 leftSideX(0), 20 rightSideX(0), 21 moveBehavior(behaviorUnKnow) 22 { 23 24 } 25 26 TouchMoveHandle::~TouchMoveHandle() 27 { 28 CCLog("~TouchMoveHandle dispose"); 29 } 30 31 bool TouchMoveHandle::init() 32 { 33 CCNotificationCenter::sharedNotificationCenter()->addObserver(this, callfuncO_selector(TouchMoveHandle::playerCrollSideLineHandler),"playerIdle", NULL); 34 35 return true; 36 } 37 38 void TouchMoveHandle::destroy() 39 { 40 CCNotificationCenter::sharedNotificationCenter()->removeObserver(this, "playerIdle"); 41 42 } 43 44 void TouchMoveHandle::handle(Player *_player, CCSprite *_backBg,CCSprite *_centerBg,CCLayer *_container,CCPoint touchPoint) 45 { 46 player = _player; 47 winWidth = CCDirector::sharedDirector()->getWinSize().width; 48 backBg = _backBg; 49 centerBg = _centerBg; 50 container = _container; 51 backBgWidth = backBg->getContentSize().width * backBg->getScaleX(); 52 centerBgWidth = centerBg->getContentSize().width * centerBg->getScaleX(); 53 this->targetPoint = ccp(touchPoint.x,player->getPosition().y); 54 leftSideX = winWidth/2; 55 rightSideX = centerBgWidth - winWidth/2; 56 57 float playerCurrentX = player->getPosition().x; 58 59 //玩家在地圖左側 60 if(playerCurrentX <= leftSideX) 61 { 62 //targetPoint也在左側,就玩家動 63 if(targetPoint.x <= leftSideX) 64 { 65 moveBehavior = behaviorUnKnow; 66 player->runTo(targetPoint); 67 68 } 69 else //touchPoint在中間,先玩家跑到邊界,過界后背景和玩家一起動 70 { 71 moveBehavior = leftToCenter; 72 player->runTo(getCrossSidePoint1()); 73 } 74 } 75 else if(playerCurrentX > leftSideX && playerCurrentX < rightSideX)//玩家在中間 76 { 77 //targetPoint在左側,先玩家背景一起動,然后再只玩家動 78 if(targetPoint.x <= leftSideX) 79 { 80 CCPoint temp = getCrossSidePoint1(); 81 player->runTo(temp); 82 moveContainer1(temp); 83 moveBehavior = centerToLeft; 84 } 85 else if(targetPoint.x > leftSideX && targetPoint.x < rightSideX)//targetPoint在中間,一起動 86 { 87 player->runTo(targetPoint); 88 moveContainer1(targetPoint); 89 moveBehavior = behaviorUnKnow; 90 } 91 else if(targetPoint.x >= rightSideX)//targetPoint在右,先玩家跑到邊界,過界后背景和玩家一起動 92 { 93 CCPoint temp = ccp(rightSideX,player->getPositionY()); 94 player->runTo(temp); 95 moveContainer1(temp); 96 moveBehavior = centerToRight; 97 } 98 } 99 else if(playerCurrentX >= rightSideX)//玩家在右側 100 { 101 if(targetPoint.x < rightSideX)//targetPoint在中間 102 { 103 CCPoint temp = ccp(rightSideX,player->getPositionY()); 104 player->runTo(temp); 105 moveBehavior = rightToCenter; 106 } 107 else if(targetPoint.x >= rightSideX) 108 { 109 player->runTo(targetPoint); 110 moveBehavior = behaviorUnKnow; 111 } 112 } 113 114 115 } 116 117 void TouchMoveHandle::playerCrollSideLineHandler() 118 { 119 if(moveBehavior == leftToCenter) 120 { 121 moveBehavior = behaviorUnKnow; 122 player->runTo(targetPoint); 123 moveContainer1(targetPoint); 124 } 125 else if(moveBehavior == centerToLeft) 126 { 127 moveBehavior = behaviorUnKnow; 128 container->stopAllActions(); 129 container->setPositionX(0); 130 backBg->stopAllActions(); 131 backBg->setPositionX(0); 132 player->runTo(targetPoint); 133 } 134 else if(moveBehavior == centerToRight) 135 { 136 moveBehavior = behaviorUnKnow; 137 container->stopAllActions(); 138 container->setPositionX(winWidth-centerBgWidth); 139 backBg->stopAllActions(); 140 backBg->setPositionX(winWidth-backBgWidth); 141 player->runTo(targetPoint); 142 } 143 else if(moveBehavior == rightToCenter) 144 { 145 moveBehavior = behaviorUnKnow; 146 player->runTo(targetPoint); 147 moveContainer1(targetPoint); 148 } 149 150 } 151 152 CCPoint TouchMoveHandle::getCrossSidePoint1() 153 { 154 CCPoint crossPoint = ccp(leftSideX,player->getPositionY()); 155 return crossPoint; 156 } 157 158 void TouchMoveHandle::moveContainer1(CCPoint target) 159 { 160 container->stopAllActions(); 161 backBg->stopAllActions(); 162 163 const float SPEED = 12; 164 float currentPlayerPosX = player->getPosition().x; 165 float disX = target.x - currentPlayerPosX; 166 float DIS_X = abs(disX); 167 float containerTartgetX = 0; 168 if(disX < 0) 169 { 170 containerTartgetX = container->getPositionX() + DIS_X; 171 } 172 else 173 { 174 containerTartgetX = container->getPositionX() - DIS_X; 175 } 176 float playerMoveTime = (DIS_X / SPEED) / 60; 177 178 CCAction *action = CCSequence::create( 179 CCMoveTo::create(playerMoveTime, ccp(containerTartgetX,0)), 180 NULL); 181 container->runAction(action); 182 183 //背景層 184 //中景層從最大橫坐標到最小橫坐標之間的距離 185 float maxCenterBgDis = centerBgWidth - winWidth; 186 //背景層的移動距離 187 float maxBackBgDis = backBgWidth - winWidth; 188 float backBgMoveScale = maxBackBgDis / maxCenterBgDis; 189 float backBgTargetPosx = containerTartgetX * backBgMoveScale; 190 CCAction *backBgAction = CCSequence::create(CCMoveTo::create(playerMoveTime, ccp(backBgTargetPosx,backBg->getPosition().y)),NULL); 191 backBg->runAction(backBgAction); 192 }