Jump to content

Panda Physics Engine: General Chat


Wolfsbane
 Share

Recommended Posts

25 minutes ago, enpu said:

You have collide function, which is called when your body collides with other body or bodies. Then you are checking another collision by using last positions (which are positions before the body was moved by physics in that frame) and modifying your body's last position by 1 pixel?

Probably my bad. O.k., I've chopped the code down a bit, this might look a bit shorter and cleaner.

var collision = false;
            var xx = this.body.last.x;
            var yy = this.body.last.y;

            if ( this.collisionAt(xx+Math.sign(this.body.velocity.x),yy,other)) {
                this.body.velocity.x *= -1;
                collision = true;
            } 

            if ( this.collisionAt(xx,yy+Math.sign(this.body.velocity.y),other)) {
                this.body.velocity.y *= -1;
                collision = true;
            } 
//...snip

So the idea is just: Find where the collision happened (to the right/left, or up/down) and then flip our x/y velocity depending on where that block is.

25 minutes ago, enpu said:

modifying your body's last position by 1 pixel?

No, I don't touch the current, or last x/y coords, I just flip the x/y velocity.

Link to comment
Share on other sites

@Wolfsbane

I did take a closer look at your breakout game. I noticed that in your refactored collision code the logic changed, since i was getting different behavior.

In both versions i did found situations when the collision was not working properly and the ball was going through the wall. This could happen when the ball was colliding with multiple bodies in the same frame, was going too fast or was taking too big "jumps" between frames (this can happen when fps drops).

There was situations when the built-in physics engine could not detect if the collision direction was UP, DOWN, RIGHT or LEFT. For example sometimes it could be UP and RIGHT both.

I have changed the physics code and added four new collision direction UPRIGHT, UPLEFT, DOWNRIGHT and DOWNLEFT. Also i added third parameter to the collide function, which is array of all the bodies that the body is colliding with. This can be useful if you want to know if there is more than one collision in specific frame etc.

Here is modified version of the project. The ball collide function now looks super simple. I also extended all classes from PhysicsSprite class, which makes the code even simpler.

collide: function(other, dir, others) {
    if (dir === 'UP' || dir === 'DOWN') {
        if (!this.dirChanged) this.body.velocity.y *= -1;
        this.dirChanged = true;
    }
    else if (dir === 'LEFT' || dir === 'RIGHT') {
        if (!this.dirChanged) this.body.velocity.x *= -1;
        this.dirChanged = true;
    }
    
    if (other.collisionGroup === game.Body.BRICK) other.collide();
    
    return true;
}

breakout_01_2.zip

What do you think? I haven't yet pushed these physics changes into the dev branch.

Link to comment
Share on other sites

Bad timing, I'm flying out in the morning (have to get up at 3am), and will be travelling for the next 4 days. :) Now.. if Panda2 only worked on an iPad....

So just some super quick thoughts, I've taken a quick look at it, and.. less code = better code as far as I'm concerned. It feels great, and the code is *much* easier to read, so ++!

I've played around for a quick 5 minutes trying to break something, but so far, it's pretty rock solid, so.. hey, I like! 

2 hours ago, enpu said:

was going too fast or was taking too big "jumps" between frames (this can happen when fps drops

I was wondering about this, especially when I saw that there is a var for setting an upper speed limit. I know Delta time-style systems can lose collisions like this, but (if it wasn't caused by my dodgy code), isn't this a bug in the Engine?

2 hours ago, enpu said:

I have changed the physics code and added four new collision direction UPRIGHT, UPLEFT, DOWNRIGHT and DOWNLEFT.

I can't think of a scenario that we would use this for rectangular collisions? (Unless.. rotated bodies?)

Could be useful for the Circle, though.

2 hours ago, enpu said:

I also extended all classes from PhysicsSprite class, which makes the code even simpler.

I didn't have luck with this syntax before, so it's good to see, too. The ball body's size has to be halved, of course. (because it's a rectangle, on a massive ball sprite). Now you can sneak the ball in between the bricks, and watch it bobble about. Delicious~

Link to comment
Share on other sites

45 minutes ago, Wolfsbane said:

I was wondering about this, especially when I saw that there is a var for setting an upper speed limit. I know Delta time-style systems can lose collisions like this, but (if it wasn't caused by my dodgy code), isn't this a bug in the Engine?

There is way to control how the delta-time system works. Let's say your body velocity x is 100, which means it's speed is 100 pixels per second. If the game runs solid 60 fps, that would mean that the body moves 1.66 pixels every frame.

Now if for some reason the frame rate drops into 30 fps, the delta-time system keeps the body in the same 100 pixels per second speed by moving it 3.33 pixels every frame.

If the frame rate would drop into 10 fps, it would mean that the body moves 10 pixels every frame. Depending on the game, too big jumps could cause problems. The built-in physics engine is so simple that if the body jumps over another body, it is not detected as a collision. For example in platformer, the player could run through wall, because the physics body jumps over it.

To prevent this, there is Timer.minFPS attribute. If the game's fps drops into the minFPS value or lower, the delta-time value (game.delta) would not be increased anymore, which means that the body would not take any longer jumps. This would then look like everything is slowing down.

So in your game if you have body that is moving 100 pixels per frame and you don't want it to move more than max 3.33 pixels every frame, set Timer.minFPS value to 30.

You can also debug your game in specific frame rate by setting System.frameRate attribute.

1 hour ago, Wolfsbane said:

I can't think of a scenario that we would use this for rectangular collisions? (Unless.. rotated bodies?)

The collision direction is the side of the rectangle that is colliding with another rectangle (rectangle has 4 sides).

So example situation, there is body A at position 0,0 and body B at position 100,100. Physics world has no gravity. Body A velocity is 100,100, so it is moving 100 pixels right and down every second, body B doesn't move. Now when body A collides with body B, there is no way to tell which side of the body A collided (down or right). It's like their corners are colliding, so how should the engine move body A at that situation?

Link to comment
Share on other sites

Hi, sorry for the slow response. I'm back to a laptop so I can give a decent-ish response.

 

On 9/20/2018 at 11:58 PM, enpu said:

Now if for some reason the frame rate drops into 30 fps, the delta-time system keeps the body in the same 100 pixels per second speed by moving it 3.33 pixels every frame.

If the frame rate would drop into 10 fps, it would mean that the body moves 10 pixels every frame. Depending on the game, too big jumps could cause problems. The built-in physics engine is so simple that if the body jumps over another body, it is not detected as a collision. For example in platformer, the player could run through wall, because the physics body jumps over it.

Right, right, so this is what I was wondering about. Is by design? Panda just doesn't want to do anything too complicated here? There are some game loop patterns like explained in http://gameprogrammingpatterns.com/game-loop.html, and also by Meth, where in if the game is lagging/losing frames, you still try to execute the physics/game logic consistently, and you just execute rendering as 'lag'. E.g. Game loop looks like:

A modified flowchart. Process Input â Update Game â Wait, then loop back to this step then â Render â Loop back to the beginning.

So, roughly stated: rather move the player at 10x slower speed, it'll execute the update() 10x, then do the rendering. (so you'll get some visual jumps, but no missed collisions).

 

On 9/20/2018 at 11:58 PM, enpu said:

You can also debug your game in specific frame rate by setting System.frameRate attribute.

Great! This is a useful tip.

 

On 9/20/2018 at 11:58 PM, enpu said:

So example situation, there is body A at position 0,0 and body B at position 100,100. Physics world has no gravity. Body A velocity is 100,100, so it is moving 100 pixels right and down every second, body B doesn't move. Now when body A collides with body B, there is no way to tell which side of the body A collided (down or right). It's like their corners are colliding, so how should the engine move body A at that situation?

Hmm... this is true... I am just a bit neutral on it. But I wasn't too keen on the 'UP'/'LEFT', etc, style either. It just looks a bit clunky to code with.

I wrote/removed a few things, but.. probably need to keep using the Physics to get some better ideas.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...