cocos2d-x学习日记之瓦片地图篇—TiledMap

瓦片地图

在游戏开发过程中,我们会遇到超过屏幕大小的地图,例如即时战略游戏,使得玩家可以在地图中滚动游戏画面。这类游戏通常会有丰富的背景元素,如果直接使用背景图切换的方式,需要为每个不同的场景准备一张背景图,而且每个背景图都不小,这样会造成资源浪费。瓦片地图就是为了解决这问题而产生的。一张大的世界地图或者背景图可以由几种地形来表示,每种地形对应一张小的的图片,我们称这些小的地形图片为瓦片。把这些瓦片拼接在一起,一个完整的地图就组合出来了,这就是瓦片地图的原理。


开发实例-利用瓦片地图工具创建一个简单的地图 使人物在地图上随意移动

1.工具:TileMap  并且将制作好的地图的tmx文件和资源导入到工程中

2.编译器:Xcode

3.新建一个HelloWorld的类 在HelloWorld.hpp里添加以下代码

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
#include "ui/CocosGUI.h"
using namespace cocos2d;
using namespace ui;

enum{
    UP,
    DOWN,
    LEFT,
    RIGHT,
}direction;

class HelloWorld : public cocos2d::Layer
{
public:
  
    static cocos2d::Scene* createScene();
    virtual bool init();
    //人物移动
   bool ontouchbegan(Touch* touch,Event* event);
    void selfMove(int x,int y);
    CREATE_FUNC(HelloWorld);
private:
    TMXTiledMap* map;
    Sprite* hero;
};

#endif // __HELLOWORLD_SCENE_H__

4.在HelloWorld.cpp文件中添加以下代码

#include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{

    auto scene = Scene::create();
    auto layer = HelloWorld::create();
    scene->addChild(layer);

 
    return scene;
}

bool HelloWorld::init()
{
   
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    map=TMXTiledMap::create("Map_1.tmx");
    this->addChild(map);
    
    TMXLayer* colorlayer=map->getLayer("颜色层");
    colorlayer->setVisible(false);
    
    //获得对象组
    TMXObjectGroup* objectGroup=map->getObjectGroup("人物层");
    ValueMap object=objectGroup->getObject("新手");
    
    //添加人物到对象层
    hero=Sprite::create("player.png");
    hero->setPosition(Vec2(object.at("x").asFloat(),object.at("y").asFloat()));
    this->addChild(hero);
    
    //人物移动
    auto listener=EventListenerTouchOneByOne::create();
    listener->onTouchBegan=CC_CALLBACK_2(HelloWorld::ontouchbegan,this);
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
    return true;
}

//人物移动回调函数
bool HelloWorld:: ontouchbegan(Touch* touch,Event* event)
{
    log("111");
    //1.获得人物的位置和触摸屏幕的位置
    auto selfPoint=hero->getPosition();
    auto touchPoint=touch->getLocation();
    //2.在HelloWorld.h文件中定义一个方向的枚举类型
    int x=touchPoint.x-selfPoint.x;//两者之间的间距用来判断人物的移动方向(横向)
    int y=touchPoint.y-selfPoint.y;//两者之间的间距用来判断人物的移动方向(纵向)
    int setX=0;//人物横向的偏移量
    int setY=0;//人物纵向的偏移量
    if(abs(x) > abs(y))//x、y的绝对值来判断人物横向还是纵向移动
    {
        if (x>=0) {
            setX=32;
            direction=RIGHT;
        }else{
            setX=-32;
            direction=LEFT;
        }

    }else{
        if (y>=0) {
            setY=32;
            direction=UP;
        }else{
            setY=-32;
            direction=DOWN;
        }
    }
    
    this->selfMove(setX,setY);
    return true;
}

void HelloWorld:: selfMove(int x,int y)
{
    auto size=Director::getInstance()->getWinSize();
    auto selfPoint=hero->getPosition();
    auto mapPoint=map->getPosition();
    auto mapSize=map->getMapSize();
    auto tileSize=map->getTileSize();
    int selfMoveNextX=selfPoint.x+x;
    int selfMoveNextY=selfPoint.y+y;
    
   
    int UPMapY=-(mapSize.height*tileSize.height-size.height);
    int DOWNMapY=0;
    int LEFTMapX=0;
    int RIGHTMapX=-(mapSize.width*tileSize.width-size.width);
    
    switch (direction) {
        case UP:
            if (selfMoveNextY>size.height/2 && mapPoint.y>UPMapY) {
                map->setPosition(Vec2(mapPoint.x,mapPoint.y-y));
            }
            else
            {
                hero->setPosition(Vec2(selfPoint.x,selfMoveNextY));
            }
            break;
          case DOWN:
            if (mapPoint.y >= DOWNMapY ||(selfMoveNextY >= size.height/2 &&  mapPoint.y>=UPMapY )) {
                hero->setPosition(Vec2(selfPoint.x,selfMoveNextY));
            }else
            {
                map->setPosition(Vec2(mapPoint.x,mapPoint.y-y));
            }
            break;
            
            case LEFT:
            if ( mapPoint.x>=LEFTMapX ||(selfMoveNextX >= size.width/2 && mapPoint.x<= RIGHTMapX)) {
                
                hero->setPosition(Vec2(selfMoveNextX,selfPoint.y));
            }
            else
            {
                map->setPosition(Vec2(mapPoint.x-x,mapPoint.y));
            }
            break;
            
            case RIGHT:
            if (selfMoveNextX>=size.width/2 && mapPoint.x > RIGHTMapX) {
                
                 map->setPosition(Vec2(mapPoint.x-x,mapPoint.y));
               
            }else
            {
                hero->setPosition(Vec2(selfMoveNextX,selfPoint.y));
            }
            break;
        default:
            break;
    }
}




  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值