cocos2dx 横板游戏触屏人物和背景移动 方法1

大多横板游戏主角的移动都是有背景一起在移动的,不单单是主角在动。当主角的位置离地图的左端距离小于屏幕宽度的一半或者主角离地图最右端的距离小于屏幕宽度的一半时,触屏之后就人物在移动,背景没有动,当主角位于这端中间的位置时,触屏之后主角移动的同时,背景也在往主角反方向移动,一旦当主角移动到两端的内边界时,背景就停止移动,只主角移动。

这段代码放到这里做个备份,不是最终版,而且也不是性能最高的解决办法,

当主角走到两端时,背景偶尔会走多了出线黑边,

功能:每次点击屏幕之后,主角停止当前的动作,走到触屏的那个点然后停下来。

 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 }
原文地址:https://www.cnblogs.com/JD85/p/2872343.html