Joystick Help! See code thanks!

SO I’m using the joystick_lib.lua and the code below to move a boxed tank with the joystick. This works perfectly fine and as intended. My issue is spawning bullets in front of the box tank which I’m calling Avatar and getting it to fire as long as I am moving the tank around with the joystick.

Really if you can help me understand how to make the bullets go in the direction the tank is facing I could do the rest. The code right now works but the bullet does not follow the tank thus it fires from a fixed location on the screen. If I add the bullets to the same display group as the tank then everything gets messed up. Thanks for any help!

[lua]local jstick1
local laserFire1
myJoystick1 = joystick.NewStick(
{
x = 40,
y = 300,
thumbSize = 12,
borderSize = 42,
snapBackSpeed = .75,
R = 255,
G = 255,
B = 255
} )


jstick1 = function ( event )
myJoystick1:move(avatar1Group, avatar1speed, true)
avatar1Group:setReferencePoint(display.CenterReferencePoint);
laserFire1()
end
Runtime:addEventListener(“enterFrame”, jstick1)


Avatar = display.newImageRect(“assets/box_tank_1.png”,40,40)
Avatar.x,Avatar.y = _W,119
physics.addBody(Avatar, “dynamic”, {friction = 5.5, bounce = 0,radius = 17} )
Avatar.myName = “Avatar”
Avatar.yScale = -1
avatar1Group:insert(Avatar)

laserFire1 = function( e )
print(“Firing Lasers”)
local laser1 = display.newRect(0,0,10,1)
laser1.x,laser1.y = Avatar.x, Avatar.y - Avatar.height
physics.addBody(laser1)
laser1.isBullet = true
laser1:applyLinearImpulse( 20, 20, laser1.x,laser1.y)
end
[/lua] [import]uid: 53149 topic_id: 34124 reply_id: 334124[/import]

I would start with rotating the bullet to the same as the tank.

laser1.rotation = Avatar.rotation

You may need to add/subtract 90 to get it right based on the original orientation of the tank.

I’m no physics expert, but it seems to me that if you apply an x force of 100 and a y of 0, it will move left to right. A force of -100, 0 will move it right to left. So you need to know the difference in the X’s and Y’s between the tank and the bullet to know if you need a positive or negative force on the X and Y axis. Maybe something like:

local dX = Avatar.x - laser1.x
local dY = Avatar.y - laser1.y
laser1:applyLinearImpulse( 20*dX, 20*dY, laser1.x,laser1.y)

For this to work you will need to create the bullet a little way away from the center of the tank and I’m going to defer that math to someone else. You know the angle (tank rotation) and some distance away (half the laser width) so a little trig should be able let you derive the X and Y where you should create the laser.
[import]uid: 199310 topic_id: 34124 reply_id: 135682[/import]

@Rob Hey thank you for the support. Funny thing, and thank God for happy accidents. I ended up with trail of bullets which is a cool effect. It’s like spraying many polys in a line. How can I add a glow effect to shapes in Corona? Is it even possible? [import]uid: 53149 topic_id: 34124 reply_id: 135706[/import]

Hello,
For the best “laser glow” effect, I would make your laser beams into images, not vector rectangles. If you have the proper image editing software, I would also feather/blur the edges somewhat.

Then, most importantly, set each laser to “add” blend mode, as such:

laser1.blendMode = "add"

This will make overlapping beams add-blend for a nice lighting effect. To see what I mean, you can read this tutorial: http://www.coronalabs.com/blog/2012/10/30/creative-effects-using-blend-modes/

Best of luck!
Brent Sorrentino [import]uid: 200026 topic_id: 34124 reply_id: 135714[/import]

@Brent
@Rob

Guy’s thanks for the awesome help. In trying to figure this thing out I discovered a wonderful happy accident. The blendMode!!! OMG! Thank you for that. It made a world of a difference. The issue I am having now for anyone that can help me is memory leaks.

What I’m doing is this: Every time the joystick is moved I am spawning these tiny cubes for a period of 5 seconds. Then in 2 seconds I start to fade them out (alpha = 0) creating a nice trail that disappears starting from the end. The effect is quite spectacular. The issue is, it works perfect on my computer, but on the device it’s slower than honey. I thought maybe I could check for the cubes that are already at alpha = 0 and then delete those with object:removeSelf().

This seems to help, but only a tiny bit. Can you help me figure out the best way of doing this?

Here’s the function handling the drawing of the cubes when the player moves. p1laser() is called from a function that detects when the joystick has moved.
[lua]
local function p1laser ()
local isActive = true

if(lightcycleTimer1 >=1) then
–laser = display.newRect(av1X,av1Y, 2,2)
laser = display.newImageRect(cachelaser1,10,10)
laser.blendMode = “add” – screen works as well
laser.x,laser.y = av1X,av1Y
laser.rotation = av1Rot
laser:setFillColor(201,35,128,255)
physics.addBody(laser,{radius = 2})
end – end of if

local function resetLC1() – Resets player 1’s light cycle
lightcycleTimer1 = 1000
end

local function lightCycTmr()
lightcycleTimer1 = lightcycleTimer1 - 10
print(lightcycleTimer1)
if(lightcycleTimer1 <=0) then
print(“You are running low on fuel”)
local lc1T = timer.performWithDelay(2000, resetLC1)
end

end
lightCycTmr() – Everytime we move reduce the light cycle

local function cleanUp()
if(laser.alpha == 0) then
print(“clean up”)
laser:removeSelf()
end
end

if(isActive == true) then
transition.to(laser, {time = 2900, alpha = 0, onComplete = cleanUp} )

else
isActive = false
end

end[/lua] [import]uid: 53149 topic_id: 34124 reply_id: 135893[/import]

Any suggestions guys? I thought maybe if I can figure out a way to instance the same image instead of loading it all the time would help. I’m a little suckish on tables. Not even sure if that’s the right move.

Thanks [import]uid: 53149 topic_id: 34124 reply_id: 135923[/import]

Hello again,
Yes, you have the correct idea… you need to find a way to “recycle” your trail objects instead of constantly creating/fading/deleting. That latter approach is what’s slowing everything down… it’s fairly “expensive” to create tons of new objects on the fly, especially on mobile.

The idea here is, you’d want to just create a table with (say) 50 of these pre-created objects inserted. As the simulation runs, it pulls one off the top of the “stack”, places it, starts the fade, and then when the fade completes that object goes back into the stack (at the bottom).

Brent [import]uid: 200026 topic_id: 34124 reply_id: 135927[/import]

@Brent - giving my code example above, could you help me integrate the tables. Please and thank you. I am artist first and programmer second. I can understand what’s going on for the most part, but conceptualize the process is my weakness :slight_smile:

Thanks [import]uid: 53149 topic_id: 34124 reply_id: 135929[/import]

Hi, happy to help… the basic setup would be like this:

--fill table "cachedLasers" with X lasers (determine how many by checking below, don't needlessly over-fill it)  
local cachedLasers = {}  
for i=1,20 do  
 local laser = display.newRect(0,0,10,10) ; laser.alpha = 0  
 cachedLasers[#cachedLasers+1] = laser  
end  
  
local table\_remove = table.remove --cache Lua function "table.remove" for better performance  
  
--function to recycle laser on 'onComplete' of fade transition  
local function recycleLaser( event ) --'event' refers to the actual laser object  
 event.alpha = 0  
 transition.cancel( event.trans )  
 cachedLasers[#cachedLasers+1] = event  
end  
  
--on joystick move  
local function putLaser()  
 local thisLaser = cachedLasers[1]  
 table\_remove( cachedLasers, 1 )  
 thisLaser.alpha = 1  
 print(#cachedLasers) --remove this after you test how many need to be in table!  
 thisLaser.x, thisLaser.y = 100, 100  
 thisLaser.trans = transition.to( thisLaser, { y=200, alpha=0, time=500, transition=easing.inOutQuad, onComplete=recycleLaser } )  
end  
  
timer.performWithDelay(50,putLaser,0)  

You’ll have to put in your own aspects here, like placing the laser bits at your Avatar X and Y, and taking out the “y=200” part of the transition (I just put that in here for testing). If any of this doesn’t make sense, just let me know!

Brent [import]uid: 200026 topic_id: 34124 reply_id: 135957[/import]

Thanks for the assistance. It works, but I get an error here.
[lua]thisLaser.alpha = 1 [/lua]

Error:

attempt to index local ‘thisLaser’ (a nil value)
stack traceback:
[import]uid: 53149 topic_id: 34124 reply_id: 135971[/import]

Actually in debugging it’s seems that once I run through the say 200 (i changed it from 20 to do 200) If I should call the function putLaser() I get the error. Maybe this is what it is supposed to do. I like what it’s doing. How do say cause to run through the for loop again to get more lasers?

Do I put the hole thing in once function and call that from joystick move? right now I’m only call putLaser() [import]uid: 53149 topic_id: 34124 reply_id: 135975[/import]

You should only run the loop once to stock the cachedLasers table. Put enough in the first time so that you never have to refill it (but don’t overfill it either, otherwise you have unused objects just sitting there).

I’d have to see your code at this point to determine why that error was popping up. As I gave it to you, it was working perfectly in my Simulator. [import]uid: 200026 topic_id: 34124 reply_id: 135978[/import]

Uhm - yes, tried putting it all into a function. FAILED! :slight_smile: I like that it spawns x number of cubes and once those x cubes are spawned it does no more. I can play with that. How do I get rid of the error once x cubes has been spawned. I’m always going to call putLaser() when the joystick has moved. THis way if the player runs over more lasers I can adjust the count. How do I get the for loop to fire again?

Really the question is, how do I get the for loop to fire again. I’m going to try and put that in a function by itself. Not sure if it’ll work, but least i can do is try right :slight_smile:

Thanks again for the amazing help [import]uid: 53149 topic_id: 34124 reply_id: 135979[/import]

The “putLaser” function should actually just be combined into your joystick move function, there’s no need to make it separate. As for stocking more lasers, I could write a quick function to “refill” the table, but shouldn’t there be a maximum limit at any time, say 100 at most? [import]uid: 200026 topic_id: 34124 reply_id: 135980[/import]

I retract that my Woot! Yes, I could use help in creating refill. Yes, the limit would be 100 until they collide with a refill object. Can you help me with the Refill part?

Thanks [import]uid: 53149 topic_id: 34124 reply_id: 135982[/import]

I can do the collision part Brent. I just need to know how to setup the refill. Thanks [import]uid: 53149 topic_id: 34124 reply_id: 135990[/import]

OK, in this case, the “refill” should be managed by a separate counter that controls whether the player can fire more lasers. It shouldn’t actually empty the table of laser objects, which is separate and created only once. You should create an “ammoCount” variable and count down to 0, and when it’s empty you just stop placing lasers… but those laser objects stay within the “cachedLasers” table. Then, when an ammo fill-up is received, you set the ammo count back up and start outputting the objects again.

The point is, you don’t want to “fill” that table of cached lasers more than once, especially if you need to (at some point) make them into physics bodies, which are a bit more expensive performance-wise.

And, the table doesn’t need to actually contain the maximum ammo level that a player can have, it only needs to contain enough that will be shown on-screen at any given time. It’s the new ammo count which controls whether you put them on the screen. Make sense?

Brent [import]uid: 200026 topic_id: 34124 reply_id: 136003[/import]

I would start with rotating the bullet to the same as the tank.

laser1.rotation = Avatar.rotation

You may need to add/subtract 90 to get it right based on the original orientation of the tank.

I’m no physics expert, but it seems to me that if you apply an x force of 100 and a y of 0, it will move left to right. A force of -100, 0 will move it right to left. So you need to know the difference in the X’s and Y’s between the tank and the bullet to know if you need a positive or negative force on the X and Y axis. Maybe something like:

local dX = Avatar.x - laser1.x
local dY = Avatar.y - laser1.y
laser1:applyLinearImpulse( 20*dX, 20*dY, laser1.x,laser1.y)

For this to work you will need to create the bullet a little way away from the center of the tank and I’m going to defer that math to someone else. You know the angle (tank rotation) and some distance away (half the laser width) so a little trig should be able let you derive the X and Y where you should create the laser.
[import]uid: 199310 topic_id: 34124 reply_id: 135682[/import]

@Rob Hey thank you for the support. Funny thing, and thank God for happy accidents. I ended up with trail of bullets which is a cool effect. It’s like spraying many polys in a line. How can I add a glow effect to shapes in Corona? Is it even possible? [import]uid: 53149 topic_id: 34124 reply_id: 135706[/import]

Hello,
For the best “laser glow” effect, I would make your laser beams into images, not vector rectangles. If you have the proper image editing software, I would also feather/blur the edges somewhat.

Then, most importantly, set each laser to “add” blend mode, as such:

laser1.blendMode = "add"

This will make overlapping beams add-blend for a nice lighting effect. To see what I mean, you can read this tutorial: http://www.coronalabs.com/blog/2012/10/30/creative-effects-using-blend-modes/

Best of luck!
Brent Sorrentino [import]uid: 200026 topic_id: 34124 reply_id: 135714[/import]