how to initiate a 'touch' event at any point within the view and have it call a function to rotate an object, and fire a bullet.

Hi Saerothir,
Sorry, I meant to reply but it slipped through the cracks. The “angle between” function that I use is printed below. “srcX” and “srcY” are, in this case, your turret X and Y positions (just plug in turret.x or turret.y, or whatever you have named your turret object). “dstX” and “dstY” are the touch location X and Y coordinates… where the user touches/drags on the sensor rectangle.

local math\_deg = math.deg --localize 'math.deg' for better performance  
local math\_atan2 = math.atan2 --localize 'math.atan2' for better performance  
  
local function angleBetween( srcX, srcY, dstX, dstY )  
 local angle = ( math\_deg( math\_atan2( dstY-srcY, dstX-srcX ) )+90 ) --; return angle  
 if ( angle \< 0 ) then angle = angle + 360 end ; return angle % 360  
end  
  
--USAGE:  
local ang = angleBetween( turret.x, turret.y, eventX, eventY )  
turret.rotation = ang  

Try this out a bit and let me know how it goes.

Brent

[import]uid: 9747 topic_id: 30680 reply_id: 123314[/import]

Well, it kinda works :]

When I launch the simulator and then click on a random point within the view the turret immediately rotates to that point, but that’s all it does…?
It doesn’t respond when I attempt to click on a different point on the screen nor does it respond to dragging…

here is my code (I know I’m missing something)

 --adds a rect to act as a base for touch event relating to the turret  
local transRect = display.newRect(0,0, 1024, 768)  
transRect:setReferencePoint(display.CenterReferencePoint);  
transRect.isVisible = false  
transRect.isHitTestable = true  
  
 function transRect:touch(e)  
 if e.phase == "began" then  
 print( "You touched the object!" );  
  
 local math\_deg = math.deg --localize 'math.deg' for better performance  
 local math\_atan2 = math.atan2 --localize 'math.atan2' for better performance  
   
 local function angleBetween( user\_turretx, user\_turrety, transRecx, transRecty )  
 local angle = ( math\_deg( math\_atan2( transRect.y-user\_turret.y, transRect.x-user\_turret.x ) )+90 ) --; return angle  
 if ( angle \< 0 ) then angle = angle + 360 end ; return angle % 360  
 end  
   
 --USAGE:  
 local ang = angleBetween( user\_turret.x, user\_turret.y, event.x, event.y )  
 user\_turret.rotation = ang  
  
  
 end  
end   
 Runtime:addEventListener("touch", transRect)  
 transRect:addEventListener( "touch", transRect )  
  

Edit –
When I click on a point within the view it is registering two touch events, the terminal shows the the string message - line 9 - twice. [import]uid: 148623 topic_id: 30680 reply_id: 123327[/import]

Hi @Saerothir,
It should look more like this. I haven’t actually tested this in the Simulator, but give it a try and let me know if it’s closer to your goals.

local transRect = display.newRect(0,0, 1024, 768)  
transRect:setReferencePoint(display.CenterReferencePoint);  
transRect.isVisible = false  
transRect.isHitTestable = true  
  
--up-reference these here, not within the function!  
local math\_deg = math.deg --localize 'math.deg' for better performance  
local math\_atan2 = math.atan2 --localize 'math.atan2' for better performance  
  
--likewise, this function should reside outside and above the touch function  
local function angleBetween( srcX, srcY, dstX, dstY )  
 local angle = ( math\_deg( math\_atan2( dstY-srcY, dstX-srcX ) )+90 ) --; return angle  
 if ( angle \< 0 ) then angle = angle + 360 end ; return angle % 360  
end  
  
local function transRect( event )  
  
 local ang = angleBetween( user\_turret.x, user\_turret.y, event.x, event.y )  
 user\_turret.rotation = ang --rotate turret on ALL touch/drag conditions  
  
 if e.phase == "began" or e.phase == "moved" then  
 print( "BEGAN/MOVED phase touch" )  
 elseif e.phase == "ended" then  
 print( "FIRE a bullet now!" )  
 end  
  
end  
  
--a touch listener on the sensor rectangle is all you need. So, delete the next line...  
Runtime:addEventListener("touch", transRect) --DELETE this!  
transRect:addEventListener( "touch", transRect )  

[import]uid: 9747 topic_id: 30680 reply_id: 123418[/import]

I certainly appreciate all your help! :slight_smile:
Just a quick note - using the code you posted, I ran it in the simulator (in a new blank project) and instead of moving the turret I had the transition.to set to move the ‘player’ group and when I did that I got the same problem, the turret’s orientation was off. This leads me to wonder if the problem is with my display group. [import]uid: 148623 topic_id: 30680 reply_id: 124004[/import]

Hi again,
So, to move both the tank and the turret, you’re actually moving the entire “player” group? This could definitely be the issue! Try setting the group’s reference to “top left” and also “center” and see if this helps. I know I said that you should avoid doing so, but if you need to move the entire group, it might actually make sense in that case.

Since you’re using physics, you could also join the turret to the tank using a “pivot” joint, allowing the turret to rotate about its point, but also staying locked in position to the tank’s center. This way, you wouldn’t need to move the entire player group, only the player object.

Brent
[import]uid: 9747 topic_id: 30680 reply_id: 124006[/import]

Well I changed the turret and tank to a bigger image, so I got rid of any reference code relating to the turret and tank.
When I try to set the ref point of the playerTank group and run it in the simulator, nothing happens…? No errors in the console, but the turret and tank disappear.

[lua]–adding new local group that will represent the tank
local playerTank = display.newGroup()
playerTank:setReferencePoint(display.CenterReferencePoint);

–adding the tank that will be controlled by the player
local user_tank = display.newImage(“gameImages/user_tank.png”);
user_tank:setReferencePoint(display.CenterReferencePoint);

–adding the turret that will be controlled by the player
local user_turret = display.newImage(“gameImages/user_turret.png”)
user_turret:setReferencePoint(display.CenterReferencePoint);[/lua]

Also, do I need to change the ‘scr’ and ‘dst’ to the actual objects they are referring to?

[lua]local function angleBetween( srcX, srcY, dstX, dstY )
local angle = ( math_deg( math_atan2( dstY-srcY, dstX-srcX ) )+90 ) --; return angle
if ( angle < 0 ) then angle = angle + 360 end ; return angle % 360
end

local function touchRect( event )

local ang = angleBetween( user_turret.x, user_turret.y, event.x, event.y )
user_turret.rotation = ang --rotate turret on ALL touch/drag conditions
local e = event.phase
if e.phase == “began” or e.phase == “moved” then
print( “BEGAN/MOVED phase touch” )
elseif e.phase == “ended” then
print( “FIRE a bullet now!” )
end

end[/lua]

I apologize for my lack of knowledge, programming is pretty new to me. [import]uid: 148623 topic_id: 30680 reply_id: 124016[/import]

My advice is still that you join the turret to the tank using a pivot joint. This way, you don’t have to worry about moving a “group”, you only have to deal with the tank as the core object… the turret will stay attached to its center point, but also have the flexibility to rotate. I use a similar process in a game I’m working on where a character has a rotating “shield” object around it, such that the shield can be set on an angular velocity while the character moves.

Add the proper items to the proper group, but don’t change the group reference points or the reference points of the items. Display groups default to 0,0 at the top left and should remain so unless you’re confident in changing that.

As for passing “dstX” and “dstY” to the angle calculation function, yes, you must pass the proper, current coordinates of the tank to that function to receive the proper angle in return.

Try this out and let me know how it goes… the code for doing physics joints is contained in the Physics guide, where you should find a specific guide for Joints (all types of Box2D joints and their parameters). A pivot joint is one of the more simple joints and shouldn’t cause any major issues for you. :slight_smile:

Brent
[import]uid: 9747 topic_id: 30680 reply_id: 124019[/import]

Hey Brent,
Sorry for the delayed response.

I made a video to show the issues I’m having:
http://www.youtube.com/watch?v=vG2rJyDJC-w&feature=youtube_gdata_player

P.S. I hope I was clear enough in explaining. [import]uid: 148623 topic_id: 30680 reply_id: 123604[/import]

Hi Saerothir,
The video is marked as private. Can you make it public for me to view? (and others who might want to comment)

Brent
[import]uid: 9747 topic_id: 30680 reply_id: 123618[/import]

Oh, sorry.
It should work now. [import]uid: 148623 topic_id: 30680 reply_id: 123620[/import]

Thanks for posting the video, it helped clarify some things! A few new things I noticed…

  1. Remove line #2 where you set the reference point of the sensor rectangle. This could be the cause of the touch response giving the wrong values when you move the tank from its starting position in the upper left.

  2. I should have noticed this before (kicking myself)… you have both the rectangle AND the function named “transRect”. This is probably causing some confusion in Lua, which might be why you’re getting the first error. Name the function something different like “senseRect”, along with all references to it, and see if that helps.

Otherwise, if you’re still having problems, please e-mail me the code for “level1.lua”. I couldn’t really see it clearly in the video, even blown up to full screen view. Please send it to bjsorrentino (at) yahoo (dot) com.

Brent [import]uid: 9747 topic_id: 30680 reply_id: 123630[/import]

I emailed you the level1.lua code. [import]uid: 148623 topic_id: 30680 reply_id: 123750[/import]

Hi @Saerothir,
I don’t know what other advice I can give. I pulled out the angle-tracking code, placed it in a new Lua simulation, and it seems to work perfectly. So quite possibly the problem is somewhere in the StickLib module, or something is going wrong in Storyboard. I don’t actually use Storyboard so I won’t pretend I’m an expert on how it all works… I just know the basics of it, and I also know it’s extremely fussy about what things you place in which “phase” of it.

I did remove all of the instances where you changed the reference points of objects (the turret, even the player group itself. You should be very careful about where you use those commands, because they can really muck with the coordinate system, touch coordinates, scaling, etc.

I sense that you want to have the turret rotate by its “base”, not the center, which is why you adjusted its reference point. I actually suggest that you design your turret image as a larger square with its “base” in the center of the image boundaries and transparent space all around. So, instead of adjusting the reference point of it in Corona, you place its base in the center of a square image, and the Corona display object rotates around its center as is default.

Anyway, try this yourself in a NEW Corona simulation, outside of Storyboard. For me it works perfectly, and the turret always tracks the touch position.

Sorry I couldn’t find the problem in your level1.lua code. It must be something within StickLib or elsewhere, and could take awhile to track down. Maybe you can narrow down the problem by looking there, or pulling your app out of Storyboard for the time being.

Best of luck!
Brent

--adding new local group that will represent the tank  
local player = display.newGroup()  
--player.xReference = 25;   
--player.yReference = 23;  
  
--adding the tank that will be controlled by the player  
local user\_tank = display.newImage("gameImages/user\_tank.png");  
  
--adding the turret that will be controlled by the player  
local user\_turret = display.newImage("gameImages/user\_turret.png")  
--user\_turret:setReferencePoint(player.CenterReferencePoint);  
user\_turret.x = 100;  
user\_turret.y = 100;   
--user\_turret.yReference = 18;  
  
--following function is a daisy-chained series of transitions to simulate the turret moving  
local function simulateTankMove()  
 transition.to( user\_turret, { time=6000, x=924 } )  
 transition.to( user\_turret, { delay=6000, time=6000, y=568 } )  
 transition.to( user\_turret, { delay=12000, time=3000, x=462, y=400 } )  
 transition.to( user\_turret, { delay=15000, time=3000, x=100, y=568 } )  
 transition.to( user\_turret, { delay=18000, time=6000, x=100, y=100, onComplete=simulateTankMove } )  
end  
simulateTankMove()  
  
--===============================================================   
--===============================================================   
--===============================================================  
  
--adds a rect to act as a base for touch event relating to the turret  
local transRect = display.newRect(0,0, 1024, 768)  
transRect:setFillColor(255,100,150,40)  
--transRect.isVisible = false  
transRect.isHitTestable = true  
  
local math\_deg = math.deg --localize 'math.deg' for better performance  
local math\_atan2 = math.atan2 --localize 'math.atan2' for better performance  
   
--likewise, this function should reside outside and above the touch function  
local function angleBetween( srcX, srcY, dstX, dstY )  
 local angle = ( math\_deg( math\_atan2( dstY-srcY, dstX-srcX ) )+90 ) --; return angle  
 if ( angle \< 0 ) then angle = angle + 360 end ; return angle % 360  
end  
   
local function touchRect( event )  
   
 local ang = angleBetween( user\_turret.x, user\_turret.y, event.x, event.y )  
 user\_turret.rotation = ang --rotate turret on ALL touch/drag conditions  
 local e = event.phase  
 if e.phase == "began" or e.phase == "moved" then  
 print( "BEGAN/MOVED phase touch" )  
 elseif e.phase == "ended" then  
 print( "FIRE a bullet now!" )  
 end  
   
end  
   
--a touch listener on the sensor rectangle is all you need. So, delete the next line...  
--Runtime:addEventListener("touch", touchRect) --DELETE this!  
transRect:addEventListener( "touch", touchRect )   
  
--===============================================================  
--===============================================================  
  
--adding objects to local group 'player'  
player:insert(user\_tank)  
player:insert(user\_turret)  

[import]uid: 9747 topic_id: 30680 reply_id: 123773[/import]

I certainly appreciate all your help! :slight_smile:
Just a quick note - using the code you posted, I ran it in the simulator (in a new blank project) and instead of moving the turret I had the transition.to set to move the ‘player’ group and when I did that I got the same problem, the turret’s orientation was off. This leads me to wonder if the problem is with my display group. [import]uid: 148623 topic_id: 30680 reply_id: 124004[/import]

Hi again,
So, to move both the tank and the turret, you’re actually moving the entire “player” group? This could definitely be the issue! Try setting the group’s reference to “top left” and also “center” and see if this helps. I know I said that you should avoid doing so, but if you need to move the entire group, it might actually make sense in that case.

Since you’re using physics, you could also join the turret to the tank using a “pivot” joint, allowing the turret to rotate about its point, but also staying locked in position to the tank’s center. This way, you wouldn’t need to move the entire player group, only the player object.

Brent
[import]uid: 9747 topic_id: 30680 reply_id: 124006[/import]

Well I changed the turret and tank to a bigger image, so I got rid of any reference code relating to the turret and tank.
When I try to set the ref point of the playerTank group and run it in the simulator, nothing happens…? No errors in the console, but the turret and tank disappear.

[lua]–adding new local group that will represent the tank
local playerTank = display.newGroup()
playerTank:setReferencePoint(display.CenterReferencePoint);

–adding the tank that will be controlled by the player
local user_tank = display.newImage(“gameImages/user_tank.png”);
user_tank:setReferencePoint(display.CenterReferencePoint);

–adding the turret that will be controlled by the player
local user_turret = display.newImage(“gameImages/user_turret.png”)
user_turret:setReferencePoint(display.CenterReferencePoint);[/lua]

Also, do I need to change the ‘scr’ and ‘dst’ to the actual objects they are referring to?

[lua]local function angleBetween( srcX, srcY, dstX, dstY )
local angle = ( math_deg( math_atan2( dstY-srcY, dstX-srcX ) )+90 ) --; return angle
if ( angle < 0 ) then angle = angle + 360 end ; return angle % 360
end

local function touchRect( event )

local ang = angleBetween( user_turret.x, user_turret.y, event.x, event.y )
user_turret.rotation = ang --rotate turret on ALL touch/drag conditions
local e = event.phase
if e.phase == “began” or e.phase == “moved” then
print( “BEGAN/MOVED phase touch” )
elseif e.phase == “ended” then
print( “FIRE a bullet now!” )
end

end[/lua]

I apologize for my lack of knowledge, programming is pretty new to me. [import]uid: 148623 topic_id: 30680 reply_id: 124016[/import]

My advice is still that you join the turret to the tank using a pivot joint. This way, you don’t have to worry about moving a “group”, you only have to deal with the tank as the core object… the turret will stay attached to its center point, but also have the flexibility to rotate. I use a similar process in a game I’m working on where a character has a rotating “shield” object around it, such that the shield can be set on an angular velocity while the character moves.

Add the proper items to the proper group, but don’t change the group reference points or the reference points of the items. Display groups default to 0,0 at the top left and should remain so unless you’re confident in changing that.

As for passing “dstX” and “dstY” to the angle calculation function, yes, you must pass the proper, current coordinates of the tank to that function to receive the proper angle in return.

Try this out and let me know how it goes… the code for doing physics joints is contained in the Physics guide, where you should find a specific guide for Joints (all types of Box2D joints and their parameters). A pivot joint is one of the more simple joints and shouldn’t cause any major issues for you. :slight_smile:

Brent
[import]uid: 9747 topic_id: 30680 reply_id: 124019[/import]

Wow, I feel so dumb! :]
Adding the physics joint solved it!
Obviously my player group was the issue, because now It works exactly how I want and there are no issues with the turret’s orientation when I rotate it.
Just have to adjust the turret’s image 'cause it’s not quite centered so it looks a bit off when I rotate it.

Time to start designing levels, enemies, and all that good stuff. :smiley:
Thank you so much for all your help!
I’ve learned quite a bit.

[import]uid: 148623 topic_id: 30680 reply_id: 125057[/import]

Wow, I feel so dumb! :]
Adding the physics joint solved it!
Obviously my player group was the issue, because now It works exactly how I want and there are no issues with the turret’s orientation when I rotate it.
Just have to adjust the turret’s image 'cause it’s not quite centered so it looks a bit off when I rotate it.

Time to start designing levels, enemies, and all that good stuff. :smiley:
Thank you so much for all your help!
I’ve learned quite a bit.

[import]uid: 148623 topic_id: 30680 reply_id: 125057[/import]