# Ways to control a characters movement in a game

i already know that I want movement to be controlled in at least 8 directions, like so: up, down, left, right, up-left, upright, downleft, downright.

things I’m running into are

• when to move
– I can create a hidden joystick with buttons centered on where a touch begins.
– Or i could have visible buttons on the screen
– if i do have buttons, do i want to split them?

• if the user starts a touch, moves, but then stops moving, do we keep moving? i think, in most cases, the answer is yes.

• minimum amount of movement before we consider it as an input

• once an inout is on, what condition turns it off besides touch.state==ENDED?

One way to move a character is to touch the screen and move your finger a small distance in the direction you want the character to move. A slight finger movement in one of the eight directions will cause the character to move in that direction. As long as your finger is touching the screen, the character will continue in its last direction. Once you lift your finger, the character will stop. Or you can lift your finger and the character will continue in its last direction until you touch the screen again to give it a new direction or it stops if you don’t move your finger far enough in a direction.

here’s a buggy joystick

``````player={x=512,y=384}
function player:moveAtAngle(angle, left, down)
--local speed = 2

local velX = 2 * math.cos(angle)
local velY = 2 * math.sin(angle)
print('velx='..velX, 'vely='..velY)
self.x = left and self.x - velX or self.x + velX
self.y = down and self.y - velY or self.y + velY
end

local joystick = {x=-100, y=-100, w=100, h=100, inittouch=false,
lasttouch=false}
local angle
function joystick:set(touch)
--touch logic
if touch.state == BEGAN and not self.inittouch then
self.inittouch = touch
self.x = touch.x
self.y = touch.y
elseif touch.state == MOVING and self.inittouch then
local v1 = vec2(touch.x, touch.y)

if v1:dist( vec2(self.x, self.y)) > 26 then
angle = v1:angleBetween( vec2(self.x, self.y) )
local left, down = false, false

left = self.x > v1.x
if self.y > v1.y then
down = self.y > v1.y
end
player:moveAtAngle(angle, left, down)
else -- < 16
player_is_moving = false
end
elseif touch.state == ENDED and self.inittouch then
if touch.id == self.inittouch.id then
self.inittouch = nil
self.x = -100
self.y = -100
end
end
end

function joystick:draw()
fill(255,0,0,100)
ellipse(self.x, self.y, 10)
fill(100,100)
ellipse(CurrentTouch.x, CurrentTouch.y, 50)
end
function draw()
background(0)
fill(0,0,222,150)
rect(player.x, player.y, 10,10)
joystick:draw()
end

function touched(t)
joystick:set(t)
end

``````

@xThomas If you want to use a joystick, here’s a version that will allow you to move multiple characters. This is setup to use 5 different characters. Just touch the screen anywhere to move a character. Use one or up to five fingers. A character will appear when you touch the screen.

``````displayMode(FULLSCREEN)

function setup()
stab={
readImage("Planet Cute:Character Cat Girl"),
readImage("Planet Cute:Character Pink Girl"),
readImage("Planet Cute:Character Princess Girl"),
readImage("Planet Cute:Character Horn Girl")
}
rm=-1
js={}
end

function draw()
background(40, 40, 50)
fill(255)
for a,b in pairs(js) do
b:draw(a)
end
end

function touched(t)
if t.state==BEGAN then
aa=0
for a,b in pairs(js) do
if b.id==0 then
b.cx=t.x
b.cy=t.y
b.id=t.id
aa=1
break
end
end
if aa==0 then
table.insert(js,jst(t.x,t.y,t.id))
end
elseif t.state==MOVING or t.state==ENDED then
for a,b in pairs(js) do
b:touched(t)
end
end
end

jst=class()

function jst:init(cx,cy,id)
self.cx=cx
self.cy=cy
self.dx=0
self.dy=0
self.sx=cx
self.sy=cy
self.id=id
end

function jst:draw(a)
fill(255)
if self.id>0 then
fill(255, 255, 255, 50)
ellipse(self.cx,self.cy,8) -- draw circle center
noFill()
stroke(255,255,255,50)
strokeWidth(4)
ellipse(self.cx,self.cy,200) -- draw outer circle
end
self.sx=self.sx+self.dx
self.sy=self.sy+self.dy
sprite(stab[a%5+1],self.sx,self.sy)
end

function jst:touched(t)
if t.state==MOVING then
if self.id==t.id then
self.dx=(t.x-self.cx)/10
self.dy=(t.y-self.cy)/10
end
end
if t.state==ENDED then
if self.id==t.id then
rm=t.id
self.id=0
self.dx=0
self.dy=0
self.cx=0
self.cy=0
end
end
end
``````

@dave1707 That’s a very interesting idea for controlling multiple characters. I haven’t seen that used in any games. For my fingers, applying more than three takes up too much screen space and feels a bit unnatural, but one to three fingers seems to work well. I may have to experiment with this. Thanks!

@mindless My thoughts was that four people could use this. One person in each corner or edge. Or two people would have no problem, one at opposite sides of the screen. If you really want to squeeze the screen, one person in each corner and one for each side. For over 5 people, more characters would need to be added in the stab table otherwise over 5 would reuse a character.