How to: Top-down Joystick movement
One of the most first things you'll want to do when creating a top-down game is to allow the player to move their character around. This guide will show you how to set up a simple top-down character movement system that works when using the WASD keys, a gamepad and an on-screen joystick for touchscreen players.
The simplest way to support all the various control schemes is to use the Joystick as your primary input method, and then use KeyboardVirtualJoystick and VirtualJoystick to simulate a joystick when a Gamepad is not connected.
Joystick control
Let's start with the Joystick:
let speed = 20
with Joystick {
if Joystick.IsEmpty {
delete behavior<move>
} else {
behavior<move> on BeforePhysics {
// Make the character look where they are going
Heading = Angle(Joystick)
ForcefulStep(Joystick * speed / TicksPerSecond)
}
}
}
We use a with
block to run the code whenever the Joystick changes.
This will replace a behavior called move
, which is responsible for moving the character.
We make this behavior run before the physics phase of each tick using BeforePhysics.
ForcefulStep is used to move the character in the direction of the Joystick.
The step is forceful, meaning if our character collides with anything during its step, it will push it out of the way.
We also adjust the Heading of the character to face the direction it is moving.
It is also good to delete a behavior when it will not do anything, as this saves processing time
and can help your game run better on lower-end devices.
In this case, when the Joystick
is a zero Vector @(0,0)
, the character won't be moving anywhere,
and so we can use delete behavior<move>
to remove the behavior.
You will also notice that we specify speed
as a variable at the top of the code.
This could instead come from a function parameter, for example.
We then divide the speed by TicksPerSecond to calculate how much of the speed
we should apply each frame.
WASD or Arrow Keys
Many games support moving with the WASD keys or the Arrow keys. Now that your Joystick is set up, you can add support for these keys with the KeyboardVirtualJoystick function:
KeyboardVirtualJoystick(up=KeyW, left=KeyA, down=KeyS, right=KeyD)
Or for arrow keys:
KeyboardVirtualJoystick(up=ArrowUp, left=ArrowLeft, down=ArrowDown, right=ArrowRight)
This function will add a behavior to the current entity that will simulate a Joystick using the keyboard, for as long as the current entity continues to exist.
Touchscreens
The VirtualJoystick function will display a virtual joystick which players can use to control their character. In most cases, this is only useful for touchscreen users, so you can use the TouchscreenMode to limit this to touchscreen users.
As VirtualJoystick
inserts a user interface element,
it must be placed inside a Section of the user interface.
The most reliable way to do this is to place it inside a BottomLeftCommand
which places it in an overlay on top of the game screen.
with TouchscreenMode {
if TouchscreenMode {
BottomLeftCommand<joystick>(offset=@(6,6)) {
VirtualJoystick(radius=5)
}
} else {
delete BottomLeftCommand<joystick>
}
}
Since BottomLeftCommand
is an overlay, it requires an offset
.
Make sure to give it an offset
that is bigger than the radius
of the VirtualJoystick
so that the joystick is clear of the corner of the screen.
It is possible however to place the VirtualJoystick
inside a BottomLeftContent
section instead. This means that anything else in BottomLeftContent
will be pushed up by the joystick,
instead of overlapping with it, which might work better for your game.
BottomLeftContent
is stacked from bottom to top, so to make sure your joystick is the bottom of the stack,
give it a low order
number like -100
.
with TouchscreenMode {
if TouchscreenMode {
BottomLeftContent<joystick>(order=-100) {
VirtualJoystick(radius=5)
}
} else {
delete BottomLeftContent<joystick>
}
}
Full code listing
This is one example of a complete game that supports top-down movement with a Joystick, WASD keys
and a virtual joystick for touchscreen users.
If you would like to try it, click the Launch Editor button in the top right of this page,
create a new project and use copy-and-paste to overwrite the contents of the main.easel
file with the code below.
pub game fn World.Main() {
SpawnEachPlayer owner {
KeyboardVirtualJoystick(up=KeyW, left=KeyA, down=KeyS, right=KeyD)
with TouchscreenMode {
if TouchscreenMode {
BottomLeftCommand<joystick>(offset=@(6,6)) {
VirtualJoystick(radius=5)
}
} else {
delete BottomLeftCommand<joystick>
}
}
Subspawn ship {
Ship
}
}
}
pub fn ship.Ship([owner]) {
use body=ship
use speed=30
use radius=1, shape=Circle, color=#00ff00
Body(pos=@(0,0))
PolygonSprite
with Joystick {
if Joystick.IsEmpty {
delete behavior<move>
} else {
behavior<move> on BeforePhysics {
Heading = Angle(Joystick)
ForcefulStep(Joystick * speed / TicksPerSecond)
}
}
}
}