-1
\$\begingroup\$

I'm studying a book of artificial intelligence applied to games. It shows several algorithms for each argument (movements, path finding.. ecc). Unfortunately (but obviously) it does not explains how to design the code (no book do that i think). I'm using Java (swing + awt + a game loop) to try these algorithms. My question is, where should i put the physics?

In other words, how the relations between my Player class (the object to move in the window) and the Physics class (algorithms of the book) must be implemented?

My Player implements update(float delta) and draw(Graphics g) methods, but i think that within update method i don't have to make calculations, but they should be delegated to another class.

I could know the algorithm that makes the player jump, but i'm very confused about where to place it!

\$\endgroup\$
  • \$\begingroup\$ "Where to put code" is a question that can only be answered within the context of your code, as it depends on your specific architecture and requirements. OTOH, it also sounds like a primer on platformer physics might help; this question has some useful information. \$\endgroup\$ – congusbongus Mar 3 '15 at 22:57
  • \$\begingroup\$ I have no requirements. I'm just learning something. I don't ask to have a perfect design, but just an initial acceptable setting. \$\endgroup\$ – Loris Mar 4 '15 at 13:36
1
\$\begingroup\$

That's how I do it in my 2D fighting game:

The characters object holds only their physics values (position, velocity, acceleration and friction).

Each character contains a set of states (standing, jumping foward, jumping back, weak punch etc.)

When a character change its state, the 'Initialize' method of that state is executed. Inside it I can set the velocity.Y of my character to give it a vertical impulse to jump, so as set the acceleration.Y to give it a gravity to pull it down continuously on each game frame.

The 'Update' method of the current State of the chracter is called once per frame. Inside it is when I execute the code to calculate the physics of the character and consequently update their position.

This design allows the independency of the physics for each state. Because in certain states I would like the character to standing in the middle of the air, in another I would like it to fall slowly and so on.

Excuse my english, I'm just learning.

-- UPDATE --

Here's my physics code:

    public void InitializePhysics(float horizontalVelocity, float verticalVelocity,
                                  float horizontalFriction, float verticalFriction,
                                  float horizontalAcceleration, float verticalAcceleration, Entity entity) 
    {
        entity.Friction = new Vector2(Math.Abs(horizontalFriction), Math.Abs(verticalFriction));

        var initialImpulse = new Vector2(horizontalVelocity, verticalVelocity);

        var directionFactor = entity.FacingRight ? 1 : -1;

        entity.Acceleration = new Vector2(horizontalAcceleration * directionFactor, verticalAcceleration);

        // This division by 2 is a correction of the Euler Integration. See this article for reference: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html
        entity.Velocity = new Vector2((initialImpulse.X + (Acceleration.X / 2)) * directionFactor,
                                       initialImpulse.Y + (Acceleration.Y / 2));
    }

    public void UpdatePhysics(Entity entity) {
        entity.Position = new Vector2(entity.Position.X + entity.Velocity.X, entity.Position.Y + entity.Velocity.Y);

        var horizontalVelocity = entity.Velocity.X;

        if (entity.Velocity.X != 0) {
            if (entity.Velocity.X > 0) {
                horizontalVelocity -= entity.Friction.X;

                if (horizontalVelocity < 0) {
                    horizontalVelocity = 0;
                }
            } else if (entity.Velocity.X < 0) {
                horizontalVelocity += entity.Friction.X;

                if (horizontalVelocity > 0) {
                    horizontalVelocity = 0;
                }
            }
        }

        var verticalVelocity = entity.Velocity.Y;

        if (entity.Velocity.Y != 0) {
            if (entity.Velocity.Y > 0) {
                verticalVelocity -= entity.Friction.Y;

                if (verticalVelocity < 0) {
                    verticalVelocity = 0;
                }
            } else if (entity.Velocity.Y < 0) {
                verticalVelocity += entity.Friction.Y;

                if (verticalVelocity > 0) {
                    verticalVelocity = 0;
                }
            }
        }

        entity.Velocity = new Vector2(horizontalVelocity + entity.Acceleration.X, verticalVelocity + entity.Acceleration.Y);
    }
\$\endgroup\$
  • \$\begingroup\$ So, are you saying that your physics is implemented within the character class? In this logic, every Entity of the game has is own Physics, but i think that in big games is not a good way to proceed :) \$\endgroup\$ – Loris Mar 4 '15 at 13:37
  • \$\begingroup\$ The processing of the physics in my case is just a Euler integration updating the position of the character with your current velocity, acceleration and friction. This calculation is made in another class, but invoked by the Update() of the state object of the character. For my game this design fits pretty well. Before implementing I thought a lot, searching for a super generic solution and I lost much time unnecessarily. \$\endgroup\$ – Emir Lima Mar 4 '15 at 14:01
  • \$\begingroup\$ You're right. I would like to know how you implemented that physics class. A kind of utility class with all static methods? Do you pass the character to that class? \$\endgroup\$ – Loris Mar 4 '15 at 14:10
  • \$\begingroup\$ Sure! That's the idea. I will update my answer with the code. But bedore I need to translate it from portuguese to english. :P \$\endgroup\$ – Emir Lima Mar 4 '15 at 14:16
1
\$\begingroup\$

your calculations should go into the update method. it's fine to have an AIManager class, that has an update() method itself which gets called in the main update loop.

this AIManager could hold a list of all the Objects that need to be updated. Since you're using java, you could use an interface to declare something to have an AI, and use this interface to iterate over your objects (which could then be completely different Classes) and have interactions managed by this AI manager.

You would do the same for the physics. have something manage the Physics, that iterates over all the objects that implement a physics interface.

\$\endgroup\$
  • \$\begingroup\$ In a big game the objects that should be updated could be... thousands! How can this problem be solved? \$\endgroup\$ – Loris Mar 4 '15 at 19:55
  • \$\begingroup\$ by cleverly optimizing in the physicsmanagers update. Octrees are quite a popular solution for this. \$\endgroup\$ – Serris Mar 5 '15 at 15:33
1
\$\begingroup\$

You're using Java so I'm going to assume off the bat that you're playing to Java's strong points and writing your game as Object Oriented as you possibly can. When you say you have a game loop I imagine you have a top level class with a main method that loops over your update and draw functions, something like the following (but yours will be far more detailed):

class Game {
    Player player;
    void main(){
        while(true){
            update();
            render();
        }
    }
    void update(){
        player.update();
        //etc
    }
    void render(){
        //draw everything to screen
    }
}

You're going to have a class for the player and what you want to do is have that class inherit from a base class for objects in your game that need physics applied to them.

class PhysicalObject {
    float x_position;
    float y_position;
    float x_velocity;
    float y_velocity;

    void update(){ ... }
    //Add some functions for algorithms:
    void applyGravity(){ ... }
}

In all likeliness you're going to want to override the update function of the base class to take things like user input and player states into consideration. Add your algorithms as functions to that base class so you can easily call them from any derived classes in whatever order makes sense for that class.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.