Handmade Network»Forums
Shazan Shums
159 posts
Some day I will make quality software. Programming FTW.
---Need help please --- Coding basic simple 2d platformer physics
I was using farseer for an XNA project but I think its an overkill for simple 2d stuff and the setup and coding pattern is hard so I was trying to code the physics myself but I think I'm stuck.
The issue is resolving collision and doing wall grab ,jumping and stuff...(maybe all stuff in a platformer like sonic)
The thing is though people say that it is easy to use a prebuilt library it is not especially if it is others code.Any guidance would be helpful.


Here's my current progress...

Physics.cs gist
Timothy Wright
76 posts / 1 project
---Need help please --- Coding basic simple 2d platformer physics
Edited by Timothy Wright on
Personally I think if you are making a meat-boy like platformer, then it will better to just make your own equations and formulas. True physics will simulate everything correctly but it won't "feel" right.

I would start with just pushing colliding objects out to the collision point, and making sure you've got the time step correct.

Here are two good references for the time step.

https://gamedevelopment.tutsplus....engine--gamedev-7493#timestepping

http://gafferongames.com/game-physics/fix-your-timestep/
Shazan Shums
159 posts
Some day I will make quality software. Programming FTW.
---Need help please --- Coding basic simple 2d platformer physics
Edited by Shazan Shums on
Thank you for your helpful guidance.

I have implemented AABB collision but it seems buggy.


Here's the problem Physics Bug.gif

It collides before hitting the object.

Here's a part of source code in main..
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
if (Physics.AABBvsAABB(Crate.AABB, Floor.AABB))
            {
                Crate.Collided = true;
                Floor.Collided = true;
            }
            Crate.Update(gameTime);
            Floor.Update(gameTime);


.... some code 

  Renderer.Draw(Crate.GetRenderPos(), Crate.Texture,Camera.get_transformation());
            Renderer.Draw(Floor.GetRenderPos(), Floor.Texture,Camera.get_transformation());
   


in entity update
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 public enum FacingDirection
    {
        Up = 0,
        Down = 1,
        Left = 2,
        Right = 3
    }

    public enum EntityTag
    {
        Player = (0 << 1),
        Enemy = (1 << 1),
        Crate = (2 << 1),
        Floor = (3 << 1)

    }

    public  struct  Entity
    {

        public bool Active ;
        public bool Visible ;
        public bool Collided ;
        public bool Special;
        public FacingDirection Direction;
        public EntityTag Tag;
        public long Health;
        public long Stamina;
        public long MaxHealth;
        public long MaxStamina;
        public float HealthRegen;
        public float StaminaRegen;
        public Texture2D Texture;
        public AABB AABB;
        public Vector2 Dim;
        public Vector2 Pos;
        public Vector2 dPos;
        public Vector2 ddPos;
        public static Color _Color = Color.White;
        public static int depth = 0;
        public Color Mask{
            get{ return _Color; }
            set { _Color = value; }
            
        }

        public void SetDim()
        {
            Dim.X = Texture.Width;
            Dim.Y = Texture.Height;
        }
        public void SetAABB()
        {
            AABB.Center = Pos;
            AABB.HalfDim = Dim/2;
        }


        public Vector2 GetRenderPos()
        {
            return AABB.Center - AABB.HalfDim;
        }

        public void Update(GameTime gt)
        {
            float dt = (float)gt.ElapsedGameTime.TotalSeconds;
            AABB.Center = Pos;
            dPos = Vector2.One;
            if (Collided)
            {
                ddPos = -ddPos * 0.1f;
                Collided = false;
            }
            dPos *= ddPos;
            Pos += dPos * dt;
        }
    }


Here's physics
1
2
3
4
5
6
7
8
9
 public struct AABB
    {
        public Vector2 Center;
        public Vector2 HalfDim;
    }
 public static bool AABBvsAABB(AABB A, AABB B)
        {
            return (Math.Abs(A.Center.X - B.Center.X) > (A.HalfDim.X + B.HalfDim.X) || Math.Abs(A.Center.Y - B.Center.Y) > (A.HalfDim.Y + B.HalfDim.Y)) ? false : true;
        }
Shazan Shums
159 posts
Some day I will make quality software. Programming FTW.
---Need help please --- Coding basic simple 2d platformer physics
Edited by Shazan Shums on
I guess it was a rendering bug.

Now the issue is about resolving velocities after collison and jump code.

Any help?
Timothy Wright
76 posts / 1 project
---Need help please --- Coding basic simple 2d platformer physics
Here are some more great resources...

http://chrishecker.com/Rigid_body_dynamics

https://gamedevelopment.tutsplus....-impulse-resolution--gamedev-6331

http://buildnewgames.com/gamephysics/ Make sure you run the javascript and read the code
Shazan Shums
159 posts
Some day I will make quality software. Programming FTW.
---Need help please --- Coding basic simple 2d platformer physics
Edited by Shazan Shums on
I found another bug Box falling through.

Here's collision resolve code


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Crate.Update(gameTime);
            Floor.Update(gameTime);
            if (Physics.AABBvsAABB(Crate.AABB, Floor.AABB))
            {
                Crate.Collided = true;
                Floor.Collided = true;
                Crate.Pos = Crate.PrevPos;
                Crate.InAir = false;
                Crate.ddPos = Vector2.Zero;
            }


I can't figure it out.


And how do you post gifs in hmn.