更改播放器动画时出错
Error while changing player animation
首先,我使用的是 cocos2d 3.6
一切正常,直到我按键盘上的右箭头键从按键事件侦听器执行 startRunning() 函数,操作成功停止但在下一行,this->runAction(Animate::create( runAnimation));
,我收到错误。
runAnimation 是 OK.I 猜测问题出在 运行 new Action 但我不知道它是什么。
代码如下:
#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;
}
};
你的 createAnimation 方法 returns 一个 autoreleased 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);
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();
}
首先,我使用的是 cocos2d 3.6
一切正常,直到我按键盘上的右箭头键从按键事件侦听器执行 startRunning() 函数,操作成功停止但在下一行,this->runAction(Animate::create( runAnimation));
,我收到错误。
runAnimation 是 OK.I 猜测问题出在 运行 new Action 但我不知道它是什么。
代码如下:
#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;
}
};
你的 createAnimation 方法 returns 一个 autoreleased 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);
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();
}