Hi everyone, I just thought I’d share something I’ve been working on. Aside from game developers I doubt many will have much of a use for it.
So for one of my upcomming games I needed to be able to handle collisions between two circular sprites, which was umm… harder than I hoped. In the end though I was able to get it going and I have a working sample channel if anyone is interested. https://github.com/Romans-I-XVI/Roku-El … on-Physics
So in this sample we are essentially spawning 20 balls with random sizes that also correlate to their mass, tell them to start moving at a random speed, and then let the ManageBounce() function do its magic
If you look at my commit history on github you might see I’ve been banging my head on the desk trying to make the code perfect. Because, although everything works great, there are special circumstances where occassionally a ball will pass through another ball. I know what the cause is, but I don’t know the solution. Once two balls have collided I have to mark that the collision has happened because if I don’t, and the collision is still occuring in the next frame even though speeds have already been altered, the collision will be processed again and the balls get stuck together. The problem that creates though is that if say another ball comes and hits the ball, while it is still registering that previous collision, it won’t register it another time (again because it doesn’t want to get stuck together) and will pass right through the ball it originally had a collision with. I’ve tried getting really crazy with it from about every angle I can think of, handling multiple collisions at a time, disabling the first collision if a second collision occurs ( this just leads back to the problem of balls getting stuck together sometimes ), manually altering speeds. In the end I reverted to the code I had originally that seemed to work just as good ( it’s hard to tell for sure since it’s so random ) and is a lot less complicated.
So if anyone has any thoughts on getting this to work 100% with balls never passing through each other, even if there were say 40+ on the screen, let me know. Otherwise enjoy the code. Hopefully somebody can use this in a game or something.
I fixed the problem of balls passing through each other! Here’s a video with a very crowded space, and yet are collisions working properly . https://youtu.be/2YFNhNFcnkM
Essentially I added an entire new function that checks if the total distance between two balls is less than it should be ( i.e. One is inside of the other, even just slightly ). If so I simply adjust the x and y positions ( without touching the speeds at all, since that is what the other function does ) so that it is at the point where the edges are just barely touching, essentially where it would be in a real world collision where balls passing through each other is physically impossible lol.
The solution wasn’t necessarily easy, but it was much easier than some of the other madness I was trying, and it is also a much more elegant solution.
The “pass trought” and “drag along” are interesting issues of simulation discretization to frames which i seem to vaguely remember. Your method of “back off” correction - does it work well when there is bunch of objects touching at the same time? For example line of balls like in Newton’s craddle (no need of wires, end balls may bounce back from the room walls).
Alternatively, how about counting collision between two bodies only when they are touching (or overlapping) AND their speed vectors are colliding? (I.e. when they are pulling apart that’s not collision or both are moving same direction and frontmost is faster, that’s also not)
Well if you add enough friction, all issues will be settled sooner than later
Looks quite neat, i share your enthusiasm!
W/o friction/gravity - it’s a screen saver. With - it made me think of those sand picture frames - where you flip and watch sand grains settle down in water.
Don’t you have something to track frames-per-second? I find it quite useful, but doing it right can be tricky. Here is what i do now (sorry for copying Lua, don’t have my B/S handy but is trivial to adapt):
FPS_label = director:createLabel {
vAlignment = "top", hAlignment="right", textXScale = 2, textYScale = 2,
textBorderTop = 30, textBorderRight = 70, color = FONT_COLOR, zOrder = 100,
text = ''
}
scene:addChild(FPS_label)
avg_deltaTime = 0.03 -- start value, unimportant
time_to_next_report = 0
function update_fps()
avg_deltaTime = (19 * avg_deltaTime + system.deltaTime) / 20 -- keep running average
time_to_next_report = time_to_next_report - system.deltaTime
if time_to_next_report <= 0 then
time_to_next_report = 1 -- every 1 second
local fps = string.format(avg_deltaTime > 0.101 and '%.1f' or '%.0f', 1/avg_deltaTime)
FPS_label.text = fps
end
end
The interesting parts are keeping (exponential) moving average to stabilize the value - and updating the displayed text less often than every frame (for humane reasons)