Asteroids Plus 2.0 - Milestone 19– Updating to Peasy-physics


This was a challenging milestone.  My goal for this entry is to review the process I took to migrate form my own homegrown ‘physics’ if we want to call it that, to peasy-physics.

Peasy-physics is created by Jürgen Wenzel and is a library that includes 4 current packages that makes life easy for front end aps.  We’ve already discussed Peasy-UI and Peasy-Input earlier in this blog, but now were focused on Peasy-Physics.

Peasy-Physics is an entity-based engine that allows for entity position, size, orientation(angle), shapes, forces, and collisions.  It also includes a canvas based diagnostic UI tool so you can visually see what the physics engine ‘thinks’ is happening, this includes shapes, colors, and detection boundary regions.

My plan for migrating form my old format to peasy is like this:

  • Setup and initialization of the engine
  • Understand and setup for shapes
  • Define the physics entities
  • Manage the additions and removal of entities in game
  • Define and manage forces
  • Define and manage collisions

One thing that I learned in doing this is how deeply intertwined my physics code was.  This made for a very long day, cutting over all the logic.

Physics Initialization:


Initialization of Peasy-Physics is simple, you import the library, and setup an initialization method.  I put mine in a minor timeout event because I w                              anted to ensure that Peasy-UI had time to load up and render in the DOM before I started playing with the physics engine.

In the Initialization you can pass a config object that setups up the diagnostic canvas for the engine, you can configure if you want the boundary regions visible in the canvas tool, and finally, you can pass the collision masking layers to the engine. 

This last part is super important.  Many engines have this type of feature so you can bind different collision events together, and more importantly, all the other collisions are ignored.  The keys in this object specifically refer to shape types.  We’ll get to that in a bit.

In my setup, I have the player shape responding to collisions with asteroids and bullets fired by the enemy ship.  My asteroids are tied to collisions with other asteroids, bullets, and enemy bullets.  My bullets collide with enemy and asteroid shapes, and enemy bullets interact with players and asteroids.

Entities:

Before we discuss shapes, let’s start with Entities.  Entities in Peasy-Physics (PP) have many properties.  Some of them are size, position, velocity, speed, shapes, and orientation.  There are others as well.  To move an entity, you can apply a force to it and the engine will move the position vector based on the Vectors passed to the Forces applied.

To setup an entity, you can create a new Entity class from PP, using the new keyword.


This is an example of how I’ve setup my Asteroid Entity for its initialization.  This Entity is then passed to the Physics engine via the addEntities() method.


You pass an array of entities into the method, and it subsequently returns a mirrored array of the entities that are converted from the physics engine itself.

I am using classes for each Game Object in the game, and each game object has a ‘PhysicsEntity’ property that is reserved for this.  This is how I manipulate the physics entity going forward in the game regarding modifying orientation or adding forces or responding to collisions.

In this example, after I get the returned instance of the physics entity, I can assign some mass to it, orientation if needed, or in this case, the collision callback, we will look deeper into that later.  The color property is for the canvas diagnostic tool, so it knows what color to draw the shapes onto the canvas.

One property that I use a bit, is the PhysicsEntity.entity property.  This I use as a reference to the overall class object so that I can have access to other class properties during collisions.  I assign ‘this’ to that entity property to get access to it.

One important note here is if there is a default force needed to be added upon creation, this is where you can add it to the entity.

Shapes:

Currently, there are Rectangle, Circle, and Stadium (capsule) shapes available to use as collision boundaries.  There are configuration parameters like size and position, vectors, and radius and types you pass into the shape object provided to the config entity.  Types is an array of labels that you can use to distinguish different collision objects.  Refer to the section on the Physics initialization, remember this?


These types are referenced in the collisions map that is passed at initialization.  This is where you designate if this shape is the ‘player’ shape, or the “bullet” shape.

Addition and Removal of Entities:

So we’ve covered the addEntities() method.  You pass an array of entity objects to it and it gets added to the Physics.entities array.  My game object classes have a spawn method, it’s a form of the factory pattern.  The spawn method ensures that the constructor has clean data when the new keyword is used.  The Physics entity is setup during the constructor call of the class instantiation.

What about removing an entity?  There are two ways of removing an entity 1) on a collision, you can return “remove” as the resolution to the collision and that entity will be automatically removed on a processed collision.

2)  Physics.removeEntities() which takes an array of entities to be spliced out of the entities array within the engine.  This takes the entity object in an array.


Since I’m using Peasy-UI, I use the data model object to bind everything to the UI.  I have to also manage that object array as well.  All my objects are in classes as well, so each GameObject class has a destroy() method that gets called when I need to unload that object.  Two things happen, first I manage the physics entity first, by setting the deleted property flag for that entity.  Also, I pass the entity reference in my game object to the removeEntities method.

Finally, I find and splice the game object out of the UI data model, and this unloads the object out of memory.

Forces:

Here is an example of how I make my ship go forwards and backwards.


You can see how we are referring to the PhysicsEntity within the player’s gameobject class.  This property has the addForces() method available after its added to the Physics engine.  So to make my ship go forward, I calculate the Vector needed in the proper direction, using standard trig functions, but also the Physic entity angle (.orientation).  You pass an object to the addForce method, that specifies a name, the direction Vector, how many milliseconds you want the force applied, and the magnitude of the force.  I do the same thing for reverse method, just flip the direction vector by 180 degrees.  Peasy-Physics has a standardized gravity and drag force available natively as well.

Collisions:

The final piece we are discussing for this entry is collision logic.  Collisions are added on the entity after its added to the engine.

The colliding callback method has the entity data and the intersection data automatically available to the callback.  It also returns a CollidingResolution type, which at the time of this writing is just a “collide” or “remove” string.

Now that I’m marking the destroyed property in the entity, I don’t need that guard condition, it will come out later.

But I can now perform different logic depending on what type of object hits me.  In this instance, this is the asteroid collision logic, and depending on if it’s another asteroid, or if it’s a bullet (player or enemy) we respond differently.  In fact, for asteroids, we simply play a sound effect file of the collision, then I return “collide”, which allows the shapes to bounce off each other.

If it’s a bullet hitting my asteroid, here’s my logic for reducing the overall health of the asteroid.  Also, if the health of the asteroid hits 0, then it gets destroyed.  I remove it from the UI data model, and return a ‘remove’ which automatically destroys the physics entity.

This actually is going to be the last content entry for this Devlog.  I appreciate all who have read up to this point.

I will be drafting a Devlog wrap up post this week, and will post in about a week's time

 This currently hosted game site: https://mookie4242.itch.io/asteroids-plus-20

Twitter: @jyoung424242

SlideShare: https://www.slideshare.net/JustinYoung3/next-gen-asteroids

GitHub: https://t.co/utxHxXKdOz

Leave a comment

Log in with itch.io to leave a comment.