Slingshot like Angry Birds?

I have a serious kinky side for games like Angry Birds et.c. where you shoot stuff at other stuff using a slingshot mechanism.

I’ve been playing around using joints and also the simple pool example. Can’t really get it to work…

Someone out there who have an example of the slingshot mechanism where the bulletobject is pulled back by a finger drag and when released catapulted in the opposite direction?

/Rickwhy [import]uid: 10657 topic_id: 3277 reply_id: 303277[/import]

It’s not a real catapult.

You can apply a force to an object

You calc distance and angle from catapult origin and use those values to setup a physics impulse in the opposite direction [import]uid: 5354 topic_id: 3277 reply_id: 9806[/import]

Yeah I know that! I got it working using the “Simple Pool” example thats included

It’s shoots perfectly just like I want. Ok lets change the subject a little…
Everything is in a “game”-group used for moving the camera. But this is the problem:

myLine = display.newLine( t.x,t.y, event.x,event.y )
game:insert(myLine)

It’s acting really weird, it’s not following the touch. I’ve think after reading around the forum it’s the group thats messing up the coordinates. How can I fix this?

Like this:

[code]-- Shoot the cue ball, using a visible force vector
local function cueShot( event )
local t = event.target

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

– Stop current cueball motion, if any
t:setLinearVelocity( 0, 0 )
t.angularVelocity = 0

target.x = t.x
target.y = t.y

startRotation = function()
target.rotation = target.rotation + 4
end

Runtime:addEventListener( “enterFrame”, startRotation )

local showTarget = transition.to( target, { alpha=0.4, xScale=0.4, yScale=0.4, time=200 } )
myLine = nil

elseif t.isFocus then
if “moved” == phase then

if ( myLine ) then
myLine.parent:remove( myLine ) – erase previous line, if any
end

myLine = display.newLine( t.x,t.y, event.x,event.y )

game:insert(myLine)

myLine:setColor( 255, 255, 255, 100 )
myLine.width = 8
elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false

local stopRotation = function()
Runtime:removeEventListener( “enterFrame”, startRotation )
end

local hideTarget = transition.to( target, { alpha=0, xScale=1.0, yScale=1.0, time=200, onComplete=stopRotation } )

if ( myLine ) then
myLine.parent:remove( myLine )
end

– Strike the ball!
boulder.bodyType = “dynamic”
t:applyForce( (t.x - event.x), (t.y - event.y), t.x, t.y )
end
end

– Stop further propagation of touch event
return true
end

boulder:addEventListener( “touch”, cueShot )
[/code] [import]uid: 10657 topic_id: 3277 reply_id: 9807[/import]

Ok

I think I can see whats going on from the description

Try having the touch object as a part of the group, so for instance the catapult basket or the “ammo” then you can get the current x / y of that object which is in the group.

I think the event x and y you are using better describe the screen co-ordinates than whats happening in the group [import]uid: 5354 topic_id: 3277 reply_id: 9810[/import]

Thank you Matthew, that sounds about right!

How would I rewrite to do that? Sorry about having you point me all the way :S I really appreciate it!! [import]uid: 10657 topic_id: 3277 reply_id: 9812[/import]

Oh wait!

The event.x isn’t that where my finger is?

This works like I put my finger on the boulder(the object that’s going to fly away) and from the boulder there goes a line to where my finger is like a force line.

The force line is acting weird which I think is because of the group is messing up the coordinates. Hope I made it a bit clearer… [import]uid: 10657 topic_id: 3277 reply_id: 9813[/import]

I think there is a drag on touch example with the simulator. (sorry at work at the mo so cant do any code)

Otherwise I would need to have a play with your code to experiment, see whats happening. [import]uid: 5354 topic_id: 3277 reply_id: 9814[/import]

but the boulder does move correctly?

if so take boulder.x and boulder.y instead of where the touch is [import]uid: 5354 topic_id: 3277 reply_id: 9815[/import]

also are you putting the line in the group as well? [import]uid: 5354 topic_id: 3277 reply_id: 9816[/import]

The boulder is shooting away fine!

When the line is not put in the group it’s acting as it should except that it is not being displayed from the boulder.

When put in the group it’s displayed from the boulder but it’s acting weird. Can’t really describe it.

Would be excellent if you woul’d like to have a look at the whole code? Should I put the whole code in here? [import]uid: 10657 topic_id: 3277 reply_id: 9818[/import]

email it to me matt at mattpringle.co.uk

will probably be this evening though…

What I would say though is the event.x and event.y are screen coordinates, so 320,480 would be the bottom right of the screen.

In the group x=320 and y=480 wont be the bottom of the screen if the group is moved.

Use the print function and read back the x and y values and see it there is an off set from what the coords should be and what they say there are

(Its probably just a case of transforming a few values to take the offset of the group [import]uid: 5354 topic_id: 3277 reply_id: 9819[/import]

Thanks a lot Matt!

I’ve sent you an email, I’ll keep trying to figure this out meanwhile! [import]uid: 10657 topic_id: 3277 reply_id: 9820[/import]

Ok had a quick look and a few pointers

–game.y = -10
–game.x = 100
–game.xScale = 0.7
–game.yScale = 0.7

the weird behaviour is coming from the scaling and translation of the game group

If you remove the scale and the x , y transition the ball and line will line up correctly.

In my mind to accomplish what you want to do, especially with scale involved, would you need to transform between the touch x and y and the inner game group x and y when scaled and moved. This would be accomplished with a bit of sin / cos manipulation of the original coordinates and where they should be. [import]uid: 5354 topic_id: 3277 reply_id: 9823[/import]

Excellent Matt!

The target and shooting mechanism is working now…

But the final question would be how do I move the camera?

Should I put everything in a new master group and move that? [import]uid: 10657 topic_id: 3277 reply_id: 9824[/import]

Ah that didn’t do it of course… it’s just recreating the problem… sorry about that!

[import]uid: 10657 topic_id: 3277 reply_id: 9825[/import]

It works to a point…

The problem of the group and the screen coordinates will still exist though, the above will only fix it for the setup if nothing is moved or scaled

Your next step would be to work out how to convert between the screen coordinates (what the event.x and event.y) read back and the actual co-ordinates in the scaled and translated group

If you ball is in a group and its position is x=100

you move the group x=-100

the ball is still at x=100 but on the screen it is now as x=0 (what the event reports)

so simply you take the group x, add it to the ball x and you get the screen x of the ball, so you can go the other way was well, 0 screen x is 100 in the groups world

add scaling in there as well and things get complicated. the distance would no longer be 100 but 100*scale of the group.

Once you have figured that out the game will be playable
[import]uid: 5354 topic_id: 3277 reply_id: 9826[/import]

Alright cool!
I got it working so the main group isn’t moving until the boulder is on it’s way. So the shooting now works.

Just gonna try and find out how I can use the boulders speed to set the scale/zoomOut of the main group.
I want it to zoom/scale out when the boulder is travelling fast!

I post my findings here if I get it to work!

Thanks for all your help!

[code]
local function moveCamera()
if (boulder.x > 230 and boulder.x < 3100) then
game.x = -boulder.x + midX

end

end

Runtime:addEventListener( “enterFrame”, moveCamera )

local function moveCamera2()
if (boulder.y > 0 and boulder.y < 190) then
game.y = -boulder.y + midY

end

end

Runtime:addEventListener( “enterFrame”, moveCamera2 ) [import]uid: 10657 topic_id: 3277 reply_id: 9832[/import]

Sweet

get the linear velocity of the boulder

vx, vy = boulder:getLinearVelocity()

to a Pythagorus conversion of the x and y,

speed = math.square( (vx*vx) + (vy*vy) )

this speed will give you an idea of how fast the ball is moving

you can then, I dont know, something like (bad code)

local speedZoomLimit = 3  
if speed \> speedZoomLimit then  
 zoom = 1 - ( speed / 10 )  
else  
zoom = 1  
end  

now I cant sell what the speed will be so /10 might not be enough, its something you would need to refine [import]uid: 5354 topic_id: 3277 reply_id: 9833[/import]

bear in mind the bird’s y position also affects the zoom level… [import]uid: 6645 topic_id: 3277 reply_id: 10131[/import]

how do you make it so the boulder is “flingable” again? [import]uid: 21962 topic_id: 3277 reply_id: 20543[/import]