Physics object - "snap back into place"?

I’m interested in creating some logic that makes a moved physics object want to “snap back” into place.

For instance, if the player(a physics object themselves) bumps into and pushes a physics object of this nature, that it would have an “elastic” feel and work counter to the force exerted by the player.

I’ve set something up right now where an “ended” collision event transitions the object back to it’s start location. This works OK for getting the object back to its original position, but this doesn’t give any resistance to the actual movement of the object when the player object pushes on it.

Please let me know if anyone has any thoughts on how to attempt this. Maybe there’s an existing API solution?

Thanks :slight_smile: [import]uid: 105707 topic_id: 28630 reply_id: 328630[/import]

You might work with the ‘dragBody’ function in ui.lua, see how they do that, and then add an eternal joint (equivalent to your touch point) to the object

binc [import]uid: 147322 topic_id: 28630 reply_id: 115461[/import]

Elaborating on binc’s suggestion, the idea is to create a touch joint (http://developer.coronalabs.com/content/game-edition-physics-joints#Touch_joint) between the object and the coordinates it should snap to. Presumably, those coordinates are wherever the object is initially created. You could/should create the joint immediately after the object itself is created.

Once you create the joint, experiment with its maxForce and frequency properties to get the level of resistance you’re looking for.

  • Andrew [import]uid: 109711 topic_id: 28630 reply_id: 115466[/import]

@binc and @aukStudios

Thank you for the insight, this is very helpful regarding the idea of using an external joint. I had been looking at ui.lua already today regarding the dragBody functionality so that’s too bad I didn’t make a connection related to this!

Thanks for the specifics as well (the dragBody function, recommendations regarding the joint and the properties to look at) :slight_smile: [import]uid: 105707 topic_id: 28630 reply_id: 115479[/import]

This is neat, I was able to quickly set up the touch joint. All is well, but I’ve got this weird thing where any physics object that pushes against my test object (my player or some other physics objects) gets a continuous translation force applied to it so that they move at a constant rate away from the test object.

I’ve not set any of the maxForce or frequency properties so I’m not sure if that will solve the problem.

Are there any basic physics properties I might be missing on my objects?

So close to getting the desired effect… looking forward to solving this :slight_smile: [import]uid: 105707 topic_id: 28630 reply_id: 115491[/import]

OK, I’ve attempted setting parameters on the joint as well as working with parameters on the physics bodies and have had no luck solving this translational force “effect” from touching the test object with the player object. Even more interesting is that if my PC takes on this force and then touches a different, non test, physics object, then it too starts moving constantly with the same vector direction. It’s “contagious”!

If it were only my player that continued to move I would think it related to my movement logic but since the other, non player, objects take on the force, that’s weird…

[import]uid: 105707 topic_id: 28630 reply_id: 115496[/import]

Hi there,

That does sound weird at first, but as I try to picture what you’re describing, I’m starting to think it sounds like normal behavior. Let me try to describe what I’m picturing, and let me know if this is not what’s going on.

What I’m imagining is something like a billiard table viewed from above. There is no gravity (since we’re viewing it from above, the gravity is “into” the screen, not down.) Your “billiard balls” are the player and various other objects, which move around and sometimes collide with each other. The so-called “test object” is the one with the snap-back behavior via the touch joint.

So, imagine the player collides with the test object. Two things could happen. First, depending on their relative masses and the bounce properties of the player and the test object, the player could just bounce off. Second, if the player is moving fast enough and has enough mass, and depending on the maxForce and frequency of the touch joint, the player might temporarily dislodge the test object from its normal coordinates. As it does so, the touch joint will “stretch” and cause the test object to snap back into place. When it does, the player will be pushed away from the test object. In either case, the player will be moving away from the test object, and at a speed equal to its original speed or less.

If the player now collides with some other object, depending on their relative masses and bounce properties, it’s quite possible that they will start moving in the same direction too. Imagine that the player is very massive and the object it collides with is very light. Then when the player hits the object, it will just push the object along in the same direction. If the masses are more similar, then they will bounce off each other like billiard balls and head in different directions.

Does this help explain your situation?

  • Andrew [import]uid: 109711 topic_id: 28630 reply_id: 115501[/import]

You also might try lowering the maxForce param, for more ‘elasticity’.

binc [import]uid: 147322 topic_id: 28630 reply_id: 115503[/import]

Hi Binc and aukStudios,

I apprecaite the perspective but I may not have been clear enough. I like the billiards analogy but rather than having the “balls” bounce off of each other and move with a gradually decaying speed as one would expect, my player gains a constant force vector in the direction that the test object rebounded. So even if I move my PC after the rebound, the PC will continue to move in that rebound direction.

For example, I move my PC to the left into the right side of the test object. The test object moves to the left and then rebounds to the right. The PC then gains this force vector and moves continuously to the right. I can move the PC to the left at a now reduced speed (PC speed - applied vector speed) and when I stop moving the PC the PC continues to the right with this force vector. The PC

I’ve experimented with different density, bounce and friction values on the PC

I’ve also experimented with the maxForce, frequency and damping ratio.

I thought maybe my Runtime event listener that I use to detect swipes for PC movement might somehow be at the root of this all but I’ve used a bunch of print commands to debug that and there’s nothing weird going on.

Very strange… [import]uid: 105707 topic_id: 28630 reply_id: 115544[/import]

I agree, that sounds like a problem with the physics engine. What you’re saying is it accelerates to the direction away from the elastic object? By the way, is your PC a strange physics shape or something? Because that may have something to do with it (I don’t know what, but that might be important)

binc [import]uid: 147322 topic_id: 28630 reply_id: 115545[/import]

I think I understand better the issue now (I’m assuming “player” and “PC” are the same thing), and I think there are two issues.

First, you probably want to set the linearDamping property (http://developer.coronalabs.com/reference/index/bodylineardamping) for your player object. This will slow its linear movement over time (simulating friction) so that it eventually stops.

Second, I’d like to understand better how you’re attempting to “stop” the player object after it rebounds off the test object. I may be wrong, but I suspect that you’re simply setting its x,y coordinates directly. This won’t work, because the physics engine “owns” the object, and simply changing its coordinates won’t affect its velocity vector. Instead, you should consider using setLinearVelocity (http://developer.coronalabs.com/reference/index/bodysetlinearvelocity).

  • Andrew [import]uid: 109711 topic_id: 28630 reply_id: 115547[/import]

@Binc - agreed, it “feels” completely like an engine issue… but given my “noob” status with Corona (and programming/scripting in general) I need to be really thorough about my investigation. I think aukStudios may be onto the root of my problem.

@aukStudios - I’ve not looked into those issues yet but your second point regarding setLinearVelocity sounds spot on. I am simply setting the x,y coordinates of my player/PC with my move function:

[lua]–“cheezy” referring to my PC
local function movecheezy (event)
cheezy.x = cheezy.x + motionx
cheezy.y = cheezy.y + motiony
end

Runtime:addEventListener(“enterFrame”, movecheezy)

–example function hooked into my swipe events to move one of the four cardinal directions
function moveUp()
motionx = 0
motiony = -speed
end[/lua]

So it sounds like I need to develop a movement solution that’s based around velocity vectors rather than setting .x and .y coordinates, correct? Please let me know if anyone knows of any sample code they recommend for this type of movement.

Thanks :slight_smile:
[import]uid: 105707 topic_id: 28630 reply_id: 115550[/import]

OK, brilliant, it was as simple as setting the .linearDamping property on my PC (“cheezy” from my sample code above). Good lord it’s amazing how nice this looks now…

So the great lesson for me is the distinction between physics properties and simply setting locations via .x and .y values. That’s perfectly clear in hindsight… I just hadn’t conceived of that distinction.

Very cool to have gone through this experience, quality learning!

@binc and @aukStudios, I really appreciate your time helping me through this.

Although I seem to now be “functional” again, I am still going to investigate using setLinearVelocity for movement rather than updating .x and .y positions.

Thanks :slight_smile:

[import]uid: 105707 topic_id: 28630 reply_id: 115552[/import]

aukStudios is correct. If you are simply setting the x and y, that’s the equivalent of teleporting ‘cheezy’ to your position, and keeping his linearVelocity. For a velocity based movement technique, try this:

[lua]local function stopCheezy()
cheezy:setLinearVelocity(0, 0)
end

local function moveCheezyLeft()
stopCheezy() – do this so it doesn’t ‘stack’ with other velocities
cheezy:setLinearVelocity(-10, 0)
end

local function moveCheezyRight()
stopCheezy()
cheezy:setLinearVelocity(10, 0)
end[/lua]

Do that with all of your movement, and then instead of making a master function, on each button touch do a moveCheezy in the specified direction.

binc [import]uid: 147322 topic_id: 28630 reply_id: 115555[/import]

@binc - great analogy with the “teleporting”. That code example is very helpful. I especially appreciate the tip regarding calling the stop function to keep the velocities from stacking.

Will keep you posted on the outcome, thanks :slight_smile: [import]uid: 105707 topic_id: 28630 reply_id: 115566[/import]

Sorry, the part you appreciated isn’t needed. I miswrote. If you’re just setting the linear velocity, you don’t need that. You could also try applying force, if you want. There you would need the stop function.

binc [import]uid: 147322 topic_id: 28630 reply_id: 115586[/import]