I developed analog joystick for one of my games. You can use and modify code below.
You can create more than one joystick (don’t forget to switch on multitouch then).
Joystick is analog - hero speed is related to stick position (slightly left - slowly left, max left - maximum speed left etc). If you free stick, il will (smoothly) return to neutral position.
The effect is below:
Below is the main.lua code (just put it on empty main.lua file).
Don’t forget to copy config.lua and build.settings and to put graphics in project folder.
I used sprite, but it can be whatever you will use (circle… I mean circle shape space ship).
display.setStatusBar(display.HiddenStatusBar) local joy local myHero local function setAnchor( obj, anchor ) obj.anchorX, obj.anchorY = anchor, anchor end -- setAnchor local function drawHero() local heroImageSheet = graphics.newImageSheet( "werewolf3.png", { width=70, height=75, numFrames=4 } ) local heroSprite = display.newSprite( heroImageSheet, { name="MyHero", start=1, count=4, time=1000 } ) heroSprite.x = 250 heroSprite.y = 70 heroSprite.fPlaying = false return heroSprite end -- end drawHero local function dragJoy( event ) local joy = event.target local phase = event.phase local stage = display.getCurrentStage() if ( phase == "began") then joy.fBusy = true stage:setFocus( joy, event.id ) joy.isFocus = true elseif ( phase == "moved" ) then local x = event.x local y = event.y local leftBorder = joy.centerX - joy.radius local rightBorder = joy.centerX + joy.radius local upperBorder = joy.centerY - joy.radius local lowerBorder = joy.centerY + joy.radius if ( x \< leftBorder ) then x = leftBorder end if ( x \> rightBorder ) then x = rightBorder end if ( y \< upperBorder ) then y = upperBorder end if ( y \> lowerBorder ) then y = lowerBorder end joy.x = x joy.y = y elseif( ( phase == "ended" ) or ( phase == "cancelled" ) ) then stage:setFocus(joy, nil) joy.isFocus = false joy.fBusy = false end -- if phase return true end -- end dragJoy local function drawJoystick( x, y ) local border = display.newRoundedRect( x, y, 100, 100, 15) border.alpha = 0.3 border:setFillColor(1,0,0) setAnchor( border, 0.5 ) local center = display.newCircle( x, y, 5 ) center:setFillColor(0.8,0,0) center.alpha = 0.5 setAnchor( center, 0.5 ) local joy = display.newCircle( x, y, 20 ) joy.alpha=0.5 joy:setFillColor(0.7,0,0) setAnchor( joy, 0.5 ) joy.centerX = x joy.centerY = y joy.radius = 30 joy:addEventListener( "touch", dragJoy ) return joy end -- drawJoystick local function drawWalls() local wall = display.newRect( 0, 0, 480, 10) setAnchor( wall,0 ) wall:setFillColor( 0.4, 0, 0 ) wall = display.newRect( 0,10, 10, 170 ) wall:setFillColor( 0.4, 0, 0 ) setAnchor( wall, 0 ) wall = display.newRect( 0, 180, 480, 10 ) wall:setFillColor( 0.4, 0, 0 ) setAnchor( wall, 0 ) wall = display.newRect( 470, 10, 10, 170 ) setAnchor( wall, 0 ) wall:setFillColor( 0.4, 0,0 ) end -- drawWalls local function updateHeroPosition() local dx = ( joy.x - joy.centerX ) \* 0.2 local x = myHero.x + dx if x \< 36 then x = 36 end -- wall coordinates if x \> 444 then x = 444 end -- wall coordinates myHero.x = x local dy = ( joy.y - joy.centerY ) \* 0.2 -- analog joy powers :-) local y = myHero.y + dy if y \< 40 then y = 40 end -- wall coordinates if y \> 154 then y = 154 end -- wall coordinates myHero.y = y if dx \< 0 then myHero.xScale = -1 end if dx \> 0 then myHero.xScale = 1 end if ( ( dx == 0 ) and ( dy == 0 ) ) then if ( myHero.fPlaying ) then myHero:pause() myHero.fPlaying = false end -- if\_playing else if ( not myHero.fPlaying) then myHero:play() myHero.fPlaying = true end -- if\_not\_fPlaying end -- because I am not sure if\_play() on playing sprite decreases efficiency end -- updateHeroPosition local function updateJoystickPosition() -- joystick auto return, if not used if ( not joy.fBusy ) then local dx = math.round( ( joy.x - joy.centerX ) / 3 ) -- smooth return local x = joy.centerX + dx joy.x = x local dy = math.round( ( joy.y - joy.centerY ) / 3 ) local y = joy.centerY + dy joy.y = y end -- if\_not\_fBusy end -- updateJoystickPosition local function updateFrame() updateHeroPosition() updateJoystickPosition() end drawWalls() myHero = drawHero() joy = drawJoystick( 350, 250 ) Runtime:addEventListener( "enterFrame", updateFrame )
Put graphic file werewolf3.png in project folder.
config.lua
application = { content = { width = 320, height = 480, scale = "letterBox", fps = 30 } }
and build.settings
settings = { orientation = { default = "landscapeRight", supported = { "landscapeRight" } } }
Enjoy the code and share your comments,

Gudicus