3
\$\begingroup\$

Apologies because this is a long post and I am inexperienced. I would really appreciate the input from some experienced developers.

These are my two goals for this project:

  1. To learn the best method of managing the game loop and flow of the program so that it is easily understandable, clean, and reusable.

  2. To learn about how to efficiently and cleanly handle the physics calculations of a game. I would like to learn the method that is implementable on a scale that can accommodate a lot of collisions.

The project will be written in using Javascript/HTML 5.

The way I was thinking about it is to include attach implement an physics object constructor that attaches a physics object to each class object that will have physics done to it.

For example:

var playerBullets = [];
playerBullets.push(Bullets()); //Bullets() is the constructor

//inside the Bullets() constructor I would have the following:
this.physics = Physics();  //where Physics() is the constructor for a physics obj

The physics object would be set up like the following:

{
  x: 0,
  y: 0,
  xVelocity: 0,
  yVelocity: 0,
  xAccel: 0,
  yAccel: 0,
  mass: 0,
  restitution: 0,
  angularVelocity: 0,
  linearDampening: 0,
}

Then from the gameLoop:

Function gameLoop() {
  ...
  update();
  draw();
}

Function update() {
  ...
  //code here to iterate through objects to update them individually
  handleCollisions();
  handlePhysics();
 }

Function handleCollisions() {
   ...
   //detect collisions between objects and mark which ones have collided with each other
}

Function handlePhysics() {
   ...
   //code to iterate through objects and update the velocities
   handleCollisions();      
}

Questions

  1. What might be some problems I would run into by doing it this way?

  2. Should I include any methods in the physics object or should I handle all of my physics operations in a special function inside the gameloop?

  3. Is it better to handle the physics together, or handle the physics of each object separately in its own update function?

  4. What is the best practice way to handle physics in a game?

EDIT I learn better by seeing examples so it would be very helpful, and I'd really appreciate it, if I could see some accompanying pseudo-code.

\$\endgroup\$
  • \$\begingroup\$ It is probably easiest to look at a very tiny example physics engine to get an idea. Maybe you can check out Box2D Lite (Lite version!!, not the full Box2D version). There's also a simpler alternative called "Impulse Engine" on github. \$\endgroup\$ – RandyGaul Jul 15 '14 at 21:50
1
\$\begingroup\$

Typically a physics engine will follow these steps:

  • Broad-phase collision detection. Typically using bounding volumes, this reduces the set of all objects to a small subset of potentially colliding objects. Some data structures to handle broad-phase are AABB trees, KD-trees, Octrees, etc.
  • Narrow-phase collision detection. From the subset of potential collision, test if a collision actually occurred by using the actual physics body. This typically involves calculating things like point of contact and normals.
  • Solver. Resolve collisions by pushing objects apart and enforcing constraints.

Because of the global nature of these calculations, it's typical to have physics objects centralized. You'll have them classified in a hierarchical structure, organized based on their bounding volumes (which is also handy for spatial queries, like finding objects near me). You might also want to separate static and dynamic objects, for efficiency (as only the latter can move, so the former don't need to be updated).

It's ok to put the physics object inside the normal game object as long as you also register it with the physics system. When you find a collision you'll want to notify the game object back; this is typically done by embedding a piece of data in the physics object that points back to the game object, so they both know about each other. You can do that in the Bullet constructor, in your example.

You can add methods to the physics objects like you would do with any other object in OOP. It may make sense for internal operations, related to the physics body, physics material, etc.

I'm curious why you didn't show a time delta in your update functions. Was this omitted for brevity or are you assuming a lockstep framerate? I find having a variable timestep gives you more flexibility but it can make the physics engine unstable (due to integration issues) if you don't run it at a high enough framerate. I've seen engines run several physics updates per frame in these cases, while still running the logic and rendering only once.

EDIT: If writing a broad phase is too much, I'd probably start with a simple array that contains the physics objects, and test everything against everything (which will become expensive once you have many).

PhysicsManager.physicsObjects = []; 

// In Bullet constructor
this.physics = Physics();
PhysicsManager.physicsObjects.push(this.physics);

// Then in physics update    
for (var i=0; i<physicsObjects.length; ++i)
    for (var j=0; j<physicsObjects.length; ++j)
         if (i != j && collides(physicsObjects[i], physicsObjects[j]))
               // Handle collision
\$\endgroup\$
  • \$\begingroup\$ I have read about broad phase and narrow phase collision detection. I was also thinking to implement the separating axis theorem. I don't have a delta time, but I was thinking about implementing one! I wasn't sure if I just should just run everything off of the frame-rate or not. As you can tell I am quite inexperienced with game design and I don't know of any specific conventions and that's why I really appreciate the response here! Could you elaborate on some of your ideas? I am not sure what you mean by registering the physics objects. I don't have a game object?? \$\endgroup\$ – Klik Jul 15 '14 at 22:45
  • \$\begingroup\$ It is difficult for me to imagine your concept of having physics objects centralized. I would be quite happy if you pointed me in the right direction here, or if maybe you would be so kind to write some pseudo-code so I can get an idea of the flow of the game thread and get a feel for the organization. Of course, if you're busy then please think nothing of it. \$\endgroup\$ – Klik Jul 15 '14 at 22:50
  • \$\begingroup\$ I believe separating axis is mostly used for narrow phase, to test intersection between two bodies. For broad phase you'll need some data structure, but it seems it may be a bit beyond your reach at the moment. Here's a post that could be a starting point for the future. I added some simple code for how to do it without a broad phase. \$\endgroup\$ – Sergio Jul 15 '14 at 23:50
  • \$\begingroup\$ One more thought. If you have few dynamic objects, you may be able to avoid the broad phase if you split static and dynamic. Then you test collision static-dynamic and dynamic-dynamic, but you don't have to test static-static. \$\endgroup\$ – Sergio Jul 15 '14 at 23:55
  • \$\begingroup\$ Hey, thanks for including some pseudo code. I understand what you mean perfectly. You've also given me enough terminology and ideas to do some research on my own (game object, lockstep framerate etc.) I also really like the idea of categorizing the physics objects into static and dynamic. I appreciate the guidance. \$\endgroup\$ – Klik Jul 16 '14 at 1:32

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.