Multiple turrets firing projectiles

I recently started playing with SSK2 and I am editing some code roaminggamer made and I was wondering, how I could modify this code to have more than one turret firing at once. I trade placing them in a table, but it did not come out so well. If anyone has any suggestions, it would be greatly appreciated, thank you.

require "ssk2.loadSSK" \_G.ssk.init( {} ) require "physics" physics.start( ) physics.setGravity(0,0) local lifetime = 5000 local projectileCount = 30 local spread = 12 local bulletSpeed = 500 local turret local fireTurret local lastTarget local character local background = display.newGroup() local content = display.newGroup() local count = 0 local function onCollision( self, event ) display.remove(self) return false end local function onCollision2( self, event ) if( event.other.myType == "bullet" ) then return false end display.remove(self) end local function activateTurret( self, event ) --[[lastTarget = ssk.display.newImageRect( content, event.x, event.y, "corona256.png", { size = 40, collision = onCollision }, { radius = 20 } )]] lastTarget = ssk.display.newRect(display.contentCenterX, display.contentCenterY, {w = 20, h = 20, fill = \_G\_}) fireTurret() end ssk.display.newRect( background, centerX, centerY, { w = fullw, h = fullh, fill = \_G\_, alpha = 0.2} ) for a = 1, 2 do turret = ssk.display.newImageRect( content, 400 + (a \* 100), bottom - 75, "rg256.png", { size = 100 } ) ssk.misc.addSmartDrag( turret ) count = count + 1 end fireTurret = function() local vec = ssk.math2d.diff( turret, lastTarget ) local angle0 = ssk.math2d.vector2Angle(vec) local angle = angle0 - spread \* (projectileCount-1)/2 for i = 1, projectileCount do local vec2 = ssk.math2d.angle2Vector( angle, true ) vec2 = ssk.math2d.normalize(vec2) vec2 = ssk.math2d.scale( vec2, bulletSpeed ) local bullet = ssk.display.newImageRect( content, turret.x, turret.y, "arrow.png", { size = 20, rotation = angle, collision = onCollision2, myType = "bullet", fill = randomColor() }, { isSensor = true, radius = 10} ) bullet:toBack() bullet:setLinearVelocity( vec2.x, vec2.y ) bullet.timer = display.remove timer.performWithDelay( lifetime, bullet ) angle = angle + spread end end timer.performWithDelay(500, activateTurret, 0)

Nutshell: Make this code into module (except init ssk in main.lua), deal with the the scope of turret and lastTurret, require the module in your code, call the fireTurret method.

How do I make this code into a module? How would I deal with the scope of turret and lastTarget? And how would I run the code and call the fireTurret method to multiple turrets?

EDIT – Is there a way to simply create a table for the turrets and modify the fireTurret code to work for all the turrets? If there is not, please answer the questions above. Thank you.

Well this is pretty straight forward, so I’ll get you part way there, but you will need to study this code line by line and understand how it works before applying it to your situation.  

I am sure this solution is NOT exactly what you need.  I converted the prior example I gave youto have multiple (3) selectable and draggable turrets that will fire indpendently using a module.

https://www.youtube.com/watch?v=wqYhFi3_AdY&feature=youtu.be

Updated main.lua:

Warning: Uses advanced SSK2 ‘features’, so you’ll need to read this line-by-line to understand how it works.

require "ssk2.loadSSK" \_G.ssk.init( {} ) require "physics" physics.start( ) physics.setGravity(0,0) local turretM = require "turretM" local turrets = {} local currentTurret local background = display.newGroup() local content = display.newGroup() local function onCollision( self, event ) display.remove(self) return false end local function onTouch( self, event ) if( event.phase ~= "began" ) then return end local target = ssk.display.newImageRect( content, event.x, event.y, "corona256.png", { size = 40, collision = onCollision }, { radius = 20 } ) turretM.fire( currentTurret, target ) end ssk.display.newRect( background, centerX, centerY, { w = fullw, h = fullh, fill = \_G\_, alpha = 0.2, touch = onTouch } ) local function onDropped( self ) for k,v in pairs( turrets ) do v:setFillColor( unpack(\_P\_) ) end self:setFillColor( unpack(\_G\_) ) currentTurret = self end currentTurret = ssk.display.newImageRect( content, centerX - 200, bottom - 75, "rg256.png", { size = 100, fill = \_P\_, onDropped = onDropped } ) ssk.misc.addSmartDrag( currentTurret, { retval = true } ) turrets[currentTurret] = currentTurret currentTurret = ssk.display.newImageRect( content, centerX, bottom - 75, "rg256.png", { size = 100, fill = \_P\_, onDropped = onDropped } ) ssk.misc.addSmartDrag( currentTurret, { retval = true } ) turrets[currentTurret] = currentTurret currentTurret = ssk.display.newImageRect( content, centerX + 200, bottom - 75, "rg256.png", { size = 100, fill = \_G\_, onDropped = onDropped } ) ssk.misc.addSmartDrag( currentTurret, { retval = true } ) turrets[currentTurret] = currentTurret

turretM.lua Module

Warning: Uses advanced SSK2 ‘features’, so you’ll need to read this line-by-line to understand how it works.

local lifetime = 5000 local projectileCount = 3 local spread = 7 local bulletSpeed = 300 local turretM = {} local function onCollision2( self, event ) if( event.other.myType == "bullet" ) then return false end display.remove(self) return false end function turretM.fire( turret, target ) local vec = ssk.math2d.diff( turret, target ) local angle0 = ssk.math2d.vector2Angle(vec) local angle = angle0 - spread \* (projectileCount-1)/2 for i = 1, projectileCount do local vec2 = ssk.math2d.angle2Vector( angle, true ) vec2 = ssk.math2d.normalize(vec2) vec2 = ssk.math2d.scale( vec2, bulletSpeed ) local bullet = ssk.display.newImageRect( target.group, turret.x, turret.y, "arrow.png", { size = 20, rotation = angle, collision = onCollision2, myType = "bullet", fill = \_Y\_ }, { isSensor = true, radius = 10} ) bullet:toBack() bullet:setLinearVelocity( vec2.x, vec2.y ) bullet.timer = display.remove timer.performWithDelay( lifetime, bullet ) angle = angle + spread end end return turretM

Code here: http://github.com/roaminggamer/RG_FreeStuff/raw/master/SSK2/forums_help/projectiles_module.zip

Please also remember. I have a bunch of free SSK2 samples and starters including turret and projectile code:

https://github.com/roaminggamer/RG_FreeStuff/tree/master/SSK2

See tools and experiments.

Best way to get this for now is to download the entire collection of free stuff https://github.com/roaminggamer/RG_FreeStuff

Thanks, this is pretty helpful. However, all I am having trouble with is inserting the turrets into a table, and then calling each of them. For example:

local turrets = {} for a = 1, 2 do turret = ...... count = count + 1 table.insert(turrets, turret) end local bullet = ssk.display.newImageRect( content, turrets[count].x, turrets[count].y, "arrow.png", { size = 20, rotation = angle, collision = onCollision2, myType = "bullet", fill = randomColor() }, { isSensor = true, radius = 10} )

EDIT: Thanks for showing me selectable turrets, I was probably going to ask about that next.

@community - If anyone else wants to jump in, please do. I can’t take this any further.

@sdktester15
I’m afraid I can’t help more with this.  We’re treading on specific game design or else you need to hire someone to help you.

I am sure you’ve got errors in your code with regards to scope and visibility.

As yourself, “Why am I getting this error (or behavior)? What is the source for it?”

Track your error messages back to the place where variables are set. Are you using the right scope? Are you using locals when you should be?
 
I will say that this code doesn’t make sense to me and is a bit redundant:

for a = 1, 2 do turret = ...... count = count + 1 table.insert(turrets, turret) end

Just do this:

for a = 1, 2 do local turret = ...... turrets[#turrets+1] = turret end -- To get the 'count' print( "Count of turrets: ", #turrets)

or

for a = 1, 2 do local turret = ...... turrets[a] = turret end -- To get the 'count' print( "Count of turrets: ", #turrets)

Of course I hate numeric indexes except in the case where you absolutely need to know the order of a table:

for a = 1, 2 do local turret = ...... turrets[turret] = turret end -- To get the 'count' print( "Count of turrets: ", table.count(turrets) ) -- ONLY with SSK2 table.\* extensions

Final note.  My answer wasn’t specifically for your issue.  I changed the turret firing code to be modular, but the rest of the example was so that you (and anyone else reading this) could simply pick up the sample and run it.
 
Answering your specific question (request for code) would not help the general community and I prefer to do the later.
 
When I answer questions I keep this quote in mind

“Give a Man a Fish, and You Feed Him for a Day. Teach a Man To Fish, and You Feed Him for a Lifetime.”

So, sorry my answer wasn’t exactly what you wanted.

It is no problem, I understand.

Nutshell: Make this code into module (except init ssk in main.lua), deal with the the scope of turret and lastTurret, require the module in your code, call the fireTurret method.

How do I make this code into a module? How would I deal with the scope of turret and lastTarget? And how would I run the code and call the fireTurret method to multiple turrets?

EDIT – Is there a way to simply create a table for the turrets and modify the fireTurret code to work for all the turrets? If there is not, please answer the questions above. Thank you.

Well this is pretty straight forward, so I’ll get you part way there, but you will need to study this code line by line and understand how it works before applying it to your situation.  

I am sure this solution is NOT exactly what you need.  I converted the prior example I gave youto have multiple (3) selectable and draggable turrets that will fire indpendently using a module.

https://www.youtube.com/watch?v=wqYhFi3_AdY&feature=youtu.be

Updated main.lua:

Warning: Uses advanced SSK2 ‘features’, so you’ll need to read this line-by-line to understand how it works.

require "ssk2.loadSSK" \_G.ssk.init( {} ) require "physics" physics.start( ) physics.setGravity(0,0) local turretM = require "turretM" local turrets = {} local currentTurret local background = display.newGroup() local content = display.newGroup() local function onCollision( self, event ) display.remove(self) return false end local function onTouch( self, event ) if( event.phase ~= "began" ) then return end local target = ssk.display.newImageRect( content, event.x, event.y, "corona256.png", { size = 40, collision = onCollision }, { radius = 20 } ) turretM.fire( currentTurret, target ) end ssk.display.newRect( background, centerX, centerY, { w = fullw, h = fullh, fill = \_G\_, alpha = 0.2, touch = onTouch } ) local function onDropped( self ) for k,v in pairs( turrets ) do v:setFillColor( unpack(\_P\_) ) end self:setFillColor( unpack(\_G\_) ) currentTurret = self end currentTurret = ssk.display.newImageRect( content, centerX - 200, bottom - 75, "rg256.png", { size = 100, fill = \_P\_, onDropped = onDropped } ) ssk.misc.addSmartDrag( currentTurret, { retval = true } ) turrets[currentTurret] = currentTurret currentTurret = ssk.display.newImageRect( content, centerX, bottom - 75, "rg256.png", { size = 100, fill = \_P\_, onDropped = onDropped } ) ssk.misc.addSmartDrag( currentTurret, { retval = true } ) turrets[currentTurret] = currentTurret currentTurret = ssk.display.newImageRect( content, centerX + 200, bottom - 75, "rg256.png", { size = 100, fill = \_G\_, onDropped = onDropped } ) ssk.misc.addSmartDrag( currentTurret, { retval = true } ) turrets[currentTurret] = currentTurret

turretM.lua Module

Warning: Uses advanced SSK2 ‘features’, so you’ll need to read this line-by-line to understand how it works.

local lifetime = 5000 local projectileCount = 3 local spread = 7 local bulletSpeed = 300 local turretM = {} local function onCollision2( self, event ) if( event.other.myType == "bullet" ) then return false end display.remove(self) return false end function turretM.fire( turret, target ) local vec = ssk.math2d.diff( turret, target ) local angle0 = ssk.math2d.vector2Angle(vec) local angle = angle0 - spread \* (projectileCount-1)/2 for i = 1, projectileCount do local vec2 = ssk.math2d.angle2Vector( angle, true ) vec2 = ssk.math2d.normalize(vec2) vec2 = ssk.math2d.scale( vec2, bulletSpeed ) local bullet = ssk.display.newImageRect( target.group, turret.x, turret.y, "arrow.png", { size = 20, rotation = angle, collision = onCollision2, myType = "bullet", fill = \_Y\_ }, { isSensor = true, radius = 10} ) bullet:toBack() bullet:setLinearVelocity( vec2.x, vec2.y ) bullet.timer = display.remove timer.performWithDelay( lifetime, bullet ) angle = angle + spread end end return turretM

Code here: http://github.com/roaminggamer/RG_FreeStuff/raw/master/SSK2/forums_help/projectiles_module.zip

Please also remember. I have a bunch of free SSK2 samples and starters including turret and projectile code:

https://github.com/roaminggamer/RG_FreeStuff/tree/master/SSK2

See tools and experiments.

Best way to get this for now is to download the entire collection of free stuff https://github.com/roaminggamer/RG_FreeStuff

Thanks, this is pretty helpful. However, all I am having trouble with is inserting the turrets into a table, and then calling each of them. For example:

local turrets = {} for a = 1, 2 do turret = ...... count = count + 1 table.insert(turrets, turret) end local bullet = ssk.display.newImageRect( content, turrets[count].x, turrets[count].y, "arrow.png", { size = 20, rotation = angle, collision = onCollision2, myType = "bullet", fill = randomColor() }, { isSensor = true, radius = 10} )

EDIT: Thanks for showing me selectable turrets, I was probably going to ask about that next.

@community - If anyone else wants to jump in, please do. I can’t take this any further.

@sdktester15
I’m afraid I can’t help more with this.  We’re treading on specific game design or else you need to hire someone to help you.

I am sure you’ve got errors in your code with regards to scope and visibility.

As yourself, “Why am I getting this error (or behavior)? What is the source for it?”

Track your error messages back to the place where variables are set. Are you using the right scope? Are you using locals when you should be?
 
I will say that this code doesn’t make sense to me and is a bit redundant:

for a = 1, 2 do turret = ...... count = count + 1 table.insert(turrets, turret) end

Just do this:

for a = 1, 2 do local turret = ...... turrets[#turrets+1] = turret end -- To get the 'count' print( "Count of turrets: ", #turrets)

or

for a = 1, 2 do local turret = ...... turrets[a] = turret end -- To get the 'count' print( "Count of turrets: ", #turrets)

Of course I hate numeric indexes except in the case where you absolutely need to know the order of a table:

for a = 1, 2 do local turret = ...... turrets[turret] = turret end -- To get the 'count' print( "Count of turrets: ", table.count(turrets) ) -- ONLY with SSK2 table.\* extensions

Final note.  My answer wasn’t specifically for your issue.  I changed the turret firing code to be modular, but the rest of the example was so that you (and anyone else reading this) could simply pick up the sample and run it.
 
Answering your specific question (request for code) would not help the general community and I prefer to do the later.
 
When I answer questions I keep this quote in mind

“Give a Man a Fish, and You Feed Him for a Day. Teach a Man To Fish, and You Feed Him for a Lifetime.”

So, sorry my answer wasn’t exactly what you wanted.

It is no problem, I understand.