Game Objects

In this section, you'll make a container for a PolygonGroup called a GameObject, which will be the base class for all objects in the games and demos in this tutorial. The idea is that a game object can manipulate its own state, including the polygon group's transform. Really, the GameObject by itself doesn't do anything, and it needs to be extended to accomplish anything cool. The GameObject class you'll create in this chapter will be just a start; you'll add on to it in later chapters when we discuss collision detection, path finding, and artificial intelligence. First, let's look the basic states of any game object. A game object can be anything, such as a static object, a projectile, a power-up, or an enemy. During the course of a game, a game object could be idle (not moving) or active (potentially moving around). Also, some objects can be destroyed, such as when an enemy is blasted or when a projectile collides with a wall. With this in mind, we give game objects three possible states: IDLE, ACTIVE, and DESTROYED, as shown in Screenshot.

Screenshot The game object life cycle.

Java graphics 09fig08.gif


When a game object is first created, it's in the IDLE state and can move to the ACTIVE state at any time. Likewise, when it's in the ACTIVE state it can return to the IDLE state at any time. From either the IDLE state or the ACTIVE state, a game object can change to the DESTROYED state. When in the DESTROYED state, a game object shouldn't return to any other state. The game manager should remove the DESTROYED game object from the world, and afterward the game object should be garbage-collected (assuming no other references to the game object exist). Different types of game objects follow this game object life cycle in different ways. For example, a static object could stay in the IDLE state for the entire game. A projectile might immediately jump to the ACTIVE state and stay there until it hits something, in which case it becomes DESTROYED. An enemy might start in the IDLE state and move to the ACTIVE state when it becomes visible. For example, if the enemy goes off the screen for a while, it might become IDLE again. Finally, an enemy moves to the DESTROYED state when the player blasts it enough times. With all this in mind, you'll create the GameObject class (see Listing 9.9). This class manages the state and provides several convenience methods for the game object's PolygonGroup and transform.

Listing 9.9 GameObject.java
package com.brackeen.javagamebook.game;
import com.brackeen.javagamebook.math3D.*;
/**
 A GameObject class is a base class for any type of object in a
 game that is represented by a PolygonGroup. For example, a
 GameObject can be a static object (like a crate), a moving
 object (like a projectile or a bad guy), or any other type of
 object (like a power-up). GameObjects have three basic
 states: STATE_IDLE, STATE_ACTIVE, or STATE_DESTROYED.
*/
public class GameObject {
 protected static final int STATE_IDLE = 0;
 protected static final int STATE_ACTIVE = 1;
 protected static final int STATE_DESTROYED = 2;
 private PolygonGroup polygonGroup;
 private int state;
 /**
 Creates a new GameObject represented by the specified
 PolygonGroup. The PolygonGroup can be null.
 */
 public GameObject(PolygonGroup polygonGroup) {
 this.polygonGroup = polygonGroup;
 state = STATE_IDLE;
 }
 /**
 Shortcut to get the location of this GameObject from the
 Transform3D.
 */
 public Vector3D getLocation() {
 return polygonGroup.getTransform().getLocation();
 }
 /**
 Gets this object's transform.
 */
 public MovingTransform3D getTransform() {
 return polygonGroup.getTransform();
 }
 /**
 Gets this object's PolygonGroup.
 */
 public PolygonGroup getPolygonGroup() {
 return polygonGroup;
 }
 /**
 Sets the state of this object. Should be either
 STATE_IDLE, STATE_ACTIVE, or STATE_DESTROYED.
 */
 protected void setState(int state) {
 this.state = state;
 }
 /**
 Sets the state of the specified object. This allows
 any GameObject to set the state of any other GameObject.
 The state should be either STATE_IDLE, STATE_ACTIVE, or
 STATE_DESTROYED.
 */
 protected void setState(GameObject object, int state) {
 object.setState(state);
 }
 /**
 Returns true if this GameObject is idle.
 */
 public boolean isIdle() {
 return (state == STATE_IDLE);
 }
 /**
 Returns true if this GameObject is active.
 */
 public boolean isActive() {
 return (state == STATE_ACTIVE);
 }
 /**
 Returns true if this GameObject is destroyed.
 */
 public boolean isDestroyed() {
 return (state == STATE_DESTROYED);
 }
 /**
 If this GameObject is in the active state, this method
 updates its PolygonGroup. Otherwise, this method does
 nothing.
 */
 public void update(GameObject player, long elapsedTime) {
 if (isActive()) {
 polygonGroup.update(elapsedTime);
 }
 }
 /**
 Notifies this GameObject whether it was visible or not
 on the last update. By default, if this GameObject is
 idle and notified as visible, it changes to the active
 state.
 */
 public void notifyVisible(boolean visible) {
 if (visible && isIdle()) {
 state = STATE_ACTIVE;
 }
 }
}


In this default game object, the game object's polygon group is updated only if it's in the ACTIVE state. A reference to the player's game object is a parameter in this method, so any game object can know the location of the player. Obviously, it is pretty common for enemies to want to know where the player is. Also, notice the notifyVisible() method. This method is designed to tell an object whether it's visible in every frame. If it's visible and the current state is IDLE, the game object automatically changes to the ACTIVE state. The rules of the game object life cycle are not strictly enforced in this class: You could theoretically move a game object state out of the DESTROYED state back to the ACTIVE state, but this could be pointless if the game object was already removed from the world.



   
Comments