Saturday, January 23, 2016

Fixing the Joystick + Adding Buttons

Now we're working on the Joystick huh?

Yeah, when the player lets go of the joystick the character should stop moving immediately.  None of this inertia nonsense that Box2d provides. 

Since I don't want to make my own physics yet (though may need to later) we have to explicitly tell the character to stop.  When do we tell it to stop?  It should stop when the player lets go of the joystick!  

What if the player is falling or jumping?  What if the player is doing some attack or move that pushes them forward?  In these cases the character should keep moving.  How do we tell it to stop moving except if it should keep moving?

Until now I had this:


Which is getting too lengthy.  Instead lets have a boolean 'currentlyActing.' Any action besides walking will set currentlyActing = true.  Some attacks may have their own movement, and they will tell themselves to stop accordingly, and walking may be able to interrupt that motion, but only at times we allow by setting keysLocked to false before the animation ends.

Why are you making things bold?

I dunno.. suddenly I wanted to.  I thought it might make things easier to read.  It's not very consistent with the rest of the blog though is it?

Nope, is that a problem?

Could be!  Let's find out!

Every other action will set currentlyActing = true and sometimes keysLocked = true. So whenever we release the left or right joystick, we simply check if currentlyActing = false and if it does, set the motion to 0.

Well, the actual system is turning out to be more complicated.. The reason is that we have 'States' and 'Actions.'

public State getState(){
    if(b2body.getLinearVelocity().y > 0 && currentAction == null)
        return State.JUMPING;

This is our getState() function which will tell us which animation frame we need to get.  If Kicking was a 'State' then we would have to say 'if the player is moving up AND the state isn't kicking, make it jumping.'  Later that would be 'not kicking, not punching' and so on.  Better to make it a separate field.
    else if(b2body.getLinearVelocity().y < 0 && currentAction == null )
        return State.FALLING;
    else if(b2body.getLinearVelocity().x != 0 && currentlyActing == false)
        return State.RUNNING;
    else if(currentAction == State.KICKING)
        return State.KICKING;

    else        return State.STANDING;
}


Now our 

@Overridepublic boolean keyUp(int keycode) {
    Gdx.app.log("lkey up","");
    if ((keycode == Input.Keys.RIGHT || keycode == Input.Keys.LEFT) && player.currentlyActing == false) {
        Gdx.app.log("lkey up","");
        player.b2body.setLinearVelocity(0f, 0f);
        player.currentState = Sarah.State.STANDING;

Is working just fine again, for our keyboard inputs.  Now we need to figure out how to get TouchUp from the Libgdx touchPad().

*Time passes*

Which doesn't exist.  Instead we just do a check to see if the touchPad is at 0:
if (hud.touchPad.getTouchPad().getKnobPercentX() == 0f && player.currentlyActing == false) {
    player.currentState = Sarah.State.STANDING;
    player.b2body.setLinearVelocity(0f, 0f);
}

And this lets our walking work nicely.  Now we stop when the touchPad is released.




Hmm does it look a bit shabbier because it's a JPG?  Hmm I need to work on getting the highest quality image possible pretty soon..

What's next?

Next we'll add a button for our kick :)


It's all working nicely, here's the code:
TextureAtlas kickButtonAtlas = new TextureAtlas("kickButton/kickButton.pack");
kickButtonSkin = new Skin(Gdx.files.internal("uiskin.json"));
kickButtonSkin.addRegions(kickButtonAtlas);
Button.ButtonStyle kickButtonStyle = new Button.ButtonStyle();
kickButtonStyle.up = kickButtonSkin.getDrawable("buttonUp");
kickButtonStyle.down = kickButtonSkin.getDrawable("buttonDown");

kickButton = new Button(kickButtonStyle);
kickButton.addListener(new InputListener() {
    public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
        //Gdx.app.log("my app", "Pressed"); //** Usually used to start Game, etc. **//        kickButtonPressed = true;
        return true;
    }

    public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
        //Gdx.app.log("my app", "Released");    }
});


And the table, because that stuff drove me nuts!
Table controls = new Table();
controls.setHeight(stage.getHeight());
controls.setWidth(stage.getWidth());
controls.align(Align.bottom).setFillParent(true);
controls.add(touchPad.getTouchPad()).expandX().align(Align.bottomLeft);
controls.add(kickButton).expandX().maxHeight(stage.getHeight()/3)
.maxWidth(stage.getHeight()/3).align(Align.bottomRight);
stage.addActor(controls);

However.. now we've got a multiple button press issue.  If we press the touchPad on the left, the kick button ignores us.  Google!

*Hours later*

Turns out that even if you are using a touch device, such as the Surface Pro 2, scene2d multi touch doesn't work on desktop.

Try it out on the device!  Multi touch works great!  But I've got an error in my fragment shader: cannot convert from 'const int' to '4-component vector of float'

So switching our nice color *= 5 to color = color + color  + color + color + color solved that.. T_T

Lastly, the fruits of our labor!




No comments:

Post a Comment