Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error while changing player animation

First of all , I'm using cocos2d 3.6 Everything works well until I press right arrow key on keyboard which execute the startRunning() function from keypress event listener,actions stopped successfully but on the next line ,this->runAction(Animate::create( runAnimation));, I get error. runAnimation is OK.I guess the problem is in running new Action but I dont know what is it.

here's the code:

#pragma once

#include "cocos2d.h"

using namespace cocos2d;

const int DIR_RIGHT = 1;
const int DIR_LEFT = -1;




class CPlayer: public Sprite
{

private:
    Animation* idleAnimation;
    Animation* runAnimation;
    Animation* bowAnimation;
    Animation* climbAnimation;
    SpriteFrame* jumpFrame;
    SpriteFrame* fallFrame;
    SpriteFrame* wallJumpFrame;

    boolean onGround = true;
    boolean running = false;
    int dir = DIR_RIGHT;
    float movementSpeed = 50; //50 unit in world space 
    float stateTime=0;
public:

    Animation* createAnimation(const char* format, float delay, bool loop){

        Animation* animation = Animation::create();
        char str[100] = { 0 };
        int frameIndex = 1;
        do
        {
            sprintf(str, format, frameIndex);

            auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
            if (frame == NULL)
                break;
            animation->addSpriteFrame(frame);
            Texture2D::TexParams texParams = { GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE };
            frame->getTexture()->setTexParameters(texParams);
            frameIndex++;
        } while (true);
        int loops = 1;
        if (loop)
            loops = -1;
        animation->setDelayPerUnit(delay);
        animation->setLoops(loops);


        return animation;

    }

    CPlayer(){

        idleAnimation = createAnimation("Idle/player_idle_%d.png", .2f, -1);
        runAnimation = createAnimation("Run/player_run_%d.png", .5f, -1);
        bowAnimation = createAnimation("Bow/bow_%d.png", .2f, -1);
        climbAnimation = createAnimation("Climb/player_climb_%d.png", .2f, -1);
        jumpFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("Fall-Jump-WallJ/player_climb_jump.png");
        fallFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("Fall-Jump-WallJ/player_climb_fall.png");
        wallJumpFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("Fall-Jump-WallJ/player_climb_wall_jump.png");

        this->runAction(Animate::create(idleAnimation));
    }

    CREATE_FUNC(CPlayer);

    void startRunning(){
        running = true;

        if (onGround){
            this->stopAllActions();
            this->runAction(Animate::create( runAnimation));
        }
    }

    void endRunning(){
        running = false;
        if (onGround){
            this->stopAllActions();
            this->runAction(Animate::create(idleAnimation));
        }

    }

    void update(float delta){
        stateTime += delta;
        if (onGround && running){
            this->setPositionX(this->getPositionX() + delta*  movementSpeed*dir);

        }
    }

    void headToRight(){
        this->setFlipX(false);
        dir = DIR_RIGHT;
    }

    void headToLeft(){
        this->setFlippedX(true);
        dir = DIR_LEFT;
    }



};
like image 573
Saleh Avatar asked Sep 27 '22 06:09

Saleh


1 Answers

Your createAnimation method returns an autoreleased animation object, which is released before you use it.

To fix this issue you need to retain your autoreleased objects after you create them, and release them in destructor or when you don't need them no more:

CPlayer(){
    idleAnimation = createAnimation("Idle/player_idle_%d.png", .2f, -1);
    runAnimation = createAnimation("Run/player_run_%d.png", .5f, -1);
    bowAnimation = createAnimation("Bow/bow_%d.png", .2f, -1);
    climbAnimation = createAnimation("Climb/player_climb_%d.png", .2f, -1);
    idleAnimation->retain();
    runAnimation->retain();
    bowAnimation->retain();
    climbAnimation->retain();
    jumpFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("Fall-Jump-WallJ/player_climb_jump.png");
    fallFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("Fall-Jump-WallJ/player_climb_fall.png");
    wallJumpFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("Fall-Jump-WallJ/player_climb_wall_jump.png");

    this->runAction(Animate::create(idleAnimation));
}

virtual ~CPlayer() {
    idleAnimation->release();
    runAnimation->release();
    bowAnimation->release();
    climbAnimation->release();
}
like image 104
musikov Avatar answered Oct 02 '22 02:10

musikov