Lib_Analog_Stick module issue.

I am having an issue with the Lib_Analog_Stick module - details below.

–text removed–

I’m by no means an expert on this library.  It’s not one of our libraries, so I’m very limited on what I can do for you.  If you want individual one-on-one support, I would recommend contacting the Particle Candy folks, who wrote the module. 

Okay, no worries. Figured I’d just check with you first.

I thought of that, but then I saw this “Please note that we cannot provide support for this sample code -the
code itself is quite straightforward, however, so it shouldn’t be a
problem to change or customize it to any individual needs.”

  • In the comments section of their post.

I guess I’ll try to contact them regardless. :wink:

If they don’t want to help, you can post a code snippet here and talk about your problem if you’re not willing to share your video with the community.

Well, so far I haven’t back from x-pressive. :\

Th issue occurs when I go to move my user_tank via the joystick. It moves the tank sideways as if the front reference point (<-- ?) is on the side.

I just drop my assets into SpriteHelper, arrange them in sheets, create custom physics bodies, and then I open up LevelHelper and simply drag&drop my objects to create levels.

The following line of code allows me to reference an object, via a custom tag, placed using LH:
[lua] local user_tank = loader:spriteWithUniqueName(“user_tank”); [/lua]

Then I specify my user_tank as the object that will be controlled by my joystick:
[lua] LeftStick:move(user_tank , 3.0, true) [/lua]
That’s pretty much it… and I have no idea why it doesn’t work right.

Something that might be worth mentioning is when I drag my tank-base and turret from LH, they come out facing to the left. I want them facing down, so I changed their rotation to -90 but when I ran it in the simulator, only the turret’s rotation was affected. The tank-base was still facing to the left?
I tried to change the rotation of the tank-base via LH and also tried using [lua] user_tank.rotation = -90 [/lua]
still no effect.

I looked in the lib_analog_stick.lua and came across this bit of code:
[lua] ---------------------------------------------
        – 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
[/lua]
I changed [lua] if rotate == true then Obj.rotation = self.angle end [/lua]
to
[lua] if rotate == true then Obj.rotation = self.angle + 90 end [/lua]

That caused my tank-base to now be facing upwards… however when I went to move it with the joystick it worked how it should - the joystick moving the tank from the front rather than the side.
So it seems like the only thing that will effect the tank’s rotation is when I add a value after self.angle.

Any thoughts?

EDIT: When I change self.angle to self.angle - 90, it then faces down - how I want - but it moves the tank from the back instead of the front. lol?!

I’m by no means an expert on this library.  It’s not one of our libraries, so I’m very limited on what I can do for you.  If you want individual one-on-one support, I would recommend contacting the Particle Candy folks, who wrote the module. 

Okay, no worries. Figured I’d just check with you first.

I thought of that, but then I saw this “Please note that we cannot provide support for this sample code -the
code itself is quite straightforward, however, so it shouldn’t be a
problem to change or customize it to any individual needs.”

  • In the comments section of their post.

I guess I’ll try to contact them regardless. :wink:

If they don’t want to help, you can post a code snippet here and talk about your problem if you’re not willing to share your video with the community.

Well, so far I haven’t back from x-pressive. :\

Th issue occurs when I go to move my user_tank via the joystick. It moves the tank sideways as if the front reference point (<-- ?) is on the side.

I just drop my assets into SpriteHelper, arrange them in sheets, create custom physics bodies, and then I open up LevelHelper and simply drag&drop my objects to create levels.

The following line of code allows me to reference an object, via a custom tag, placed using LH:
[lua] local user_tank = loader:spriteWithUniqueName(“user_tank”); [/lua]

Then I specify my user_tank as the object that will be controlled by my joystick:
[lua] LeftStick:move(user_tank , 3.0, true) [/lua]
That’s pretty much it… and I have no idea why it doesn’t work right.

Something that might be worth mentioning is when I drag my tank-base and turret from LH, they come out facing to the left. I want them facing down, so I changed their rotation to -90 but when I ran it in the simulator, only the turret’s rotation was affected. The tank-base was still facing to the left?
I tried to change the rotation of the tank-base via LH and also tried using [lua] user_tank.rotation = -90 [/lua]
still no effect.

I looked in the lib_analog_stick.lua and came across this bit of code:
[lua] ---------------------------------------------
        – 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
[/lua]
I changed [lua] if rotate == true then Obj.rotation = self.angle end [/lua]
to
[lua] if rotate == true then Obj.rotation = self.angle + 90 end [/lua]

That caused my tank-base to now be facing upwards… however when I went to move it with the joystick it worked how it should - the joystick moving the tank from the front rather than the side.
So it seems like the only thing that will effect the tank’s rotation is when I add a value after self.angle.

Any thoughts?

EDIT: When I change self.angle to self.angle - 90, it then faces down - how I want - but it moves the tank from the back instead of the front. lol?!

Have you checked up the LH API on fliping sprites?

Vladu B made special api calls for these types of situations, like transformation methods that fixes issues working in Box2d

Maybe you should ask Bogdan Vladu (maker of LH and SH)…got a feeling he knows a thing or two about this

I do all my levels and sprites in SH and LH because it saves a lot of time. His codes are robust and best of all, he answers Q´s fast so you don’t get stuck in problems

Yes, I’ve tried.
I emailed him and he said “you need to get the rotation delta of the analog stick and add that delta to the rotation of the tank.”

Unfortunately he does not know how to do that with a joystick, and I also do not know how… so unless someone else has a solution, I’ll just have to find a different joystick module. :slight_smile:

If you post me the project folder with everything inside I will take a look and see if I can help you out (nothing is worse than get stuck and loose hope :wink:

send it to my email: henrruud@online.no if you like

and I´ll try to help you man

If you dont use delta function it will transform from the same position everytime you trigger an event like i.e.

transform.to ( myTanks, { time=200, rotation=10, xScale= .5, yScale=.5, delta = true } ) 

the last param will do the trick

Thank you for offering to help me out. :smiley:
lol I’ve tried ever way I can think of to try and fix it: changing the rotation via LH, SH, direct code, adding a value to part of the lib-analog_stick, etc… etc… :wacko:

The code that deals with the joystick is pretty minimal, but if you still want me to I can email you the project.

level1.lua
[lua]
local StickLib = require(“lib_analog_stick”)


–============================================================================–
–======================== Creating a JoyStick --=============================–

local Text = display.newText( " ", _W*.6, _H-20, native.systemFont, 15 )
 
–Creates analog stick that controls the tank body’s speed and direction
local LeftStick = StickLib.NewStick(
        {
            
        x             = _W*.1,
        y             = _H*.85,
        thumbSize     = 20,
        borderSize    = 46,
        snapBackSpeed = .75,
        R             = 256,
        G             = 255,
        B             = 255
        })
        

local function main( event )
        
        --Sets Left analog to control the tank body and set the speed.
        LeftStick:move(user_tank , 3.0, true)
         
         
        --show stick info
        Text.text = “ANGLE = “…LeftStick:getAngle()…”   DISTANCE = “…math.ceil(LeftStick:getDistance())…”   PERCENT = “…math.ceil(LeftStick:getPercent()*100)…”%”
        --[[if Runtime:hasEventSource( “LeftStick” ) then
        Runtime:addEventListener( “enterFrame”, main )
    end]]
end
Runtime:addEventListener( “enterFrame”, main )
[/lua]
stick_analog_lib.lua
[lua]

 
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)
        Group.Border.strokeWidth = 1
        Group.Border:setFillColor  (Props.R,Props.G,Props.B,46)
        Group.Border:setStrokeColor(Props.R,Props.G,Props.B,255)
        Group:insert(Group.Border)
 
        Group.Thumb = display.newCircle(0,0,Props.thumbSize)
        Group.Thumb.strokeWidth = 1
        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:insert(Group.Thumb)
 
        ---------------------------------------------
        – 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 - 90 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
        
        ---------------------------------------------
        – GETTER METHODS
        ---------------------------------------------
        function Group:getDistance() return self.distance    end
        function Group:getPercent () return self.percent     end
        function Group:getAngle   () return Ceil(self.angle) 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
                        if S.Timer ~= nil then timer.cancel(S.Timer); S.Timer = nil
                        display.getCurrentStage():setFocus( T, event.id )
                       end
                        display.getCurrentStage():setFocus( T )
                        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
                                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]

it really sucks that it doesn’t work right, 'cause implementing this particular module is very simple.
One thing that might be worth noting, that I just remembered, is if I am not using LH or SH but instead I have just a .png image in my main project folder, when I would rotate the actual file (image) it would effect how the object was handled by the joystick…? o.O

Just send it to me and I will look at it and try to figure it out whats causing the problem

henrruud@online.no

If it is a large zip file, just send it by dropbox. LevelHelper and SpriteHelper has its own API and approach to Corona API

Have you checked up the LH API on fliping sprites?

Vladu B made special api calls for these types of situations, like transformation methods that fixes issues working in Box2d

Maybe you should ask Bogdan Vladu (maker of LH and SH)…got a feeling he knows a thing or two about this

I do all my levels and sprites in SH and LH because it saves a lot of time. His codes are robust and best of all, he answers Q´s fast so you don’t get stuck in problems

Yes, I’ve tried.
I emailed him and he said “you need to get the rotation delta of the analog stick and add that delta to the rotation of the tank.”

Unfortunately he does not know how to do that with a joystick, and I also do not know how… so unless someone else has a solution, I’ll just have to find a different joystick module. :slight_smile:

If you post me the project folder with everything inside I will take a look and see if I can help you out (nothing is worse than get stuck and loose hope :wink:

send it to my email: henrruud@online.no if you like

and I´ll try to help you man

If you dont use delta function it will transform from the same position everytime you trigger an event like i.e.

transform.to ( myTanks, { time=200, rotation=10, xScale= .5, yScale=.5, delta = true } ) 

the last param will do the trick

Thank you for offering to help me out. :smiley:
lol I’ve tried ever way I can think of to try and fix it: changing the rotation via LH, SH, direct code, adding a value to part of the lib-analog_stick, etc… etc… :wacko:

The code that deals with the joystick is pretty minimal, but if you still want me to I can email you the project.

level1.lua
[lua]
local StickLib = require(“lib_analog_stick”)


–============================================================================–
–======================== Creating a JoyStick --=============================–

local Text = display.newText( " ", _W*.6, _H-20, native.systemFont, 15 )
 
–Creates analog stick that controls the tank body’s speed and direction
local LeftStick = StickLib.NewStick(
        {
            
        x             = _W*.1,
        y             = _H*.85,
        thumbSize     = 20,
        borderSize    = 46,
        snapBackSpeed = .75,
        R             = 256,
        G             = 255,
        B             = 255
        })
        

local function main( event )
        
        --Sets Left analog to control the tank body and set the speed.
        LeftStick:move(user_tank , 3.0, true)
         
         
        --show stick info
        Text.text = “ANGLE = “…LeftStick:getAngle()…”   DISTANCE = “…math.ceil(LeftStick:getDistance())…”   PERCENT = “…math.ceil(LeftStick:getPercent()*100)…”%”
        --[[if Runtime:hasEventSource( “LeftStick” ) then
        Runtime:addEventListener( “enterFrame”, main )
    end]]
end
Runtime:addEventListener( “enterFrame”, main )
[/lua]
stick_analog_lib.lua
[lua]

 
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)
        Group.Border.strokeWidth = 1
        Group.Border:setFillColor  (Props.R,Props.G,Props.B,46)
        Group.Border:setStrokeColor(Props.R,Props.G,Props.B,255)
        Group:insert(Group.Border)
 
        Group.Thumb = display.newCircle(0,0,Props.thumbSize)
        Group.Thumb.strokeWidth = 1
        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:insert(Group.Thumb)
 
        ---------------------------------------------
        – 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 - 90 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
        
        ---------------------------------------------
        – GETTER METHODS
        ---------------------------------------------
        function Group:getDistance() return self.distance    end
        function Group:getPercent () return self.percent     end
        function Group:getAngle   () return Ceil(self.angle) 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
                        if S.Timer ~= nil then timer.cancel(S.Timer); S.Timer = nil
                        display.getCurrentStage():setFocus( T, event.id )
                       end
                        display.getCurrentStage():setFocus( T )
                        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
                                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]

it really sucks that it doesn’t work right, 'cause implementing this particular module is very simple.
One thing that might be worth noting, that I just remembered, is if I am not using LH or SH but instead I have just a .png image in my main project folder, when I would rotate the actual file (image) it would effect how the object was handled by the joystick…? o.O

Just send it to me and I will look at it and try to figure it out whats causing the problem

henrruud@online.no

If it is a large zip file, just send it by dropbox. LevelHelper and SpriteHelper has its own API and approach to Corona API

Had the same trouble here - any thoughts? 

http://forums.coronalabs.com/topic/36316-trouble-getting-sprite-to-move-with-gamexcbs-dpad-demo/