Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving a sprite along a pre-defined path in Phaser.IO

I have a sprite and a path for it (path = [[1,1],[1,2],[1,3]), what is the best practice for doing it using the game.physics and not simply chage the x,y values?

like image 443
Erez Hochman Avatar asked Jan 05 '15 18:01

Erez Hochman


1 Answers

Presuming you have enabled physics and have already assigned each of the coordinates in your path to regions of your stage.

Moving in straight lines

I would suggest Physics.Arcade.movetoXY().

The function returns the angle to the target location if you need to rotate your sprite.

sprite.rotation = game.physics.arcade.moveToXY(
    sprite, 
    target.x, 
    target.y, 
    300 // speed, 
    500 // maxTimeToFinish(ms)
);

If your sprite is drifting past the target and not stopping, be sure to include something like this in your main update() loop:

player.body.velocity.x = 0;
player.body.velocity.y = 0;

As your example is only moving in straight line this method will work well. You can just use the xy position of your final tile and set your sprite moving. This method does not account for drag, acceleration and a few other variables your game might have.

A lot of what to recommend depends on your use case.

Patroling a tile path

If you wanted the sprite to 'patrol' along a path then you would use a tween, as this offers the best performance.

Tile-based complicated movement

If your sprite was following a more complicated path such as avoiding obsticles or following another game object, you would use a Phaser.Timer (for Pokemen-style, tile-by-tile movement) or your game's update() loop (for smooth movement), to run a function that calculates which direction to move in and then executes that move using a Phaser.Arcade.Physics method (moveToXY, accelerateToXy etc) to move.

The best way to do this is with an A* path-finding algorithm, which work out a path for your sprite, taking into account obsticles, dead ends and difficult terrain to give the quickest path.

rot.js is a library of tile-based methods, including an A* path finder.

Tile-based character movement

In tile-based movement with obstacle collisions be careful - the arcade collisions in Phaser fire upon contact with the target (including corner pixels), and this can make moving between obstacles or moving past openings difficult.

You can find that simply increasing velocity in a direction does not work any more.

Solve this by making your character's arcade body smaller than a tile by a few pixels with sprite.body.setBounds(), and use the excellent Math.snapTo() to keep your sprite in the center of a tile.

You can adapt this for all four directions, and add to your update() loop for smooth tile based character movement.

if (cursors.left.isDown) {
    game.physics.arcade.moveToXY(
    sprite, 
    sprite.body.x - 70, // target x position
    Phaser.Math.snapTo(sprite.body.y, 70), // keep y position the same as we are moving along x axis
    250 // velocity to move at
) };
like image 155
Jake Whiteley Avatar answered Sep 26 '22 21:09

Jake Whiteley