OidZone Programmers Reference - Exerpt


Lord Generic Productions
Project: OidZone Programmer's Reference
Subject: Programming Theory


This document is intended to introduce you to Simultaneous Event Driven Programming, and how it applies to the OidZone Sprite Engine, the heart of OidZone. We will discuss some general programming theory, the issues involved, and how I addressed those issues in OidZone.

Procedure-Driven vs Event-Driven Programs
All computer programs can be divided more or less into two catagories:

Procedure Driven programs work sequentially, from beginning to end. You start the program with initial parameters, and the program does its thing and spits out a result. Examples of this are programs that compute PI to 10,000 decimal places, or slide show or self-running demo programs. Procedure Driven programs have a definate beginning, maybe where you input all your parameters, a middle, where computation happens, and an end, where you get some kind of output.

Event Driven programs are interactive. They work constantly in the background, and respond to your input. Anything you do to interact with the program is called an Event. An Event Driven program looks for events and processes them as they occur. The word processor I'm writing this on is an Event Driven program. It waits for me to type something. When I do, it displays the letters I type, and advances the cursor. At any time, I can perform any of a hundred or so separate functions, like bolding a word, or korekting my speling, or whatever. Event Driven programs have no idea what you are going to do when, they just respond to whatever you do whenever you do it.

Event driven programs are made up of smaller procedure driven programs. When you do an event, the program sends the appropriate input to the procedures, which compute and output some result that the main program. The word processor, for example, has procedures for getting the right letter from the keyboard, for storing the letter in the document I'm writing, displaying the appropriate letter on the screen in the appropriate font, and moving the cursor to the next letter position. The main program waits for my typing event, then sequentially goes through each of those procedures, then waits for the next event.

Sequential Event Driven vs Simultaneous Event Driven Programs
Event Driven programs generally fall into these Categories: Sequential Event Driven and Simultaneous Event Driven programs

Sequential Event Driven programs sit around and wait for you to do something, then process the events one at a time. My word processor is a Sequential Event Driven program. It looks for and processes events one at a time. Most Windows(tm) applications as well as spreadsheets, drawing programs, and most Adventure type games are Sequential Event Driven programs. They go action, reaction, action, reaction, etc...

Simultaneous Event Driven programs have many independent events taking place at the same time. Instead of the user's input driving the program, it's only one of many events the program is processing at any given time, and the program will process the other events and change the system state regardless of his input.

In Simultaneous Event Driven programs, time is sliced into discrete "frames." During each frame, many independent events may take place, including reacting to the user's actions. After all the events are processed, the programs "state", what the user sees on his screen, is updated all at once, so everything appears to be happening simultaneously. After the state is updated, then time advances to the next frame and it is processed.

OidZone is an example of a Simultaneous Event Driven program. During each frame, the program itself generates and processes many discrete events. These events include:

Resetting the Virtual Screen
Moving Oids around
Animating the Oids
Moving the player's ship
Moving and keeping track of shots
Processing collisions
Poping the shots when they hit something or when they reach their range
Breaking the oids\mines or destroying them when they are hit
Blowing things up
Scaling sprites
Merging sprites with the background and drawing them into the Virtual Screen
Wraping sprites when they reach the screen edges
Swarming the mines at the player
Updating the screen
Animating the logo
Animating the info bar at the top of the screen
Updating the scores when needed
Playing sound effects.
Displaying game messages, Game Over, Prepare to Enter, Player 2, etc.

OidZone also checks for player input. It reads the ctrl, alt, and shift keys simultaneously and the rest of the keyboard sequentially. Each frame it can process these user events simultaneously:

Thrust
Rotate left or right
Fire

along with one of these

Hyperspace
About OidZone
Quit Game
Flip Keyboard Controls

There is a lot happening bethind the scenes at any given time, and most of it the player has no control over. In Simultaneous Event Driven programming, your "characters" are given some initial parameters, and then are sent on their way, you don't usually know where. Every once in awhile, you check their progress, "correct" them if necessary, then let them go and do whatever they are supposed to do.

Example: Our Oids need the following initial information to do their job (oiding around):

X Horizontal position in the OidZone
Y Vertical position in the OidZone
dx Horizontal differential offset left or right
dy Vertical differential offset up or down
size Size - large, medium, or small
anim Animation frame 1-30 to start on. Each Oid should start on a different frame
active Is this Oid still "alive?"
type Is this an Oid or a Swarm Mine?

dx and dy determine which of the 12 possible directions the oid will move in. They are respectively the sin and cos of the angle the oid is moving times the speed of the oid in pixels per frame.

During each frame, OidZone:

Adds dx to X and dy to Y to get the new location of the Oid

Checks to see if it has reached either screen boundary. If so, it wraps X or Y or both to the correct screen position.

Chooses the next animation frame in the Oid Animation

If it's a mine, OidZone course corrects it so it's always moving toward the player.

Checks to see if it hit anything.

Draw appropriate sprite into Virtual Screen
Go on to next Oid

This same process is followed for EVERY character. The general flow for the program goes like this for each character:

Game Start:
Init_thing()
Set initial parameters of character(s)

During Game:
Set_VS()
Reset the Virtual Screen at the beginning of each frame

Do_thing()
Process player input, course correction AI, update animation frame, collision detection, adjust size and other object parameters, get sprite ready and send to Sprite Engine.

Do_interr()
Interactions with other objects. Say a Shot hits an Oid, maybe this would handle turning the shot off, breaking the Oid and creatiing a new Oid.

Do_next()
Go on to next character. The order you do the characters is important. The first Character processed is the first one drawn to the Virtual Screen, and will be displayed behind everything else that comes after it. If you want to blow up your ship, you do_explode() after you do_ship(), because you want the explosion on top of your ship sprite. The explosion will start small in the middle of the ship, then grow to bigger than the ship. At that point, you stop drawing the ship under the explosion, so when the explosion animation goes to black your ship is gone.

Do_junk()
Any behind the scenes stuff, like animating the game logo, info bar, or whatever.

Do_Screen()
Update the Graphics Screen. Each Do_thing() routine sends it's sprite and parameters to the Sprite Engine, which moves and clips the sprite, and then "draws" it into the Virtual Screen at the correct coordinates. The drawing routine creates a Screen_Update table, which tells Do_screen which areas of the Graphics screen need to be updated using the corresponding areas of the Virtual Screen. Do_screen then copies those regions from the Virtual Screen and display_images() them onto the Graphics screen. We do this once at the end of each frame, so all changes appear simultaneous. If we updated the screen as each sprite is drawn, overlapping objects would "flicker" as they are drawn sequentially. I'll explain this in more detail later.