Shooting projectile in direction of touch.

How do I get my projectile to fire from my main character in the direction I touch on screen?

I am having difficulty getting this right.

Your help will be appreciated. [import]uid: 165082 topic_id: 33470 reply_id: 333470[/import]

I thought there was a bullet module in the Community code, but I couldn’t find it when I went to look. It’s some pretty simple trigonometry math. But I think we need to know a bit more about what you’re trying to do.

How are you planning on moving your bullets? Are you using a transition.to or are you going to use a Runtime enterFrame listener?

I assume you know your origin X, Y and your touch point is your target X, Y. Does your bullet stop there or does it continue off screen if it misses?

Do you need the angle information to draw your bullet at the right angle or is it a small bullet where angle doesn’t matter for drawing?

[import]uid: 199310 topic_id: 33470 reply_id: 133001[/import]

I actually have my old donkey kong attempt at barrel shooting. It was one of my very first projects so it’s probably pretty bad, but you should be able to get some kinda idea out of it, hopefully lol.

[code]
display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()
physics.setDrawMode ( “hybrid” )
physics.setGravity( 0, 0 )

shooting = false

local player = {}
local whtv = {}

player[1] = display.newCircle( 280, 250, 10 )
physics.addBody( player[1], “dynamic”, { radius = 10, isSensor = true } )
player[1].isVisible = false

player[2] = display.newCircle( 200, 80, 10 )
physics.addBody( player[2], “dynamic”, { radius = 10, isSensor = true } )
player[2].isVisible = false

local barrel = {}

barrel[1] = display.newRoundedRect( 350, 220, 85, 60, 10 )
barrel[1].strokeWidth = 3
barrel[1]:setFillColor(96, 51, 17)
barrel[1]:setStrokeColor(50, 50, 50)
physics.addBody( barrel[1], “dynamic” )
whtv[1] = display.newRect( 340, 245, 65, 10 )
whtv[1]:rotate ( 88 )
whtv[1]:setFillColor( 0, 0, 0 )
physics.addBody( whtv[1], “dynamic” )

barrel[1].myName = “barrel1”

myJoint = physics.newJoint( “weld”, barrel[1], player[1], (barrel[1].x), (barrel[1].y) )

barrel[2] = display.newRoundedRect( 50, 50, 85, 60, 10 )
barrel[2].strokeWidth = 3
barrel[2]:setFillColor(96, 51, 17)
barrel[2]:setStrokeColor(50, 50, 50)
physics.addBody( barrel[2], “dynamic” )
whtv[2] = display.newRect( 80, 75, 65, 10 )
whtv[2]:rotate ( 88 )
whtv[2]:setFillColor( 0, 0, 0 )
physics.addBody( whtv[2], “dynamic” )

barrel[2].myName = “barrel2”

myJoint = physics.newJoint( “weld”, barrel[2], player[2], (barrel[2].x), (barrel[2].y) )
physics.newJoint( “weld”, barrel[1], whtv[1], barrel[1].x, barrel[1].y )
physics.newJoint( “weld”, barrel[2], whtv[2], (barrel[2].x), (barrel[2].y) )

local myText = display.newText("", 50, 50, native.systemFont, 16)
myText:setTextColor(255, 255, 255)
local myText2 = display.newText("", 150, 150, native.systemFont, 16)
myText2:setTextColor(255, 255, 255)

local function testingz()
barrel[1].angularVelocity = 150
barrel[2].angularVelocity = -150
d = barrel[1].angularVelocity
f = barrel[2].angularVelocity
end
Runtime:addEventListener( “enterFrame”, testingz )

– local function test()
– barrel2.angularVelocity = 0

– end
– Runtime:addEventListener( “touch”, test )
i = 1
local function shoot( event )

– shootx = (player2.x - barrel2.x)/2 + barrel2.x
– shooty = (player2.y - barrel2.y)/2 + barrel2.y
if event.phase == “began” then
if shooting == false then
shootx = (player[i].x + barrel[i].x)/2
shooty = (player[i].y + barrel[i].y)/2

movex = player[i].x - barrel[i].x
movey = player[i].y - barrel[i].y

shoot = display.newCircle(shootx, shooty, 8)
physics.addBody( shoot, “dynamic”, { radius = 8, isSensor = true } )
shoot.myName = “shoot”

shoot:setLinearVelocity(movex*2, movey*2)
shooting = true
end
end

end
Runtime:addEventListener( “touch”, shoot )

– local whtv[1]mare = display.newCircle( 353, 262.5, 5)

local function text()
myText.text = shootx
myText2.text = shooty

end
Runtime:addEventListener( “touch”, text )

function pizdo()
shoot.x = whtvx
shoot.y = whtvy
end

local function onCol( event )
if event.phase == “began” then
if event.object1.myName == “barrel1” and event.object2.myName == “shoot” then
event.object2:removeSelf()
event.object2 = nil
i = 1
shooting = false
end
if event.object1.myName == “barrel2” and event.object2.myName == “shoot” then
event.object2:removeSelf()
event.object2 = nil
i = 2
shooting = false
end
end
end
Runtime:addEventListener( “collision”, onCol)
[/code] [import]uid: 77199 topic_id: 33470 reply_id: 133015[/import]

Hello Nick,
Do these two posts help solve it for you? If not, I have another method I can explain to you which doesn’t necessarily involve any trig or angle calculation (but it assumes you’re using physics, which I assume you are). Let me know if you need this and I’ll dig up the old forum post I wrote about it.

Brent
[import]uid: 200026 topic_id: 33470 reply_id: 133038[/import]

Hi Brent,

That would be very appreciated. Yes I am using physics. I will try both options and see which works best.

Thank you very much. [import]uid: 165082 topic_id: 33470 reply_id: 133048[/import]

Thank you Rob and hatethinkingofnames.

I will try out the one that hatethinkingofnames has posted and also try out the one Brent is going to post.

Thanks alot guys. [import]uid: 165082 topic_id: 33470 reply_id: 133049[/import]

I use this, works perfectly for me. I use a charge that changes the power depending on how long you hold, you don’t have to use that if you don’t want to, you can just set the power. Also, I use a canShoot boolean, to make sure you don’t shoot again until the bullet hit something, but you can take that away too if you like, just take the if away.

This is my code:

[lua]function shoot(event)
if(canShoot==true) then
if(event.phase == “began”) then
power = 250
Runtime:removeEventListener(“enterFrame”, charge)
Runtime:addEventListener(“enterFrame”, charge)
end
if(event.phase == “ended” or event.phase == “cancelled”) then
Runtime:removeEventListener(“enterFrame”, charge)
local position = character

– Create new bullet
local bullet = createBullet(position.x, position.y)
bullet.isBullet = true

–Calcula las fuerzas en x y en y
catetoX = event.x - position.x
catetoY = event.y - position.y
tangente = math.abs(catetoY/catetoX)
angulo = (math.atan(tangente))

–Angulo en radian
hipotenusa = power
fx = (math.cos(angulo))*hipotenusa
fy = (math.sin(angulo))*hipotenusa

local modx = 1
local mody = 1
if(catetoX<0) then
modx = -1
end
if(catetoY>0) then
mody = -1
end

– Dispara
bullet:applyForce(fx*modx, -fy*mody, bullet.x, bullet.y )
canShoot = false

bullet.collisioned = false
end
end
end

function charge()
if(power>=1300) then
up = false
elseif(power<=250) then
up = true
end
if(up) then
power = power+25
else
power = power-25
end
print(power)
end[/lua] [import]uid: 53195 topic_id: 33470 reply_id: 133051[/import]

I thought there was a bullet module in the Community code, but I couldn’t find it when I went to look. It’s some pretty simple trigonometry math. But I think we need to know a bit more about what you’re trying to do.

How are you planning on moving your bullets? Are you using a transition.to or are you going to use a Runtime enterFrame listener?

I assume you know your origin X, Y and your touch point is your target X, Y. Does your bullet stop there or does it continue off screen if it misses?

Do you need the angle information to draw your bullet at the right angle or is it a small bullet where angle doesn’t matter for drawing?

[import]uid: 199310 topic_id: 33470 reply_id: 133001[/import]

Hello Nick,
OK, if you’re using physics, basically you don’t need to worry about any tricky angle conversion or trig. Why? Because you’re probably going to apply a linear impulse or linear velocity to the bullet… and both of those APIs simply accept X and Y velocity coordinates as their arguments (not an angle).

So, let’s imagine your character is at (0,0) and the user touches the screen at (100,-50). You’d then place the bullet at (0,0) (character location) and then apply the *difference* between the bullet location and the touch location as the X and Y velocities (or impulse) on the bullet. In this simple case, it would just be 100 and -50, but you’d have to calculate the difference each time, because obviously the character isn’t always going to be at (0,0).

Additionally, you need to factor the forces down to a certain ceiling amount. If the character was at (0,0) and the user clicked at (800,-500), the bullet would fire at some hyper-excessive speed. So, you need to basically cap the top force (X or Y) at a certain level and then factor down the other one in the same ratio. I describe that method here…

http://developer.coronalabs.com/forum/2012/09/24/how-set-maximum-force-applied-object

Hopefully this makes sense… if you have any further questions, just let me know.

Brent
[import]uid: 200026 topic_id: 33470 reply_id: 133157[/import]

I actually have my old donkey kong attempt at barrel shooting. It was one of my very first projects so it’s probably pretty bad, but you should be able to get some kinda idea out of it, hopefully lol.

[code]
display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start()
physics.setDrawMode ( “hybrid” )
physics.setGravity( 0, 0 )

shooting = false

local player = {}
local whtv = {}

player[1] = display.newCircle( 280, 250, 10 )
physics.addBody( player[1], “dynamic”, { radius = 10, isSensor = true } )
player[1].isVisible = false

player[2] = display.newCircle( 200, 80, 10 )
physics.addBody( player[2], “dynamic”, { radius = 10, isSensor = true } )
player[2].isVisible = false

local barrel = {}

barrel[1] = display.newRoundedRect( 350, 220, 85, 60, 10 )
barrel[1].strokeWidth = 3
barrel[1]:setFillColor(96, 51, 17)
barrel[1]:setStrokeColor(50, 50, 50)
physics.addBody( barrel[1], “dynamic” )
whtv[1] = display.newRect( 340, 245, 65, 10 )
whtv[1]:rotate ( 88 )
whtv[1]:setFillColor( 0, 0, 0 )
physics.addBody( whtv[1], “dynamic” )

barrel[1].myName = “barrel1”

myJoint = physics.newJoint( “weld”, barrel[1], player[1], (barrel[1].x), (barrel[1].y) )

barrel[2] = display.newRoundedRect( 50, 50, 85, 60, 10 )
barrel[2].strokeWidth = 3
barrel[2]:setFillColor(96, 51, 17)
barrel[2]:setStrokeColor(50, 50, 50)
physics.addBody( barrel[2], “dynamic” )
whtv[2] = display.newRect( 80, 75, 65, 10 )
whtv[2]:rotate ( 88 )
whtv[2]:setFillColor( 0, 0, 0 )
physics.addBody( whtv[2], “dynamic” )

barrel[2].myName = “barrel2”

myJoint = physics.newJoint( “weld”, barrel[2], player[2], (barrel[2].x), (barrel[2].y) )
physics.newJoint( “weld”, barrel[1], whtv[1], barrel[1].x, barrel[1].y )
physics.newJoint( “weld”, barrel[2], whtv[2], (barrel[2].x), (barrel[2].y) )

local myText = display.newText("", 50, 50, native.systemFont, 16)
myText:setTextColor(255, 255, 255)
local myText2 = display.newText("", 150, 150, native.systemFont, 16)
myText2:setTextColor(255, 255, 255)

local function testingz()
barrel[1].angularVelocity = 150
barrel[2].angularVelocity = -150
d = barrel[1].angularVelocity
f = barrel[2].angularVelocity
end
Runtime:addEventListener( “enterFrame”, testingz )

– local function test()
– barrel2.angularVelocity = 0

– end
– Runtime:addEventListener( “touch”, test )
i = 1
local function shoot( event )

– shootx = (player2.x - barrel2.x)/2 + barrel2.x
– shooty = (player2.y - barrel2.y)/2 + barrel2.y
if event.phase == “began” then
if shooting == false then
shootx = (player[i].x + barrel[i].x)/2
shooty = (player[i].y + barrel[i].y)/2

movex = player[i].x - barrel[i].x
movey = player[i].y - barrel[i].y

shoot = display.newCircle(shootx, shooty, 8)
physics.addBody( shoot, “dynamic”, { radius = 8, isSensor = true } )
shoot.myName = “shoot”

shoot:setLinearVelocity(movex*2, movey*2)
shooting = true
end
end

end
Runtime:addEventListener( “touch”, shoot )

– local whtv[1]mare = display.newCircle( 353, 262.5, 5)

local function text()
myText.text = shootx
myText2.text = shooty

end
Runtime:addEventListener( “touch”, text )

function pizdo()
shoot.x = whtvx
shoot.y = whtvy
end

local function onCol( event )
if event.phase == “began” then
if event.object1.myName == “barrel1” and event.object2.myName == “shoot” then
event.object2:removeSelf()
event.object2 = nil
i = 1
shooting = false
end
if event.object1.myName == “barrel2” and event.object2.myName == “shoot” then
event.object2:removeSelf()
event.object2 = nil
i = 2
shooting = false
end
end
end
Runtime:addEventListener( “collision”, onCol)
[/code] [import]uid: 77199 topic_id: 33470 reply_id: 133015[/import]

Hello Nick,
Do these two posts help solve it for you? If not, I have another method I can explain to you which doesn’t necessarily involve any trig or angle calculation (but it assumes you’re using physics, which I assume you are). Let me know if you need this and I’ll dig up the old forum post I wrote about it.

Brent
[import]uid: 200026 topic_id: 33470 reply_id: 133038[/import]

Hi Brent,

That would be very appreciated. Yes I am using physics. I will try both options and see which works best.

Thank you very much. [import]uid: 165082 topic_id: 33470 reply_id: 133048[/import]

Thank you Rob and hatethinkingofnames.

I will try out the one that hatethinkingofnames has posted and also try out the one Brent is going to post.

Thanks alot guys. [import]uid: 165082 topic_id: 33470 reply_id: 133049[/import]

I use this, works perfectly for me. I use a charge that changes the power depending on how long you hold, you don’t have to use that if you don’t want to, you can just set the power. Also, I use a canShoot boolean, to make sure you don’t shoot again until the bullet hit something, but you can take that away too if you like, just take the if away.

This is my code:

[lua]function shoot(event)
if(canShoot==true) then
if(event.phase == “began”) then
power = 250
Runtime:removeEventListener(“enterFrame”, charge)
Runtime:addEventListener(“enterFrame”, charge)
end
if(event.phase == “ended” or event.phase == “cancelled”) then
Runtime:removeEventListener(“enterFrame”, charge)
local position = character

– Create new bullet
local bullet = createBullet(position.x, position.y)
bullet.isBullet = true

–Calcula las fuerzas en x y en y
catetoX = event.x - position.x
catetoY = event.y - position.y
tangente = math.abs(catetoY/catetoX)
angulo = (math.atan(tangente))

–Angulo en radian
hipotenusa = power
fx = (math.cos(angulo))*hipotenusa
fy = (math.sin(angulo))*hipotenusa

local modx = 1
local mody = 1
if(catetoX<0) then
modx = -1
end
if(catetoY>0) then
mody = -1
end

– Dispara
bullet:applyForce(fx*modx, -fy*mody, bullet.x, bullet.y )
canShoot = false

bullet.collisioned = false
end
end
end

function charge()
if(power>=1300) then
up = false
elseif(power<=250) then
up = true
end
if(up) then
power = power+25
else
power = power-25
end
print(power)
end[/lua] [import]uid: 53195 topic_id: 33470 reply_id: 133051[/import]

Hello Nick,
OK, if you’re using physics, basically you don’t need to worry about any tricky angle conversion or trig. Why? Because you’re probably going to apply a linear impulse or linear velocity to the bullet… and both of those APIs simply accept X and Y velocity coordinates as their arguments (not an angle).

So, let’s imagine your character is at (0,0) and the user touches the screen at (100,-50). You’d then place the bullet at (0,0) (character location) and then apply the *difference* between the bullet location and the touch location as the X and Y velocities (or impulse) on the bullet. In this simple case, it would just be 100 and -50, but you’d have to calculate the difference each time, because obviously the character isn’t always going to be at (0,0).

Additionally, you need to factor the forces down to a certain ceiling amount. If the character was at (0,0) and the user clicked at (800,-500), the bullet would fire at some hyper-excessive speed. So, you need to basically cap the top force (X or Y) at a certain level and then factor down the other one in the same ratio. I describe that method here…

http://developer.coronalabs.com/forum/2012/09/24/how-set-maximum-force-applied-object

Hopefully this makes sense… if you have any further questions, just let me know.

Brent
[import]uid: 200026 topic_id: 33470 reply_id: 133157[/import]

Thank guys,

Going to give them a try now, if I don’t come right i’ll let you know.

Thank you for the replies.

Cheers. [import]uid: 165082 topic_id: 33470 reply_id: 133472[/import]

Thank guys,

Going to give them a try now, if I don’t come right i’ll let you know.

Thank you for the replies.

Cheers. [import]uid: 165082 topic_id: 33470 reply_id: 133472[/import]