making a cannon

i have a cannon that rotates when you touch it and i want to launch a cannonball from it when the cannon has a rotation that is more than 40
but i cant seem to get it to work
please help
here is my code
[lua]local launch = display.newImage( “launch.png”, 200, 20)
local ball = display.newImage( “bird.png” )
ball.x = 600; ball.y = 150
physics.addBody( ball, { density = 15,friction=0.5, bounce=0.3, radius=18} )
ball.linearDamping = 0.3
ball.angularDamping = 0.8
ball.isBullet = true – force continuous collision detection, to stop really fast shots from passing through other balls

target = display.newImage( “bird.png” )
target.x = ball.x; target.y = ball.y; target.alpha = 0

local function resetball(event)
local phase = event.phase
if “ended” == phase then
ball:setLinearVelocity( 0, 0 )
ball.angularVelocity = 0
ball.alpha = 0
ball.x = 600
ball.y = 150
ball.xScale = 2.0; ball.yScale = 2.0
ball.bodyType = “static”
local dropBall = transition.to( ball, { alpha=1.0, xScale=1.0, yScale=1.0, time=400 } )
end
end

Reset:addEventListener( “touch”, resetball )
cannon1 = display.newImage( “cannon.png”,575,70 )
cannon1.targetRotation = 0
cannon1.isRotating = false
cannon1.isTouched = false

local checkKeepRot

function rotateObj(obj)
if obj.rotation >= 360 then
obj.rotation = obj.rotation - 360
end
obj.targetRotation = obj.targetRotation + 10
if obj.targetRotation > 90 then
obj.targetRotation = obj.targetRotation - 100

end
–print(“targetRot=”…obj.targetRotation)
transition.to(obj, { time=150, rotation = obj.targetRotation, onComplete=checkKeepRot })
obj.isRotating = true
end

function checkKeepRot(target)
if target.isTouched == true then
rotateObj(target)
else
target.isRotating = false
end
end

function move(event)
if event.phase==“began” then
if cannon1.isRotating == false then
rotateObj(cannon1)
end
cannon1.isTouched = true
end
if event.phase==“ended” then
cannon1.isTouched = false
end
end

function shoot(event)
if event.phase==“began” then
if cannon.rotation > 40 then
ball:applyForce( 500, 200, ball.x, ball.y )
end
end
end
launch:addEventListener(“touch”, shoot)

cannon1:addEventListener(“touch”, move)[/lua] [import]uid: 28068 topic_id: 6457 reply_id: 306457[/import]

thanks in advance [import]uid: 28068 topic_id: 6457 reply_id: 22315[/import]

please help [import]uid: 28068 topic_id: 6457 reply_id: 22424[/import]

A complete, self-contained runnable piece of code would be great. After adding

[lua]physics = require(“physics”)
physics.start()[/lua]

to the start, it errors on a missing global called Reset on this line

[lua]Reset:addEventListener( “touch”, resetball )[/lua]

I changed it to ‘ball’ then found you have ‘cannon’ instead of ‘cannon1’ on this line

[lua]if cannon.rotation > 40 then[/lua]

after changing it to cannon1, it now gets to the ‘shoot’ function [import]uid: 23949 topic_id: 6457 reply_id: 22429[/import]

in the game you make crates and destroy them by shooting a cannonball at then
-i can make crates
-i can destroy them by shooting a cannon ball
-i can rotate the cannon
THE PROBLEM:
i want the force applied on the cannonball to change based on the cannons rotation

p.s.: i updated the code a little
i didn’t post the whole code the first time because it is a little long

[lua]local physics = require(“physics”)
local gameUI = require(“gameUI”)
physics.start()
physics.setGravity( 0, 0 )

–the sky
local sky = display.newImage( “sky.png” )

–the boundries
–bottom
local ground = display.newImage( “ground.png” )
ground.x = 300
ground.y = 1060
physics.addBody( ground )
ground.bodyType = “static”
–top
local ground4 = display.newImage( “ground.png” )
ground4.x = 300
ground4.y = -40
physics.addBody( ground4 )
ground4.bodyType = “static”
–right side
local ground3 = display.newImage( “ground.png” )
ground3.x = 720
ground3.y = 500
physics.addBody( ground3 )
ground3.bodyType = “static”
ground3.rotation = 90

local launch = display.newImage( “down.png” )
launch.x = 125
launch.y = 180
local editButton = display.newImage( “edit.png”, 100, 20)
local Reset=display.newImage(“reset.png”,150, 30)
local boxGenerator = display.newImage( “crate.png”, 100, 960 )
local wallmaker = display.newImage( “wall.png”, 125, 760 )
– Create ball
local function dragBody( event )
local t = event.target

local phase = event.phase
if “began” == phase then
display.getCurrentStage():setFocus( t )
t.isFocus = true

– Store initial position
t.x0 = event.x - t.x
t.y0 = event.y - t.y

– Make body type temporarily “kinematic” (to avoid gravitional forces)
event.target.bodyType = “kinematic”

– Stop current motion, if any
event.target:setLinearVelocity( 0, 0 )
event.target.angularVelocity = 0

elseif t.isFocus then
if “moved” == phase then
t.x = event.x - t.x0
t.y = event.y - t.y0

elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false

– Switch body type back to “dynamic”, unless we’ve marked this sprite as a platform
if ( not event.target.isPlatform ) then
event.target.bodyType = “dynamic”
end

end
end

– Stop further propagation of touch event!
return true
end

function moveCircle( event )
local phase = event.phase

if “ended” == phase then
local function onLocalPostCollision(self, event)
if ( event.force > 55 ) then
boom = display.newImage(“boom.png”)
boom.x = self.x
boom.y = self.y
transition.to( boom, { time=1500, alpha=0, xScale=1.5, yScale=1.5 } )
self:removeSelf()
print( "postCollision force: " … event.force … ", friction: " … event.friction )
end
end

local crate = display.newImage( “crate.png” )
physics.addBody( crate, { density = 5,friction=0.5, bounce=0.3, filter=finish1CollisionFilter } )
crate.x = event.x
crate.y = event.y
crate:addEventListener( “touch”, dragBody )
crate.postCollision = onLocalPostCollision
crate:addEventListener( “postCollision”, crate )

end
end
boxGenerator:addEventListener( “touch”, moveCircle )

function wallMaker( event )
local phase = event.phase

if “ended” == phase then
local function onLocalPostCollision(self, event)
if ( event.force > 35 ) then
boom = display.newImage(“boom.png”)
boom.x = self.x
boom.y = self.y
transition.to( boom, { time=1500, alpha=0, xScale=1.5, yScale=1.5 } )
self:removeSelf()
print( "postCollision force: " … event.force … ", friction: " … event.friction )
end
end
local wall = display.newImage( “wall.png” )
physics.addBody( wall, { density=3.0, friction=0.5, bounce=0.3 } )
wall.x = event.x
wall.y = event.y
wall:addEventListener( “touch”, dragBody )
wall.postCollision = onLocalPostCollision
wall:addEventListener( “postCollision”, wall )
end
end
wallmaker:addEventListener( “touch”, wallMaker )

function gravity( event )
local phase = event.phase

if “ended” == phase then
physics.setGravity ( 10, 0 )

end
end
launch:addEventListener( “touch”, gravity )
function gravityup( event )
local phase = event.phase

if “ended” == phase then
physics.setGravity ( 0, 0 )

end
end
editButton:addEventListener( “touch”, gravityup )

local function editMode(event)

end
editButton:addEventListener( “touch”, editMode)

local launch = display.newImage( “launch.png”, 200, 20)
local ball = display.newImage( “bird.png” )
ball.x = 625; ball.y = 150
physics.addBody( ball, { density = 15,friction=0.5, bounce=0.3, radius=18} )
ball.linearDamping = 0.3
ball.angularDamping = 0.8
ball.isBullet = true – force continuous collision detection, to stop really fast shots from passing through other balls

target = display.newImage( “bird.png” )
target.x = ball.x; target.y = ball.y; target.alpha = 0

local function resetball(event)
local phase = event.phase
if “ended” == phase then
ball:setLinearVelocity( 0, 0 )
ball.angularVelocity = 0
ball.alpha = 0
ball.x = 625
ball.y = 150
ball.xScale = 2.0; ball.yScale = 2.0
ball.bodyType = “static”
local dropBall = transition.to( ball, { alpha=1.0, xScale=1.0, yScale=1.0, time=400 } )
end
end

Reset:addEventListener( “touch”, resetball )
cannon1 = display.newImage( “cannon.png”,600,70 )
cannon1.targetRotation = 0
cannon1.isRotating = false
cannon1.isTouched = false

local checkKeepRot

function rotateObj(obj)
if obj.rotation >= 360 then
obj.rotation = obj.rotation - 360
end
obj.targetRotation = obj.targetRotation + 10
if obj.targetRotation > 90 then
obj.targetRotation = obj.targetRotation - 100
end
–print(“targetRot=”…obj.targetRotation)
transition.to(obj, { time=150, rotation = obj.targetRotation, onComplete=checkKeepRot })
obj.isRotating = true
end

function checkKeepRot(target)
if target.isTouched == true then
rotateObj(target)
else
target.isRotating = false
end
end

function move(event)
if event.phase==“began” then
if cannon1.isRotating == false then
rotateObj(cannon1)
end
cannon1.isTouched = true
end
if event.phase==“ended” then
cannon1.isTouched = false
end
end

local checkKeepRot

function rotateObj(obj)
if obj.rotation >= 360 then
obj.rotation = obj.rotation - 360
end
obj.targetRotation = obj.targetRotation + 10
if obj.targetRotation > 90 then
obj.targetRotation = obj.targetRotation - 100

end
–print(“targetRot=”…obj.targetRotation)
transition.to(obj, { time=150, rotation = obj.targetRotation, onComplete=checkKeepRot })
obj.isRotating = true
end

function checkKeepRot(target)
if target.isTouched == true then
rotateObj(target)
else
target.isRotating = false
end
end

function move(event)
if event.phase==“began” then
if cannon1.isRotating == false then
rotateObj(cannon1)
end
cannon1.isTouched = true
end
if event.phase==“ended” then
cannon1.isTouched = false
end
end
function shoot(event)
if event.phase==“began” then
ball:setLinearVelocity( 0, 0 )
ball.angularVelocity = 0
ball.alpha = 0
ball.x = 600
ball.y = 150
ball.xScale = .8; ball.yScale = .8
local dropBall = transition.to( ball, { alpha=1.0, xScale=1.0, yScale=1.0, time=40 } )
physics.setGravity( 10, 0 )
ball.bodyType = “dynamic”
ball:applyForce( -000, 30000, ball.x, ball.y )
boom = display.newImage(“boom.png”)
boom.x = 625
boom.y = 150
transition.to( boom, { time=1500, alpha=0, xScale=1.5, yScale=1.5 } )
print( "postCollision force: " … event.force … ", friction: " … event.friction )
end
end
launch:addEventListener(“touch”, shoot)
cannon1:addEventListener(“touch”, move)
[/lua] [import]uid: 28068 topic_id: 6457 reply_id: 22436[/import]

What is it supposed to do? Could you please state your exact problem, i.e. what is going wrong? Possible to attach the entire project including assets (images)? [import]uid: 23949 topic_id: 6457 reply_id: 22427[/import]

Sounds like a math problem. I had a similar issue, but I solved it. I will post my code when I get off work.
What I did was I created an invisible cannonball that follows the cannon rotation
Then when I press fire, I create another ball from the invisible cannonball’s location.

The tricky part is the applyForce. I have the code, but it’s at home, lol.

[import]uid: 12455 topic_id: 6457 reply_id: 22445[/import]

thanks
i have been stuck on this forever [import]uid: 28068 topic_id: 6457 reply_id: 22464[/import]

it would be really nice if you could post the code :slight_smile: [import]uid: 28068 topic_id: 6457 reply_id: 22531[/import]

HEEEEEEEELLLLLLLLLPPPPPPPPPPP
HEEEEEELP
HHHHHHELP
HELLLLLLP
HELPPPPPP [import]uid: 28068 topic_id: 6457 reply_id: 22811[/import]

Have you looked at the Ghosts vs Monsters sample? [import]uid: 12108 topic_id: 6457 reply_id: 22816[/import]

I putted the applyForce directly in my cannonball function.
Yours might be different, but here’s my code.

I created a cannonball and placed it at the tip of the cannongun. I made the cannonball invisible and made it follow the cannongun as it rotates up and down. When the player hits the firebutton, a new steelball will spawn from the cannonball location.

My game is differnt from yours so my code might not work for yours, but I hope it helps you out.

[lua]local cannonSteelBall = function (event)
– steelball = display.newImage ( “steelball.png”)
steelball = display.newCircle(0, 0, 12.5)
steelball:setFillColor( 80, 80, 55, 255)
physics.addBody(steelball, “dynamic”, { density = 0.55, friction = 0.1})
steelball.objectName = “steelball”
steelball.x = cannonball.x
steelball.y = cannonball.y
steelball.rotation = cannonball.rotation
steelball.isVisible = true
steelball.isBullet = true
steelball.isBodyActive = true

levelGroup:insert(steelball)
gameGroup:insert(levelGroup)

– R is Range (Higher Number means cannonball will shoot further/faster)
local R = 370

local xForce = R - (((180 - cannongun.rotation)/90) * R)
local yForce = R * ((cannongun.rotation - 180)/180)

steelball:applyForce( xForce, yForce, steelball.x, steelball.y)

steelball.collision = onDragonCollision
steelball:addEventListener(“collision”, steelball)

end [import]uid: 12455 topic_id: 6457 reply_id: 23169[/import]

could you please explain the calculations below?
[lua]-- R is Range (Higher Number means cannonball will shoot further/faster)
local R = 370

local xForce = R - (((180 - cannongun.rotation)/90) * R)
local yForce = R * ((cannongun.rotation - 180)/180)

steelball:applyForce( xForce, yForce, steelball.x, steelball.y)[/lua] [import]uid: 22024 topic_id: 6457 reply_id: 23214[/import]

sure.

[lua] cannongun.rotation = 180 – default

my cannongun is facing right and it can rotate from 180 to 90
degree.

180 degree means the cannongun is pointing rightward
90 degree means the cannongun is pointing upward.[/lua][text]
if you do the math, as the cannongun rotates upward, xForce is
getting weaker, and yForce is getting stronger.

example: I dont want the cannonball to shoot rightward
if my cannongun is pointing upward. [import]uid: 12455 topic_id: 6457 reply_id: 23406[/import]

hmm, this is different than what i want to do.

i posted it in different topic but anyways,

if the player touches the cannon and moves around the screen, it should calculate the rotation also calculate how far he touched the screen from canon. when he touching ended it should create a new bulletObj and applyForces(xForce, yForce) to it with rotation value.

i did some part of it, but when player touches far from canon it calculates wrong.

these are the images which should clear your mind:
http://img25.imageshack.us/img25/9978/29066137.png
http://img683.imageshack.us/img683/2980/76339418.png

this is the code that i tried.

[lua]local onTouch = function( event )
local t = event.target

local phase = event.phase

local x,y = t:localToContent( t.x - t.xOrigin, t.y - t.yOrigin )
local dx = event.x - x
local dy = event.y - y
local angle = math.atan2( dy, dx )

if “began” == phase then

display.getCurrentStage():setFocus( t )
t.isFocus = true
t.xStart = t.x
t.yStart = t.y
t.angleStart = angle
t.rotationStart = t.rotation

t:stopAtFrame(1)
elseif t.isFocus then
if “moved” == phase then

local pi = math.pi
local delta = (angle - t.angleStart)
delta = delta * 180 / pi
t.rotation = t.rotationStart + delta
–print("event.x: " … event.x … ", event.y: " … event.y … " , t.x: " … t.x … ", t.y: " … t.y)
elseif “ended” == phase or “cancelled” == phase then

display.getCurrentStage():setFocus( nil )
t.isFocus = false

local bulletObj = display.newImageRect(“media/bulletObj.png”, 30, 2)
bulletObj.x = t.x
bulletObj.y = t.y
bulletObj.rotation = t.rotation
physics.addBody(bulletObj, { isSensor=“true”, friction=5, density=5 })
gameGroup:insert( bulletObj)

local distanceBetween = mCeil(mSqrt( ((dy) ^ 2) + ((dx) ^ 2) ))
print(distanceBetween)

–this is where i got stuck
local xForce = (event.x - t.x) * 1.75
local yForce = (event.y - t.y) * 1.75

bulletObj:applyForce(xForce, yForce, bulletObj.x, bulletObj.y )
end
end
return true
end[/lua]
[import]uid: 22024 topic_id: 6457 reply_id: 23431[/import]

Hey Teex84,

I have a tank with a turret on top (separate images) and I am trying to figure out how to have the turret pivot or rotate around a center point of the tank by dragging the turret with my finger. (Does that make sense?)

Do you know how I would go about coding that? [import]uid: 46629 topic_id: 6457 reply_id: 33780[/import]