• 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 }
  • 相关阅读:
    JMeter怎样测试WebSocket
    Android—基于OpenCV+Android实现人脸检测
    Android—实现科大讯飞语音合成
    Could not resolve com.android.support.constraint:constraint-layout:1.1.3.
    Mac上利用Aria2加速百度网盘下载
    将Excel表中的数据导入MySQL数据库
    Android Studio 添加模块依赖
    Mac上基于hexo+GitHub搭建个人博客(一)
    微信小程序—setTimeout定时器的坑
    微信小程序-腾讯地图显示偏差问题
  • 原文地址:https://www.cnblogs.com/JD85/p/2872343.html
Copyright © 2020-2023  润新知