One
essential “core part” of your engine & game, are entities. It’s a root
class used for many different “things” in your game. Dynamic things I should
add. Stuff that can be spawned, eventually in big numbers, stuff that can be
removed/killed. Things that can move or think, and have their own status (ie. “dead”,
“very angry”, “watching TV”, …). You, my friend, are an Entity. And so is your mother.
All the junk in this Tower22 kitchen, but also the lightsources, dirt decals, floor, walls, and invisible (A.I. nodes, sound emitters) are entities. 3D entities mostly, but the idea is the same.
In
this LibGDX case, the Entity is also basically a wrapper around the “Sprite”
class, though keep in mind that not every Entity is necessarily a visual thing.
A sound emitter could also be considered as an entity. So the very abstract
base class, doesn’t even have a Sprite. Yet most of them are drawable. The very
base entity class has the following properties:
public class EnEntityBase {
int entityId; // Unique number. Can be used for searching
String name; // Name like "Player". Can be used for searching as well, though may not be unique
Vector2 position; // Meters away from center
Vector2 size; // In meters
float rotationAngle; // In degrees
} // EnEntityBase
Note the
position and size are (LibGDX) 2D vectors. They are just tuples (X and Y
coordinate), but also include all kinds of handy math functions we may need
later on. Oh, and witness here how we made a firm decision for our engine here:
it’s a 2D engine. Otherwise we would have to use Vector3 types, to begin with
(amongst some other differences).
Size is
used for setting Sprite dimensions, in case of drawable entities. But it could
also be an ellipsoid, in case of a trigger or sound effect that starts buzzing
once the camera is within range.
Most
basic functions we are about to add now, are either “virtual” (doing nothing at
this abstract level), or involve the coordinate system. Setting positions and
such. And then there are a few “virtual” methods, like render(). The base class
doesn’t do anything with it, but other classes that inherit, can override this
method. For starters, the class would look like this (function implementations
missing):
public class EnEntityBase {
int entityId; // Unique number. Can be used for searching
String name; // Name like "Player". Can be used for searching as well, though may not be unique
Vector2 position; // Meters away from center
Vector2 size; // In meters
float rotationAngle; // In degrees
boolean flagKill; // If true, next update shall return false, so it gets removed from the entitySystem
public void kill()
{
this.flagKill = true; // Return false next update cycle
} // kill
public boolean update( float deltaSecs ) {
return (this.flagKill == false);
}
public void render( Batch batch )
public int getId()
public void setId( int id )
public String getName()
public void setName( String name )
public Vector2 getSize()
public void setSize( float radius )
public void setSize( float width, float height )
public Vector2 getPosition()
public void setPosition( Vector2 pos )
public void setPosition( float x, float y )
public void move( Vector2 direction )
public void move( float deltaX, float deltaY )
public float getRotation()
public void setRotation( float angleDegrees )
public void rotate( float deltaDegrees )
} // EnEntityBase
Note the
functions “render” and “update”. Render is about drawing, but may not be called
if the entity is invisible / off the screen. Update on the other hand is always
called, regardless. So, where render is just for drawing, update is for A.I.,
updating animation frames, doing physics, et cetera. Update returns TRUE or
FALSE. FALSE means the entity wants to get killed, removed from the system,
self-destruct.
Another
thing to explain: the difference between “setPosition” and “move”, where the
latter adds a delta up to the existing position, while “set” changes it. Same
thing for rotate.
Next
file would be “EnEntitySprite”. Another kinda global, high-level class. It
overrules the Base class, and adds a LibGDX sprite:
public class EnEntitySprite extends EnEntityBase {
Sprite sprite;
public EnEntitySprite( )
{
this.sprite = new Sprite( );
this.setSize( 2 );
this.setPosition( 0,0 );
} // create
@Override
public void render( Batch batch )
{
// Update Size / origin / position
float width = this.size.x * this.renderScale;
float height= this.size.y * this.renderScale;
this.sprite.setSize( width, height );
this.sprite.setOrigin( width * 0.5f, height * 0.5f );
this.sprite.setPosition( this.position.x - width * 0.5f, this.position.y - height * 0.5f );
// Render
this.sprite.draw( batch );
} // render
...
} // EnEntitySprite
The plan
for today is to replace the original (LibGDX sprite) in the Game code with this
class above – just to see if it works. We need to add one more thing first
though, the sprite image itself. Grab your pencils and move on to the next chapter gentlemen.
No comments:
Post a Comment