Construction of Basic Entities

When first deciding on a game’s premise, designers usually have visions of the eventual gameplay in their minds. They envision large starships hurling energy blasts at nearby rocks to avoid a destructive collision, or small amphibians trying desperately to avoid being crushed by traffic. Regardless of the genre or implementation of the game, certain common attributes of the game world are needed for representation of items in game. For example, a player-controlled frog will always have at a bare minimum a current position with an x- and y-representation, as well as a height and width. If we decide to take our game into the world of graphics, we need some way to show the frog on the screen. When these core elements can be pulled from a game, they compose the set of attributes needed when developing game entities.

An entity is an object that has attributes needed for playing the game, without regard to whether the game is 2D or 3D. Some of the most basic components an object could hold follow:

  • A position represented by an x-, y-, and, z-coordinate system

  • A height and width value for representing bounds of the particular object

  • A state that indicates at minimum ALIVE or DEAD

  • The current frame of an animation sequence

  • Information relating to current velocity and current levels of heath or armor

  • An image or generalized access to relevant content for the game (such as models or textures)

This list could easily go on and on until we cover an entire book on the subject (or at least a good portion of one). This section identifies these basic components in a fundamental implementation. Do not consider this discussion anything more than a starting point for developing game entities. A great many implementations, ideas, and opinions on the subject are available—and this is just to get a new game programmer started.

Building the Basic Entity

Now that a general idea of what an entity is has been established, let’s take the steps to construct one. Immediately, a number of important questions come to mind, and there is much to be decided. Should entity be a class? An interface? How should the internal methods for accessing attributes be handled? Although these questions are important, it is even more important to take a second to contemplate the ideas of game programming. Developing games is a process not a solution. When a programmer (even a skilled one) begins programming in a new medium, a certain amount of time is required to transfer the existing skill set that may exist to the new problem domain. We are trying to learn to program games; the coding process might seem similar, but it is not always directly transferable. For the sake of providing a common platform from which to begin, the entities for this basic system will be implemented as a class with a set of interfaces that will allow us to extend those basic attributes as needed.

Let’s look at a sample entity class called Actor. The Actor class takes its name from a long line of simulation programs and other nomenclature. Its name defines that an Actor will be responsible for exhibiting some sort of prescribed behavior, either from a player-controlled instance or any of the numerous baddies that are bound to make their evil presence known. A sample version of the Actor class follows:

class Actor implements Updater,Drawable,Loggable{   static final int ALIVE = 1;   static final int DEAD  = 2;   private int state;   private int x;   private int y; private int height; private int width; //default constructor. Actor(){} //accessor functions for updating the entity public void setState(int curr_state){     state = curr_state; } public int getState(){     return state; } public void setX(int curr_x){     x= curr_x; } public int getX(){     return x; } public void setY(int curr_y){     y = curr_y; } public int getY(){     return y; } public void setHeight(int curr_height){     height = curr_height; } public int getHeight(){     return height; } public void setWidth(int curr_width){     width = curr_width; } public int getWidth(){     return width; } //update ourselves properly public void update(){} //can we collide with you? public boolean collidesWith(Updateable other) {     boolean bool = true;     return  bool; } //If we can collide, then lets do so if needed. public void handleCollisions(){} //can I be seen this frame? public boolean isVisible() {       boolean bool = true;     return  bool; } //Local definition of drawing routines as needed. public void Draw(){} //Make sure we can write out debug and major event info. public void logDebugString(Object s){} public void logString(Object s){}

This class gives us straightforward access to all the major attributes and functions that might be needed in a 2D game. With extended definitions of the functions and a few added members, this code could be converted and extended into a 3D game. Though certainly not the only way to tackle this problem, this solution is a great place to begin from an architectural perspective.

One of the things that probably jumps quickly to mind are the three main interfaces that Actor is responsible for implementing. Each of these interfaces is responsible for taking care of certain aspects of the gameplay and the execution of the game logic. Let’s look at each of them individually.

public interface Updater{   public boolean collidesWith(Updateable other);   public void handleCollisions();   public void update(); }

The Updater interface is responsible for defining the core collision routines for this particular Actor, as well as specifying how he will update himself when the time comes. Each Actor that is alive during a pass in the game loop must know how it is to process its updates. Generally, updates are directly related to the physics model that is implemented into the game. If the Player Actor has a speed of 4 milliseconds, the coordinates should be updated to reflect this change in position in each frame. The actual implementation of the update() method is left to the domain of the game in question. The collidesWith() method will be implemented to identify if this Actor can collide with another Updateable object. It will return true if an Actor can collide with a specified other. This feature allows us to define specific collisions for specific interactions rather than one main solution for every object in the world. The handleCollision() method will process the selected collision routine once the need to do so has been identified.

The Drawable interface is listed as follows:

public interface Drawable{     public boolean isVisible(); public void draw();+ }

In the Drawable interface, each Actor class knows whether it should be drawn to the screen through the isVisible() method. This method can be used as a control mechanism and a built-in optimization for a game. If most of the Actor classes in a game don’t need to be drawn, they can short-circuit the code that would normally trigger the group to draw, or process collisions, for example. This characteristic allows the game to do less work with respect to the current situation in the game. The draw() method is ultimately what games are all about. This method allows for the local implementation of the display as needed by the given entity. This implementation could be rendering code for a 2D or 3D game and is defined based on the overall usage of graphics in a given game. The draw() method is left mostly for conceptual purposes. Actual games may find limited use for the localized implementation of rendering beyond specifying a particular style of rendering, such as drawing an object reversed from its normal facing or causing some other special coloring effect to be used on the Actor. Many games choose to work with a construct called DisplayManager.

DisplayManager is responsible for dealing directly with the drawing of the objects and pulls information from the Actor classes present in the game to create the actual display. These methods will be further discussed in Chapter 3, “2D Graphics Programming.”

The Loggable interface may seem the least obvious with regard for the need to implement this interface at the base entity level. The definition of the interface follows:

public interface Loggable {   public void logDebugString(String s);   public void logString(String s); }

Many games that are written in Java are window-based applications or applets that allow the developers to use the standard output on the machine to print and display messages regarding input or execution. This is one of the coolest features in Java. The concern does arise as Java games have a more full-screen implementation. When an application takes over responsibility for a full-screen application, the debugging results may be limited. Creating a basic control that allows the Actor or its subclasses to write to the screen or to a text or HTML file is a particularly valuable tool. The specific implementations of these methods are not particularly difficult to imagine. One thing that should be noted is the argument list could be modified to take objects instead of just strings. This modification allows for a much more open-ended and robust implementation. Some developers prefer to work with a system-wide logger that can retrieve the information needed from the Actor classes and any other objects within the system. Either method works equivalently.

At this point this core concept has been outlined, and now the overall implementation should be a bit more thoroughly explained. Any number of Actor classes can exist in a game. Some of them will be mobile, some of them can be animated, some modify others when they interact, and some of them are controlled by AI. They can be created and extended as far and wide as you need, but they still can lay claim to that core characteristic that an object must be displayable in a game world.

Although this idea isn’t a big step for programmers who use object-oriented programming on a daily basis, consider the alternative by which many early games were coded. So many global variables floating around made debugging incredibly difficult. Everything was customized to the application itself, meaning a lot of rework was required to get a basic game framework in place to run on the next project. Many game programmers ditch a lot of their previous work anyway, but that’s another story.

Now that the discussion has further detailed the concept of the Actor class, progress can continue. Remember, this is a rudimentary discussion of these classes, and the concepts are intended to be expanded on as needed. This chapter is by no means the final word on game entities. So, what comes next? Now this family of objects needs management.



Practical Java Game Programming
Practical Java Game Programming (Charles River Media Game Development)
ISBN: 1584503262
EAN: 2147483647
Year: 2003
Pages: 171

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net