Skip to: Site menu | Main content


Welcome to PSP-Programming.com, a place for developers to get together.

Welcome to the forums. Here you can find other user tutorials as well as homebrew releases and the source code repository. You can also ask for help with your code here and post your own homebrew!

PSP-Programming.com Forums
February 10, 2012, 12:11:59 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

News: Join our IRC channel: ##psp-programming on freenode
Home Help Search Shop Login Register
Digg This!
Pages: [1]
Print
Author Topic: Contribution: 2D Game Physics & Vector Classes  (Read 1545 times)
stinkee2
I thought the most important rule was "Why do today what you can put off 'till tomorrow"
Jr. Member
**

Karma: +5/-0
Offline Offline

Posts: 62
663.93 points

View Inventory
Send Money to stinkee2
Im so thirsty I could eat a house - Stinkee2


View Profile
« on: December 13, 2009, 09:56:14 PM »

Once and A while, I Think of something that other people Might really want to use in their code but dont know how to implement.

This time, I have made 2 simple Classes:
Physics and Vectors

PhysicsObject.cpp
Code:
#include <math.h>
float PI_D_180 = M_PI / 180;
float _180_D_PI = 180 / M_PI;
#define Deg2Rad(Degrees) Degrees * PI_D_180
#define Rad2Deg(Radians) Radians * _180_D_PI
#define GetAngleBetween(V1,V2) Rad2Deg(atan2(V1.Y - V2.Y,V1.X - V2.X))
class Vector
            {
                public:
                Vector(float X,float Y)
                    {
                        this->X = X;
                        this->Y = Y;
                    }
                Vector()
                    {
                        this->X = 240.0f;
                        this->Y = 136.0f;
                    }
                ~Vector()
                    {
                    }
                float X;
                float Y;
                Vector operator + (const Vector &V) const
                    {
                        return Vector(this->X + V.X,this->Y + V.Y);
                    }
                Vector operator - (const Vector &V) const
                    {
                        return Vector(this->X - V.X,this->Y - V.Y);
                    }
                Vector operator * (const Vector &V) const
                    {
                        return Vector(this->X * V.X,this->Y * V.Y);
                    }
                Vector operator / (const Vector &V) const
                    {
                        return Vector(this->X / V.X,this->Y / V.Y);
                    }
                Vector operator += (const Vector &V)
                    {
                        return Vector(this->X += V.X,this->Y += V.Y);
                    }
                Vector operator -= (const Vector &V)
                    {
                        return Vector(this->X -= V.X,this->Y -= V.Y);
                    }
                Vector operator *= (const Vector &V)
                    {
                        return Vector(this->X *= V.X,this->Y *= V.Y);
                    }
                Vector operator /= (const Vector &V)
                    {
                        return Vector(this->X /= V.X,this->Y /= V.Y);
                    }
                float Magnitude() const
                    {
                        return sqrtf(this->X * this->X + this->Y * this->Y);
                    }
                float CrossProduct(const Vector &V) const
                    {
                        return (this->X * V.Y) - (this->Y * V.X);
                    }
                Vector DotProduct(const Vector &V) const
                    {
                         return *this * V;
                    }
                Vector Normalize() const
                    {
                        float mag = this->Magnitude();
                        return Vector(X / mag,Y / mag);
                    }
                float DistanceFrom(const Vector &V) const
                    {
                        return sqrtf(pow((this->X - V.X),2) + pow((this->Y - V.Y),2));
                    }
                Vector Move(float Angle,float Distance) const
                    {
                        if(Angle == -1.0f)
                        {
                            return *this;
                        }
                        return Vector(this->X + cosf(Deg2Rad(Angle)) * Distance,this->Y + sinf(Deg2Rad(Angle)) * Distance);
                    }
                Vector Move(const Vector &V) const
                    {
                        return *this + V;
                    }
                Vector RotateAround(const Vector &V,float Degrees) const
                    {
                        if(Deg2Rad(Degrees) != GetAngleBetween(Vector(*this),V))
                        {
                            if(Degrees >= 360)
                            {
                                Degrees -= 360;
                            }
                            if(Degrees <= -360)
                            {
                                Degrees += 360;
                            }
                            int xx = this->X;
                            int yy = this->Y;
                            int x = xx - V.X;
                            int y = yy - V.Y;
                            int xnew = cosf(Deg2Rad(Degrees)) * x - sinf(Deg2Rad(Degrees)) * y;
                            int ynew = sinf(Deg2Rad(Degrees)) * x + cosf(Deg2Rad(Degrees)) * y;
                            return Vector(xnew + V.X,ynew + V.Y);
                        }
                        return *this;
                    }
                void ScreenWrap(int Size)
                    {
                        if(this->Y < Size)
                        {
                            this->Y = 272 - Size;
                        }
                        if(this->Y > 272 - Size)
                        {
                            this->Y = Size;
                        }
                        if(this->X < Size)
                        {
                            this->X = 480 - Size;
                        }
                        if(this->X > 480 - Size)
                        {
                            this->X = Size;
                        }
                    }
                void ScreenStick(int Size)
                    {
                        if(this->Y < Size)
                        {
                            this->Y = Size;
                        }
                        if(this->Y > 272 - Size)
                        {
                            this->Y = 272 - Size;
                        }
                        if(this->X < Size)
                        {
                            this->X = Size;
                        }
                        if(this->X > 480 - Size)
                        {
                            this->X = 480 - Size;
                        }
                    }
                bool PastLeftScreen(int Size) const
                    {
                        if(this->X < Size + 2)
                        {
                            return true;
                        }
                        return false;
                    }
                bool PastRightScreen(int Size) const
                    {
                        if(this->X > 480 - Size - 2)
                        {
                            return true;
                        }
                        return false;
                    }
                bool PastTopScreen(int Size) const
                    {
                        if(this->Y < Size + 2)
                        {
                             return true;
                        }
                        return false;
                    }
                bool PastBottomScreen(int Size) const
                    {
                        if(this->Y > 272 - Size - 2)
                        {
                            return true;
                        }
                        return false;
                    }
                bool OutsideScreenRect(int Size) const
                    {
                        if(this->X < 0 - Size)
                        {
                            return true;
                        }
                        if(this->X > 480 + Size)
                        {
                            return true;
                        }
                        if(this->Y < 0 - Size)
                        {
                            return true;
                                }
                        if(this->Y > 272 + Size)
                        {
                            return true;
                        }
                        return false;
                    }
            };
        class PhysicsObject
            {
                public:
                PhysicsObject(bool Active = false)
                    {
                        Position = Vector(240.0f,136.0f);
                        Velocity = Vector(0.0f,0.0f);
                        Acceleration = Vector(0.0f,0.0f);
                        Gravity = Vector(0.0f,0.5f);
                        Mass = 10.0f; //Just In case you
                        Elasticity = 1.0f; //want to code
                        Friction = 1.0f; //collision response
                        Inactive = Active;
                    }
                ~PhysicsObject()
                    {
                    }
                Vector Position;
                Vector Velocity;
                Vector Acceleration;
                Vector Gravity;
                float Mass; //Just In case you
                float Elasticity; //want to code
                float Friction; //collision response
                bool Inactive;
                void Throw(float Angle,float Force)
                    {
                        Velocity = Velocity.Move(Angle,Force);
                    }
                void ThrowAt(const Vector &V,float Force)
                    {
                        Velocity = Velocity.Move(GetAngleBetween(Position,V),Force);
                    }
                void UpdatePhysics(bool Colliding)
                    {
                        if(Colliding)
                        {
                            return;
                        }
                        Acceleration = Gravity;
                        Velocity += Acceleration;
                        Position += Velocity;
                    }
            };

Example of Use you say?

Code:
...Needed Includes...
#include "PhysicsObject.cpp"
int main()
{
    ...Setup Callbacks & Initialize Graphics 'n Stuff...
    PhysicsObject PObj = PhysicsObject(); //Create A PhysicsObject
    PObj.Throw(-45,7.1f); //Throw it upwards to the right with a force of 7.1
    while(true)
    {
        DrawSomething(Pobj.Position,White);//Draw an object at the PhysicsObject's Position
        PObj.UpdatePhysics(false);//Update the Physics
        PObj.Position.ScreenWrap(10);//Make the position "Loop" Through the Screen. 10 is just the size of the bounding square of the object being drawn
    }
    return 0;
}

Make Believe Functions:
DrawSomething(Vector,Color); (this just draws something at a position with a color...)

Explanation:

What the PhysicsObject Class is is just a class that holds a position and makes that position act like an object that is being acted on by Gravity.

The Vector Class is a class that has 2 variables. X and Y, this just makes typing much easier. not to mention all the useful methods I threw in there like DistanceFrom(Vector) and all the operators (+,-,*,/).

How To Use:
1.)Create A new PhysicsObject.
2.)Set the Gravity if you dont like its current state.
3.)Create A Player or Sprite or Whatever you want to apply physics to.
4.)Set your Player or Sprite or Whatever's Position to the PhysicsObject's Position
5.) Call PhysicsObject::UpdatePhysics(false) on the PhysicsObject you created (change False to True if the player or sprite or whatever is colliding with something else)

Sorry, I didnt have time for Collision Detection & Response .  Sad
Logged

Dumping... 0.000001%, Speed: 1 byte/h.
An Abort of this application will corrupt your BIOS,Void your warranty, and Render your computer useless.
Please wait...


Raphael
Global Moderator
Hero Member
*

Karma: +230/-10
Offline Offline

Posts: 1431
193700.11 points

View Inventory
Send Money to Raphael


View Profile WWW
« Reply #1 on: December 14, 2009, 07:57:41 AM »

Moved to Source Code Repository, where it belongs. Thanks for the code Smile
Logged

Don't push the river, it flows.
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
http://www.homebrew-illuminati.co.uk - serious homebrew development for all platforms
Alexander Berl
"A good mod is a combination playground monitor, priest, big brother/sister, psychiatrist, professor and more."
stinkee2
I thought the most important rule was "Why do today what you can put off 'till tomorrow"
Jr. Member
**

Karma: +5/-0
Offline Offline

Posts: 62
663.93 points

View Inventory
Send Money to stinkee2
Im so thirsty I could eat a house - Stinkee2


View Profile
« Reply #2 on: December 14, 2009, 12:30:27 PM »

Whoops, Sorry, I Guess I Skipped over that forum while looking for a place to post this Embarassed.
The only 2 I read having to do with Programming (C or C++) were Progress Logs and C / C++ Help.
And this isnt really a Progress log.

I Apologize.
Logged

Dumping... 0.000001%, Speed: 1 byte/h.
An Abort of this application will corrupt your BIOS,Void your warranty, and Render your computer useless.
Please wait...
Pages: [1]
Print
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.198 seconds with 26 queries.
Sister Sites: Guitar Hero 4   BrokeniTouch.com