Spinning / Moving Physics Object

Hi All,

I’m having some issues at the moment with a physics body in a game I’m working on. Basically the idea is I have a fan which is spinning which has a physics body set up on it. I want to have this fan moving on the screen (could be moving in any direction) as well as spinning at the same time. The issue I’m having is if I use a transition to rotate the fan when an object collides with it, it doesn’t bounce away correctly it kind of sticks to the object.

I did a bit of reading around the place and seen that you can use motors to get a similar effect. I tried this which worked great as far as physics goes, but when the object moves side to side the fans rotation speed isn’t constant and will change depending where in the animation it is.

To move the fan side to side I have a loop which moves through different transitions which looks like this:-

--Object Animation  
function animateScreenObject(screenObj)  
 animStep = screenObjects[screenObj]['animationStep']  
 animXpos = screenObjects[screenObj]['animation'][animStep \* 3 + 2] + (screenObjects[screenObj]['width'] / 2)  
 animYpos = screenObjects[screenObj]['animation'][animStep \* 3 + 3] + (screenObjects[screenObj]['height'] / 2)  
 animSpeed = screenObjects[screenObj]['animation'][animStep \* 3 + 1] + 0  
 screenObjects[screenObj]['animationStep'] = screenObjects[screenObj]['animationStep'] + 1  
 if screenObjects[screenObj]['animationStep'] \>= #screenObjects[screenObj]['animation'] / 3 then  
 screenObjects[screenObj]['animationStep'] = 0  
 end  
 loopAnimation = function()  
 animateScreenObject(screenObj)  
 end  
 screenObjects[screenObj]['transition'] = transition.to(screenObjects[screenObj]['object'], {x = animXpos, y = animYpos, time = animSpeed, onComplete = loopAnimation, transition=easing.inQuad })  
 screenObjects[screenObj]['object']['transition'] = screenObjects[screenObj]['transition']  
end  

To set up the motor I have this (please note, I don’t full understand how motors work… I have a feeling I could possibly use this method just need to change something here)

screenObjects[#screenObjects]['object'].bodyType = 'dynamic'  
screenObjects[#screenObjects]['joint'] = physics.newJoint( "pivot", anchor, screenObjects[#screenObjects]['object'], screenObjects[#screenObjects]['object'].x, screenObjects[#screenObjects]['object'].y )  
screenObjects[#screenObjects]['joint'].maxMotorTorque = 10  
screenObjects[#screenObjects]['joint'].motorSpeed = -200  

This method the physics seems to work better (so bounces off the blades correctly) but the blade speed is constantly changing through out the animation between positions. I thought it could have been the position relative to the joint, so I created a joint which moves with the object but it had the same affect unfortunately.

The test I’m doing for rotations at the moment is just

transition.to(screenObjects[#screenObjects]['object'], {rotation = -8000,time = 100000})  

It’s very primitive I know… I originally had some code which handled it much better but took it out as using this system when an object collides with it, it will stick to it and not bounce off correctly.

I was going to make a video of it, but unfortunately I’m running late for work. Thought I’d post this for now and see if anyone can offer any suggestions as to what I can do to get this working properly. I’m only knew to corona and I’m sure I’m over looking something simple… Unfortunately I just can’t figure out what it could be looking at examples / documentation / forums at the moment. If anyone can point me in the right direction, it would be greatly appreciated!

Thanks in advance,
Stevil [import]uid: 133056 topic_id: 28249 reply_id: 328249[/import]

Okay here are some videos to show what I mean, if you look at the first one which shows how the fan re-acts as a motor

http://imstevil.com/motor/

You can see that the fan slows down at the end of the transition rather than spinning at a constant speed (which is the desired results). And here is the link to the system using a transition

http://imstevil.com/transition/

I don’t record the movement animation as it’s fine, it’s constantly spinning but you can see the obvious issue with the collision with it.

Anyone have any suggestions as to what I could do for this?

Again, thanks in advance! [import]uid: 133056 topic_id: 28249 reply_id: 114169[/import]

I have a feeling if I want to go with a motor I should be trying another type of motor type, possibly a wheel maybe?

I’ve gone back to try some things with just the normal rotation system, and put a print statement on the collision event and it’s only got the one collision with the fan despite being stuck to it that entire time.

Here is a quick sample of some code that shows exactly whats happening using the normal rotation method (code is way to messy from my game to post that here!)

local physics = require "physics"  
physics.start()   
physics.setDrawMode('hybrid')  
  
ball = display.newCircle(150, 0, 20)  
physics.addBody(ball, "dynamic", {radius = 20})  
  
board = display.newRect(20,20,200,10)  
board.x=150  
board.y=400  
physics.addBody(board, "static")  
  
transition.to(board, {rotation = 500, time = 3000})  

[import]uid: 133056 topic_id: 28249 reply_id: 114182[/import]

_"http://imstevil.com/transition/

I don’t record the movement animation as it’s fine, it’s constantly spinning but you can see the obvious issue with the collision with it.

Anyone have any suggestions as to what I could do for this?"_

To me this looked really good beyond the collision issue you mentioned - I wonder if perhaps this is due to the shape of your physics bodies. Could we see a video like this with physics draw mode set to hybrid, please?

Peach :slight_smile: [import]uid: 52491 topic_id: 28249 reply_id: 114204[/import]

Hi Peach,

Thanks for replying! I’m not 100% sure it would be the shape of it, if you look at the example code I posted above, it’s just a rotating flat surface and it has the same problem. Just incase I have attached a video though:-

http://imstevil.com/transitionv2/

This one you can see the animation a bit better and but doesn’t show it sticking as well… can still see it sticking though.

I’m guessing the issue when just using a rotation like that, it wouldn’t actually apply the force of the rotation despite the fact it’s rotating. When it hits, it probably just assumes that it’s hitting an object at what ever the current angle is. I have tried stopping the transition and letting it bounce and then starting the transition again, but that isn’t ideal as it doesn’t apply the force of the fan an looks a bit jittery.

I have a feeling this is why motors would work better, I believe they apply the force to the object when rotating. As I’m new to all of this, I’m not sure which way to go with the joints to get this to work correctly.

I think ideally what I want is the motor effect on a single object, without having to setup a joint on it… or making a joint which won’t actually affect the rotation when I use transition.to to move the object.

I’m sure there is probably an easy way to do it, but being a n00b the solution is eluding me at the moment :frowning: [import]uid: 133056 topic_id: 28249 reply_id: 114239[/import]

Hey again Stevil,

It looks like you made the shape perfectly - before giving a motor joint another go one thing I’d suggest is reading the section about “sticking” in this blog post to see if it helps; http://www.coronalabs.com/blog/2011/08/08/solutions-to-common-physics-challenges/

If not, perhaps you might provide some plug and play with a circle and an object shaped like the blades (doesn’t have to look like it, just same body shape) that people could have a play with to see if they can get the joint working as you wish?

Peach :slight_smile: [import]uid: 52491 topic_id: 28249 reply_id: 114283[/import]

Hi Peach,

Thanks for that, I tried the things in there but it’s not going to work exactly how I want. Going to be to hard to apply the force in the way the fan is actually spinning and the angles on the fan blades.

After playing with motors a bit I’ve realized the physics body actually affects the the rotation of it. I would have thought it would have just rotated at the center, but apparently not. When I use a perfect square, or a perfect circle, the animation while it moves works great, but as soon as I go a custom shape which might be a bit unbalanced / off centered the movement animation becomes unstable.

I guess one option I have is making the fan 4 bladed and then have it with a balanced physics body… You can see this working here (just use any image for the fan, cna see the physics body still):-

--Sets Up Physics  
local physics = require "physics"  
physics.start()   
physics.setDrawMode('hybrid')  
  
--Sets Up Board   
board = display.newImageRect("fan.png",80,80)  
  
--fanShape = {0,-37, 37,-10, 23,34, -23,34, -37,-10 }  
--fanShape = {-5,-37, 25,-37, 5, 37,-5, 37}  
fanShape = {}  
fanShape[1] = {-5,-37, 5,-37, 5, 37,-5, 37}  
fanShape[2] = {-37,-5, 37,-5, 37, 5,-37, 5}  
physics.addBody(board, "dynamic",{shape=fanShape[1]}, {shape=fanShape[2]})  
board.x=150  
board.y=400  
  
--Sets Up Ball  
function dropBall()  
 ball = display.newCircle(board.x, 0, 20)  
 physics.addBody(ball, "dynamic", {radius = 20})   
end  
timer.performWithDelay(2000, dropBall, 0 )  
  
--Sets Up Anchor Point  
anchor = display.newRect(150,-30,1,1)  
physics.addBody(anchor, "static")  
  
--Sets Up Joint / Motor  
joint = physics.newJoint("pivot", board, anchor, board.x, board.y)  
joint.maxMotorTorque = 10000  
joint.motorSpeed = -200  
  
--Moves Blade  
function topRight()  
 transition.to(board, {x=300,y=30,time=4000,onComplete=bottomRight})  
end  
function bottomRight()  
 transition.to(board, {x=300,y=430,time=4000,onComplete=bottomLeft})  
end  
function bottomLeft()  
 transition.to(board, {x=30,y=430,time=4000,onComplete=topLeft})  
end  
function topLeft()  
 transition.to(board, {x=30,y=30,time=4000,onComplete=topRight})  
end  
topRight()  

Despite this working, I’d rather know how to fix it rather than just ignoring the problem and going another way. I’m sure this is something I will come across in future games / projects. I’m trying to google / forum search for a solution to motors with custom physics bodies but can’t find anything. If anyone knows of the right direction to point me in for this it would be a great help! I’ll keep search to see if I can find anything, if I can I’ll post it back here =)

Stevil [import]uid: 133056 topic_id: 28249 reply_id: 114367[/import]

Hi Stevil,

I had a go, and still learning physics myself. I think by replacing the transition move with a touch joint, you can remove the stickiness, but it seems to add a bounce effect. Seems everything I tried fixed something but created more issues:

[lua]display.setStatusBar(display.HiddenStatusBar)

local physics = require “physics”
physics.start()
physics.setDrawMode(‘hybrid’)
– Rotate a coordinate around the origin
local function angleVectorX(vx, vy, va)
local angle = va * math.pi / 180
return vx * math.cos(angle) - vy * math.sin(angle)
end
local function angleVectorY(vx, vy, va)
local angle = va * math.pi / 180
return vx * math.sin(angle) + vy * math.cos(angle)
end
– Some polygons for our fan shape
local poly_shapes = {
{ – 60 degree fan blade
0, 0,
angleVectorX(10, 0, 0), angleVectorY(10, 0, 0),
angleVectorX(50, -5, 60), angleVectorY(50, -5, 60),
angleVectorX(50, 5, 60), angleVectorY(50, 5, 60),
angleVectorX(10, 0, 120), angleVectorY(10, 0, 120),
},
{ – 180 degree fan blade
0, 0,
angleVectorX(10, 0, 120), angleVectorY(10, 0, 120),
angleVectorX(50, -5, 180), angleVectorY(50, -5, 180),
angleVectorX(50, 5, 180), angleVectorY(50, 5, 180),
angleVectorX(10, 0, 240), angleVectorY(10, 0, 240),
},
{ – 300 degree fan blade
0, 0,
angleVectorX(10, 0, 240), angleVectorY(10, 0, 240),
angleVectorX(50, -5, 300), angleVectorY(50, -5, 300),
angleVectorX(50, 5, 300), angleVectorY(50, 5, 300),
angleVectorX(10, 0, 360), angleVectorY(10, 0, 360),
},
{ – 240 degree fan blade
0, 0,
angleVectorX(10, 0, 180), angleVectorY(10, 0, 180),
angleVectorX(50, -5, 240), angleVectorY(50, -5, 240),
angleVectorX(50, 5, 240), angleVectorY(50, 5, 240),
angleVectorX(10, 0, 300), angleVectorY(10, 0, 300),
},
{ – A regular pentagon
angleVectorX(0, -37, 0), angleVectorY(0, -37, 0),
angleVectorX(0, -37, 72), angleVectorY(0, -37, 72),
angleVectorX(0, -37, 144), angleVectorY(0, -37, 144),
angleVectorX(0, -37, 216), angleVectorY(0, -37, 216),
angleVectorX(0, -37, 288), angleVectorY(0, -37, 288),
},
}

– A stationary spinning fan
local poly_fan1 = display.newCircle(display.contentCenterX, display.contentCenterY * 0.5, 10)
physics.addBody(poly_fan1, “kinematic”,
{shape = poly_shapes[1], bounce = 1},
{shape = poly_shapes[2], bounce = 1},
{shape = poly_shapes[3], bounce = 1}
–{shape = poly_shapes[4], bounce = 1},
–{shape = poly_shapes[5], bounce = 1},
)
poly_fan1.angularVelocity = 300

– A moving spinning fan
local poly_fan2 = display.newCircle(display.contentCenterX, display.contentCenterY * 1.5, 10)
physics.addBody(poly_fan2, “dynamic”,
{shape = poly_shapes[1], bounce = 1},
{shape = poly_shapes[2], bounce = 1},
{shape = poly_shapes[3], bounce = 1}
–{shape = poly_shapes[4], bounce = 1},
–{shape = poly_shapes[5], bounce = 1},
)

– An anchor for our moving/spinning fan
local anchor = display.newCircle(display.contentCenterX, display.contentCenterY * 1.5, 10)
physics.addBody(anchor, “dynamic”, {radius = 10})
anchor.isFixedRotation = true

– A motor between our anchor and fan
local j = physics.newJoint(“pivot”, anchor, poly_fan2, display.contentCenterX, display.contentCenterY * 1.5)
j.isMotorEnabled = true
j.maxMotorTorque = 100000
j.motorSpeed = 400

– Apply physics movements to the anchor
anchor.moveJoint = physics.newJoint(“touch”, anchor, anchor.x, anchor.y)
anchor.moveJoint.dampingRatio = 1
function poly_left()
anchor.moveJoint:setTarget(display.contentWidth * 0.25, display.contentCenterY * 1.5)
timer.performWithDelay(2000, poly_right)
end
function poly_right()
anchor.moveJoint:setTarget(display.contentWidth * 0.75, display.contentCenterY * 1.5)
timer.performWithDelay(2000, poly_left)
end
timer.performWithDelay(2000, poly_left)

– Auto dropping ball
local ball = display.newCircle(display.contentCenterX, 5, 10)
physics.addBody(ball, {radius = 10})

function ballResurrect()
ball.x = 120 --math.random(0.25 * display.contentWidth, 0.75 * display.contentWidth)
ball.y = 5
ball:setLinearVelocity(0, 0)
end
timer.performWithDelay(2000, ballResurrect, 0)[/lua] [import]uid: 154787 topic_id: 28249 reply_id: 114406[/import]

If you actually edit lines, 65, 66, 67 (stationary spinning blades) and line 118 (the ball) to edit bounce to be 0.1 in each instance I believe this should fix that crazy bounce :wink: [import]uid: 52491 topic_id: 28249 reply_id: 114442[/import]

I got it working when going left to right, but when I started going in a full square it’s still slowing down unfortunately.

I’m actually friends with G81 and we’ve been discussing this over skype for the last couple of days. This is the first chance I’ve had to look at his example though. Seems to work okay, but the movement speed of fan is going to be too hard to control.

The “isFixedRotation” could possibly be the key, when I apply it to my object it stops spinning all together. But it sounds exactly like what I’m looking for:-

A boolean for whether the rotation of the body should be locked, even if the body is under load or subjected to off-center forces. The default is false.

Reading that, in theory it should just be a matter of setting this to true… but obviously a bit more involved in that. I’ll look into it and see how I go, if I figure anything out I’ll post it back here for reference, in the mean time, if anyone knows anymore about this an can point me in the right direction I’d appreciate it! [import]uid: 133056 topic_id: 28249 reply_id: 114552[/import]

Okay… I’ve just tried something interesting which has seemed to have worked. It’s a bit of a strange solution, and possibly not ideal, but it seems to have worked. What I have done is enabled the motor and set it’s speed to 0, and then I’m using a transition to rotate it. So effectively a combination of both, which I’m pretty surprised I haven’t tried up until this point.

You can see in the video it’s still not ideal by any means… but considering how much hair I’ve pulled out an complex solutions I’ve looked into, this is easy enough for me to walk away an forget about it for awhile :wink:

http://imstevil.com/fixed/
[import]uid: 133056 topic_id: 28249 reply_id: 114559[/import]

That looks good - a PitA workaround, but very good!

Glad to hear you guys have been able to chat over Skype about this, it helps to have a second set of eyes at times.

Fixed rotation is used namely to keep an object from rotating so yeah, not quite right in this case.

Unrelated, I like your artwork - colorful and cartoony! [import]uid: 52491 topic_id: 28249 reply_id: 114568[/import]

Yeh, reading up i wad wrong in what i was thinking. i’m sure there is a better way to do this i’m just not sure i care at the moment :wink: i’ll keep it in mind for future games.

Thanks for the compliment about the gfx, i actually hired someone to do them.spent a bit of money on the project to try an make sure i hit the groung running with web apps. hopefully i can at least break even with this one!

As for the original issue, if g81 or i come up with a better solution we’ll post it here. im sure someone will be looking to do similar to this in the future [import]uid: 133056 topic_id: 28249 reply_id: 114580[/import]

Hey,

Would love to hear it if either of you come up with something, though I hope to have a proper go at it myself whenever I next get some downtime. (It’s a rare occurrence ;))

I think the graphics look great and were a good investment, I wish you the best of luck with, at the very least breaking even - though naturally I hope you do a bit better than that :wink:

Peach :slight_smile: [import]uid: 52491 topic_id: 28249 reply_id: 114647[/import]