Jump to content

Acceleration Tween


Recommended Posts

(sorry moderators, another one like this has already posted before I'd finished writing!)




I've just been getting into phaser over the last few days, and have come slightly unstuck attempting to make smooth player movement. For the most part phaser has the tools available in the physics system to achieve this (acceleration, drag) but I have been unable to make direction changes smooth.


It works correctly if the player sprite travels just in one direction and then moves in the opposite direction, as the drag and acceleration handles the change correctly. However, if travelling diagonally (holding down W and A, applying both x and y acceleration), and then releasing one key, the change in direction happens instantly. What I'd like to achieve is some drag that happens during this change in velocity so that the player slides a little before fully changing direction. (I hope I've explained this correctly).


I wanted to try achieving this by tweening the acceleration to 0 when a key is released. However, I cannot seem to be able to get the tween working correctly. I don't think I'm adding acceleration correctly to the tween manager - other tween examples I've seen have just needed to access the parameters of the sprite object, whereas this seems slightly more complex to me.


TL;DR - does the below look correct?




This is done in the create function

//playergame.player = game.add.sprite(game.width/2, game.height/2, "player");game.player.anchor.setTo(0.5, 0.5);   //player physicsgame.physics.startSystem(Phaser.Physics.ARCADE);game.physics.enable(game.player, Phaser.Physics.ARCADE);game.player.body.maxVelocity.setTo(playerMaxSpeed, playerMaxSpeed);game.player.body.drag.setTo(playerDrag, playerDrag);game.playerAccelerationTween = game.add.tween(game.player.body.acceleration); 
And this in the update
if (inputIsActive("W")) {game.player.body.acceleration.y = -playerAcceleration;} if (inputIsActive("S")) {game.player.body.acceleration.y = playerAcceleration;} if (inputIsActive("A")) {game.player.body.acceleration.x = -playerAcceleration;} if (inputIsActive("D")) {game.player.body.acceleration.x = playerAcceleration;} if (!inputIsActive("W") && !inputIsActive("S")) {game.playerAccelerationTween.to({y: 0}, 2000, Phaser.Easing.Linear.None);} if (!inputIsActive("A") && !inputIsActive("D")) {game.playerAccelerationTween.to({x: 0}, 2000, Phaser.Easing.Linear.None);}



Apologies if this has been answered elsewhere or is easily available in the documentation, I'm quite new to coding in general and this stumped me.


Thanks in advance!

Link to comment
Share on other sites

The problem I see with this is that the tween to zero will continue to be active if you press a button again.

Also you will get multiple tweens active, because if you call ".to" on a already running tween, it will chain the tween at the end of the current one (and all already chained ones.)


You could stop the tween when ever a new button is pressed.

But it seems very complicated.


I am not really sure, why the drag isn't working for you.


A different solution might be (not sure, not tested)  instead of starting a tween (and instead of setting the acceleration to zero) you could, when no button is pushed just do this: reduce the acceleration (if it's above 0) or increase it (if it's below zero) by a small amount.


This way you also don't stop instantly, and you need no tweens.


But to not be framerate dependend you would have to use variables that store the time since the last frame (game.time.time is the current time in ms) and adjust the amount by which you reduce the acceleration depending on how much time has elapsed. (But in step one you can just try a fixed amount.)

Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...