1.实现大地图的滚动
设置地图只会横向向左滚动,当主角超过屏幕中点时地图就开始卷动
#ifndef _PLAYER_H_ #define _PLAYER_H_ #include "Entity.h" class Player : public Entity { public: bool init(); CREATE_FUNC(Player); void run(); void setTMXTiledMap(TMXTiledMap* map); virtual void setTagPosition(int x,int y); private: void setViewPointByPlayer(); TMXTiledMap* m_map; }; #endif
#include "Player.h" #include "AnimationUtil.h" bool Player::init(){ return true; } void Player::run(){ SpriteFrameCache* frameCache = SpriteFrameCache::getInstance(); frameCache->addSpriteFramesWithFile("runs.plist","runs.png"); Animation* action = AnimationUtil::createWithStringFrameName("run",0.1f,-1); mSprite->runAction(Animate::create(action)); } void Player::setViewPointByPlayer(){ if (mSprite == NULL) { return; } //获取格子的数量 Size mapTiledNum = m_map->getMapSize(); //获取格子的大小 Size tiledSize = m_map->getTileSize(); //地图大小,这点有点不好理解啊 Size mapSize = Size(mapTiledNum.width*tiledSize.width,mapTiledNum.height*tiledSize.height); //屏幕大小 Size visibileSize = Director::getInstance()->getVisibleSize(); //主角坐标 Point pos = getPosition(); //如果主角坐标小于屏幕的一半,则取屏幕中点坐标,否则去主角坐标 float x = std::max(pos.x,visibileSize.width/2); float y = std::max(pos.y,visibileSize.height/2); //如果x,y坐标大于右上角的极限值,则取极限值坐标 x = std::min(x,mapSize.width - visibileSize.width/2); y = std::min(x,mapSize.height - visibileSize.height/2); //目标点 Point destPos = Point(x,y); //屏幕中点 Point centerPos = Point(visibileSize.width/2,visibileSize.height/2); //计算屏幕中点和所要移动的目的点之间的距离 Point viewPos = centerPos - destPos; //获取父类 Layer* parent = (Layer*)getParent(); parent->setPosition(viewPos); } void Player::setTagPosition(int x,int y){ Entity::setTagPosition(x,y); setViewPointByPlayer(); } void Player::setTMXTiledMap(TMXTiledMap* map){ this->m_map = map; }
这个函数的功能是让地图所在图层以主角为中心进行移动,也就是让事件的焦点停留在主角身上,屏幕随着主角移动。
每当主角的坐标改变时,都会让地图坐标随着一起改变。
或许地图会出现一些细细的黑边,需要加上这句
Director::getInstance()->setProjection(Director::Projection::_2D);加哪里都是阔以的。
2.三方移动控制器
实现主角向前,上,下移动
#ifndef _THREED_DIRECTION_CONTROLLER_H_ #define _THREED_DIRECTION_CONTROLLER_H_ #include "Controller.h" class ThreeDirectionController : public Controller { public: CREATE_FUNC(ThreeDirectionController); bool init(); void setXSpeed(int xSpeed); void setYSpeed(int ySpeed); void update(float dt); private: int xSpeed; int ySpeed; void registTouchListener(); }; #endif
#include "ThreeDirectionController.h" bool ThreeDirectionController::init(){ this->xSpeed = 0; this->ySpeed = 0; registTouchListener(); this->scheduleUpdate(); return true; } void ThreeDirectionController::setXSpeed(int xSpeed){ this->xSpeed = xSpeed; } void ThreeDirectionController::setYSpeed(int ySpeed){ this->ySpeed = ySpeed; } void ThreeDirectionController::update(float dt){ if (m_listener == NULL) { return; } Point pos = m_listener->getTagPosition(); pos.x += xSpeed; pos.y += ySpeed; m_listener->setTagPosition(pos.x,pos.y); } void ThreeDirectionController::registTouchListener(){ auto listenr = EventListenerTouchOneByOne::create(); listenr->onTouchBegan = [](Touch* touch,Event* event){ return true; }; listenr->onTouchMoved = [&](Touch* touch,Event* event){ //获取点击的坐标 Point touchPos = Director::getInstance()->convertToGL(touch->getLocationInView()); //获取主角的位置 Point pos = m_listener->getTagPosition(); int iSpeed = 0; //当点击精灵上方的时候 if (touchPos.y > pos.y) { iSpeed = 1; }else { iSpeed = -1; } setYSpeed(iSpeed); }; listenr->onTouchEnded = [&](Touch* touch,Event* event){ //停止移动 setYSpeed(0); }; _eventDispatcher->addEventListenerWithSceneGraPHPriority(listenr,this); }在TollgateScene的addPlayer中添加
ThreeDirectionController* controller = ThreeDirectionController::create(); controller->setXSpeed(1); controller->setYSpeed(0); this->addChild(controller); player->setController(controller);