Thanks for the reply. Multitouch is already activated. Like I mentioned before, "touch"ing the button and using the joystick at the same time works as it should. I just can’t get double “tap” to work. Do you know if there is a way to set focus for a tap event like you can for a touch event?
I’m still confused. To get a double tap you would need to create a counter to check how many taps happened. Then do something like
if counter == 2 then Do something end
This what you need?
Sorry for the delay… haven’t been able to get back on here to post my code. Below is the extracted code I’m running. The analog stick changes the rotation and the gas button propels the car. The “tap” listener works fine if you’re not touching the analog stick, but I need it to work even if your thumb is on the analog stick like the gas button does. Any help would be appreciated.
This is the code in scene running the game itself:
[lua]local physics = require “physics”
physics.start()
physics.setVelocityIterations( 6 ) --try and fix instability with pivot joints
physics.setGravity(0, 0)
system.activate(“multitouch”)
system.setTapDelay(.5)
local StickLib = require(“lib_analog_stick”)
–=========================================================================
–Zero Gravity Nitro boost function
–=========================================================================
local function nitroBoost5 ( event )
if gameIsActive == 1 then
if numNitro > 0 then
if ( event.numTaps == 2 ) then
if boosted == 1 then
nitroBoostChannel = audio.play(nitroBoostSound, {channel=17})
boosted = 0
numNitro = numNitro - 1
nitroStatus.text = "Nitro: "…numNitro
backWheel:applyLinearImpulse( xDirection*3, yDirection*3, backWheel.x, backWheel.y )
frontWheel:applyLinearImpulse( xDirection*3, yDirection*3, frontWheel.x, frontWheel.y )
local function limitTap1()
boosted = 1
end
timer.performWithDelay(1000, limitTap1)
end
else
return true
end
end
end
end
gas:addEventListener( “tap”, nitroBoost5 )
– CREATE ANALOG STICK
brakeArrow.alpha = 0
gravityArrow.alpha = 0
gravityArrow2.alpha = 0
jumpArrow.alpha = 0
directionArrow.alpha = .5
gasArrow.xScale = .6
gasArrow.yScale = .6
MyStick = StickLib.NewStick(
{
x = brakeArrow.x+brakeArrow.x*.25,
y = brakeArrow.y+brakeArrow.y*.25,
thumbSize = 40,
borderSize = 80,
snapBackSpeed = .2,
R = 25,
G = 255,
B = 255
} )
local crossHair = display.newImageRect(hud, “images/crossHair.png”, 140, 140)
crossHair.x = MyStick.x
crossHair.y = MyStick.y
crossHair.alpha = .6
– MAIN LOOP
local function main( event )
if gameIsActive == 1 then
– SHOW STICK INFO
– Text.text = “ANGLE = “…MyStick:getAngle()…” DIST = “…math.ceil(MyStick:getDistance())…” PERCENT = “…math.ceil(MyStick:getPercent()*100)…”%”
--print("MyStick:getAngle = "…MyStick:getAngle())
--print("MyStick:getDistance = "…MyStick:getDistance())
--print("MyStick:getPercent = "…MyStick:getPercent()*100)
--print("POSICAO X / Y " …hero.x,hero.y)
moving = MyStick:getMoving()
local percent = MyStick:getPercent()*100
local boostPower = carTable.JUMP_POWER*.5
if bodyGroup.rotation <= 90 then
xDirection = (bodyGroup.rotation * .111111111111111) * boostPower * 2
yDirection = ((90 - bodyGroup.rotation) * -.111111111111111) * boostPower * 2
elseif bodyGroup.rotation > 90 and bodyGroup.rotation <= 180 then
xDirection = ((180 - bodyGroup.rotation) * .111111111111111) * boostPower * 2
yDirection = ((bodyGroup.rotation - 90) * .111111111111111) * boostPower * 2
elseif bodyGroup.rotation > 180 and bodyGroup.rotation <= 270 then
xDirection = ((180 - bodyGroup.rotation) * .111111111111111) * boostPower * 2
yDirection = ((bodyGroup.rotation - 270) * -.111111111111111) * boostPower * 2
elseif bodyGroup.rotation > 270 and bodyGroup.rotation <= 360 then
xDirection = ((360 - bodyGroup.rotation) * -.111111111111111) * boostPower * 2
yDirection = ((270 - bodyGroup.rotation) * .111111111111111) * boostPower * 2
end
if globals.gasPressed == true then
bodyGroup.isFixedRotation = true
if body3 then
body3:setSequence(“boosting”)
body3:play()
end
if percent > 0 then
bodyGroup.rotation = globals.angle
gasArrow.rotation = globals.angle - 90
end
MyStick:boost(bodyGroup, xDirection, yDirection, true, boostPower)
else
if percent > 0 then
globals.angle = MyStick:getAngle()
bodyGroup.isFixedRotation = true
if body3 then
body3:setSequence(“noBoost”)
body3:play()
end
bodyGroup.rotation = globals.angle
gasArrow.rotation = globals.angle - 90
MyStick:boost(bodyGroup, 0, 0, false, boostPower)
end
end
else
bodyGroup.isFixedRotation = false
if body3 then
body3:setSequence(“noBoost”)
body3:play()
end
globals.angle = bodyGroup.rotation
gasArrow.rotation = globals.angle - 90
MyStick:boost(bodyGroup, 0, 0, false, boostPower)
end
end
Runtime:addEventListener( “enterFrame”, main )
–=========================================================================
–Gas Function - Zero Gravity
–=========================================================================
function gas:touch( event )
if gameIsActive == 1 then
if event.phase == “began” then
event.target.alpha = .2
globals.gasPressed = true
elseif event.phase == “ended” or event.phase == “cancelled” then
event.target.alpha = 0
globals.gasPressed = false
end
end
return true
end
gas:addEventListener( “touch”, gas )
[/lua]
This is the code that includes the functions needed for the analog stick:
[lua]
module (…, package.seeall)
–[[
ANALOG STICK MODULE FOR CORONA SDK
PRODUCT : ANALOG STICK MODULE FOR CORONA SDK
VERSION : 1.0.1
AUTHOR : X-PRESSIVE.COM / MIKE DOGAN GAMES & ENTERTAINMENT
WEB SITE : www.x-pressive.com
SUPPORT : support@x-pressive.com
PUBLISHER: X-PRESSIVE.COM
COPYRIGHT: ©2011 X-PRESSIVE.COM / MIKE DOGAN GAMES & ENTERTAINMENT
USAGE:
- INCLUDE THE MODULE:
StickLib = require(“lib_analog_stick”)
- CREATE A STICK (RETURNS A DISPLAY GROUP HANDLE):
MyStick = StickLib.NewStick(
{
x = [X-COORD],
y = [Y-COORD],
thumbSize = [THUMB SIZE],
borderSize = [BORDER SIZE],
snapBackSpeed = [THUMB SNAP BACK SPEED 0.0 - 1.0],
R = [COLOR RED 0 - 255],
G = [COLOR GREEN 0 - 255],
B = [COLOR BLUE 0 - 255],
} )
- TO MOVE AN OBJECT:
MyStick:move( ObjectHandle, maxSpeed, rotate = true | false)
OR GET STICK INFO TO MOVE ANY OBJECT MANUALLY:
MyStick:getAngle () - RETURNS THE CURRENT ANGLE (DIRECTION) FROM 0 (TOP) TO 360 (CLOCKWISE)
MyStick:getDistance() - RETURNS DISTANCE FROM THUMB TO CENTER IN PIXELS
MyStick:getPercent () - RETURNS DISTANCE FROM THUMB TO CENTER (NORMALIZED, 0.0 - 1.0)
- REMOVE STICK
MyStick:delete()
MyStick = nil
–]]
local Pi = math.pi
local Sqr = math.sqrt
local Rad = math.rad
local Sin = math.sin
local Cos = math.cos
local Ceil = math.ceil
local Atan2 = math.atan2
– FUNCTION: CREATE
function NewStick( Props )
local Group = display.newGroup()
Group.x = Props.x
Group.y = Props.y
Group.Timer = nil
Group.angle = 0
Group.distance = 0
Group.percent = 0
Group.maxDist = Props.borderSize
Group.snapBackSpeed = Props.snapBackSpeed ~= nil and Props.snapBackSpeed or .7
Group.Border = display.newCircle(0,0,Props.borderSize)
– for use images uncomment the line down and comment line up
– Group.Border = display.newImage(“joystickmain1a.png”)
Group.Border.strokeWidth = 2
--Group.Border:setFillColor (Props.R,Props.G,Props.B,46)
--Group.Border:setStrokeColor(Props.R,Props.G,Props.B,255)
Group.Border:setFillColor (Props.R,Props.G,Props.B,0)
Group.Border:setStrokeColor(Props.R,Props.G,Props.B,0)
Group:insert(Group.Border)
Group.Thumb = display.newCircle(0,0,Props.thumbSize)
– for use images uncomment the line down and comment line up
– Group.Thumb = display.newImage(“joystickmain1b.png”)
Group.Thumb.strokeWidth = 3
Group.Thumb:setFillColor (Props.R,Props.G,Props.B,96)
Group.Thumb:setStrokeColor(Props.R,Props.G,Props.B,255)
Group.Thumb.x0 = 0
Group.Thumb.y0 = 0
Group.Thumb.alpha = .2
Group:insert(Group.Thumb)
Group.collisionDetected = false
Group.lockedAngle = false
Group.beingMoved = false
---------------------------------------------
– METHOD: DELETE STICK
---------------------------------------------
function Group:delete()
self.Border = nil
self.Thumb = nil
if self.Timer ~= nil then timer.cancel(self.Timer); self.Timer = nil end
self:removeSelf()
end
---------------------------------------------
– METHOD: MOVE AN OBJECT
---------------------------------------------
function Group:move(Obj, maxSpeed, rotate)
if rotate == true then Obj.rotation = self.angle end
Obj.x = Obj.x + Cos( Rad(self.angle-90) ) * (maxSpeed * self.percent)
Obj.y = Obj.y + Sin( Rad(self.angle-90) ) * (maxSpeed * self.percent)
end
---------------------------------------------
– METHOD: BOOST CAR
---------------------------------------------
function Group:boost(Obj, xDirection, yDirection, rotate, boostPower)
if rotate == true then
if self.percent > 0 then
Obj.rotation = self.angle
–print("selfAngle = "…self.angle)
if self.angle <= 90 then
xDirection = (self.angle * .111111111111111) * boostPower * 2
yDirection = ((90 - self.angle) * -.111111111111111) * boostPower * 2
elseif self.angle > 90 and self.angle <= 180 then
xDirection = ((180 - self.angle) * .111111111111111) * boostPower * 2
yDirection = ((self.angle - 90) * .111111111111111) * boostPower * 2
elseif self.angle > 180 and self.angle <= 270 then
xDirection = ((180 - self.angle) * .111111111111111) * boostPower * 2
yDirection = ((self.angle - 270) * -.111111111111111) * boostPower * 2
elseif self.angle > 270 and self.angle <= 360 then
xDirection = ((360 - self.angle) * -.111111111111111) * boostPower * 2
yDirection = ((270 - self.angle) * .111111111111111) * boostPower * 2
end
else
–Obj.rotation = self.angle
if Obj.rotation <= 90 then
xDirection = (Obj.rotation * .111111111111111) * boostPower * 2
yDirection = ((90 - Obj.rotation) * -.111111111111111) * boostPower * 2
elseif Obj.rotation > 90 and Obj.rotation <= 180 then
xDirection = ((180 - Obj.rotation) * .111111111111111) * boostPower * 2
yDirection = ((Obj.rotation - 90) * .111111111111111) * boostPower * 2
elseif Obj.rotation > 180 and Obj.rotation <= 270 then
xDirection = ((180 - Obj.rotation) * .111111111111111) * boostPower * 2
yDirection = ((Obj.rotation - 270) * -.111111111111111) * boostPower * 2
elseif Obj.rotation > 270 and Obj.rotation <= 360 then
xDirection = ((360 - Obj.rotation) * -.111111111111111) * boostPower * 2
yDirection = ((270 - Obj.rotation) * .111111111111111) * boostPower * 2
end
end
end
–print(xDirection, yDirection)
–print("percent = "…self.percent)
if self.percent > 0 then
Obj:applyForce( xDirection–[[* self.percent–]], yDirection–[[* self.percent–]], Obj.x, Obj.y )
else
Obj:applyForce( xDirection, yDirection, Obj.x, Obj.y )
end
end
– METHOD: SLIDE AN OBJECT
---------------------------------------------
function Group:slide(Obj, maxSpeed)
if(self.getMoving()) then
Obj.model.x = ( Obj.model.x + Cos( Rad(self.angle-90) ) * (-maxSpeed * self.percent) )
Obj.model.y = ( Obj.model.y + Sin( Rad(self.angle-90) ) * (-maxSpeed * self.percent) )
end
if (math.abs(Obj.knockbackX) >= 5) then
Obj.model.x = Obj.model.x + Obj.knockbackX
Obj.knockbackX = Obj.knockbackX * .75
end
if (math.abs(Obj.knockbackY) >= 5) then
Obj.model.y = Obj.model.y + Obj.knockbackY
Obj.knockbackY = Obj.knockbackY * .75
end
end
– METHOD: ROTATE AN OBJECT
function Group:rotate(Obj, rotate)
if rotate == true then Obj.rotation = self.angle end
end
---------------------------------------------
– GETTER METHODS
---------------------------------------------
function Group:getDistance() return self.distance end
function Group:getPercent () return self.percent end
function Group:getAngle () return Ceil(self.angle) end
function Group:getMoving () return Group.beingMoved end
---------------------------------------------
– HANDLER: ON DRAG
---------------------------------------------
Group.onDrag = function ( event )
local T = event.target – THUMB
local S = T.parent – STICK
local phase = event.phase
local ex,ey = S:contentToLocal(event.x, event.y)
ex = ex - T.x0
ey = ey - T.y0
if “began” == phase then
Group.beingMoved = true
if S.Timer ~= nil then timer.cancel(S.Timer); S.Timer = nil end
--display.getCurrentStage():setFocus( T )
display.getCurrentStage():setFocus( T, event.id )
T.isFocus = true
– STORE INITIAL POSITION
T.x0 = ex - T.x
T.y0 = ey - T.y
elseif T.isFocus then
if “moved” == phase then
-----------
S.distance = Sqr (ex*ex + ey*ey)
if S.distance > S.maxDist then S.distance = S.maxDist end
S.angle = ( (Atan2( ex-0,ey-0 )*180 / Pi) - 180 ) * -1
S.percent = S.distance / S.maxDist
-----------
T.x = Cos( Rad(S.angle-90) ) * (S.maxDist * S.percent)
T.y = Sin( Rad(S.angle-90) ) * (S.maxDist * S.percent)
elseif “ended”== phase or “cancelled” == phase then
Group.beingMoved = false
T.x0 = 0
T.y0 = 0
T.isFocus = false
--display.getCurrentStage():setFocus( nil )
display.getCurrentStage():setFocus( nil, event.id )
S.Timer = timer.performWithDelay( 33, S.onRelease, 0 )
S.Timer.MyStick = S
end
end
– STOP FURTHER PROPAGATION OF TOUCH EVENT!
return true
end
---------------------------------------------
– HANDLER: ON DRAG RELEASE
---------------------------------------------
Group.onRelease = function( event )
local S = event.source.MyStick
local T = S.Thumb
local dist = S.distance > S.maxDist and S.maxDist or S.distance
dist = dist * S.snapBackSpeed
T.x = Cos( Rad(S.angle-90) ) * dist
T.y = Sin( Rad(S.angle-90) ) * dist
local ex = T.x
local ey = T.y
-----------
S.distance = Sqr (ex*ex + ey*ey)
if S.distance > S.maxDist then S.distance = S.maxDist end
S.angle = ( (Atan2( ex-0,ey-0 )*180 / Pi) - 180 ) * -1
S.percent = S.distance / S.maxDist
-----------
if S.distance < .5 then
S.distance = 0
S.percent = 0
T.x = 0
T.y = 0
timer.cancel(S.Timer); S.Timer = nil
end
end
Group.Thumb:addEventListener( “touch”, Group.onDrag )
return Group
end
[/lua]
I do apologize if the code I posted looks terrible. I’ve had a heck of a time getting the formatting to translate. I appreciate any help. Thanks.
I’ll be able to take a look in a couple hours.
Great… I appreciate it.
Anyone able to help me out?
I have the same problem when I updated to 2016.2830.
I used to be able to hold the left joystick for directional control and tap the right joystick to fire at the same time. Now I can only tap to shoot when I stop moving!
Greg
If it’s the problem above can you try an older build? I did this in a couple games in an older build and it did work. Can’t say exactly which build though. I can say it was before the new console was introduced.
Yes the problem started for me with version .2830.
Greg, are you using “tap” or “touch”?
I have touch working just fine whide holding the stick, but tap isn’t working while holding the stick. It sounds like, for your particular issue, you can remedy your problem by using touch and have it fire at event.phase = “began”.
I use touch for movement - left stick
I use touch to fire in a chosen direction - right stick
I was using tap to fire directly ahead - right stick before it stopped working
Alright, I was able to figure out a work around for my situation. I read that tap events look for the release at the same approximate point as the tap. So I’m guessing that holding down the analog stick is throwing that all out of wack. So I decided to create my own version of a tap event using “touch” instead. To make it work, I had to create an invisible duplicate button over the top of the original button and never “return true” on it. This allows a touch event to pass through and still activate my original gas button. After building and testing on my phone, it works perfectly. You can effectively adjust the tap delay by changing the delay time in “timer.performWithDelay(300, resetTap)”. With the little testing I’ve done so far, 300 milliseconds seems to be a good number. I hope this helps you in your situation. Here is the code I came up with:
[lua]
local tapped = 0
function gas2:touch( event )
if gameIsActive == 1 then
if event.phase == “began” then
if numNitro > 0 then
tapped = tapped + 1
if tapped == 2 then
if globals.boosted == 1 then
nitroBoostChannel = audio.play(nitroBoostSound, {channel=17})
--print(“Nitro Boost Activated”)
globals.boosted = 0
numNitro = numNitro - 1
nitroStatus.text = "Nitro: "…numNitro
backWheel:applyLinearImpulse( xDirection*3, yDirection*3, backWheel.x, backWheel.y )
frontWheel:applyLinearImpulse( xDirection*3, yDirection*3, frontWheel.x, frontWheel.y )
local function limitTap1()
globals.boosted = 1
--print(“Boosted Reset”)
end
timer.performWithDelay(1000, limitTap1)
end
end
local function resetTap()
tapped = 0
end
timer.performWithDelay(300, resetTap)
end
end
end
end
gas2:addEventListener( “touch”, gas2 )
[/lua]