在将它交换到 coco2dx 中的另一个之后,如何将精灵恢复为原始图像?

How do I restore the sprite into original image after swapped it to another one in coco2dx?

在我的游戏环境中,精灵是一个微笑的宝宝,当宝宝被触摸时,当前精灵图像变为哭泣的婴儿,然后在3秒的哭声效果结束后,精灵将恢复为微笑宝贝形象。

我的问题是

  1. 如何换回上一张图片?

我把笑脸宝宝换成了哭脸宝宝,不知道怎么和原来的笑脸宝宝互换?

  1. 如何保证一次点击? 每次小精灵被触摸时,音频都会开始播放,这是不理想的,因为我希望事件函数只在上一个事件处理完成后调用。

这是我的代码,非常感谢!

bool HelloWorld::init()
{
    // 1. super init first
if ( !Layer::init() )
{
    return false;
}

Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();

//add background scene
auto backgroundSprite = Sprite :: create("scene001.jpg");
backgroundSprite->setAnchorPoint(Vec2(0,0));
backgroundSprite->setScaleX((visibleSize.width / backgroundSprite->getContentSize().width) * 1);
backgroundSprite->setScaleY((visibleSize.height / backgroundSprite->getContentSize().height) * 1);
addChild(backgroundSprite);

//add smileBaby sprite
auto smileBabySprite = Sprite :: create("figure001.png");

smileBabySprite -> setPosition(Vec2(500,400));
addChild(smileBabySprite);

//add crying audio
auto audio = CocosDenshion::SimpleAudioEngine::getInstance();

auto babyListener = EventListenerTouchOneByOne::create();
babyListener -> onTouchBegan = [smileBabySprite, audio](Touch* touch, Event* event)
{
    //change smileBaby sprite to cryingBaby sprite
    smileBabySprite->setTexture(CCTextureCache::sharedTextureCache()->addImage("figure002.png"));
    audio -> playEffect("babycry.mp3",false,1.0f,1.0f,1.0f);

    return true;
};

babyListener -> onTouchEnded=[smileBabySprite](Touch* touch, Event* event )
{

};



_eventDispatcher -> addEventListenerWithSceneGraphPriority(babyListener, this);

return true;

}

您想要的是保持状态关于婴儿是否在哭。最好的办法是将此逻辑保留在自定义 Node 子类中。

这里有一些(几乎是伪的)代码可以帮助您入门:

Baby.h:

#pragma once

#include "cocos2d.h"

class Baby : public cocos2d::Node
{
private:
    cocos2d::Sprite *_sprite;    // Weak reference
    bool _crying;
    float _cryingTime;

public:
    CREATE_FUNC(Baby);

protected:
    virtual bool init() override;
    virtual void update(float delta) override;

public:
    void touched();
    bool isInside(cocos2d::Touch *touch) const
protected:
    void setSprite();
};

Baby.cpp:

#include "Baby.h"

USING_NS_CC;

bool Baby::init()
{
    if (!Node::init())
        return false;
    _crying = false;
    setSprite();
    scheduleUpdate();
    return true;
}

void Baby::update(float delta)
{
    Node::update(delta);
    if (_crying) {
        _cryingTime -= delta;
        if (_cryingTime <= 0.0f) {
            _crying = false;
            setSprite();
        }
    }
}

void Baby::touched()
{
    if (_crying)
        return;      // Already crying
    _crying = true;
    _cryingTime = 3.0f;    // Length of audio, I guess?
    setSprite();

    // Start crying sound here
}

bool Baby::isInside(Touch *touch) const
{
    Vec2 locationInNode = _sprite->convertToNodeSpace(touch->getLocation());
    Size size = _sprite->getContentSize();
    Rect rect = Rect(0.0f, 0.0f, size.width, size.height);
    return rect.containsPoint(locationInNode);
}

void Baby::setSprite()
{
    if (_sprite)
        _sprite->removeFromParent();

    _sprite = Sprite::initWithFile(_crying ? "baby_crying.png" : "baby.png");
    Vec2 size = getContentSize();
    _sprite->setPosition(size.width * 0.5f, size.height * 0.5f);
    addChild(_sprite);
}

您在父级中添加 Baby 节点而不是精灵,使用:

_baby = Baby::create();
_baby->setPosition(Wherever);
addChild(_baby);

其中_baby是一个实例变量并使用isInside()方法来测试触摸事件是否在精灵的边界内并调用其touched()方法:

Touch *touch = ...;
if (_baby->isInside(touch)) {
    _baby->touched();
}

并且 Baby 对象将根据状态忽略触摸。