Space Pirates: The Quest For More Booty

Frank Lesniak
Matt Gore
Scott Johnson

 

Introduction

In the beginning, our team envisioned a fabulous game - similar to the classic Solar Winds. It would be a 2D space flying game that incorporated missions and a trading/money system.

Once we began coding our project, we immediately found that such a task would be impossible in the time we had allocated. Thus, we have instead worked toward a game-ready engine that could easily be used to create a mission-based storyline complete with a trading system. The data structures are all in place - all that needs to be added is the story itself.

Our engine has many applications besides space games. It is not hard to envision the same engine being used for a Zelda-like game. Instead of a space ship, you have Link. Instead of bullets/missiles, you have a sword. Instead of asteroids, you have a forest (trees). The missions and monetary system would not be difficult to implement.

Thus, our goal is to create a fully working 2D data structure/graphics engine to be able to be used to create a mission-based game with some system of trade.

 

We are using Orkut (http://www.orkut.com) to collaborate via the Internet.

 

Data Structures

Sparse Array

  • List of addresses that each point to the first object in any given row

  • Length=RowsInUniverse*4 bytes (RowsInUniverse dwords)

Star Array

  • List of addresses that each point to the first star in any given row

  • Length=100 dwords (400 bytes)

AsteroidObject

  • Memory address of next object in sparse array’s row (0 if NULL) – 4 bytes (dword)

  • Memory address of previous object in sparse array’s row (0 if this is the first object) – 4 bytes (dword)

  • Row number (i.e. the index of this object in SparseArray) – 4 bytes (dword)

  • Column number (i.e. the index of this object in the current row) – 4 bytes (dword)

  • Object Size (how many “spots” this object takes up, measured to the right and downward – each object is a square) – 2 bytes (word)

  • Object Type – number that identifies the object – 2 bytes (word)

StarObject (NOT in "space" sparse array - EXIST ONLY IN STAR ARRAY)

  • Memory address of next object in sparse array’s row (0 if NULL) – 4 bytes (dword)

  • Memory address of previous object in sparse array’s row (0 if this is the first object) – 4 bytes (dword)

  • Row number (i.e. the index of this object in StarArray) – 2 bytes (word)

  • Column number (i.e. the index of this object in the current row) – 2 bytes (word)

  • Object Type – number that identifies the object – 2 bytes (word)

  • Velocity Modifier - factor that identifies how many times slower a star is than the ship (i.e we want to multiply the ship's velocity vectors by this modifier to effectively slow the stars down) - 2 bytes (word)

Pickups/Bullets/Missiles/Lasers:

  • Memory address of next object in sparse array’s row (0 if NULL) – 4 bytes (dword)

  • Memory address of previous object in sparse array’s row (0 if this is the first object) – 4 bytes (dword)

  • Row number (i.e. the index of this object in StarArray) – 4 bytes (dword)

  • Column number (i.e. the index of this object in the current row) – 4 bytes (dword)

  • Object Size (how many “spots” this object takes up, measured to the right and downward – each object is a square) – 2 bytes (word)

  • Object Type – number that identifies the object – 2 bytes (word)

  • Up Velocity - 2 bytes / 1 word (signed)

  • Right Velocity - 2 bytes / 1 word (signed)

  • Quantity/Damage - 2 bytes / 1 word

Planets:

  • Memory address of next object in sparse array’s row (0 if NULL) – 4 bytes (dword)

  • Memory address of previous object in sparse array’s row (0 if this is the first object) – 4 bytes (dword)

  • Row number (i.e. the index of this object in StarArray) – 4 bytes (dword)

  • Column number (i.e. the index of this object in the current row) – 4 bytes (dword)

  • Object Size (how many “spots” this object takes up, measured to the right and downward – each object is a square) – 2 bytes (word)

  • Object Type – number that identifies the object – 2 bytes (word)

  • Pointer/Index into PlanetNameArray - 2 bytes (word)

  • PlanetFlags (identifies what kinds of locales a planet might have) - 2 bytes (word)

  • Person 0 Type - 2 bytes (word)

  • Person 1 Type - 2 bytes (word)

  • Person 2 Type - 2 bytes (word)

  • Object Type (stores a mission-oriented object for pickup by ship) - 2 bytes (word)

  • Price Modifier - 8 bytes (qword)

  • Market Flags (identifies what's for sale in the market) - 2 bytes (word)

Ships:

  • Memory address of next object in sparse array’s row (0 if NULL) – 4 bytes (dword)

  • Memory address of previous object in sparse array’s row (0 if this is the first object) – 4 bytes (dword)

  • Row number (i.e. the index of this object in StarArray) – 4 bytes (dword)

  • Column number (i.e. the index of this object in the current row) – 4 bytes (dword)

  • Object Size (how many “spots” this object takes up, measured to the right and downward – each object is a square) – 2 bytes (word)

  • Object Type – number that identifies the object – 2 bytes (word)

  • Up Velocity - 2 bytes / word (signed)

  • Right Velocity - 2 bytes / word (signed)

  • Direction (0-35) - 2 bytes / word

  • Max Velocity (upgradeable) - 2 bytes / word (signed, but never negative)

  • Pointer/Index into ShipNameArray - 2 bytes / word

  • Hit Points (shield strength) - 2 bytes / word

  • Laser Type - 2 bytes / word

  • Max Quantity (maximum total quantity ship can hold - not maximum number of object types! - upgradable) - 2 bytes / word

  • Cargo Size (number of object types that this ship can hold - upgradable) - 2 bytes / word

  • Thereafter, the structure holds the following two elements for each of the total possible cargo objects (specified by Cargo Size above)

  • Cargo Type (specifies the "object type" of the cargo, 0 if empty) - 2 bytes / word

  • Cargo Quantity (specifies how many of this type of object the ship is carrying - mainly used for weapons/credits) - 2 bytes / word

 

Code Inspection/Testing:

The code will be checked by each one of us, and since it is fairly modular it will be easy to check the test cases for one object, and then apply those principles to the rest of the similar objects. We will be sure to test each function as it is written.

 

MAIN LOOP PSUEDO CODE

 _InstallHandlers

Allocate Memory for Data Structures

Initialize Data Structures

Initialize Game Flags

Create Universe

Evaluate Game Flags & Jump to appropriate code section

ControlLoop:

_DisplayMenu

            Evaluate menu choice:

If  Resume

set space mode flag

            else if load

                        set load flag

            else if save

                        set save flag

            else if new game

                        set new game flag

            else if quit

                        set quit flag 

jmp to EvalGameFlags  

SpaceLoop:           

Mask GameFlags so that we only have bits 6 & 5, shift right so that it is 0, 1, 2, 3 -> SpeedChange

Mask GameFlags so that we only have bits 8 & 7, shift right so that it is 0, 1, 2 -> DirectionChange

_ChangeVelocity(*OurShip, word SpeedChange, word DirectionChange)

Set GameFlags' bits 8, 7, 6, & 5 to 0

//Fireweapon/Drop Code Here

//AI Code Here

NULL -> CurrentObject

.UpdateSpaceLoop

_FindNextObject(CurrentObject) -> CurrentObject

If CurrentObject=NULL

    then jump to .Draw

_IsMoving(CurrentObject) -> DirectionObjectIsMoving

If DirectionObjectIsMoving=-1 //Not moving

    then jump to .UpdateSpaceLoop

_MoveObject(CurrentObject, DirectionObjectIsMoving)

_CheckCollision(CurrentObject) -> (ObjectCollidedWith, Type) //Priority goes to bounce before absorb

If Type=Nothing

    then jump to .UpdateSpaceLoop

If Type=Bounce

    _BounceUpdate(CurrentObject, ObjectCollidedWith)

    Jump to .UpdateSpaceLoop

If Type=Absorb

    _AbsorbUpdate(CurrentObject, ObjectCollidedWith)

    Jump to .UpdateSpaceLoop

.Draw

_DrawBackground

_DrawStarsToBuffer

_DrawCloseObjectsToBuffer

//_DrawStatusBarToBuffer, etc

_CopyBufferToScreen

End of Space Loop (return to tick control)

 

Control Loop

New

            call  _GenerateUniverse

            set flag to control mode                       

Load

            call       _LoadGame

            set flag to control mode

Save

            call       _SaveGame

            set flag to control mode 

EvalGameFlags 

            check game mode flags 

            if space mode

                        jmp      SpaceLoop

            else if control mode

                        jmp      ControlLoop

            else if    load

                        jmp      Load

            else if save

                        jmp      Save

            else if new game

                        jmp      New 

            else if quit

                        jmp      Quit 

End of Control Loop (return to tick control)

Planet Loop

            not yet implemented...

            will handle/evaluate users choice based on mouse clicks, etc

            will handle trading/item exchanges

            will handle communication/conversation

End of Planet Loop (return to tick control)

Quit: 

            _UninstallHandlers 

            exit to dos

 

 

Major Sections of our Program:

Space (movement, collision, object pickups, etc)

Planet Mode (trade, get missions, drop off/pickup mission objects, etc).

 

 

Functions (Major):

_InstallHandlers - Installs Keyboard, Mouse, Timer, etc. ISRs

_UninstallHandlers - Removes Keyboard, Mouse, Timer, etc. ISRs

_DisplayMenu - Displays a menu of choices for the user, according to which game flags are set

obj* _FindNextObject(obj*) - Finds the next object in the sparse array after the passed in object. Returns a pointer to that object

short _IsMoving - Check's an object's status to see if it is moving on this cycle. Returns 1 if so.

(long, obj*) _DetectCollision(obj*) - Returns collision type and object pointer to object that this object is colliding with)

_BounceUpdate(obj1*, obj2*) - Update both obj1's and obj2's information to according to a bounce

_AbsorbUpdate(obj1*, obj2*) - Figures out which of two objects gets absorbed and deletes it from Space

_MoveObject(obj*) - Moves the object in the direction specified by its velocity vector

_FireWeapon(obj*, keypress) - Creates appropriate weapon (according to keypress) in front of obj with a velocity at least that of the obj (same direction)

_ChangeVelocity(obj*, keypress) - Changes the object's velocity (direction, too) according to keypress

_UpdateBackground(viewershipobj*) - Updates the background

_MapBackground - Maps the Background to the video buffer

[objects*] _FindScreenObjects(viewershipobj*) - Finds all the object within a radial distance of the ship and returns them in a pointer to an array

_MapScreenObjects - Map the screen by finding all objects within a radial distance of the viewer's ship and putting them on the screenbuffer in their respective locations

_UpdateOverlay - Updates the screen's overlay

_MapOverlay - Maps the screen's overlay to video buffer

_DrawScreen - Copies the video buffer to the video memory

_GenerateUniverse - Creates objects at random locations in the sparse array

_LoadGame - Loads a game

_SaveGame - Saves current game

 

Some Complicated Algorithms:

Insertion Algorithm

  • If (rowptr=NULL) or (rowptr's 1st element's column >= new element's column)
    A=RowPtr=1st element in row (could be NULL)
    RowPtr=New Address
    New's Previous Pointer = NULL
    New's Next Pointer = A
    If A not= NULL then A's previous pointer = New pointer address
  • ELSE
    while not (A's next pointer = NULL or A's next element's column >= new column)
        then A=A's next element
    B=A's next pointer
    A's next pointer=New Address
    New's previous pointer=A
    New's next pointer=B
    if B not= NULL then B's previous pointer = New Address

 

Deletion Algorithm

  • If (deleteThis=NULL) then ERROR!
  • else if (DeleteThis' Previous Pointer not = NULL)
    ColumnPtr=DeleteThis' Next Ptr=A
    If A not = NULL then A's previous pointer = NULL
  • else //deleteThis' previous pointer=A not = NULL
    B=deletethis's next pointer
    A's Next Pointer = B
    if B not = NULL then B's previous pointer=A