Search code examples
cocos2d-iphonebox2djoystick

Using SneakyJoystick in a layer to control a game character in a different layer


What I'm trying to achieve is the ability to use a Cocos2d SneakyInput SneakyJoystick to control the movement of my LHSprite (created using level helper) Character/Player in my box2d/cocos2d game.

I can get it to work, however, the sneakyJoystick joystick is in the same layer that my gameplay is in, and seen as though my game screen 'follows' the character - the joystick actually moves off the screen when the camera/screen is moved.

I have tried setting the joystick up in a separate layer ('MyUILayer'), and using it to control my character in my 'GameLayer'.

Here is how i've tried doing this:

in 'MyUILayer' i have the code to set up the following sneakyJoystick components:

@interface MyUILayer : CCLayer {
    SneakyJoystick *leftJoystick;
    SneakyButton * jumpButton;
    SneakyButton * attackButton;
}

@property (readonly) SneakyButton *jumpButton;
@property (readonly) SneakyButton *attackButton;
@property (readonly) SneakyJoystick *leftJoystick;

Now, in 'GameLayer I tried to access the value created by the sneakyJoystick called 'leftJoystick' in 'MyUILayer'.

in the declaration file (GameLayer.h):

    #import "MyUILayer.h"
    @interface GameLayer : CCLayer {
    //.............
        LHSprite *character;
        b2Body *characterBody;
        SneakyJoystick *characterJoystick;
        SneakyButton *jumpButton;
        SneakyButton *attackButton;
//.............
    }

in GameLayer.mm:

        //in my INIT method
{
        MyUILayer *UILAYER = [[MyUILayer alloc]init];
        characterJoystick = UILAYER.leftJoystick;
        [self scheduleUpdate];
// Define what 'character' is and what 'characterBody' is ('character is a LHSprite, and 'characterBody' is a b2Body)
}
//in my tick method
{    
b2Vec2 force;
    force.Set(characterJoystick.velocity.x * 10.0f, 0.0f);

    characterBody->ApplyForce(force, characterBody->GetWorldCenter());
}

I really can't understand why 'characterBody', in 'GameLayer' won't move based on the value of 'leftJoystick', in 'MyUILayer'.

Sorry if its a bit long winded! - I have also uploaded my project file, so you can take a look at the project itself: https://dl.dropbox.com/u/2578642/ZOMPLETED%202.zip

Huge thanks to anyone who can help!


Solution

  • The problem lies in the way you are associating the MyUILayer with the GameLayer. On myscene.mm, you are creating a MyUILayer and a GameLayer, and adding them both to the scene. This is ok. But then, you make a NEW MyUILayer on GameLayer, and associate that joystick. You should associate the joystick in the MyScene.mm by using properties like so:

    In MyScene.mm

    // Control Layer
    MyUILayer * controlLayer = [MyUILayer node];
    [self addChild:controlLayer z:2 tag:2];
    
    // Gameplay Layer
    GameLayer *gameplayLayer = [GameLayer node];
    gameplayLayer.attackButton = controlLayer.attackButton;
    gameplayLayer.leftJoystick = controlLayer.leftJoystick;
    gameplayLayer.jumpButton = controlLayer.jumpButton;
    [self addChild:gameplayLayer z:1 tag:1];
    

    In GameLayer.h add

    @property (nonatomic, retain) SneakyButton *jumpButton;
    @property (nonatomic, retain) SneakyButton *attackButton;
    @property (nonatomic, retain) SneakyJoystick *leftJoystick;
    

    In GameLayer.mm add

    @synthesize jumpButton = jumpButton;
    @synthesize attackButton = attackButton;
    @synthesize leftJoystick = characterJoystick;
    

    In GameLayer.mm, remove the UILAYER code in the init method

    - (id)init
    {
        self = [super init];
        if (self) {
            //instalize physics
            [self initPhysics];
            [self lvlHelper];
            [self characterLoad];
            [self runAction:[CCFollow actionWithTarget:character worldBoundary:CGRectMake(0, -100, 870, 420)]];
            [self scheduleUpdate];
        }
        return self;
    }