The Arcade Game Engine
Total Page:16
File Type:pdf, Size:1020Kb
C Sc 335 (OO Design and Programming) Final Project Fall 2010 Final Project: Virtual Arcade Cabinet Written By: Jude Nelson Run By: Eric Stewart Overview Back in the 1980s, video arcade games were in their prime. Local restaurants, pubs, and arcades lured customers with all of the latest titles: Pacman, BattleZone, Galaxian, Donkey Kong, Tempest, Gee Bee, Dragon's Lair, Dig Dug, Tron, Asteroids, Centipede, Defender, and more. (Un)fortunately, the rise of home videogame systems and home computers relegated these gems to the back storage rooms of many establishments. They are not forgotten, however--even today, arcade cabinets are collected by enthusiasts and arcade ROM emulation systems such as MAME allow my generation to experience these relics first-hand on modern hardware. In this semester project, you will be creating a re-usable and modular game engine in Java that will allow enthusiasts to quickly implement and bring back to life the videogames of lore within the comfort of our own homes. The focus of this project is not on the games themselves, but on the engine that will allow us to emulate these games. Game Engine Intro From Wikipedia (http://en.wikipedia.org/wiki/Game_engine): "A game engine is a software system designed for the creation and development of computer and video games. There are many game engines that are designed to work on video game consoles and desktop operating systems such as Linux, Mac OS X, and Microsoft Windows. The core functionality typically provided by a game engine includes a rendering engine (“renderer”) for 2D or 3D graphics, a physics engine or collision detection (and collision response), sound, scripting, animation, artificial intelligence, networking, streaming, memory management, threading, and a scene graph. The process of game development is frequently economized by in large part reusing the same game engine to create different games." The game engine you will create for this project will be relatively simple, but it will be sufficient to emulate most 1980's arcade games. As it turns out, 1980's arcade games have a lot in common: They all have at least one user-controlled entity (the user's avatar). They all have 2D representations (with the exception of BattleZone and Tempest, which are wire-frame 3D). They all have a consistent scoring system. They all have a user-modifiable high score table. They all have a playfield of non-user objects, each with a specific, pre-defined behavior. Some of the objects are scenery and are just for show; some are entities that can "kill" the user's avatar upon physical contact; some impede the user's avatar's movement; some can "kill" other objects upon contact, etc. They all have a simple goal the user must complete via performing a sequence of actions through their avatar in the game. They all have a way to start and stop at any time. They all have some sort of sound effects. They all have a series of buttons (and sometimes joysticks) from which to receive user input. They all have a concept of "lives". The game ends when the user spends all of his/her "lives." Since these games have a lot in common, we can create a game engine that handles all of this functionality. Then, to implement a 1980s video arcade game, all we have to do is create a class that describes to the engine the specifics of the game and how to go about recreating it. The idea is to make all of these details invisible to the game engine itself, while being flexible enough to accommodate a wide variety of videogames. The game programmer should have to specify as little as possible about the game to make it work. The Arcade Game Engine A 1980s arcade game, abstractly, can be described as a collection of actors (at least one of which is controlled by the user), a set of states, and mechanism to transition between states when needed. An actor is an entity within a game that serves a purpose relevant to gameplay. For example, in the game Asteroids, the wedge-shaped ship is the user-controlled actor, while all of the asteroids, alien ships, bullets, and explosions are game-controlled actors. A game state is simply the pre-defined behavior of the game under certain pre-defined conditions. Using our Asteroids example, the game starts out in the "title screen" state, during which the game engine displays the title of the game and possibly a computer-controlled demo of the game. When the user inserts a coin, the game transitions to the "game play state", where the game will respond to user input, and optionally play sound effects and update the game-controlled actors until the user has run out of lives. Then the game transitions to the "end game state", where the game informs the user that they have lost (or won). When this state terminates, the game may transition to the "enter your initials" state if the user has earned a high enough score to be entered into the high score table. This state (and the "end game state", if the user does NOT have a high score) transitions to the "display high score" state, where the highest 10 or so scores are displayed to the user. Finally, the game transitions back to the "title screen" state. There are many state transition possibilities in general, but this is one of the most common state transition patterns you will encounter (your game engine should not assume that every game behaves like this, however!). The game engine should define at least one class that describes an actor. In 1980s arcade games, actors always have at least these attributes: position in the scene spatial dimensions in the scene a way to update itself periodically (e.g. what the actor does on a frame-by-frame basis if nothing interacts with it) In our Asteroids example, an asteroid rotates slightly and moves slightly in a pre-defined direction once per frame. An explosion will radiate particles outward for a pre-defined number of frames before being destroyed by the game engine. The user's ship will try to get the user's input and act on it (if the user is inputting commands). a way to interact with another actor, based on the game state and the other actor's type and attributes In our Asteroids example, an asteroid will split into two smaller asteroids if a bullet actor occupies the same spatial dimensions as the asteroid, but an asteroid will do nothing if it intersects another asteroid. If the asteroid occupies the same space as the user's ship, it will destroy the ship if the user is "alive", or will do nothing if the user is already dead. an avatar This is a data structure that describes what the actor "looks like" in the playfield. In our Asteroids example, the user-controlled ship's avatar looks like a triangular wedge. An Asteroid looks like an amorphous polygon. An alien ship looks like a flying saucer. A bullet looks like a point. An explosion looks like a collection of points. a way to provide the scene with an avatar to render There are other actor attributes, of course, but these are universal. The game engine is responsible for: scene management Managing and rendering the visible components of the game. sound management Managing and playing back music and audio sound effects. input management Getting valid user input in a timely fashion. object management Retrieving and saving data to and from disk. actor management Creating, destroying, and updating the actors, based on the state of the game and the attributes of other actors. Scene Management The game engine needs to have access to the Swing container on which you intend to render each frame of the game. Given a collection of actors, it should be able to render the avatar for each actor. The actor should only know how to give its avatar to this part of the engine, and the engine should be able to access the avatar for information on how to render it. This information can be an image, a geometric description, or a method to be called that will perform the rendering instructions directly. This part of the engine is NOT responsible for loading avatar information from disk, but it may optionally cache the information. This part of the codebase should be able to determine what state the game is in, so it can display things other than actor avatars for the user (e.g. the high score table, the title screen, etc.) Keep in mind, however, that the engine renders avatars, not actors (or anything else). Errors related to rendering should be handled and recovered from as elegantly as possible and only report irrecoverable errors to the user. The code in this section may optionally run in separate threads, so as to render a particular number of frames per second regardless of how light the system load may be. Sound Management The engine needs to be able to load or stream sound effects and music from disk via the Object Management code. It should be able to cache sound effects in RAM, but background music should be streamed. It should be able to handle errors and exceptions transparently and report an error to the user only if it cannot recover. The code that governs sound playback should be interruptible, so sounds can be stopped immediately if necessary. The sound management logic must appear to the outside as hardware-agnostic--that is, outside entities should not need to know anything about how the Sound Management code gets the sounds and plays them for it to be able to ask it to play a sound.