Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Studio Chat / Sleep(200) w/Gravity causes overlapping sprites?

Author
Message
Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 20th Aug 2020 06:00 Edited at: 20th Aug 2020 18:24
I seem to be missing something fundamental about how gravity physics work? The following code drops rows of rectangular sprites from the top of the screen while drawing a series of horizontal bars up the screen indicating where the top of each row of sprites should be:



But this code is producing unexpected results. As illustrated below, the blue horizontal lines indicate where the tops of each row of sprites should be when PhysicsHorizontalY~0, and everything looks pretty good once all of the stacks have stopped bouncing (despite restitution=0).



But then around the 13th time it runs the Sleep(200) statement the pile of sprites starts to sag, with varying degrees of vertical compression per row but all of the sprites in each row behaving the same way:



By iteration 23 the stacks have sagged by more than two rows - of sprites, not pixels:



They bounce up and down a few more times and still have not recovered their original positions by the 100th iteration:



BUT...simply comment out Sleep(500) and the sprites remain rooted in place to at least a count of 1000. Sleep thus appears to be impacting physics calculations in some way that causes the sprites to suddenly begin moving when no force has been applied after several seconds. It is unclear why this should be the case but it would be helpful to use something like Sleep without impacting physics like this.

Has anybody else noticed this? Any suggestions?

Attachments

Login to view attachments
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 20th Aug 2020 21:42
I have not experienced this but I have also avoided the sleep command:

Quote: "Suspend the app for a specified number of milliseconds. It is not recommended that you use this command to suspend an app for more than the time of one frame (roughly 17 milliseconds)."

(https://www.appgamekit.com/documentation/Reference/Core/Sleep.htm)

This may cause a sync issue with amount of movement of the object per step but its just a guess.
blink0k
Moderator
11
Years of Service
User Offline
Joined: 22nd Feb 2013
Location: the land of oz
Posted: 20th Aug 2020 22:24
it will also make the physics step huge
Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 21st Aug 2020 23:39
Thanks for your responses!

I've used Sleep>17 frequently without issue, mostly when debugging, but this is the first game I've written using gravity.

To be clear, I am trying to completely prevent bouncing when a sprite falling from the top of the screen lands atop one below. This is a problem because I am using GetSpriteHit to highlight a row, column or diagonal line of sprites and cannot get accurate results because the sprites are bouncing for so long. The documentation suggests Restitution(0) should eliminate bounce but this doesn't seem to be the case in my experience. The first sprite dropped, which lands on the bottom of the screen, does appear to stop completely when it hits, as expected. But the second sprite bounces a pixel or two when it collides with the first and the third sprite bounces even more. It gets worse going up the screen until about half way, at which point the bouncing starts reducing again. Making matters worse, all of the sprites beneath each dropped sprite also bounce when the sprite lands and there's a similar issue when sprites are removed from the middle or bottom of a sprite stack, those above it drop to fill the hole left and they all bounce a bunch again. The only difference Restitution(0) appears to make is that the first row also bounces when Restitution is not set, and Restitution(1) is clearly not what I need!

I've tried replacing the arbitrary loop my example was using to delay further execution until the sprites stopped moving with one checking VelocityY. Unfortunately, while the loop returns 0 for VelocityY for all of the sprites when tested, it is apparently not really 0. Maybe it's coincidentally testing the sprites at the top or bottom of their bounce and their MOMENTUM is technically zero at that instant, but the sprites visibly continue bouncing up and down for another 140+ iterations of the loop checking VelocityY (at 30 fps) before they finally stop moving enough to get accurate results. I was able to reduce the time it takes to do that to less than a second by changing SyncRate to 0 temporarily before checking VelocityY and returning to 30 FPS when VelocityY registers 0 for multiple iterations, but that feels like a poor workaround when there must be a better solution? Or, I could force all of the sprites into their expected locations after temporarily turning off physics but that also feels like a work around and might also look strange when the sprites suddenly snap into place.

Is there some other setting that actually prevents ALL bounce? SetSpriteVelocity doesn't seem to do what I need and wouldn't help until all of the sprites settle in their expected locations prior to the GetSpriteHit loop anyway. Neither Friction, Mass, nor Damping fix the issue. There's no SetSpriteMomentum and no other sprite physics commands look like an obvious solution. Is there maybe some scene setting or a Tier 2 solution (which I have not yet tried but would be willing to try if it would fix this problem)?
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 22nd Aug 2020 02:17 Edited at: 22nd Aug 2020 02:24
What is your SetPhysicsGravity() set to? Not sure maybe changing to a heavy mass with your SetSpritePhysicsRestitution() turned off might settle them? I do have situations where sprites stack up, compress and spring out, wobble or whatever but to me it always adds to the user experience. If your looking for very static results you may want to just have your own "gravity" with changing Y position and look for collisions or Y positions to stop the movement.

Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 22nd Aug 2020 05:52
I overlooked SetPhysicsGravity in the example I posted, thanks! The documentation doesn't really say what the default PhysicsGravity value is, nor does there appear to be a GetPhysicsGravity so I'm not sure how I could tell, but I'd guess 1G, which the documentation says is roughly SetPhysicsGravity(0, 50). I plugged that into the example and it appears to me to run exactly the same.

Dropping PhysicsGravity to 10 on the Y axis makes the sprites fall so slowly they are actually impacting in the air as they are created. This returns to normal appearance when FPS is 60. There may be a little less bounce but it takes more iterations to resolve residual movement, which I can speed up with the SyncRate change, but ends up using the same inelegant workaround. Setting it to 1...well, that does not produce the user experience I was hoping for.

As expected, increasing PhysicsGravity to 100 loads the sprites a little more quickly, they might be bouncing a little less energetically, and take fewer iterations to stop completely. Going up from there only appears to produce not only more bounce, but the opposite, where the sprites are being compressed and/.or overlapping so that whole rows are displaced until everything settles.

Moving onto changing mass, my example started at 0 so there's only room to go up from there. To test this I increased mass in increments of 100 in each column across the board, with values from 100 to 1700, and then from 1000 to 17000. I'd have expected to see some kind of ripple effect with the right most sprites settling more quickly than the left most, but all of the sprites appeared to settle identically regardless of mass?

And, yeah, I've already started toying with implementing my own gravity. It's just, you know, that's one of the things AppGameKit was supposed to handle for me so I didn't have to?

Thanks, again!
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 22nd Aug 2020 14:11
I think you need to re-consider your approach on the physics and sleep thing, I just mangled your code here quickly but got much closer results to what I think you were expecting:


Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 23rd Aug 2020 05:37
Thanks! I was using Sleep to slow down processing to try to figure out why sprites with Restitution=0 were bouncing at all and discovered that when I did, apparently stable sprites suddenly started moving again, overlapping and collapsing into each other. Sleep therefore appeared to cause a problem with physics. But I can find other ways to pause execution than sleep now that I know they do not work well together. The real issue is bouncing sprites.

To address your example, all of your physics settings look the same as mine:

PhysicsGravity=50
PhysicsOn=2
CanRotate=0
Restitution=0

I tried running your code side-by-side with mine and aside from cosmetic differences, they both appear to behave the same to me at first glance. Sprites in both examples fall at the same rate, bounce and take time to settle. Have I overlooked some difference between our examples? I uploaded my scene settings before I realized your example doesn't use one, so there's no use comparing those.

Beyond that, I don't want to waste a lot more of your time on this, particularly if sprite bounce cannot be eliminated regardless of Restitution. I should probably just report this as a bug on GitHub at this point and see how the support team reacts. Maybe they can explain it, or if not, fix it?

Thanks, again!
jd_zoo
5
Years of Service
User Offline
Joined: 12th May 2018
Location: Nova Scotia
Posted: 23rd Aug 2020 14:21
Again this is a not bug at all, if you want zero bounce and objects to align exactly you need to provide your own movement. The physics engine is running gravity for you but also dealing with the impact of the sprites which gives it a natural bounciness. You can turn off the sprite's physics when it hits a certain position to stop this. The difference in my example is not merely cosmetic as you are implementing everything in one step in the main loop and hoping it falls in place, which is not a proper technique and you need to rework your approach. The example I provided would be the correct way to have objects fall with zero restitution, and on my system the bounce is minimal. If this is still too much "bounce" for you than you will need to implement your own Y movement based on each step.
Ron2019
4
Years of Service
User Offline
Joined: 27th Jul 2019
Location:
Posted: 23rd Aug 2020 18:05
OK, thanks!

Login to post a reply

Server time is: 2024-03-28 14:07:32
Your offset time is: 2024-03-28 14:07:32