TiledMap吃西瓜解读


#include <stdio.h>

#include <iostream>

using namespace std;

#include "cocos2d.h"

using namespace cocos2d;

#include "ui/CocosGUI.h"

using namespace cocos2d::ui;

enum GoDirection{

    Left = 0,

    Right = 1,

    Up = 2,

    Down = 3,

    None = 4

    

};

class ZTEDU_10:public Layer{

public:

    static Scene* createScene();

    bool init()override;

    CREATE_FUNC(ZTEDU_10);

    void movePlayer(Vec2 p);

    void heroGoTo(Vec2 p);

    void onEnter()override;

    void onExit()override;

    virtual bool onTouchBegan(Touch *touch, Event *unused_event) override;

    virtual void onTouchMoved(Touch *touch, Event *unused_event) override;

    virtual void onTouchEnded(Touch *touch, Event *unused_event) override;

    virtual void onTouchCancelled(Touch *touch, Event *unused_event) override;

    GoDirection getTheDirection(Sprite* enemy);

    void createEnemy();

    void createBullet(Vec2 p);

    void collision(float dt); //碰撞

private:

    Size winSize;

    Rect rect;

    bool canAtk;

    Vec2 begainPoint;

    Sprite* hero;

    TMXTiledMap* _tileMap;

    TMXLayer* wallLayer;

    TMXLayer* waterLayer;

    Vector<Sprite*>* enemyVector;

    Vector<Sprite*>* bulletVector;

    };



#define MAX_X 30

#define MAX_Y 10

Scene* ZTEDU_10::createScene()

{

    auto scene = Scene::create();

    auto layer = ZTEDU_10::create();

    scene->addChild(layer);

    return scene;

}

bool ZTEDU_10::init(){

    if (!Layer::init()) {

        return false;

    }

   

    _tileMap = TMXTiledMap::create("map.tmx");

    this->addChild(_tileMap);


    wallLayer = _tileMap->getLayer("meta");//获取阴影

    wallLayer->setVisible(true);//显示不可见阴影

    

    hero = Sprite::create("www.png");//英雄

    _tileMap->addChild(hero,10);

    

    auto objectsValue = _tileMap->getObjectGroup("hero");//获取对象组

    auto sp_point = objectsValue->getObject("lxb");//获取对象

    

    //set the hero pos//设置坐标X转化为float类型

    Vec2 heroPoint = Vec2(sp_point.at("x").asFloat(),sp_point.at("y").asFloat());

    hero->setAnchorPoint(Vec2(0.5,0.5));

    hero->setPosition(heroPoint);

    

    waterLayer = _tileMap->getLayer("water");//获取西瓜


    canAtk = false;

    enemyVector = new Vector<Sprite*>();//敌人

    bulletVector = new Vector<Sprite*>();//子弹

    winSize = Director::getInstance()->getWinSize();//窗口

    rect = Rect(0, 0, winSize.width, winSize.height);//窗口rect 大小

    auto chenkbox = CheckBox::create("projectile-button-off.png"

                                     ,"projectile-button-on.png"

                                     ,"projectile-button-on.png"

                                     ,"projectile-button-off.png"

                                     ,"projectile-button-off.png");

    

    chenkbox->setAnchorPoint(Vec2(0, 0));

    chenkbox->setPosition(Vec2(winSize.width, 0));

    this->addChild(chenkbox,10);

    chenkbox->addEventListener([=](Ref* psender,CheckBox::EventType type){

        switch (type) {

            case CheckBox::EventType::SELECTED :

                canAtk = true;

                break;

            case CheckBox::EventType::UNSELECTED :

                canAtk = false;

                break;

            default:

                break;

        }

    });

    createEnemy();//创建敌人

    

    return true;

}


void ZTEDU_10::movePlayer(Vec2 p)

{

    //获取目标位置

    int x = p.x / _tileMap->getTileSize().width;//每块的宽度 转换成块数

    //_tileMap->getMapSize().height*_tileMap->getTileSize().height总高度  p.y :是从下往上的高度

    //getTileSize().height每一块的高度

    int y = (_tileMap->getMapSize().height*_tileMap->getTileSize().height-p.y)/_tileMap->getTileSize().height;

    Vec2 tiledCoord = Vec2(x,y); //块的坐标(哪一块)

    log("x = %d,y = %d",x,y);

    //范围检测

    if (tiledCoord.x<0||tiledCoord.x>=MAX_X||tiledCoord.y<0||tiledCoord.y>=MAX_Y) {

        return;

    }

//key-value

    //墙的碰撞检测  getTileGIDAt:获取属性的值是唯一的

    int tiled_id = wallLayer->getTileGIDAt(tiledCoord);

    log("%d",tiled_id);

    if (tiled_id)

    {

        auto _value = _tileMap->getPropertiesForGID(tiled_id);//通过GID获取属性字典

        auto _valueStr = _value.getDescription();//通过GID来获取。。。的属性

        log("*************Value : %s",_valueStr.c_str());//当我们使用GID来查找指定tile的属性的时候。它返回一个属性字典,因此,我们可以遍历一下,看是否有可碰撞的物体被设置成”True“,或者是仅仅就是那样。编译并运行工程,因此还没有设置玩家的位置。

        if (!_value.isNull())//不为空

        {   //查找不到返回_valueStr.find("isHit")   -1

            if (_valueStr.find("isHit")!=-1)//查找是否有属性,查找不到为-1  find就是遍历查找

            {

                //它返回一个属性字典

                auto collidableValue = _value.asValueMap().at("isHit").asString().c_str();

                auto strTure = "true";

                log("%s",collidableValue);

                if (collidableValue&&strcmp(collidableValue, strTure)==0)//比较

                {

                    log("can't move");

                    return;

                }

            }

        }

    }

    //西瓜的碰撞检测  可以走过去

    int water_id = waterLayer->getTileGIDAt(tiledCoord);

    

    if (water_id) {

        auto _value = _tileMap->getPropertiesForGID(water_id);

        auto _valueStr = _value.getDescription();

        log("Value %s",_valueStr.c_str());

        if (!_value.isNull())

        {

            if (_valueStr.find("CanEat")!=-1)

            {

                auto collidableValue = _value.asValueMap().at("CanEat").asString().c_str();

                auto strTure = "True";

                log("%s",collidableValue);

                if (collidableValue&&strcmp(collidableValue, strTure))

                {         //移除指定位置砖块对象

                    waterLayer->removeTileAt(tiledCoord);

                }

            }

        }

    }

     heroGoTo(p);


}

void ZTEDU_10::heroGoTo(Vec2 p)

{

    Vec2 worldPoint = _tileMap->convertToWorldSpace(p);//转换世界坐标系

    log("p:(%f,%f)",p.x,p.y);

    log("p:(%f,%f)",worldPoint.x,worldPoint.y);


    //位置点处于中间时候,屏幕移动

    if (worldPoint.x>winSize.width/2) {

        float _x = p.x - winSize.width/2;

        if (_x<=winSize.width)//大于屏幕的一半

        {

            _tileMap->setPositionX(-_x);

        }

    }

    else if (worldPoint.x<winSize.width/4)

    {

        float _x = p.x - winSize.width/4;

        if(_x>=0)

        {

            _tileMap->setPositionX(-_x);

        }

    }

    hero->setPosition(p);

}

bool ZTEDU_10::onTouchBegan(Touch *touch, Event *unused_event)

{

    auto touchLocation = touch->getLocation();

    begainPoint = _tileMap->convertToNodeSpace(touchLocation);

    return true;

}

void ZTEDU_10::onTouchMoved(Touch *touch, Event *unused_event)

{

    

}

void ZTEDU_10::onTouchEnded(Touch *touch, Event *unused_event)

{

    Vec2 endLocation = touch->getLocation();

    Vec2 endPoint = _tileMap->convertToNodeSpace(endLocation);

    

     if (canAtk)

     {

       this->createBullet(endLocation); //发射子弹

       return;

     }

    

    if (begainPoint.equals(endPoint)) //=

    {

        auto heroPoint = hero->getPosition();

        auto disPos = endPoint-heroPoint;

        log("dispos.x = %f,y = %f",disPos.x,disPos.y);

        //左右移动

        if (abs(disPos.x)>abs(disPos.y))//绝对值

        {

            if (disPos.x>0)

            {

                heroPoint.x += _tileMap->getTileSize().width;

                log("hero.x is %f",heroPoint.x);

            }

            else

            {

                heroPoint.x -= _tileMap->getTileSize().width;

                log("hero.x is %f",heroPoint.x);

            }

        }

        //上下移动

        else

        {

            if (disPos.y>0)

            {

                heroPoint.y += _tileMap->getTileSize().height;

                log("hero.y is %f",heroPoint.y);

            }

            else

            {

                heroPoint.y -= _tileMap->getTileSize().height;

                log("hero.y is %f",heroPoint.y);

            }

        }

        this->movePlayer(heroPoint);

    }

    


}

void ZTEDU_10::onTouchCancelled(Touch *touch, Event *unused_event)

{

    

}

void ZTEDU_10::onEnter()

{

    Layer::onEnter();

    auto  touchListener = EventListenerTouchOneByOne::create();

    touchListener->onTouchBegan = CC_CALLBACK_2(ZTEDU_10::onTouchBegan,this);

    touchListener->onTouchMoved = CC_CALLBACK_2(ZTEDU_10::onTouchMoved,this);

    touchListener->onTouchEnded = CC_CALLBACK_2(ZTEDU_10::onTouchEnded, this);

    touchListener->onTouchCancelled = CC_CALLBACK_2(ZTEDU_10::onTouchCancelled,this);

    touchListener->setSwallowTouches(true);

    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);

    

    schedule(CC_CALLBACK_1(ZTEDU_10::collision, this),"collision");

    

    schedule([=](float dt){

        if (enemyVector->size()<=1)

        {

            //return ;

            createEnemy();

        }

        for(auto obj : *enemyVector)

        {

            GoDirection direction = getTheDirection(obj);

            switch (direction)

            {

                case Left:

                {

                    Vec2 point = obj->getPosition();

                    point.x = point.x - _tileMap->getTileSize().width;

                    obj->setPosition(point);

                    break;

                }

                case Right:

                {

                    Vec2 point = obj->getPosition();

                    point.x += _tileMap->getTileSize().width;

                    obj->setPosition(point);

                    break;

                }

                case Up:

                {

                    Vec2 point = obj->getPosition();

                    point.y += _tileMap->getTileSize().height;

                    obj->setPosition(point);

                    break;

                }

                case Down:

                {

                    Vec2 point = obj->getPosition();

                    point.y -= _tileMap->getTileSize().height;

                    obj->setPosition(point);

                    break;

                }

    

                default:

                {

                    Vec2 point = obj->getPosition();

                    int x = arc4random()%2;

                    int y = arc4random()%2;

                    if (x) {

                        point.x += _tileMap->getTileSize().width;

                    }

                    else

                        point.x -= _tileMap->getTileSize().width;

                    if (y) {

                        point.y += _tileMap->getTileSize().height;

                    }

                    else

                        point.y -= _tileMap->getTileSize().height;

                    obj->setPosition(point);

                }

                    break;

            }

        }

    }, 0.5,"UpdateEnemy");

    

    

    

    

    

    

}

void ZTEDU_10::onExit()

{

    

}

GoDirection ZTEDU_10::getTheDirection(Sprite* enemy)

{

    Vec2 heroPoint = hero->getPosition();

    Vec2 enemyPoint = enemy->getPosition();

    Vec2 directPoint = heroPoint-enemyPoint;

    if (abs(directPoint.x)>abs(directPoint.y))

    {

        if (directPoint.x>32)

        {

            return GoDirection::Right;

        }

        else if (directPoint.x<-32)

        {

            return GoDirection::Left;

        }

        else

        {

            return GoDirection::None;

        }

    }

    else

    {

        if (directPoint.y>32)

        {

            return GoDirection::Up;

        }

        else if (directPoint.y<-32)

        {

            return GoDirection::Down;

        }

        else

        {

            return GoDirection::None;

        }

    }

}

void ZTEDU_10::createEnemy()

{

    

    auto enemyGroup = _tileMap->getObjectGroup("enemy")->getObjects();

    for(auto obj: enemyGroup)//范围for 循环

    {

        if (!obj.isNull())

        {

            auto namestr = obj.asValueMap().at("name").asString().c_str();

            auto keyStr = "enemy";

            if (strcmp(namestr, keyStr)==0)

            {

                auto enemySprite = Sprite::create("enemy1.png");

                float x = obj.asValueMap().at("x").asFloat();

                float y = obj.asValueMap().at("y").asFloat();

                enemySprite->setPosition(x,y);

                _tileMap->addChild(enemySprite,10);

                enemyVector->pushBack(enemySprite);

            }

        }

    }

}

void ZTEDU_10::createBullet(Vec2 p)

{

    p = _tileMap->convertToNodeSpace(p);

    Vec2 heroPoint = hero->getPosition();

    

    Vec2 disPoint = p - heroPoint;

    float distance = sqrt(disPoint.x * disPoint.x + disPoint.y * disPoint.y);

    

    float n = 1000/distance;

    

    disPoint = disPoint*n;

    

    auto action = MoveBy::create(10, disPoint);

    auto bullet = Sprite::create("Projectile.png");

    bullet->setPosition(heroPoint);

    _tileMap->addChild(bullet,8);

    bulletVector->pushBack(bullet);

    bullet->runAction(action);

//    Label::createWithSystemFont

    

}

void ZTEDU_10::collision(float dt)//碰撞

{

    if (bulletVector->size()<=0 || enemyVector->size()<=0)

    {

        return;

    }


    for (Vector<Sprite*>::iterator bullet_itr = bulletVector->begin();bullet_itr != bulletVector->end();)

    {

        Sprite* bullet = (Sprite*)*bullet_itr;

        Vec2 point = _tileMap->convertToWorldSpace(bullet->getPosition());

        if (!(this->rect.containsPoint(point)))//子弹是否在屏幕内

        {

            bullet_itr = bulletVector->erase(bullet_itr);//容器清除

            log("0000000");

            bullet->removeFromParentAndCleanup(true);//removeFromParentAndCleanup表示把sprite从屏幕上删除

            //删除父节点中的当前节点并清除动作及回调函数

        }

        else

        {

            Rect _bulletRect = bullet->getBoundingBox();

            for (Vector<Sprite*>::iterator enemy_itr = enemyVector->begin();enemy_itr!=enemyVector->end();)

            {

                Sprite* enemy = (Sprite*)*enemy_itr;

                Rect _enemyRect = enemy->getBoundingBox();

                if (_bulletRect.intersectsRect(_enemyRect))

                {

                    enemy_itr = enemyVector->erase(enemy_itr);

                    //--enemy_itr;

                    enemy->removeFromParentAndCleanup(true);

                    //容器移除

                    bullet_itr = bulletVector->erase(bullet_itr);

                    --bullet_itr;

                    //删除父节点

                    bullet->removeFromParentAndCleanup(true);

                    break;

                }

                else

                {

                    ++enemy_itr;

                }

            }

            ++bullet_itr;

        }

        

    }

    log("bulletVector %zd",bulletVector->size());

    log("enemyVector %zd",enemyVector->size());


}

#define MAX_X 30

#define MAX_Y 10

Scene* ZTEDU_10::createScene()

{

    auto scene = Scene::create();

    auto layer = ZTEDU_10::create();

    scene->addChild(layer);

    return scene;

}

bool ZTEDU_10::init(){

    if (!Layer::init()) {

        return false;

    }

   

    _tileMap = TMXTiledMap::create("map.tmx");

    this->addChild(_tileMap);


    wallLayer = _tileMap->getLayer("meta");//获取阴影

    wallLayer->setVisible(true);//显示不可见阴影

    

    hero = Sprite::create("www.png");//英雄

    _tileMap->addChild(hero,10);

    

    auto objectsValue = _tileMap->getObjectGroup("hero");//获取对象组

    auto sp_point = objectsValue->getObject("lxb");//获取对象

    

    //set the hero pos//设置坐标X转化为float类型

    Vec2 heroPoint = Vec2(sp_point.at("x").asFloat(),sp_point.at("y").asFloat());

    hero->setAnchorPoint(Vec2(0.5,0.5));

    hero->setPosition(heroPoint);

    

    waterLayer = _tileMap->getLayer("water");//获取西瓜


    canAtk = false;

    enemyVector = new Vector<Sprite*>();//敌人

    bulletVector = new Vector<Sprite*>();//子弹

    winSize = Director::getInstance()->getWinSize();//窗口

    rect = Rect(0, 0, winSize.width, winSize.height);//窗口rect 大小

    auto chenkbox = CheckBox::create("projectile-button-off.png"

                                     ,"projectile-button-on.png"

                                     ,"projectile-button-on.png"

                                     ,"projectile-button-off.png"

                                     ,"projectile-button-off.png");

    

    chenkbox->setAnchorPoint(Vec2(0, 0));

    chenkbox->setPosition(Vec2(winSize.width, 0));

    this->addChild(chenkbox,10);

    chenkbox->addEventListener([=](Ref* psender,CheckBox::EventType type){

        switch (type) {

            case CheckBox::EventType::SELECTED :

                canAtk = true;

                break;

            case CheckBox::EventType::UNSELECTED :

                canAtk = false;

                break;

            default:

                break;

        }

    });

    createEnemy();//创建敌人

    

    return true;

}


void ZTEDU_10::movePlayer(Vec2 p)

{

    //获取目标位置

    int x = p.x / _tileMap->getTileSize().width;//每块的宽度 转换成块数

    //_tileMap->getMapSize().height*_tileMap->getTileSize().height总高度  p.y :是从下往上的高度

    //getTileSize().height每一块的高度

    int y = (_tileMap->getMapSize().height*_tileMap->getTileSize().height-p.y)/_tileMap->getTileSize().height;

    Vec2 tiledCoord = Vec2(x,y); //块的坐标(哪一块)

    log("x = %d,y = %d",x,y);

    //范围检测

    if (tiledCoord.x<0||tiledCoord.x>=MAX_X||tiledCoord.y<0||tiledCoord.y>=MAX_Y) {

        return;

    }

    //墙的碰撞检测  getTileGIDAt:获取属性值

    int tiled_id = wallLayer->getTileGIDAt(tiledCoord);

    log("%d",tiled_id);

    if (tiled_id)

    {

        auto _value = _tileMap->getPropertiesForGID(tiled_id);//通过GID获取属性字典

        auto _valueStr = _value.getDescription();//通过GID来获取。。。的属性

        log("*************Value : %s",_valueStr.c_str());//当我们使用GID来查找指定tile的属性的时候。它返回一个属性字典,因此,我们可以遍历一下,看是否有可碰撞的物体被设置成”True“,或者是仅仅就是那样。编译并运行工程,因此还没有设置玩家的位置。

        if (!_value.isNull())//不为空

        {   //查找不到返回_valueStr.find("isHit")   -1

            if (_valueStr.find("isHit")!=-1)//查找是否有属性,查找不到为-1  find就是遍历查找

            {

                //它返回一个属性字典

                auto collidableValue = _value.asValueMap().at("isHit").asString().c_str();

                auto strTure = "true";

                log("%s",collidableValue);

                if (collidableValue&&strcmp(collidableValue, strTure)==0)//比较

                {

                    log("can't move");

                    return;

                }

            }

        }

    }

    //西瓜的碰撞检测  可以走过去

    int water_id = waterLayer->getTileGIDAt(tiledCoord);

    

    if (water_id) {

        auto _value = _tileMap->getPropertiesForGID(water_id);

        auto _valueStr = _value.getDescription();

        log("Value %s",_valueStr.c_str());

        if (!_value.isNull())

        {

            if (_valueStr.find("CanEat")!=-1)

            {

                auto collidableValue = _value.asValueMap().at("CanEat").asString().c_str();

                auto strTure = "True";

                log("%s",collidableValue);

                if (collidableValue&&strcmp(collidableValue, strTure))

                {         //移除指定位置砖块对象

                    waterLayer->removeTileAt(tiledCoord);

                }

            }

        }

    }

     heroGoTo(p);


}

void ZTEDU_10::heroGoTo(Vec2 p)

{

    Vec2 worldPoint = _tileMap->convertToWorldSpace(p);//转换世界坐标系

    log("p:(%f,%f)",p.x,p.y);

    log("p:(%f,%f)",worldPoint.x,worldPoint.y);


    //位置点处于中间时候,屏幕移动

    if (worldPoint.x>winSize.width/2) {

        float _x = p.x - winSize.width/2;

        if (_x<=winSize.width)//大于屏幕的一半

        {

            _tileMap->setPositionX(-_x);

        }

    }

    else if (worldPoint.x<winSize.width/4)

    {

        float _x = p.x - winSize.width/4;

        if(_x>=0)

        {

            _tileMap->setPositionX(-_x);

        }

    }

    hero->setPosition(p);

}

bool ZTEDU_10::onTouchBegan(Touch *touch, Event *unused_event)

{

    auto touchLocation = touch->getLocation();

    begainPoint = _tileMap->convertToNodeSpace(touchLocation);

    return true;

}

void ZTEDU_10::onTouchMoved(Touch *touch, Event *unused_event)

{

    

}

void ZTEDU_10::onTouchEnded(Touch *touch, Event *unused_event)

{

    Vec2 endLocation = touch->getLocation();

    Vec2 endPoint = _tileMap->convertToNodeSpace(endLocation);

    

     if (canAtk)

     {

       this->createBullet(endLocation); //发射子弹

       return;

     }

    

    if (begainPoint.equals(endPoint)) //=

    {

        auto heroPoint = hero->getPosition();

        auto disPos = endPoint-heroPoint;

        log("dispos.x = %f,y = %f",disPos.x,disPos.y);

        //左右移动

        if (abs(disPos.x)>abs(disPos.y))//绝对值

        {

            if (disPos.x>0)

            {

                heroPoint.x += _tileMap->getTileSize().width;

                log("hero.x is %f",heroPoint.x);

            }

            else

            {

                heroPoint.x -= _tileMap->getTileSize().width;

                log("hero.x is %f",heroPoint.x);

            }

        }

        //上下移动

        else

        {

            if (disPos.y>0)

            {

                heroPoint.y += _tileMap->getTileSize().height;

                log("hero.y is %f",heroPoint.y);

            }

            else

            {

                heroPoint.y -= _tileMap->getTileSize().height;

                log("hero.y is %f",heroPoint.y);

            }

        }

        this->movePlayer(heroPoint);

    }

    


}

void ZTEDU_10::onTouchCancelled(Touch *touch, Event *unused_event)

{

    

}

void ZTEDU_10::onEnter()

{

    Layer::onEnter();

    auto  touchListener = EventListenerTouchOneByOne::create();

    touchListener->onTouchBegan = CC_CALLBACK_2(ZTEDU_10::onTouchBegan,this);

    touchListener->onTouchMoved = CC_CALLBACK_2(ZTEDU_10::onTouchMoved,this);

    touchListener->onTouchEnded = CC_CALLBACK_2(ZTEDU_10::onTouchEnded, this);

    touchListener->onTouchCancelled = CC_CALLBACK_2(ZTEDU_10::onTouchCancelled,this);

    touchListener->setSwallowTouches(true);

    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);

    

    schedule(CC_CALLBACK_1(ZTEDU_10::collision, this),"collision");

    

    schedule([=](float dt){

        if (enemyVector->size()<=1)

        {

            //return ;

            createEnemy();

        }

        for(auto obj : *enemyVector)

        {

            GoDirection direction = getTheDirection(obj);

            switch (direction)

            {

                case Left:

                {

                    Vec2 point = obj->getPosition();

                    point.x = point.x - _tileMap->getTileSize().width;

                    obj->setPosition(point);

                    break;

                }

                case Right:

                {

                    Vec2 point = obj->getPosition();

                    point.x += _tileMap->getTileSize().width;

                    obj->setPosition(point);

                    break;

                }

                case Up:

                {

                    Vec2 point = obj->getPosition();

                    point.y += _tileMap->getTileSize().height;

                    obj->setPosition(point);

                    break;

                }

                case Down:

                {

                    Vec2 point = obj->getPosition();

                    point.y -= _tileMap->getTileSize().height;

                    obj->setPosition(point);

                    break;

                }

    

                default:

                {

                    Vec2 point = obj->getPosition();

                    int x = arc4random()%2;

                    int y = arc4random()%2;

                    if (x) {

                        point.x += _tileMap->getTileSize().width;

                    }

                    else

                        point.x -= _tileMap->getTileSize().width;

                    if (y) {

                        point.y += _tileMap->getTileSize().height;

                    }

                    else

                        point.y -= _tileMap->getTileSize().height;

                    obj->setPosition(point);

                }

                    break;

            }

        }

    }, 0.5,"UpdateEnemy");

    

    

    

    

    

    

}

void ZTEDU_10::onExit()

{

    

}

GoDirection ZTEDU_10::getTheDirection(Sprite* enemy)

{

    Vec2 heroPoint = hero->getPosition();

    Vec2 enemyPoint = enemy->getPosition();

    Vec2 directPoint = heroPoint-enemyPoint;

    if (abs(directPoint.x)>abs(directPoint.y))

    {

        if (directPoint.x>32)

        {

            return GoDirection::Right;

        }

        else if (directPoint.x<-32)

        {

            return GoDirection::Left;

        }

        else

        {

            return GoDirection::None;

        }

    }

    else

    {

        if (directPoint.y>32)

        {

            return GoDirection::Up;

        }

        else if (directPoint.y<-32)

        {

            return GoDirection::Down;

        }

        else

        {

            return GoDirection::None;

        }

    }

}

void ZTEDU_10::createEnemy()

{

    

    auto enemyGroup = _tileMap->getObjectGroup("enemy")->getObjects();

    for(auto obj: enemyGroup)//范围for 循环

    {

        if (!obj.isNull())

        {

            auto namestr = obj.asValueMap().at("name").asString().c_str();

            auto keyStr = "enemy";

            if (strcmp(namestr, keyStr)==0)

            {

                auto enemySprite = Sprite::create("enemy1.png");

                float x = obj.asValueMap().at("x").asFloat();

                float y = obj.asValueMap().at("y").asFloat();

                enemySprite->setPosition(x,y);

                _tileMap->addChild(enemySprite,10);

                enemyVector->pushBack(enemySprite);

            }

        }

    }

}

void ZTEDU_10::createBullet(Vec2 p)

{

    p = _tileMap->convertToNodeSpace(p);

    Vec2 heroPoint = hero->getPosition();

    

    Vec2 disPoint = p - heroPoint;

    float distance = sqrt(disPoint.x * disPoint.x + disPoint.y * disPoint.y);

    

    float n = 1000/distance;

    

    disPoint = disPoint*n;

    

    auto action = MoveBy::create(10, disPoint);

    auto bullet = Sprite::create("Projectile.png");

    bullet->setPosition(heroPoint);

    _tileMap->addChild(bullet,8);

    bulletVector->pushBack(bullet);

    bullet->runAction(action);

//    Label::createWithSystemFont

    

}

void ZTEDU_10::collision(float dt)//碰撞

{

    if (bulletVector->size()<=0 || enemyVector->size()<=0)

    {

        return;

    }


    for (Vector<Sprite*>::iterator bullet_itr = bulletVector->begin();bullet_itr != bulletVector->end();)

    {

        Sprite* bullet = (Sprite*)*bullet_itr;

        Vec2 point = _tileMap->convertToWorldSpace(bullet->getPosition());

        if (!(this->rect.containsPoint(point)))//子弹是否在屏幕内

        {

            bullet_itr = bulletVector->erase(bullet_itr);//容器清除

            log("0000000");

            bullet->removeFromParentAndCleanup(true);//removeFromParentAndCleanup表示把sprite从屏幕上删除

            //删除父节点中的当前节点并清除动作及回调函数

        }

        else

        {

            Rect _bulletRect = bullet->getBoundingBox();

            for (Vector<Sprite*>::iterator enemy_itr = enemyVector->begin();enemy_itr!=enemyVector->end();)

            {

                Sprite* enemy = (Sprite*)*enemy_itr;

                Rect _enemyRect = enemy->getBoundingBox();

                if (_bulletRect.intersectsRect(_enemyRect))

                {

                    enemy_itr = enemyVector->erase(enemy_itr);

                    //--enemy_itr;

                    enemy->removeFromParentAndCleanup(true);

                    //容器移除

                    bullet_itr = bulletVector->erase(bullet_itr);

                    --bullet_itr;

                    //删除父节点

                    bullet->removeFromParentAndCleanup(true);

                    break;

                }

                else

                {

                    ++enemy_itr;

                }

            }

            ++bullet_itr;

        }

        

    }

    log("bulletVector %zd",bulletVector->size());

    log("enemyVector %zd",enemyVector->size());


}

#define MAX_X 30

#define MAX_Y 10

Scene* ZTEDU_10::createScene()

{

    auto scene = Scene::create();

    auto layer = ZTEDU_10::create();

    scene->addChild(layer);

    return scene;

}

bool ZTEDU_10::init(){

    if (!Layer::init()) {

        return false;

    }

   

    _tileMap = TMXTiledMap::create("map.tmx");

    this->addChild(_tileMap);


    wallLayer = _tileMap->getLayer("meta");//获取阴影

    wallLayer->setVisible(true);//显示不可见阴影

    

    hero = Sprite::create("www.png");//英雄

    _tileMap->addChild(hero,10);

    

    auto objectsValue = _tileMap->getObjectGroup("hero");//获取对象组

    auto sp_point = objectsValue->getObject("lxb");//获取对象

    

    //set the hero pos//设置坐标X转化为float类型

    Vec2 heroPoint = Vec2(sp_point.at("x").asFloat(),sp_point.at("y").asFloat());

    hero->setAnchorPoint(Vec2(0.5,0.5));

    hero->setPosition(heroPoint);

    

    waterLayer = _tileMap->getLayer("water");//获取西瓜


    canAtk = false;

    enemyVector = new Vector<Sprite*>();//敌人

    bulletVector = new Vector<Sprite*>();//子弹

    winSize = Director::getInstance()->getWinSize();//窗口

    rect = Rect(0, 0, winSize.width, winSize.height);//窗口rect 大小

    auto chenkbox = CheckBox::create("projectile-button-off.png"

                                     ,"projectile-button-on.png"

                                     ,"projectile-button-on.png"

                                     ,"projectile-button-off.png"

                                     ,"projectile-button-off.png");

    

    chenkbox->setAnchorPoint(Vec2(0, 0));

    chenkbox->setPosition(Vec2(winSize.width, 0));

    this->addChild(chenkbox,10);

    chenkbox->addEventListener([=](Ref* psender,CheckBox::EventType type){

        switch (type) {

            case CheckBox::EventType::SELECTED :

                canAtk = true;

                break;

            case CheckBox::EventType::UNSELECTED :

                canAtk = false;

                break;

            default:

                break;

        }

    });

    createEnemy();//创建敌人

    

    return true;

}


void ZTEDU_10::movePlayer(Vec2 p)

{

    //获取目标位置

    int x = p.x / _tileMap->getTileSize().width;//每块的宽度 转换成块数

    //_tileMap->getMapSize().height*_tileMap->getTileSize().height总高度  p.y :是从下往上的高度

    //getTileSize().height每一块的高度

    int y = (_tileMap->getMapSize().height*_tileMap->getTileSize().height-p.y)/_tileMap->getTileSize().height;

    Vec2 tiledCoord = Vec2(x,y); //块的坐标(哪一块)

    log("x = %d,y = %d",x,y);

    //范围检测

    if (tiledCoord.x<0||tiledCoord.x>=MAX_X||tiledCoord.y<0||tiledCoord.y>=MAX_Y) {

        return;

    }

    //墙的碰撞检测  getTileGIDAt:获取属性值

    int tiled_id = wallLayer->getTileGIDAt(tiledCoord);

    log("%d",tiled_id);

    if (tiled_id)

    {

        auto _value = _tileMap->getPropertiesForGID(tiled_id);//通过GID获取属性字典

        auto _valueStr = _value.getDescription();//通过GID来获取。。。的属性

        log("*************Value : %s",_valueStr.c_str());//当我们使用GID来查找指定tile的属性的时候。它返回一个属性字典,因此,我们可以遍历一下,看是否有可碰撞的物体被设置成”True“,或者是仅仅就是那样。编译并运行工程,因此还没有设置玩家的位置。

        if (!_value.isNull())//不为空

        {   //查找不到返回_valueStr.find("isHit")   -1

            if (_valueStr.find("isHit")!=-1)//查找是否有属性,查找不到为-1  find就是遍历查找

            {

                //它返回一个属性字典

                auto collidableValue = _value.asValueMap().at("isHit").asString().c_str();

                auto strTure = "true";

                log("%s",collidableValue);

                if (collidableValue&&strcmp(collidableValue, strTure)==0)//比较

                {

                    log("can't move");

                    return;

                }

            }

        }

    }

    //西瓜的碰撞检测  可以走过去

    int water_id = waterLayer->getTileGIDAt(tiledCoord);

    

    if (water_id) {

        auto _value = _tileMap->getPropertiesForGID(water_id);

        auto _valueStr = _value.getDescription();

        log("Value %s",_valueStr.c_str());

        if (!_value.isNull())

        {

            if (_valueStr.find("CanEat")!=-1)

            {

                auto collidableValue = _value.asValueMap().at("CanEat").asString().c_str();

                auto strTure = "True";

                log("%s",collidableValue);

                if (collidableValue&&strcmp(collidableValue, strTure))

                {         //移除指定位置砖块对象

                    waterLayer->removeTileAt(tiledCoord);

                }

            }

        }

    }

     heroGoTo(p);


}

void ZTEDU_10::heroGoTo(Vec2 p)

{

    Vec2 worldPoint = _tileMap->convertToWorldSpace(p);//转换世界坐标系

    log("p:(%f,%f)",p.x,p.y);

    log("p:(%f,%f)",worldPoint.x,worldPoint.y);


    //位置点处于中间时候,屏幕移动

    if (worldPoint.x>winSize.width/2) {

        float _x = p.x - winSize.width/2;

        if (_x<=winSize.width)//大于屏幕的一半

        {

            _tileMap->setPositionX(-_x);

        }

    }

    else if (worldPoint.x<winSize.width/4)

    {

        float _x = p.x - winSize.width/4;

        if(_x>=0)

        {

            _tileMap->setPositionX(-_x);

        }

    }

    hero->setPosition(p);

}

bool ZTEDU_10::onTouchBegan(Touch *touch, Event *unused_event)

{

    auto touchLocation = touch->getLocation();

    begainPoint = _tileMap->convertToNodeSpace(touchLocation);

    return true;

}

void ZTEDU_10::onTouchMoved(Touch *touch, Event *unused_event)

{

    

}

void ZTEDU_10::onTouchEnded(Touch *touch, Event *unused_event)

{

    Vec2 endLocation = touch->getLocation();

    Vec2 endPoint = _tileMap->convertToNodeSpace(endLocation);

    

     if (canAtk)

     {

       this->createBullet(endLocation); //发射子弹

       return;

     }

    

    if (begainPoint.equals(endPoint)) //=

    {

        auto heroPoint = hero->getPosition();

        auto disPos = endPoint-heroPoint;

        log("dispos.x = %f,y = %f",disPos.x,disPos.y);

        //左右移动

        if (abs(disPos.x)>abs(disPos.y))//绝对值

        {

            if (disPos.x>0)

            {

                heroPoint.x += _tileMap->getTileSize().width;

                log("hero.x is %f",heroPoint.x);

            }

            else

            {

                heroPoint.x -= _tileMap->getTileSize().width;

                log("hero.x is %f",heroPoint.x);

            }

        }

        //上下移动

        else

        {

            if (disPos.y>0)

            {

                heroPoint.y += _tileMap->getTileSize().height;

                log("hero.y is %f",heroPoint.y);

            }

            else

            {

                heroPoint.y -= _tileMap->getTileSize().height;

                log("hero.y is %f",heroPoint.y);

            }

        }

        this->movePlayer(heroPoint);

    }

    


}

void ZTEDU_10::onTouchCancelled(Touch *touch, Event *unused_event)

{

    

}

void ZTEDU_10::onEnter()

{

    Layer::onEnter();

    auto  touchListener = EventListenerTouchOneByOne::create();

    touchListener->onTouchBegan = CC_CALLBACK_2(ZTEDU_10::onTouchBegan,this);

    touchListener->onTouchMoved = CC_CALLBACK_2(ZTEDU_10::onTouchMoved,this);

    touchListener->onTouchEnded = CC_CALLBACK_2(ZTEDU_10::onTouchEnded, this);

    touchListener->onTouchCancelled = CC_CALLBACK_2(ZTEDU_10::onTouchCancelled,this);

    touchListener->setSwallowTouches(true);

    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);

    

    schedule(CC_CALLBACK_1(ZTEDU_10::collision, this),"collision");

    

    schedule([=](float dt){

        if (enemyVector->size()<=1)

        {

            //return ;

            createEnemy();

        }

        for(auto obj : *enemyVector)

        {

            GoDirection direction = getTheDirection(obj);

            switch (direction)

            {

                case Left:

                {

                    Vec2 point = obj->getPosition();

                    point.x = point.x - _tileMap->getTileSize().width;

                    obj->setPosition(point);

                    break;

                }

                case Right:

                {

                    Vec2 point = obj->getPosition();

                    point.x += _tileMap->getTileSize().width;

                    obj->setPosition(point);

                    break;

                }

                case Up:

                {

                    Vec2 point = obj->getPosition();

                    point.y += _tileMap->getTileSize().height;

                    obj->setPosition(point);

                    break;

                }

                case Down:

                {

                    Vec2 point = obj->getPosition();

                    point.y -= _tileMap->getTileSize().height;

                    obj->setPosition(point);

                    break;

                }

    

                default:

                {

                    Vec2 point = obj->getPosition();

                    int x = arc4random()%2;

                    int y = arc4random()%2;

                    if (x) {

                        point.x += _tileMap->getTileSize().width;

                    }

                    else

                        point.x -= _tileMap->getTileSize().width;

                    if (y) {

                        point.y += _tileMap->getTileSize().height;

                    }

                    else

                        point.y -= _tileMap->getTileSize().height;

                    obj->setPosition(point);

                }

                    break;

            }

        }

    }, 0.5,"UpdateEnemy");

    

    

    

    

    

    

}

void ZTEDU_10::onExit()

{

    

}

GoDirection ZTEDU_10::getTheDirection(Sprite* enemy)

{

    Vec2 heroPoint = hero->getPosition();

    Vec2 enemyPoint = enemy->getPosition();

    Vec2 directPoint = heroPoint-enemyPoint;

    if (abs(directPoint.x)>abs(directPoint.y))

    {

        if (directPoint.x>32)

        {

            return GoDirection::Right;

        }

        else if (directPoint.x<-32)

        {

            return GoDirection::Left;

        }

        else

        {

            return GoDirection::None;

        }

    }

    else

    {

        if (directPoint.y>32)

        {

            return GoDirection::Up;

        }

        else if (directPoint.y<-32)

        {

            return GoDirection::Down;

        }

        else

        {

            return GoDirection::None;

        }

    }

}

void ZTEDU_10::createEnemy()

{

    

    auto enemyGroup = _tileMap->getObjectGroup("enemy")->getObjects();

    for(auto obj: enemyGroup)//范围for 循环

    {

        if (!obj.isNull())

        {

            auto namestr = obj.asValueMap().at("name").asString().c_str();

            auto keyStr = "enemy";

            if (strcmp(namestr, keyStr)==0)

            {

                auto enemySprite = Sprite::create("enemy1.png");

                float x = obj.asValueMap().at("x").asFloat();

                float y = obj.asValueMap().at("y").asFloat();

                enemySprite->setPosition(x,y);

                _tileMap->addChild(enemySprite,10);

                enemyVector->pushBack(enemySprite);

            }

        }

    }

}

void ZTEDU_10::createBullet(Vec2 p)

{

    p = _tileMap->convertToNodeSpace(p);

    Vec2 heroPoint = hero->getPosition();

    

    Vec2 disPoint = p - heroPoint;

    float distance = sqrt(disPoint.x * disPoint.x + disPoint.y * disPoint.y);

    

    float n = 1000/distance;

    

    disPoint = disPoint*n;

    

    auto action = MoveBy::create(10, disPoint);

    auto bullet = Sprite::create("Projectile.png");

    bullet->setPosition(heroPoint);

    _tileMap->addChild(bullet,8);

    bulletVector->pushBack(bullet);

    bullet->runAction(action);

//    Label::createWithSystemFont

    

}

void ZTEDU_10::collision(float dt)//碰撞

{

    if (bulletVector->size()<=0 || enemyVector->size()<=0)

    {

        return;

    }


    for (Vector<Sprite*>::iterator bullet_itr = bulletVector->begin();bullet_itr != bulletVector->end();)

    {

        Sprite* bullet = (Sprite*)*bullet_itr;

        Vec2 point = _tileMap->convertToWorldSpace(bullet->getPosition());

        if (!(this->rect.containsPoint(point)))//子弹是否在屏幕内

        {

            bullet_itr = bulletVector->erase(bullet_itr);//容器清除

            log("0000000");

            bullet->removeFromParentAndCleanup(true);//removeFromParentAndCleanup表示把sprite从屏幕上删除

            //删除父节点中的当前节点并清除动作及回调函数

        }

        else

        {

            Rect _bulletRect = bullet->getBoundingBox();

            for (Vector<Sprite*>::iterator enemy_itr = enemyVector->begin();enemy_itr!=enemyVector->end();)

            {

                Sprite* enemy = (Sprite*)*enemy_itr;

                Rect _enemyRect = enemy->getBoundingBox();

                if (_bulletRect.intersectsRect(_enemyRect))

                {

                    enemy_itr = enemyVector->erase(enemy_itr);

                    //--enemy_itr;

                    enemy->removeFromParentAndCleanup(true);

                    //容器移除

                    bullet_itr = bulletVector->erase(bullet_itr);

                    --bullet_itr;

                    //删除父节点

                    bullet->removeFromParentAndCleanup(true);

                    break;

                }

                else

                {

                    ++enemy_itr;

                }

            }

            ++bullet_itr;

        }

        

    }

    log("bulletVector %zd",bulletVector->size());

    log("enemyVector %zd",enemyVector->size());


}







//例如:保卫萝卜

vector<Point> Animal::getWalkPath(const char* key)

{

    

    

    auto objectsValue = _tileMap->getObjectGroup(key);//获取对象组

    cout<<objectsValue<<endl;

    auto sp_point = objectsValue->getObjects();//获取对象数组

    int myX = 0;

    int myY = 0;

    for (auto  pos:sp_point)

    {//瓦片容器自动存在自身的ValueMap(),查找,并转化为int类型

        

        //设置坐标X转化为int类型

        myX = pos.asValueMap()["x"].asInt();

        myY = pos.asValueMap().at("y").asInt();

        

        

        PointVector.push_back(Point(myX,myY));

        

        

    }

    return PointVector;

}



void Animal::bulletwithmonsterhit(float dt)

{

    auto _MyVec=VecManager::getInstance();

    //炮架_Cannon

    for (int i = 0; i < _MyVec->getShellVec().size();i++)

    {

        Shell* _Shell=(Shell*)_MyVec->getShellVec().at(i);

        //怪物_monste

        for (int j = 0;j < _MyVec->getDiglettVec().size();j++)

        {

            Diglett*_Diglett=(Diglett*)_MyVec->getDiglettVec().at(j);

            

            if (_Diglett->getmonsterHP()==0)

            {

                continue;

            }

            

            float offx=_Diglett->getPositionX()-_Shell->getPositionX();

            float offy=_Diglett->getPositionY()-_Shell->getPositionY();

            

            float distance=sqrt(offx*offx+offy*offy);

            

            if (distance<=120)

            {

                float ratio=offy/offx;

                float angle=(atanf(ratio))/M_PI*180;//1、求的弧度。2、将弧度转换角度

                

                if (angle>0)

                {

                    if (offy>0)

                    {

                        _Shell->setRotation(90-angle);

                    }else

                    {

                        _Shell->setRotation(270-angle);

                    }

                }else if(angle<0)

                {

                    if (offy>0)

                    {

                        _Shell->setRotation(-90-angle);

                    }else

                    {

                        _Shell->setRotation(-270-angle);

                    }

                    

                }else if (angle==0)

                {

                    if (offy>0)

                    {

                        _Shell->setRotation(90);

                    }else

                    {

                        _Shell->setRotation(-90);

                    }

                }

               

               if (!_Shell->getislaunch())

                {

                    bullet =Bullet::create(_Diglett->getPosition(),_Shell->getPosition());

                    this->addChild(bullet,99);

                    bullet->setPosition(Vec2(wezi));

                    float t=distance/400;

                    auto move=MoveTo::create(t,_Diglett->getPosition());


                    _Diglett->setislaunch(true);


                    break;

                }

                break;

            }

        }

    }

}




//动作容器 一般配合序列动作

    Vector<FiniteTimeAction*>AnctionAnrry;

    auto startPos = PointVector.at(0);

    

    for (unsigned int i = 1; i < PointVector.size(); ++i)

    {

        float d = PointVector.at(i-1).getDistance(PointVector.at(i));

        float t = d/100;

       

        AnctionAnrry.pushBack(MoveTo::create(t,PointVector.at(i)));

    }

    auto action1= Sequence::create(AnctionAnrry);

    ddd->setPosition(startPos);

    auto seqAction=Sequence::create(action1,nullptr);

    

    

    ddd->runAction(seqAction);







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值