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);