Question

So after taking a little break after being very frustrated for months on end with this issue, I am now back and attempting to solve my issue once and for all.

I’m not going to post code, because the code I have is messy and patchy and is from countless points of view.

My issue is this:

I have a sprite, and his information is stored in a class called player.m. I have a game level, and it is stored in GameLevelLayer.m

I have player.m store velocity, direction, and all the information about the character, and then I have the GameLevelLayer.m implement, move, use bounds to check collisions, etc.

I now want to make the character move using a spritesheet (I know how to do spritesheeting, I just don’t know how to do it while working with two different classes)

My question is, do I create the batchnodes and spritesheet information (CCBatchnodes, caches, etc) and all of the actions and everything in player.m, and then run them in GameLevelLayer.m? Or do I create all that in GameLevelLayer.m

I really need some help here because I’ve been stuck on this for months

EDIT:

Here is where I am, thanks to a suggestion from a community member.

This is my entire player.m (Long story short, I define everything about the player 'you might just want to pay attention to the init, because that seems to be the problem. The other stuff is my physics engine')

#import "Player.h"
#import "SimpleAudioEngine.h"
#import "GameLevelLayer.h"

@implementation Player

@synthesize velocity = _velocity;
@synthesize desiredPosition = _desiredPosition;
@synthesize onGround = _onGround;
@synthesize forwardMarch = _forwardMarch, mightAsWellJump = _mightAsWellJump, isGoingLeft = _isGoingLeft;
@synthesize WalkAction = _WalkAction;
@synthesize isMoving = _isMoving;

-(id)initWithTexture:(CCTexture2D *)texture{
if (self = [super init]) {

    self.velocity = ccp(0.0, 0.0);

    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile: @"BankerSpriteSheet_default.plist"];

    CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"BankerSpriteSheet_default.png"];
    [self addChild:spriteSheet];

    NSMutableArray *walkAnimFrames = [NSMutableArray array];
    for(int i = 1; i <=6; ++i) {
        [walkAnimFrames addObject: [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName: [NSString stringWithFormat:@"banker%d.png", i]]];

        CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];
        self = [super initWithSpriteFrameName:@"banker1.png"];
        self.WalkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
        //[_Banker runAction:_WalkAction];
        [spriteSheet addChild:self];
        [[CCAnimationCache sharedAnimationCache] addAnimation:walkAnim name:@"walkAnim"];
    }
}
return self;
}

-(void)update:(ccTime)dt {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults synchronize];
CGPoint jumpForce = ccp(0.0, 310.0);
float jumpCutoff = 150.0;

if (self.mightAsWellJump && self.onGround) {
    self.velocity = ccpAdd(self.velocity, jumpForce);
    if (![defaults boolForKey:@"All Muted"]) {
        if (![defaults boolForKey:@"SFX Muted"]) {
            [[SimpleAudioEngine sharedEngine] playEffect:@"jump.wav"];
        }
    }

} else if (!self.mightAsWellJump && self.velocity.y > jumpCutoff) {
    self.velocity = ccp(self.velocity.x, jumpCutoff);
}

CGPoint gravity = ccp(0.0, -450.0);
CGPoint gravityStep = ccpMult(gravity, dt);
CGPoint forwardMove = ccp(800.0, 0.0);
CGPoint forwardStep = ccpMult(forwardMove, dt);

self.velocity = ccp(self.velocity.x * 0.90, self.velocity.y); //2

if (self.forwardMarch) {
        self.velocity = ccpAdd(self.velocity, forwardStep);
    if (!self.isMoving) {
        //[self runAction: _WalkAction];
        //self.isMoving = YES;
    }
} //3

CGPoint minMovement = ccp(0.0, -450.0);
CGPoint maxMovement = ccp(120.0, 250.0);
self.velocity = ccpClamp(self.velocity, minMovement, maxMovement);

self.velocity = ccpAdd(self.velocity, gravityStep);

CGPoint stepVelocity = ccpMult(self.velocity, dt);
if (!self.isGoingLeft) {
    self.desiredPosition = ccpAdd(self.position, stepVelocity);
}else{
    self.desiredPosition = ccp(self.position.x-stepVelocity.x, self.position.y+stepVelocity.y);
}

}

-(CGRect)collisionBoundingBox {

CGRect collisionBox = CGRectInset(self.boundingBox, 3, 0);
//CGRect collisionBox = self.boundingBox;
//collisionBox = CGRectOffset(collisionBox, 0, -2);
CGPoint diff = ccpSub(self.desiredPosition, self.position);
CGRect returnBoundingBox = CGRectOffset(collisionBox, diff.x, diff.y);
return returnBoundingBox;

}



@end

So now the issue is, how do i get the player to appear in the game like a normal sprite, and then how do I run the animations when the player begins to move forward

Was it helpful?

Solution

Your game architecture is very good! Keep player properties on player and use GameLayer only to send player actions is the best approach.

If your Player Class extends from CCSprite, put everithing related to player in your Player Class: Run animations on it, load the cache on player constructor (use the CCSprite initWithTexture:rect:rotated: or a custom autorelease constructor, like a +(id)player ).

Then, in your GameLevelLayer you will need a CCSpriteBatchNode to add your player to it. You can use this batch node to add other objects that use same spritesheet.

EDIT:

Reviewing your code, your initWithTexture is wrong. The correct is to call [super initWithTexture:]:

-(id)initWithTexture:(CCTexture2D *)texture{
    if (self = [super initWithTexture:texture]) {

Then, in your GameLevelLayer, create your player and add it to a CCSpriteBatchNode:

// *** In GameLevelLayer.m ***
// Create player
Player *player = [Player spriteWithFile:@"player.png"];
// Create batch node
CCSpriteBatchNode *batchNode = [CCSpriteBatchNode batchNodeWithTexture:player.texture];
// Add batch node as child
[self addChild:batchNode];
// Add player as batch node's child
[batchNode addChild:player];
// Set player position
player.position = ccp(100,100);

Your GameLevelLayer needs to do only this to create your Player. And when it detects user input, call methods like "jump", "moveRight", "moveLeft" in your player. Also detect collisions and send actions to player like "die", "getSpecialItem".

// *** In GameLevelLayer.m ***
[player jump];
[player die];

So, your player needs to handle these methods and performs its own logic to do the actions:

// *** In Player.m ***
- (void)moveRight
{
    self.position = ccpAdd(self.position, ccp(10,0));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top