CCAnimation and CCAnimate leak? - cocos2d-iphone

In my #Monster class, there are 3 different walk animation.
"Monster.h"
#interface Monster : CCSprite{
CCAction *fWalk;
CCAction *bWalk;
CCAction *hWalk;
}
#property (nonatomic, retain) CCAction *fWalk;
#property (nonatomic, retain) CCAction *bWalk;
#property (nonatomic, retain) CCAction *hWalk;
"Monster.m"
+ (id) monsterInit...
{
Monster *sprite = ...// initialization
NSMutableArray *frameArray = [NSMutableArray array];
for ( int i = 0; i < 3; i++ ) {
NSString *fileName = [NSString stringWithFormation:#"%d.png", i];
[frameArray addObject[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:fileName]];
}
CCAnimation *walk = [CCAnimation animationWithFrames:frameArray delay:0.1f];
self.fWalk = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walk restoreOriginalFrame:NO]];
[frameArray removeAllObjects];
for ( int i = 3; i < 6; i++ ) {
NSString *fileName = [NSString stringWithFormation:#"%d.png", i];
[frameArray addObject[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:fileName]];
}
walk = [CCAnimation animationWithFrames:frameArray delay:0.1f];
sprite.bWalk = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walk restoreOriginalFrame:NO]];
[frameArray removeAllObjects];
for ( int i = 6; i < 9; i++ ) {
NSString *fileName = [NSString stringWithFormation:#"%d.png", i];
[frameArray addObject[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:fileName]];
}
walk = [CCAnimation animationWithFrames:frameArray delay:0.1f];
sprite.hWalk = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walk restoreOriginalFrame:NO]];
return sprite;
}
- (void) dealloc
{
[fWalk release];
[bWalk release];
[hWalk release];
[super dealloc];
}
When I run this app with performance tool - Leaks. Instruments display statement which is "CCAnimation *walk...", "self.fWalk...", "walk = ...", "self.bWalk...", "walk = ...", "self.hWalk.." induce memory leaks.
I checked source code about CCAnimation and CCAnimate, they are all "autorelease".I don't know why this leaks happened.
Any idea on what to do?

You have to retain the actions if you plan to use them later, because they are autoreleased when created with the actionWithAction method. Like this:
self.fWalk = [[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walk restoreOriginalFrame:NO]] retain];
Otherwise, your monster class doesn't own the actions and they are autoreleased when you leave the init method.

Ok but when you save all animations into an Array like this:
CCAnimation *anim = [CCAnimation animationWithSpriteFrames:animFrames delay:pDelay];
CCAnimate *animate = [CCAnimate actionWithAnimation:anim];
CCCallFunc *callback = [CCCallFunc actionWithTarget:pTarget selector:pCallBack];
CCSequence *seq = [CCSequence actions:animate, callback , nil];
NSMutableDictionary *animations;
[animations setValue:seq forKey:pName];
- (void)dealloc {
for (NSString* key in [animations allKeys]) {
CCAction *action = [animations objectForKey:key];
[self stopAction:action];
[action stop];
}
[animations removeAllObjects];
//[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
}
The CCAnimation is not release...

Related

EXC_BAD_ACCESS when using NSKeyedUnarchiver to load saved state

I have subclassed a CCSprite to make an object that can be encoded and decoded. I want to save sprites state and load it again at particular positions. Everything seems to be okay apart from decoding with NSKeyedUnarchiver (see loadIconSpriteState below) which gives an EXC_BAD_ACCESS Below is the code:
HelloWorldLayer.h
#interface CCIconSprite : CCSprite {
NSString *iconName;
float iconXPos;
float iconYPos;
}
#property (nonatomic, retain) NSString *iconName;
#property (nonatomic, assign) float iconXPos;
#property (nonatomic, assign) float iconYPos;
+ (id)iconWithType:(NSString*)imageName;
- (id)initWithIconType:(NSString*)imageName;
#end
#interface HelloWorldLayer : CCLayer < NSCoding>
{
CCIconSprite* testSprite;
BOOL savedState;
CGSize size;
CCMoveTo* moveTo;
NSMutableArray* saveSpriteArray;
NSData* savedSpriteData;
}
+(CCScene *) scene;
#end
HelloWorldLayer.m:
CCIconSprite implementation:
#implementation CCIconSprite
#synthesize iconXPos;
#synthesize iconYPos;
#synthesize iconName;
+ (id)iconWithType:(NSString*)imageName
{
return [[[[self class] alloc] initWithIconType:imageName] autorelease];
}
- (id)initWithIconType:(NSString*)imageName
{
self = [super initWithFile:imageName];
if (!self) return nil;
iconName = imageName;
self.position = ccp(iconXPos, iconYPos);
return self;
}
Encoding and decoding:
- (id)initWithCoder:(NSCoder *)decoder {
NSString* imageFileName = [decoder decodeObjectForKey:#"imageFileName"];
self = [self initWithIconType:imageFileName];
if (!self) return nil;
self.iconXPos = [decoder decodeFloatForKey:#"iconXPos"];
self.iconYPos = [decoder decodeFloatForKey:#"iconYPos"];
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:iconName forKey:#"imageFileName"];
[encoder encodeFloat:self.iconXPos forKey:#"iconXPos"];
[encoder encodeFloat:self.iconYPos forKey:#"iconYPos"];
}
#end
HelloWorldLayer implementation:
#implementation HelloWorldLayer
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if( (self=[super init]) ) {
self.scale = 0.5;
savedState = NO;
size = [[CCDirector sharedDirector] winSize];
testSprite = [CCIconSprite spriteWithFile:#"Icon.png"];
testSprite.position = ccp(size.width/4, size.width/4);
testSprite.anchorPoint = ccp(0,0);
[self addChild:testSprite];
moveTo = [CCMoveTo actionWithDuration:3 position:ccp(3*size.width/4, 3*size.width/4)];
[testSprite runAction:moveTo];
[self schedule:#selector(saveAndLoadSpriteState)];
}
return self;
}
Saving and loading state:
-(void)saveIconSpriteState {
saveSpriteArray = [[NSMutableArray alloc] init];
[saveSpriteArray addObject:testSprite];
savedSpriteData = [NSKeyedArchiver archivedDataWithRootObject:saveSpriteArray];
}
-(void)loadIconSpriteState {
[NSKeyedUnarchiver unarchiveObjectWithData:savedSpriteData];
}
-(void)saveAndLoadSpriteState {
if ((testSprite.position.x > size.width/2) && !savedState) {
savedState = YES;
[self saveIconSpriteState];
}
else if ((testSprite.position.x == 3*size.width/4) && savedState) {
savedState = NO;
[self loadIconSpriteState];
[testSprite runAction:moveTo];
}
}
#end
EDIT
After setting an exception break point I got the following error
Assertion failure in -[CCIconSprite initWithFile:]
pointing to the in line:
NSAssert(filename != nil, #"Invalid filename for sprite");
in the
-(id) initWithFile:(NSString*)filename
method of the CCSprite.m class.
Just a hunch but maybe that's it. When decoding a string, you should copy it because you don't own it at this point, nor are you assigning it to a strong or copy property.
- (id)initWithCoder:(NSCoder *)decoder {
NSString* imageFileName = [[decoder decodeObjectForKey:#"imageFileName"] copy];
self = [self initWithIconType:imageFileName];
if (!self) return nil;
...
}
If that's not it, set a breakpoint and verify that the string is indeed correct when encoding and when decoding.

Changing State for an object in Cocos2d

firstly i would like to apologise for being a complete novice but I have researched the web and can not find a solution to my current problem.
I have 3 objects (sprites) that i have set up individually with switch statements and want to use my main gameplay layer to change their states randomly to an animation that i have already defined in the objects individual header and implementation files.
I have set up a self schedule updater and arc4random method that works but it will not change the state of the object, as it only calls the CCLOG that I have also included in the statement.
I have listed to code below and i know it is a bit of a mess but still very much in my first steps of being a beginner, if anyone can point me in the right direction (that's if i have explained this in a way you can understand!) I would be very grateful.
Thanks in advance for even looking at this question.
//-------------------below is my gameplaylayer header file---------//
// GamePlayLayer.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "CCLayer.h"
#import "SneakyJoystick.h"
#import "SneakyButton.h"
#import "SneakyButtonSkinnedBase.h"
#import "SneakyJoystickSkinnedBase.h"
#import "Constants.h"
#import "CommonProtocols.h"
#import "TBT.h"
#import "MBT.h"
#import "BBT.h"
#import "BC.h"
#import "GameCharacter.h"
#import <stdlib.h>
#interface GamePlayLayer : CCLayer <GamePlayLayerDelegate> {
CCSprite *vikingSprite;
SneakyJoystick *leftJoystick;
SneakyButton *jumpButton;
SneakyButton *attackButton;
CCSpriteBatchNode *sceneSpriteBatchNode;
}
#property (readwrite) CharacterStates characterState;
-(void)changeState:(CharacterStates)newState;
-(void)addEnemy;
#end
//---------------------Below is my gameplaylayer implementation file-------------//
// GamePlayLayer.m
#import "GamePlayLayer.h"
#implementation GamePlayLayer
#synthesize characterState;
-(void) dealloc {
[leftJoystick release];
[jumpButton release];
[attackButton release];
[super dealloc];
}
-(void)initJoystickAndButtons {
CGSize screenSize = [CCDirector sharedDirector].winSize;
//---DELETED MOST OF THE ABOVE METHOD AS NOT NEEDED FOR THIS QUESTION----//
-(void) update:(ccTime)deltaTime {
CCArray *listOfGameObjects =
[sceneSpriteBatchNode children];
for (GameCharacter *tempChar in listOfGameObjects) {
[tempChar updateStateWithDeltaTime:deltaTime andListOfGameObjects:listOfGameObjects];
}
}
-(void) createObjectOfType: (GameObjectType)objectType
withHealth:(int)initialHealth atLocation:(CGPoint)spawnLocation withZValue:(int)ZValue {
if (objectType == kEnemyType1BT) {
CCLOG(#"creating the 1BT");
TBT *tBT = [[TBT alloc] initWithSpriteFrameName:#"BT_anim_1.png"];
[tBT setCharacterHealth:initialHealth];
[tBT setPosition:spawnLocation];
[sceneSpriteBatchNode addChild:tBT
z:ZValue
tag:k1BTtagValue];
[tBT release];}
if (objectType == kEnemyType3BT){
CCLOG(#"creating the radar enemy");
BBT *bBT = [[BBT alloc] initWithSpriteFrameName:#"BT_anim_1.png"];
[bBT setCharacterHealth:initialHealth];
[bBT setPosition:spawnLocation];
[sceneSpriteBatchNode addChild:bBT
z:ZValue
tag:k3BTtagValue];
[bBT release];
}
if (objectType == kEnemyType2BT){
CCLOG(#"creating the radar enemy");
MBT *mBT = [[MBT alloc] initWithSpriteFrameName:#"BT_anim_1.png"];
[mBT setCharacterHealth:initialHealth];
[mBT setPosition:spawnLocation];
[sceneSpriteBatchNode addChild:mBT
z:ZValue
tag:k2BTtagValue];
[mBT release];
}
}
//--PROBLEM I HAVE IS BELOW--//
-(void)addEnemy {
int x = (arc4random() % 3);
TBT *tBT = (TBT*)
[sceneSpriteBatchNode getChildByTag:kEnemyType1BT];
//--Just using one object(sprite) to begin with--//
if (x>0) {
CCLOG(#"RANDOM KSTATETEST!!!!!!");
[tBT changeState:kStatetest]; <---it is not changing state to kStatetest
}
-(id)init {
self = [super init];
if (self !=nil) {
CGSize screenSize = [CCDirector sharedDirector]. winSize;
self.TouchEnabled = YES;
srandom(time(NULL));
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[[CCSpriteFrameCache sharedSpriteFrameCache]
addSpriteFramesWithFile:#"scene1atlas.plist"]; // 1
sceneSpriteBatchNode =
[CCSpriteBatchNode batchNodeWithFile:#"scene1atlas.png"]; // 2
} else {
[[CCSpriteFrameCache sharedSpriteFrameCache]
addSpriteFramesWithFile:#"scene1atlasiPhone.plist"]; // 1
sceneSpriteBatchNode =
[CCSpriteBatchNode batchNodeWithFile:#"scene1atlasiPhone.png"];// 2
}
[self addChild:sceneSpriteBatchNode z:0]; // 3
[self initJoystickAndButtons]; // 4
BC *viking = [[BC alloc]
initWithSpriteFrame:[[CCSpriteFrameCache
sharedSpriteFrameCache]
spriteFrameByName:#"BCmoving_anim_1.png"]];
//[viking setJoystick:leftJoystick];
[viking setJumpButton:jumpButton];
[viking setAttackButton:attackButton];
[viking setPosition:ccp(screenSize.width * 0.19f,
screenSize.height * 0.19f)];
[viking setCharacterHealth:3];
[sceneSpriteBatchNode
addChild:viking
z:kVikingSpriteZValue
tag:kVikingSpriteTagValue]; heatlh is set to 100
[self schedule:#selector(addEnemy) interval:1.0f];
[self createObjectOfType:kEnemyType1BT withHealth:3 atLocation:ccp(screenSize.width * 0.0439f, screenSize.height * 0.822f) withZValue:10];
[self createObjectOfType:kEnemyType3BT withHealth:3 atLocation:ccp(screenSize.width * 0.0439f, screenSize.height * 0.45f) withZValue:10];
[self createObjectOfType:kEnemyType2BT withHealth:3 atLocation:ccp(screenSize.width * 0.0439f, screenSize.height * 0.638f) withZValue:10];
//Sets up the schedular call that will fire the update method in GamePlayLayer.m every frame.
[self scheduleUpdate];
}
return self;
}
#end
//----------------- below is one of my objects header files--------------//
#import <Foundation/Foundation.h>
#import "GameCharacter.h"
#interface TBT : GameCharacter{
CCAnimation *tiltingAnim;
CCAnimation *transmittingAnim;
CCAnimation *loseLifeAnim;
CCAnimation *throwingAnim;
CCAnimation *afterThrowingAnim;
CCAnimation *shootPhaserAnim;
GameCharacter *vikingCharacter;
id <GamePlayLayerDelegate> delegate;
}
#property (nonatomic,assign) id <GamePlayLayerDelegate> delegate;
#property (nonatomic, retain) CCAnimation *tiltingAnim;
#property (nonatomic, retain) CCAnimation *transmittingAnim;
//#property (nonatomic, retain) CCAnimation *takingAHitAnim;
#property (nonatomic, retain) CCAnimation *loseLifeAnim;
#property (nonatomic, retain) CCAnimation *throwingAnim;
#property (nonatomic,retain) CCAnimation *afterThrowingAnim;
#property (nonatomic,retain) CCAnimation *shootPhaserAnim;
-(void)initAnimations;
#end
//-----------------below is the .m file for one of my objects--------------//
#import "TBT.h"
#implementation TBT
#synthesize delegate;
#synthesize tiltingAnim;
#synthesize transmittingAnim;
#synthesize loseLifeAnim;
#synthesize throwingAnim;
#synthesize afterThrowingAnim;
#synthesize shootPhaserAnim;
-(void) dealloc {
delegate = nil;
[tiltingAnim release];
[transmittingAnim release];
[loseLifeAnim release];
[throwingAnim release];
[afterThrowingAnim release];
[shootPhaserAnim release];
[super dealloc];
}
-(void)shootPhaser {
CGPoint phaserFiringPosition;
PhaserDirection phaserDir;
CGRect boundingBox = [self boundingBox];
CGPoint position = [self position];
float xPosition = position.x + boundingBox.size.width * 0.542f;
float yPosition = position.y + boundingBox.size.height * 0.25f;
if ([self flipX]) {
CCLOG(#"TBT Facing right, Firing to the right");
phaserDir = kDirectionRight;
} else {
CCLOG(#"TBT Facing left, Firing to the left");
xPosition = xPosition * -1.0f;
phaserDir = kDirectionLeft;
}
phaserFiringPosition = ccp(xPosition, yPosition);
[delegate createPhaserWithDirection:phaserDir andPosition:phaserFiringPosition];
}
-(void)changeState:(CharacterStates)newState {
[self stopAllActions];
id action = nil;
[self setCharacterState:newState];
switch (newState) {
case kStatespawning:
CCLOG(#"TBT->Changing State to Spwaning");
[self setDisplayFrame:
[[CCSpriteFrameCache sharedSpriteFrameCache]
spriteFrameByName:#"BT_anim_1.png"]];
break;
case kStateIdle:
CCLOG(#"TBT->schaning state to idle");
[self setDisplayFrame:
[[CCSpriteFrameCache sharedSpriteFrameCache]
spriteFrameByName:#"BT_anim_1.png"]];
break;
case kStatetest:
CCLOG(#"TBT->Changing State to test");
action = [CCSequence actions : [CCDelayTime actionWithDuration:1.5f],[CCAnimate actionWithAnimation:transmittingAnim], nil];
break;
default:
CCLOG(#"unhandled state %d in TBT", newState);
break;
}
if (action !=nil) {
[self runAction:action];
}
}
-(void)updateStateWithDeltaTime: (ccTime)deltaTime andListOfGameObjects:(CCArray*)listOfGameObjects {
if (characterState == kStateDead)
return;
if ((([self numberOfRunningActions] == 0) && (characterState != kStateDead)) ) {
CCLOG(#"TBT Going to Idle");
[self changeState:kStateIdle];
return;
}
}
-(void)initAnimations {
[self setTiltingAnim:[self loadPlistForAnimationWithName:#"tiltingAnim" andClassName:NSStringFromClass([self class])]];
[self setTransmittingAnim:[self loadPlistForAnimationWithName:#"transmittingAnim" andClassName:NSStringFromClass([self class])]];
}
-(id) initWithSpriteFrameName:(NSString*)frameName{
if ((self=[super init])) {
if ((self = [super initWithSpriteFrameName:frameName])) {
CCLOG(#"### TBT initialized");
[self initAnimations];
characterHealth = 3.0f;
gameObjectType = kEnemyType1BT;
[self changeState:kStatespawning];
}}
return self;
}
#end
Finally found out that all I needed was to add the following code to my TBT gameCharacters-(void)updateStateWithDeltaTime: method...
if (characterState == kStateTest) {
if (characterState != kStateTest) {
[self changeState:kStateTest];
return;
}
now it works fine.
Thanks again to Mikael for trying to help me.

Change Animation Cocos2d

I have some question about Animation;
I have class with animation;
#interface Player : CCNode{
CCSprite *_player;
CCSpriteBatchNode *spriteSheet;
CCAction *walkAction;
CCAnimation *walkAnim;
int playerSpeed;
int xPos;
int yPos;
int state;
int currentAnim;
}
#property (nonatomic, retain) CCSprite *_player;
-(id)init {
if( (self=[super init] )) {
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"duckAnimDown.plist"];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"DuckAnimTurn.plist"];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"duckAnimUp.plist"];
currentAnim = 0;
state = 0;
[self chekState];
}
return self;
}
-(void)setState:(int)st {
state = st;
[self chekState];
}
-(void)chekState{
[self stopAllActions];
walkAnim = nil;
if (state == 1 && currentAnim != state) {
[spriteSheet removeChild:_player cleanup:YES];
spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"duckAnimDown.png"];
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for (int i = 1; i <= 12 ; ++i) {
[walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"duck_down%d.png", i]]];
}
walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.04f];//0.06
_player = [CCSprite spriteWithSpriteFrameName:#"duck_down1.png"];
walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
}
if (state == 2 && currentAnim != state) {
[spriteSheet removeChild:_player cleanup:YES];
spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"DuckAnimTurn.png"];
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for (int i = 1; i <= 10 ; ++i) {
[walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"duck_turn%d.png", i]]];
}
walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.04f];//0.06
_player = [CCSprite spriteWithSpriteFrameName:#"duck_turn1.png"];
walkAction = [CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO];
}
if (state == 3 && currentAnim != state) {
[spriteSheet removeChild:_player cleanup:YES];
spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"duckAnimUp.png"];
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for (int i = 1; i <= 13 ; ++i) {
[walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"duck_up%d.png", i]]];
}
walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.04f];//0.06
_player = [CCSprite spriteWithSpriteFrameName:#"duck_up1.png"];
walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
}
if (currentAnim != state) {
[_player runAction:walkAction];
[spriteSheet addChild:_player];
[self addChild:spriteSheet];
currentAnim = state;
}
}
I use this class in GameplayScene;
duckSprite = [Player node];
To change animation i call: [duckSprite setState:2];
It's ok, but when i change animation FPS are very low 20 - 25;
What is wrong in my code?
Thanks.
Probably the problem is that you are doing too much things in your checkState method.
You can move almost all of it to the init method and then just call runAction for the appropriate animation.
Also you should probably use just one sprite sheet for all the animations. This way you won't need to reload the player sprite every time the animation changes.
Here is a tutorial which explains everything nicely.

Creating multiple sprites (Novice Cocos2d Question)

I have a CCLayer class where I create an animated sprite that is the "hero" for the game. Now, I am trying to create multiple enemies for him to fight, and I'm having trouble. I want to create a class called "Enemy" that holds everything relevant to the enemy, and just create multiple instances of that class for all my enemies. How do I go about doing this?
Here's the class I have so far (where i create teh hero, called "_bear".
#import "FightGame.h"
#import "SneakyJoystick.h"
#import "SneakyJoystickSkinnedBase.h"
#import "ColoredCircleSprite.h"
#import "CCTouchDispatcher.h"
#import "GManager.h"
CCSprite *player;
BOOL _moving, _crouched, _jumping, _actionTouch, _maxJump, _leftJumping, _rightJumping, _punching, _kicking, _touchSet;
int startX, startY;
#implementation FightGame
#synthesize bear = _bear;
#synthesize jumpAction = _jumpAction;
#synthesize walkAction = _walkAction;
#synthesize punchAction = _punchAction;
#synthesize kickAction = _kickAction;
#synthesize crouchAction = _crouchAction;
#synthesize currentTouch;
+(id) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
FightGame *layer = [FightGame node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] )) {
/*player = [CCSprite spriteWithFile: #"Person1.png"];
player.position = ccp( 50, 100 );
[self addChild:player]; */
//bools
_maxJump = FALSE;
_jumping = FALSE;
_leftJumping = FALSE;
_rightJumping = FALSE;
_touchSet = FALSE;
//Animated Bear
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"Fighter.plist"];
CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode
batchNodeWithFile:#"Fighter.png"];
[self addChild:spriteSheet];
//load frames
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 6; ++i) {
[walkAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"walk%i.png", i]]];
}
NSMutableArray *punchAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 2; ++i) {
[punchAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"punch%i.png", i]]];
}
NSMutableArray *jumpAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 3; ++i) {
[jumpAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"jump%i.png", i]]];
}
NSMutableArray *kickAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 3; ++i) {
[kickAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"kick%i.png", i]]];
}
//create animation
CCAnimation *walkAnim = [CCAnimation
animationWithFrames:walkAnimFrames delay:0.1f];
CCAnimation *punchAnim = [CCAnimation
animationWithFrames:punchAnimFrames delay:0.1f];
CCAnimation *jumpAnim = [CCAnimation
animationWithFrames:jumpAnimFrames delay:0.5f];
CCAnimation *kickAnim = [CCAnimation
animationWithFrames:kickAnimFrames delay:0.1f];
CGSize winSize = [CCDirector sharedDirector].winSize;
self.bear = [CCSprite spriteWithSpriteFrameName:#"walk1.png"];
_bear.position = ccp(winSize.width/2, winSize.height/2);
//creating the actions
self.walkAction = [CCRepeatForever actionWithAction:
[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
self.punchAction = [CCRepeat actionWithAction:[CCAnimate actionWithAnimation:punchAnim] times:1];
self.jumpAction = [CCRepeat actionWithAction:[CCAnimate actionWithAnimation:jumpAnim] times:1];
self.kickAction = [CCRepeat actionWithAction:[CCAnimate actionWithAnimation:kickAnim] times:1];
[spriteSheet addChild:_bear];
//end animated bear, start joystick
SneakyJoystickSkinnedBase *leftJoy = [[[SneakyJoystickSkinnedBase alloc] init] autorelease];
leftJoy.position = ccp(60,60);
leftJoy.backgroundSprite = [ColoredCircleSprite circleWithColor:ccc4(105, 105, 105, 200) radius:55];
leftJoy.thumbSprite = [ColoredCircleSprite circleWithColor:ccc4(255, 0, 0, 200) radius:25];
leftJoy.joystick = [[SneakyJoystick alloc] initWithRect:CGRectMake(0,0,128,128)];
leftJoystick = [leftJoy.joystick retain];
[self addChild:leftJoy];
[self schedule:#selector(nextFrame:)];
self.isTouchEnabled = YES;
}
return self;
}
I could just give you the answer on this but that is useless. You need to crawl before you can run. Go to RayWenderlich.com and do at least some of his Cocos2D tutorials. You will get yourself up to speed quickly enough.

CCSpriteBatchNode

I'm creating a class named Player ... in the init method I want to use a CCSpriteBatchNode:
#interface Player : CCNode {
CCSprite *player;
CCSpriteBatchNode *spriteSheet;
CCAction *walkAction;
int playerSpeed;
int xPos;
int yPos;
}
#property (nonatomic, retain) CCSprite *player;
#property (nonatomic, retain) CCSpriteBatchNode *spriteSheet;
#property (nonatomic, retain) CCAction *walkAction;
#property int playerSpeed;
#property int xPos;
#property int yPos;
-(id)init {
if( (self=[super init] )) {
playerSpeed = 70;
xPos = 160;
yPos = 10;
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"bugA.plist"];
spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"bugA.png"];
[player useBatchNode:spriteSheet];
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for (int i = 1; i <= 8 ; ++i) {
[walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"bug%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];
player = [CCSprite spriteWithSpriteFrameName:#"bug1.png"];
walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
[player runAction:walkAction];
[spriteSheet addChild:player];
}
return self;
}
then in HelloWorldScene I want to use this class with animation
Player *pl = [Player node];
[self addChild:pl.player];
but nothing works. What am I doing wrong?
Thanks.
Here your code with some modification
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"bugA.plist"];
spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"bugA.png"];
//add :
[self addChild:spriteSheet];
//instead of :
[player useBatchNode:spriteSheet];
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for (int i = 1; i <= 8 ; ++i) {
[walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"bug%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];
player = [CCSprite spriteWithSpriteFrameName:#"bug1.png"];
//add to show the player in the middle of the screen
CGSize winSize = [CCDirector sharedDirector].winSize;
player.position = ccp(winSize.width/2, winSize.height/2);
walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
[player runAction:walkAction];
[spriteSheet addChild:player];
To use this code just call
Player *pl = [Player node];
[self addChild:pl];
Did you try to call you class like that [self addChild:pl]; instead of [self addChild:pl.player]; ?