More moving stuff around

git-svn-id: https://aklabs.dyndns.org/svn/aklabs/trunk/games/spaceshooter@52 eb184899-6090-47d4-a65b-558f62f6ea1c
This commit is contained in:
andrew
2010-07-29 01:46:34 +00:00
commit 6a0f35c88a
110 changed files with 24350 additions and 0 deletions

268
cpp/Character.cpp Executable file
View File

@@ -0,0 +1,268 @@
#include <libgame/libgame.h>
#include "Character.h"
#include "GameLogic.h"
#include "Common.h"
#include "GameDisplay.h"
Character::Character()
{
this->lastDirChangeTime = SDL_GetTicks();
}
void Character::update()
{
GameStatus &status = GameStatus::NewSingleton();
//GameOptions &opts = GameOptions::NewSingleton();
GameDisplay &display = GameDisplay::NewSingleton();
Game &game = Game::NewSingleton();
//std::cerr << "Updating character with userType " << this->userType << "\n";
if ( !this->hasState(STATE_DYING) && !this->hasState(STATE_DEAD) ) {
if ( (this->userType & ENEMYTYPE_ENEMY2) == ENEMYTYPE_ENEMY2 ) {
//std::cerr << "WAVY ENEMY IS CHECKING TIMES\n";
if (SDL_GetTicks() > (this->lastDirChangeTime + 1000)) {
if ( this->hasState(STATE_MOVERIGHT) ) {
this->removeState(STATE_MOVERIGHT);
this->addState(STATE_MOVELEFT);
} else {
this->removeState(STATE_MOVELEFT);
this->addState(STATE_MOVERIGHT);
}
this->lastDirChangeTime = SDL_GetTicks();
} else {
if ( this->velocity.x == 0 ) {
this->velocity.x = 3;
this->addState(STATE_MOVERIGHT);
}
}
} else if ((this->userType & ENEMYTYPE_ENEMY3) == ENEMYTYPE_ENEMY3 ) {
if ( this->velocity.x == 0 ) {
this->velocity.x = this->velocity.y;
}
if ( this->target != NULL ) {
if ( this->target->getPosition().x - this->position.x > -(this->velocity.x) ||
this->target->getPosition().x - this->position.x < this->velocity.x ) {
this->position.x = this->target->getPosition().x;
} else if ( this->target->getPosition().x < this->position.x ) {
this->removeState(STATE_MOVERIGHT);
this->addState(STATE_MOVELEFT);
} else if ( this->target->getPosition().x > this->position.x ) {
this->removeState(STATE_MOVELEFT);
this->addState(STATE_MOVERIGHT);
}
if ( this->target->getPosition().x == this->position.x ) {
this->velocity.y = status.enemyVelocity.y;
} else {
this->velocity.y = status.enemyVelocity.y / 2;
}
if ( this->target->hasState(STATE_DEAD) || this->target->hasState(STATE_DYING) ) {
this->target = NULL;
}
}
} else if ( (this->userType & ENEMYTYPE_ENEMY4) == ENEMYTYPE_ENEMY4 ) {
if ( this->target != NULL ) {
if ( this->position.x - this->velocity.x <= 0 ) {
this->removeState(STATE_MOVELEFT);
this->addState(STATE_MOVERIGHT);
} else if ( this->position.x + this->velocity.x > 800 ) {
this->removeState(STATE_MOVERIGHT);
this->addState(STATE_MOVELEFT);
}
if ( this->position.y + this->velocity.y > 600 ) {
this->removeState(STATE_MOVEDOWN);
this->addState(STATE_MOVEUP);
} else if ( this->position.y - this->velocity.y <= 0 ) {
this->removeState(STATE_MOVEUP);
this->addState(STATE_MOVEDOWN);
}
}
}
}
if ( this->health <= 0 && (!this->hasState(STATE_DYING))) {
std::cerr << "Character " << this << " is now dying\n";
game.playSound(this->deathSound);
this->setState(STATE_DYING);
if ( ((rand()%100)+1) <= status.powerDropChance ) {
Actor *pwup = game.newActor();
if ( pwup != NULL ) {
int pwuptype = (rand()%3)+1;
std::cerr << "Generating powerup type " << pwuptype << "\n";
switch ( pwuptype ) {
case 1:
pwup->setUserType(ACTOR_TEAM_POWERUP | POWERUP_SPREADSHOT);
pwup->addAnimation(game.getAnimation(ANIM_PWUP_SPREADSHOT), STATE_DEFAULT);
break;
case 2:
pwup->setUserType(ACTOR_TEAM_POWERUP | POWERUP_ONEUP);
pwup->addAnimation(game.getAnimation(ANIM_PWUP_ONEUP), STATE_DEFAULT);
break;
case 3:
pwup->setUserType(ACTOR_TEAM_POWERUP | POWERUP_SHIELDRECHARGE);
pwup->addAnimation(game.getAnimation(ANIM_PWUP_SHIELD), STATE_DEFAULT);
break;
case 4:
pwup->setUserType(ACTOR_TEAM_POWERUP | POWERUP_BIGSHIP);
pwup->addAnimation(game.getAnimation(ANIM_PWUP_BIGSHIP), STATE_DEFAULT);
break;
}
pwup->setPosition((Vector){this->position.x, this->position.y, 0});
pwup->setState(STATE_NONE);
display.addActor(pwup, LAYER_SPRITE3);
display.colliders.push_back(pwup);
}
}
}
if ( this->state != STATE_DYING && ((this->userType & ACTOR_TEAM_ENEMY) == ACTOR_TEAM_ENEMY) ) {
if ( ((rand()%100)+1) < status.enemyShootChance ) {
this->fireProjectile();
}
}
Actor::update();
}
void Character::fireProjectile(Vector velocity, int playSound)
{
// FIXME : Causes segfault on win32, modification of memory after it's freed
// TODO : get a generator for the Projectile class
SDL_Surface *laserFrame = NULL;
SDL_Surface *playerFrame = NULL;
Game &myGame = Game::NewSingleton();
GameDisplay &gameDisplay = GameDisplay::NewSingleton();
GameStatus &status = GameStatus::NewSingleton();
Projectile *shotActor = NULL;
if ( this->hasState(STATE_DEAD) || this->hasState(STATE_DYING) ) {
return;
}
if ( this->hasState(STATE_SPREADSHOT) && (!this->hasState(STATE_FIRING))) {
this->addState(STATE_FIRING);
this->projectileAnim = myGame.getAnimation(ANIM_PLAYERSPREAD1);
this->fireProjectile((Vector){-5, 10, 0}, 0);
this->lastFireTime = 0;
this->projectileAnim = myGame.getAnimation(ANIM_PLAYERSPREAD3);
this->fireProjectile((Vector){5, 10, 0}, 0);
this->lastFireTime = 0;
this->projectileAnim = myGame.getAnimation(ANIM_PLAYERSPREAD2);
this->fireProjectile((Vector){0, 10, 0}, 0);
this->lastFireTime = SDL_GetTicks();
myGame.playSound(this->projectileSound);
this->removeState(STATE_FIRING);
}
if ( SDL_GetTicks() - this->lastFireTime > status.weaponSpeed && (this->projectileAnim != NULL) ) {
//std::cerr << "TRYING TO FIRE\n";
shotActor = new Projectile();
if ( shotActor == NULL ) {
std::cerr << "firePlayerLaser BAILING OUT for NULL Projectile!\n";
return;
}
//std::cerr << "Got new projectile\n";
this->lastFireTime = SDL_GetTicks();
shotActor->addAnimation(this->projectileAnim, STATE_DEFAULT);
shotActor->addAnimation(NULL, STATE_DYING);
shotActor->addAnimation(NULL, STATE_DEAD);
Vector playerPos = this->getPosition();
laserFrame = shotActor->nextFrame();
playerFrame = this->nextFrame();
if ( laserFrame == NULL || playerFrame == NULL ) {
return;
}
shotActor->setPosition((Vector){(playerPos.x + ((playerFrame->w/2) - (laserFrame->w/2))),
playerPos.y, playerPos.z});
if ( velocity.x < 0 ) {
shotActor->addState(STATE_MOVELEFT);
velocity.x = -(velocity.x);
} else if ( velocity.x > 0 )
shotActor->addState(STATE_MOVERIGHT);
if ( (this->userType & ACTOR_TEAM_PLAYER) == ACTOR_TEAM_PLAYER )
shotActor->addState(STATE_MOVEUP);
else if ( ((this->userType & ENEMYTYPE_ENEMY4 ) == ENEMYTYPE_ENEMY4) &&
(this->target != NULL) && (this->target->getPosition().y < this->position.y) ) {
shotActor->addState(STATE_MOVEUP);
} else
shotActor->addState(STATE_MOVEDOWN);
shotActor->setVelocity((Vector){velocity.x, velocity.y, velocity.z});
shotActor->setUserType((this->userType & ACTOR_TEAMMASK) | ACTORTYPE_PROJECTILE);
shotActor->damage = this->weaponDamage;
shotActor->parent = this;
//std::cerr << "Setting player's laser bolt to do " << shotActor->damage << " points of damage\n";
gameDisplay.addActor(shotActor, LAYER_SPRITE2);
if ( playSound == 1)
myGame.playSound(this->projectileSound);
gameDisplay.colliders.push_back(shotActor);
std::cerr << "Added new laser beam " << shotActor << " to colliders list.\n";
}
}
void Character::collide(Character *ptr)
{
std::cerr << "CHARACTER [" << this << "] I AM COLLIDING WITH " << ptr << "\n";
if ( ptr != NULL &&
(this->state != STATE_DYING && this->state != STATE_DEAD) &&
(!ptr->hasState(STATE_DYING) && !ptr->hasState(STATE_DEAD))) {
std::cerr << "I DID " << this->damage << " POINTS OF DAMAGE TO " << ptr << "\n";
ptr->health -= this->damage;
} else if ( ptr == NULL ) {
std::cerr << " I CANNOT COLLIDE WITH NULL\n";
} else {
std::cerr << "I AM DEAD, I CAN'T COLLIDE WITH SHIT\n";
}
}
void Projectile::collide(Character *ptr)
{
//std::cerr << "PROJECTILE [" << this << "] I AM COLLIDING WITH " << ptr << "\n";
if ( ptr != NULL &&
(this->state != STATE_DYING && this->state != STATE_DEAD) &&
(!ptr->hasState(STATE_DYING) && !ptr->hasState(STATE_DEAD)) &&
((ptr->getUserType() & ACTOR_TEAM_POWERUP) != ACTOR_TEAM_POWERUP) ) {
//std::cerr << "I DID " << this->damage << " POINTS OF DAMAGE TO " << ptr << "\n";
ptr->health = ptr->health - this->damage;
if ( (ptr->getUserType() & ACTOR_TEAMMASK) != (this->getUserType() & ACTOR_TEAMMASK) ) {
//std::cerr << "Projectile " << this << " with userType " << this->getUserType() << " is killing itself against an object with userType " << ptr->getUserType() << "!\n";
this->state = STATE_DEAD;
}
if ( this->parent != NULL && ((ptr->getUserType() & ACTORTYPE_PROJECTILE) != ACTORTYPE_PROJECTILE) ) {
((Character *)this->parent)->score += ptr->score;
}
}
}
void Player::collide(Character *ptr)
{
Game &game = Game::NewSingleton();
Character::collide(ptr);
if ( (ptr->getUserType() & ACTOR_TEAM_POWERUP) == ACTOR_TEAM_POWERUP ) {
if ( ((ptr->getUserType() & POWERUP_ONEUP) == POWERUP_ONEUP) && this->lives < 4 ) {
this->lives += 1;
} else if ( (ptr->getUserType() & POWERUP_BIGSHIP) == POWERUP_BIGSHIP ) {
this->addAnimation(game.getAnimation(ANIM_PLAYERDOUBLE), STATE_DEFAULT);
this->projectileAnim = game.getAnimation(ANIM_PLAYERLASERDOUBLE);
} else if ( (ptr->getUserType() & POWERUP_SHIELDRECHARGE) == POWERUP_SHIELDRECHARGE ) {
this->health = 100;
} else if ( (ptr->getUserType() & POWERUP_SPREADSHOT) == POWERUP_SPREADSHOT ) {
this->addState(STATE_SPREADSHOT);
}
ptr->setState(STATE_DEAD);
}
}
void Player::update()
{
GameOptions &opts = GameOptions::NewSingleton();
//std::cerr << "During update player health is " << this->health << "\n";
if ( this->playerDieTimer != 0 && this->state != STATE_DYING ) {
// without this, input from the player will make us reappear on the screen
this->state = STATE_DYING;
}
if ( this->health <= 0 && (this->state != STATE_DYING && this->state != STATE_DEAD)) {
this->setState(STATE_DYING);
this->playerDieTimer = SDL_GetTicks();
} else if ( this->state == STATE_DYING && (SDL_GetTicks() - this->playerDieTimer < 5000) ) {
return;
} else if ( (this->state == STATE_DYING || this->state == STATE_DEAD)&& (SDL_GetTicks() - this->playerDieTimer > 5000) && (this->lives > -1) ) {
this->setState(STATE_NONE);
this->lives -= 1;
this->playerDieTimer = 0;
this->health = opts.playerStartHealth;
}
Actor::update();
}

54
cpp/Character.h Executable file
View File

@@ -0,0 +1,54 @@
#ifndef __CHARACTER_H__
#define __CHARACTER_H__
#include <libgame/libgame.h>
#define STATE_SPREADSHOT 0x00200000
#define STATE_FIRING 0x00400000
class Character : public Actor
{
unsigned int lastDirChangeTime; // used by the Wavy Enemy subtype (ACTORTYPE_ENEMY3)
unsigned int lastFireTime;
public:
Character();
virtual void collide(Character *ptr);
// ... don't move the order of the 'damage' element. It will break the Projectile class.
// (It makes senseif you look at it long enough. No, I didn't design it that way. Yes, I'm ashamed of it.
// Yes, I'll fix it later.)
int damage; // the damage dealt when something runs in to us
Actor *target;
Animation *projectileAnim;
std::string projectileSound;
std::string deathSound;
int health;
int weaponDamage; // the damage dealt when we use our weapon on something
int score;
virtual void fireProjectile(Vector velocity = (Vector){0,10,0}, int playSound = 1);
virtual void update();
};
class Projectile : public Actor
{
public:
// we don't use the health or weaponDamage items in the Character class,
// but because of the way I handled characters damaging each other, this was
// a simpler hack than redoing the classes properly.
void collide(Character *ptr);
int damage;
};
class Player : public Character
{
Uint32 playerShieldTimer; // used to track the amount of time the player's shield has been fading
Uint32 playerFailTimer; // timer for player fail
Uint32 playerDieTimer; // timer for when the player dies
public:
int lives;
void collide(Character *ptr);
void update();
};
#endif // __CHARACTER_H__

125
cpp/Common.h Normal file
View File

@@ -0,0 +1,125 @@
#ifndef __HSA_COMMON_H__
#define __HSA_COMMON_H__
extern const int enemyWeights[][10];
extern const int maxVisibleEnemies[][5];
extern int curVisibleEnemies[][5];
// high nibble of user type is the "team" the actor is on
#define ACTOR_TEAMMASK 0xF0000000
#define ACTOR_TEAMTYPEMASK 0x0FF00000
#define ACTOR_PARENTMASK 0x000F0000
#define ACTOR_TYPEMASK 0x0000FFFF
#define ACTOR_TEAM_PLAYER 0x20000000
#define ACTOR_TEAM_POWERUP 0x40000000
#define ACTOR_TEAM_ENEMY 0x80000000
#define ACTORTYPE_NORMAL 0x00000000
#define ACTORTYPE_NODELETE 0x00000002
#define ACTORTYPE_PLAYER 0x00000004
#define ACTORTYPE_CHARACTER 0x00000008
#define ACTORTYPE_PROJECTILE 0x00000010
#define ACTORTYPE_UNDEFINED 0x00000020
#define POWERUP_SPREADSHOT 0x00000200
#define POWERUP_ONEUP 0x00000400
#define POWERUP_BIGSHIP 0x00000800
#define POWERUP_SHIELDRECHARGE 0x00001000
#define ENEMYTYPE_ENEMY1 0x00200000
#define ENEMYTYPE_ENEMY2 0x00400000
#define ENEMYTYPE_ENEMY3 0x00800000
#define ENEMYTYPE_ENEMY4 0x01000000
#define ENEMYTYPE_DESTROYER1 0x04000000
#define ENEMYTYPE_DESTROYER2 0x08000000
// ------- KEY CONSTANTS --------------------
#define ANIM_PLAYERSINGLE "PLAYER SMALL SHIP"
#define ANIM_PLAYERDOUBLE "PLAYER BIG SHIP"
#define ANIM_EXPLOSION "EXPLOSION"
#define ANIM_OPTIONMENU "OPTION MENU"
#define ANIM_OPTIONPTR "OPTION POINTER"
#define ANIM_TITLEMENU "TITLE MENU"
#define ANIM_TITLEPTR "TITLE POINTER"
#define ANIM_PLAYERLASERSINGLE "SINGLE PLAYER LASER"
#define ANIM_PLAYERLASERDOUBLE "DOUBLE PLAYER LASER"
#define ANIM_PLAYERSPREAD1 "PLAYER SPREAD LEFT"
#define ANIM_PLAYERSPREAD2 ANIM_PLAYERLASERSINGLE
#define ANIM_PLAYERSPREAD3 "PLAYER SPREAD RIGHT"
#define ANIM_HUDLIVES "HUD LIVES ANIM"
#define ANIM_ENEMYFIGHTER1 "ENEMY FIGHTER 1"
#define ANIM_ENEMYFIGHTER2 "ENEMY FIGHTER 2"
#define ANIM_ENEMYFIGHTER3 "ENEMY FIGHTER 3"
#define ANIM_ENEMYFIGHTER4 "ENEMY FIGHTER 4"
#define ANIM_ENEMYDESTROYER1 "ENEMY DESTROYER 1"
#define ANIM_ENEMYDESTROYER2 "ENEMY DESTROYER 2"
#define ANIM_ENEMYLASERSINGLE "ENEMY LASER SINGLE"
#define ANIM_ENEMYLASERDOUBLE "ENEMY LASER DOUBLE"
#define ANIM_PWUP_BIGSHIP "POWERUP BIG SHIP"
#define ANIM_PWUP_ONEUP "POWERUP ONE UP"
#define ANIM_PWUP_SHIELD "POWERUP SHIELD RECHARGE"
#define ANIM_PWUP_SPREADSHOT "POWERUP SPREAD SHOT"
#define ACTOR_STARBACKGROUND "STARFIELD BACKGROUND"
#define ACTOR_OPTMENUBACKGROUND "MENU BACKGROUND"
#define ACTOR_TITLEBACKGROUND "TITLE BACKGROUND"
#define ACTOR_HUDLIVES "HUD LIVES ACTOR"
#define MUSICFILE_TITLESCREEN "music/title theme - gradius 3 fire scramble.ogg"
#define MUSICFILE_GAMESCREEN "music/background theme - carrieraces.ogg"
#define MUSICFILE_CREDITSCREEN "music/credits - mobile suit gundam formula wars eternal wind.ogg"
#define MUSICFILE_FAILSCREEN "music/game over - gundam wing endless duel game over.ogg"
#define SPRITEFILE_ENEMYFIGHTER1 "sprites/Enemy Fighter 1.png"
#define SPRITEFILE_ENEMYFIGHTER2 "sprites/Enemy Fighter 2.png"
#define SPRITEFILE_ENEMYFIGHTER3 "sprites/Enemy Fighter 3.png"
#define SPRITEFILE_ENEMYFIGHTER4 "sprites/Enemy Fighter 4.png"
#define SPRITEFILE_ENEMYLASER1 "sprites/Enemy Laser Single.png"
#define SPRITEFILE_ENEMYLASER2 "sprites/Enemy Laser Double.png"
#define SPRITEFILE_PLAYERSHIP1 "sprites/Player Ship 1.png"
#define SPRITEFILE_PLAYERSHIP2 "sprites/Player Ship 2.png"
#define SPRITEFILE_PLAYERSHIP3 "sprites/Player Ship Menu.png"
#define SPRITEFILE_PLAYERSHIELDHIT "sprites/Player Shield Hit.png"
#define SPRITEFILE_POWERUP_SHIELD "sprites/Powerup - Shield Recharge.png"
#define SPRITEFILE_POWERUP_SPREAD "sprites/Powerup - Spreadshot.png"
#define SPRITEFILE_POWERUP_SHIP "sprites/Powerup - Bigger Ship.png"
#define SPRITEFILE_POWERUP_ONEUP "sprites/Powerup - One Up.png"
#define SPRITEFILE_ENEMYDESTROYER1 "sprites/Star Destroyer 1.png"
#define SPRITEFILE_ENEMYDESTROYER2 "sprites/Star Destroyer 2.png"
#define SPRITEFILE_EXPLOSION "sprites/explosion.png"
#define SPRITEFILE_PLAYERLASER1 "sprites/Player Laser Single.png"
#define SPRITEFILE_PLAYERLASER2 "sprites/Player Laser Double.png"
#define SPRITEFILE_PLAYERSPREAD1 "sprites/Player Laser Spread -30deg.png"
#define SPRITEFILE_PLAYERSPREAD2 SPRITEFILE_PLAYERLASER1
#define SPRITEFILE_PLAYERSPREAD3 "sprites/Player Laser Spread 30deg.png"
#define SOUNDFILE_PLAYERLASERSHOT "sounds/lasershot.wav"
#define SOUNDFILE_ENEMYLASERSHOT "sounds/enemylasershot.wav"
#define SOUNDFILE_EXPLOSION "sounds/EXPLODE.WAV"
#define SOUNDFILE_PLAYERSTART "sounds/sci_fi_takeoff.wav"
#define SOUNDFILE_PLAYERHIT "sounds/FORCEFI.wav"
#define BACKGROUNDFILE_CREDITS "backgrounds/credits background - 800x600.png"
#define BACKGROUNDFILE_FAIL "backgrounds/fail background - 800x600.png"
#define BACKGROUNDFILE_HELP "backgrounds/help background - 800x600.png"
#define BACKGROUNDFILE_PLAIN "backgrounds/Background-800x600.png"
#define BACKGROUNDFILE_MENU "backgrounds/title screen - 800 x 600.png"
#define BACKGROUNDFILE_OPTIONS "backgrounds/Options Background.png"
#define GAMEOPT_DIFFICULTY "DIFFICULTY"
#define GAMEOPT_SOUNDEFFECTS "SOUND FX"
#define GAMEOPT_MUSIC "MUSIC"
#define GAMEOPT_MUSICVOL "MUS. VOL."
#define GAMEOPT_SOUNDVOL "SND. VOL."
#define GAMEOPT_P1CONTROL "P1 CONTROL"
#define GAMEOPT_P2CONTROL "P2 CONTROL"
#define CONTROLOPT_KEYBOARD "KEYBOARD"
#define CONTROLOPT_NONE "NONE"
#define DIFFICULTY_EASY "EASY"
#define DIFFICULTY_NORMAL "NORMAL"
#define DIFFICULTY_HARD "HARD"
#define DIFFICULTY_IMMORTAL "I AM IMMORTAL"
#endif // __COMMON_H__

16
cpp/Control.h Executable file
View File

@@ -0,0 +1,16 @@
#ifndef __CONTROL_H__
#define __CONTROL_H__
struct Controller
{
int joyNum; // set to > -1 to get the number of the joystick used to control this item
int keyBoard; // set to 1 to let the keyboard control this player
int mouse; // set to 1 to let the mouse control this player
Controller( int joyNum = -1, int keyBoard = 0, int mouse = 0) {
this->joyNum = joyNum;
this->keyBoard = keyBoard;
this->mouse = mouse;
}
};
#endif

303
cpp/GameDisplay.cpp Executable file
View File

@@ -0,0 +1,303 @@
#include <libgame/libgame.h>
#include "GameLogic.h"
#include "GameDisplay.h"
#include "Character.h"
#include "HUD.h"
#include "Common.h"
GameDisplay::GameDisplay()
{
//Character::Character();
this->player1 = player1;
this->player2 = player2;
this->hud1 = NULL;
this->hud2 = NULL;
}
SDL_Surface *GameDisplay::nextFrame()
{
Game &theGame = Game::NewSingleton();
SDL_Surface *frame = NULL;
SDL_Rect destRect;
Player *player = NULL;
GameStatus &gamestatus = GameStatus::NewSingleton();
Vector position;
char fpsString[32];
if ( this->active == 0 ) {
return NULL;
}
Display2D::nextFrame();
player = this->player1;
for ( int i = 0 ; i < 2 ; i++ ) {
//std::cerr << "Player is " << player << "\n";
if ( player == NULL )
continue;
frame = player->nextFrame();
if ( frame == NULL ) {
continue;
}
position = player->getPosition();
destRect.x = (Sint16)position.x;
destRect.y = (Sint16)position.y;
destRect.w = frame->w;
destRect.h = frame->h;
//std::cerr << "Rendering player\n";
SDL_BlitSurface(frame, NULL, this->canvas, &destRect);
frame = NULL;
if ( gamestatus.status == GAMESTATE_PLAYMULTI) {
//std::cerr << "Playing multiplayer..\n";
player = this->player2;
} else {
//std::cerr << "Playing single player..\n";
player = NULL;
}
}
//std::cerr << "Done rendering players\n";
if ( this->hud1 != NULL ) {
this->hud1->update();
frame = this->hud1->nextFrame();
if ( frame != NULL ) {
position = this->hud1->getPosition();
destRect.x = (Sint16)position.x;
destRect.y = (Sint16)position.y;
destRect.w = frame->w;
destRect.h = frame->h;
SDL_BlitSurface(frame, NULL, this->canvas, &destRect);
}
}
if ( this->hud2 != NULL ) {
this->hud2->update();
frame = this->hud2->nextFrame();
if ( frame != NULL ) {
position = this->hud2->getPosition();
destRect.x = (Sint16)position.x;
destRect.y = (Sint16)position.y;
destRect.w = frame->w;
destRect.h = frame->h;
SDL_BlitSurface(frame, NULL, this->canvas, &destRect);
}
}
FontRenderer &textEngine = FontRenderer::NewSingleton();
memset((char *)&fpsString, 0x00, 32);
sprintf((char *)&fpsString, "%d FPS", theGame.realfps);
textEngine.setColor((SDL_Color){0x2E,0x8F,0x2C,0}, (SDL_Color){0,0,0,0}, 1);
textEngine.renderString(std::string((char *)&fpsString), this->canvas, "arial", (Vector){150,20,0}, 20);
return this->canvas;
}
void GameDisplay::update(int logicOnly)
{
ActorList::iterator actor;
ActorList::iterator oldActor;
//GameOptions &opts = GameOptions::NewSingleton();
Actor *realActor;
std::vector<Actor *>::iterator actorIter;
Vector position;
if ( this->active == 0 ) {
return;
}
Display2D::update(logicOnly);
if ( this->player1 != NULL )
this->player1->update();
if ( this->player2 != NULL )
this->player2->update();
oldActor = this->colliders.begin();
while ( oldActor != this->colliders.end() ) {
//std::cerr << "COLLIDER " << (*oldActor) << " has state " << (*oldActor)->getState() << " and current animation " << (*oldActor)->getAnimation((*oldActor)->getState()) << "\n";
position = (*oldActor)->getPosition();
if ( (*oldActor)->hasState(STATE_DYING) ||
(*oldActor)->hasState(STATE_DEAD) ||
((position.x > this->canvas->w ||
position.y > this->canvas->h ||
position.x < 0 ||
position.y < 0 )) ) {
if ( ((*oldActor)->getUserType() & ACTORTYPE_PLAYER) == ACTORTYPE_PLAYER ) {
oldActor++;
continue;
}
std::cerr << "ERASING FROM COLLIDERS " << (*oldActor) << " userType " << (*oldActor)->getUserType() << " state " << (*oldActor)->getState() << " position (" << position.x << "x" << position.y << ")\n";
actor = oldActor;
//while ( oldActor == actor ) {
// I've seen this a few times ... don't ask me how ...
//std::cerr << "actor " << (*oldActor) << " is still trying to delete from colliders list\n";
oldActor = this->colliders.erase(oldActor);
//}
continue;
}
oldActor++;
}
// remove actors that are out of screen bounds
for ( int i = 0; i < MAX_LAYERS ; i++ ) {
actor = this->layers[i].begin();
while ( actor != this->layers[i].end() ) {
position = (*actor)->getPosition();
realActor = (*actor);
if ( realActor->hasState(STATE_DEAD) ||
(position.x > this->canvas->w ||
position.y > this->canvas->h ||
position.x < 0 ||
position.y < 0 )) {
if ( realActor == this->player1 || realActor == this->player2 ) {
actor++;
continue;
}
actor = this->layers[i].erase(actor);
if ( this->removeActor(realActor) != 0) {
std::cerr << "Couldn't remove actor from actor list\n";
}
std::cerr << "Trying to delete object " << realActor << " type " << realActor->getUserType() << " from memory\n";
if ( (realActor->getUserType() & ACTORTYPE_CHARACTER) == ACTORTYPE_CHARACTER ) {
std::cerr << "DELETING CHARACTER " << realActor << " ON LAYER " << i << " has userType " << realActor->getUserType() << " and state " << realActor->getState() << " and current animation " << realActor->getAnimation(realActor->getState()) << "\n";
Character *tmp = (Character *)realActor;
delete tmp;
} else if ( (realActor->getUserType() & ACTORTYPE_PROJECTILE) == ACTORTYPE_PROJECTILE ) {
std::cerr << "DELETING PROJECTILE " << realActor << " ON LAYER " << i << " has userType " << realActor->getUserType() << " and state " << realActor->getState() << " and current animation " << realActor->getAnimation(realActor->getState()) << "\n";
Projectile *tmp = (Projectile *)realActor;
delete tmp;
} else if ( (realActor->getUserType() & ACTORTYPE_NORMAL) == ACTORTYPE_NORMAL ) {
std::cerr << "DELETING ACTOR " << realActor << " ON LAYER " << i << " has userType " << realActor->getUserType() << " and state " << realActor->getState() << " and current animation " << realActor->getAnimation(realActor->getState()) << "\n";
delete realActor;
}
continue;
}
actor++;
}
}
}
void GameDisplay::clampActor(Actor *actor)
{
Vector position;
SDL_Surface *curFrame;
SDL_Rect frameSize;
if ( actor == NULL ) {
return;
}
position = actor->getPosition();
curFrame = actor->nextFrame();
frameSize.x = 0;
frameSize.y = 0;
if ( curFrame ) {
frameSize.w = curFrame->w;
frameSize.h = curFrame->h;
} else {
frameSize.w = frameSize.h = 0;
}
if ( (position.x + frameSize.w) > this->canvas->w ) {
position.x = (this->canvas->w - frameSize.w);
} else if ( position.x < 0 ) {
position.x = 1;
}
if ( (position.y + frameSize.h) > this->canvas->h ) {
position.y = (this->canvas->h - frameSize.h);
} else if ( position.y < 0 ) {
position.y = 1;
}
actor->setPosition(position);
}
void GameDisplay::setPlayers(Player *player1, Player *player2)
{
this->player1 = player1;
this->player2 = player2;
}
void GameDisplay::setHUDs(HUDDisplay *hud1, HUDDisplay *hud2)
{
this->hud1 = hud1;
this->hud2 = hud2;
}
void GameDisplay::runCollisions()
{
std::vector<Actor *>::iterator iter;
std::vector<Actor *>::iterator iter2;
Actor *actor1;
Actor *actor2;
iter = this->colliders.begin();
iter2 = iter + 1;
SDL_Surface *tmpFrame;
SDL_Rect r1;
SDL_Rect r2;
//std::cerr << "Starting collisions...\n";
while ( iter != this->colliders.end() ) {
if ( (*iter) == NULL ) {
iter++;
continue;
}
tmpFrame = (*iter)->nextFrame();
r1.x = (Sint16)(*iter)->getPosition().x;
r1.y = (Sint16)(*iter)->getPosition().y;
if ( tmpFrame == NULL ) {
r1.w = 0;
r1.h = 0;
} else {
r1.w = tmpFrame->w;
r1.h = tmpFrame->h;
}
while ( iter2 != this->colliders.end()) {
if ( (*iter2) == NULL ) {
iter2++;
continue;
}
std::cerr << "TRYING TO COLLIDE " << (*iter) << " AGAINST " << (*iter2) << "\n";
tmpFrame = (*iter2)->nextFrame();
if ( tmpFrame == NULL ) {
r2.w = 0;
r2.h = 0;
} else {
r2.w = tmpFrame->w;
r2.h = tmpFrame->h;
}
r2.x = (Sint16)(*iter2)->getPosition().x;
r2.y = (Sint16)(*iter2)->getPosition().y;
if ( (((r1.x > r2.x && r1.x < r2.x + r2.w) || (r1.x + r1.w > r2.x && r1.x + r1.w < r2.x + r2.w)) && ((r1.y > r2.y && r1.y < r2.y + r2.h) || (r1.y + r1.h > r2.y && r1.y + r1.h < r2.y + r2.h))) ||
(((r2.x > r1.x && r2.x < r1.x + r1.w) || (r2.x + r2.w > r1.x && r2.x + r2.w < r1.x + r1.w)) && ((r2.y > r1.y && r2.y < r1.y + r1.h) || (r2.y + r2.h > r1.y && r2.y + r2.h < r1.y + r1.h))) ) {
// collision
//if ( (*iter)->userType & ACTOR_TEAMMASK != (*iter2)->userType & ACTOR_TEAMMASK ) {
if ( ((*iter)->getUserType() & ACTOR_TEAMMASK) != ((*iter2)->getUserType() & ACTOR_TEAMMASK)) {
actor1 = (*iter);
actor2 = (*iter2);
// for now just change every collided object's state to dying to show it's working
while ( actor1 != NULL ) {
std::cerr << "COLLIDING " << actor1 << " WITH " << actor2 << "\n";
if ( (actor1->getUserType() & ACTORTYPE_PLAYER) == ACTORTYPE_PLAYER ) {
((Character *)actor1)->collide((Character *)actor2);
} else if ( (actor1->getUserType() & ACTORTYPE_CHARACTER) == ACTORTYPE_CHARACTER ) {
((Character *)actor1)->collide((Character *)actor2);
} else if ( (actor1->getUserType() & ACTORTYPE_PROJECTILE) == ACTORTYPE_PROJECTILE ) {
((Projectile *)actor1)->collide((Character *)actor2);
} else if ( (actor1->getUserType() & ACTORTYPE_NORMAL) == ACTORTYPE_NORMAL ) {
actor1->collide(actor2);
}
if ( actor1 == (*iter2) ) {
actor1 = NULL;
} else {
std::cerr << "Running second round of reverse collisions\n";
actor1 = (*iter2);
actor2 = (*iter);
}
}
}
}
iter2++;
}
iter++;
iter2 = iter + 1;
}
}

29
cpp/GameDisplay.h Executable file
View File

@@ -0,0 +1,29 @@
#ifndef __GAMEDISPLAY_H__
#define __GAMEDISPLAY_H__
#include "Character.h"
#include "HUD.h"
class GameDisplay : public Display2D
{
protected:
Player *player1;
Player *player2;
HUDDisplay *hud1;
HUDDisplay *hud2;
GameDisplay();
public:
static GameDisplay &NewSingleton() {
static GameDisplay entity;
return entity;
}
std::vector<Actor *> colliders;
void update(int logicOnly = 0);
SDL_Surface *nextFrame();
void setHUDs(HUDDisplay *hud1, HUDDisplay *hud2);
void setPlayers(Player *player1, Player *player2);
void clampActor(Actor *actor);
void runCollisions();
};
#endif // __GAMEDISPLAY_H__

110
cpp/GameLogic.cpp Normal file
View File

@@ -0,0 +1,110 @@
#include "GameLogic.h"
ControlMap::ControlMap()
{
this->controlType = CONTROL_TYPE_KEYBOARD;
this->joystick = NULL;
this->moveUp = CONTROL_KEY_MOVEUP;
this->moveDown = CONTROL_KEY_MOVEDOWN;
this->moveLeft = CONTROL_KEY_MOVELEFT;
this->moveRight = CONTROL_KEY_MOVERIGHT;
this->fire = CONTROL_KEY_FIRE;
this->lastFireButtonState = 0;
}
GameOptions::GameOptions()
{
this->enemyBaseShootChance = 2;
this->difficultyLevel = 1;
this->bossExplodeLength = 5000;
this->playerBaseSpeed.x = 3;
this->playerBaseSpeed.y = 3;
this->playerBaseSpeed.z = 0;
this->enemyBaseSpeed.x = 1;
this->enemyBaseSpeed.y = 1;
this->enemyBaseSpeed.z = 0;
this->playerStartLives = 3;
this->playerStartHealth = 100;
this->playerBaseDamage = 5;
this->playMusic = 0;
this->playSound = 0;
this->playerShieldTime = 5000;
this->bossBaseTrip = 10000;
this->playerFailTime = 5000;
this->musicVolume = 80;
this->soundVolume = 60;
this->enemyBaseSpawnInterval = 1000;
this->enemyBaseSpawnChance = 5;
}
GameStatus::GameStatus()
{
this->enemyVelocity.x = 0;
this->enemyVelocity.y = 0;
this->enemyVelocity.z = 0;
this->status = GAMESTATE_TITLEMENU;
this->curLevel = 0;
this->levelTimer = 0;
this->levelScore = 0;
this->levelPowerups = 0;
this->levelLives = 0;
this->bossOnScreen = 0;
this->enemyShootChance = 2;
this->weaponSpeed = 100;
this->enemySpawnChance = 5;
this->enemySpawnInterval = 1000;
this->enemyLastSpawned = 0;
this->powerDropChance = 100;
this->bossExplodeTimer = 0;
this->running = 1;
}
void GameStatus::nextLevel(Player *player1, Player *player2, int curLevel)
{
GameOptions &opts = GameOptions::NewSingleton();
Player *player = player1;
if ( curLevel != -1 ) {
this->curLevel = curLevel;
}
this->enemyShootChance = (opts.enemyBaseShootChance * (curLevel+1));
this->enemyWeaponSpeed = (opts.enemyBaseWeaponSpeed * (curLevel+1)) + opts.difficultyLevel;
this->enemySpawnChance = (opts.enemyBaseSpawnChance + (curLevel+1)) + opts.difficultyLevel;
this->enemySpawnInterval = opts.enemyBaseSpawnInterval - (curLevel * -50);
this->enemyVelocity.x = opts.enemyBaseSpeed.x + ((curLevel+1)/3) + opts.difficultyLevel;
this->enemyVelocity.y = opts.enemyBaseSpeed.y + ((curLevel+1)/3) + opts.difficultyLevel;
this->enemyVelocity.z = opts.enemyBaseSpeed.z + ((curLevel+1)/3) + opts.difficultyLevel;
this->powerDropChance = (curLevel+1);
if ( player2 == NULL ) {
this->levelScore = player1->score;
} else {
this->levelScore = (player1->score + player2->score)/2;
}
while ( player != NULL ) {
if ( curLevel == 0 ) {
player->score = 0;
player->setVelocity((Vector){opts.playerBaseSpeed.x + opts.difficultyLevel, opts.playerBaseSpeed.y + opts.difficultyLevel, 0} );
player->health = opts.playerStartHealth;
player->lives = opts.playerStartLives;
this->enemySpawnChance *= opts.difficultyLevel;
this->enemyWeaponSpeed *= opts.difficultyLevel;
this->enemySpawnInterval /= opts.difficultyLevel;
this->enemyVelocity.y += opts.difficultyLevel;
} else {
player->score += 100 * this->levelPowerups;
player->score -= ( 200 * this->levelLives);
player->score -= (unsigned int)(1000 * ((float)(SDL_GetTicks() - this->levelTimer) / 60000));
player->score += 10000 * this->curLevel;
}
if ( player == player2 ) {
break;
}
player = player2;
}
this->levelTimer = SDL_GetTicks();
this->levelLives = 0;
this->levelPowerups = 0;
if ( curLevel != 0 )
this->curLevel += 1;
else
this->curLevel = curLevel;
}

116
cpp/GameLogic.h Normal file
View File

@@ -0,0 +1,116 @@
#ifndef __GAMELOGIC_H__
#define __GAMELOGIC_H__
#include <SDL.h>
#include <libgame/libgame.h>
#include "Character.h"
#define GAMESTATE_TITLEMENU 0
#define GAMESTATE_PLAYSINGLE 1
#define GAMESTATE_PLAYMULTI 2
#define GAMESTATE_FAILSCREEN 3
#define GAMESTATE_HELPSCREEN 4
#define GAMESTATE_CREDITSCREEN 5
#define GAMESTATE_OPTIONSCREEN 6
#define CONTROL_TYPE_KEYBOARD 0
#define CONTROL_TYPE_JOYSTICK 1
#define CONTROL_TYPE_NONE 2
// --------- some defines for default control configurations
#define CONTROL_KEY_MOVELEFT SDLK_LEFT
#define CONTROL_KEY_MOVERIGHT SDLK_RIGHT
#define CONTROL_KEY_MOVEDOWN SDLK_DOWN
#define CONTROL_KEY_MOVEUP SDLK_UP
#define CONTROL_KEY_FIRE SDLK_SPACE
// the CONTROL_JS_Px_MOVEx defines refer to state maps for the joystick hats
// ... controlling the spaceships via control stick currently isn't supported
#define CONTROL_JS_MOVELEFT SDL_HAT_LEFT
#define CONTROL_JS_MOVERIGHT SDL_HAT_RIGHT
#define CONTROL_JS_MOVEUP SDL_HAT_UP
#define CONTROL_JS_MOVEDOWN SDL_HAT_DOWN
// this refers to a button pressed on the joystick for firing
#define CONTROL_JS_FIRE 1
struct ControlMap
{
int controlType; // one of the CONTROL_TYPE defines
SDL_Joystick *joystick; // if CONTROL_JOYSTICK, this is the joystick opened for this control map
int moveUp;
int moveDown;
int moveLeft;
int moveRight;
int fire;
// used by the joystick monitoring stuff
int lastFireButtonState;
ControlMap();
};
class GameOptions
{
protected:
GameOptions();
public:
static GameOptions &NewSingleton()
{
static GameOptions singleton;
return singleton;
}
int difficultyLevel; // integer from 1+ specifying the difficulty of the game
Uint32 bossExplodeLength; // default 5000, specifies how long the boss should explode (and fade) for
Vector playerBaseSpeed; // base movement speed for the player
Vector enemyBaseSpeed; // base movement speed for enemies
int enemyBaseShootChance; // base chance that an enemy will fire
int enemyBaseWeaponSpeed; // base speed of the enemy's weapons
int enemyBaseSpawnChance; // base spawn chance of the enemy ships
int enemyBaseSpawnInterval; // base spawn interval for enemies
int playerStartLives; // base number of lives for the player
int playerStartHealth; // base health for the player
int playerBaseDamage; // base weapon damage for the player's laser bolts
int playMusic; // 1 = play background music, 0 = stop background music
int playSound; // 1 = play sound effects, 0 = don't play sound effects
int playerShieldTime; // defaults to 5000 (5 seconds), fade time for the player shield effect
int bossBaseTrip; // determines at what interval (default 10,000) that the boss should appear
int playerFailTime; // amount of time to wait after the player loses all lives (default 5000) before showing the fail screen
int musicVolume; // 1 - 128
int soundVolume; // 1 - 128
ControlMap controlMaps[2]; // idx 0 = player 1, idx 1 = player 2
};
// options and values that can change during gameplay should go here (i.e. things that
// don't get set directly in the Options screen); everything else should go into the
// GameOptions struct, above
class GameStatus
{
protected:
GameStatus();
public:
static GameStatus &NewSingleton()
{
static GameStatus singleton;
return singleton;
}
int running; // is the game still running? (are we exiting)
void nextLevel(Player *player1, Player *player2, int curLevel = -1);
Vector enemyVelocity; // current speed of enemies on this level
int enemyWeaponSpeed;
int status; // game status flags
int curLevel; // current level (1, 2, 3, etc)
Uint32 levelTimer; // time currently spent on this level
int levelScore; // score for the previous level (used when calculating score)
int levelPowerups; // the number of powerups you got this level (for score)
int levelLives; // the number of lives you used this level (for score)
int bossOnScreen; // 0 = boss is not on screen, 1 = boss is on screen
int enemyShootChance; // chance per update that an enemy will fire (currently stupid)
Uint32 weaponSpeed; // player weapon shoot speed
int enemySpawnChance; // chance per update that an enemy will spawn
Uint32 enemySpawnInterval; // minimum time in milliseconds between enemy spawns
Uint32 enemyLastSpawned; // last SDL_GetTicks when an enemy was spawned
int powerDropChance; // integer from 0 to 100 specifying the chance that a powerup will spawn when an enemy dies
Uint32 bossExplodeTimer; // used to track how long the boss has been exploding
};
#endif // __GAMELOGIC_H__

78
cpp/HUD.cpp Executable file
View File

@@ -0,0 +1,78 @@
#include "HUD.h"
#include "Character.h"
#include <SDL_gfxPrimitives.h>
HUDDisplay::HUDDisplay()
{
this->target = NULL;
this->livesActor = NULL;
this->text = "";
}
void HUDDisplay::setText(std::string text)
{
this->text = text;
}
void HUDDisplay::setLivesActor(Actor *actor)
{
this->livesActor = actor;
}
void HUDDisplay::setTarget(Player *tgt)
{
this->target = tgt;
}
SDL_Surface *HUDDisplay::nextFrame()
{
if ( this->active == 1 ) {
return this->canvas;
} else {
return NULL;
}
}
void HUDDisplay::update(int logicOnly)
{
SDL_Surface *curFrame;
char scoreVal[64];
if ( this->active == 0 || logicOnly == 1 ) {
return;
}
memset((char *)&scoreVal, 0, 64);
sprintf((char *)&scoreVal, "%d", this->target->score);
SDL_SetColorKey(this->canvas, SDL_SRCCOLORKEY, SDL_MapRGB(this->canvas->format, 0, 0, 0));
SDL_FillRect(this->canvas, NULL, SDL_MapRGB(this->canvas->format, 0, 0, 0));
//stringColor(this->canvas, 10, 10, (char *)&scoreVal, SDL_MapRGB(this->canvas->format, 0xB8, 0x13, 0x26));
//std::cerr << "Player score is " << scoreVal << " (" << this->target->score << ")\n";
stringRGBA(this->canvas, 0, 0, this->text.c_str(), 255, 255, 255, 255);
stringRGBA(this->canvas, 0, 15, (char *)&scoreVal, 255, 0, 0, 255);
rectangleRGBA(this->canvas, 0, 29, 101, 51, 255, 0, 0, 255);
if ( target->health > 0 ) {
boxRGBA(this->canvas, 1, 30, 0 + (target->health), 50, 0x68, 0x10, 0x20, 255);
} else
boxRGBA(this->canvas, 1, 30, 0, 50, 0x68, 0x10, 0x20, 255);
if ( this->livesActor == NULL ) {
return;
}
curFrame = this->livesActor->nextFrame();
if ( curFrame == NULL ) {
return;
}
SDL_Rect destRect;
destRect.x = 0;
destRect.y = 60;
destRect.w = curFrame->w;
destRect.h = curFrame->h;
for ( int i = 0; i < this->target->lives ; i++ ) {
destRect.x = i*curFrame->w;
SDL_BlitSurface(curFrame, NULL, this->canvas, &destRect);
}
}

21
cpp/HUD.h Executable file
View File

@@ -0,0 +1,21 @@
#ifndef __HUD_H__
#define __HUD_H__
#include "Character.h"
class HUDDisplay : public Display2D
{
protected:
Player *target;
Actor *livesActor;
std::string text;
public:
HUDDisplay();
SDL_Surface *nextFrame();
void setText(std::string text);
void setTarget(Player *tgt);
void setLivesActor(Actor *actor);
void update(int logicOnly = 0);
};
#endif // __HUD_H__

88
cpp/Holy Shit Aliens.vpj Normal file
View File

@@ -0,0 +1,88 @@
<!DOCTYPE Project SYSTEM "http://www.slickedit.com/dtd/vse/8.1/vpj.dtd">
<Project
Version="8.1"
VendorName="SlickEdit"
WorkingDir=".">
<Config
Name="Release"
OutputFile="">
<Menu>
<Target
Name="Compile"
MenuCaption="&amp;Compile"
CaptureOutputWith="ProcessBuffer"
SaveOption="SaveCurrent"
RunFromDir="%rw">
<Exec/>
</Target>
<Target
Name="Build"
MenuCaption="&amp;Build"
CaptureOutputWith="ProcessBuffer"
SaveOption="SaveWorkspaceFiles"
RunFromDir="%rw">
<Exec/>
</Target>
<Target
Name="Rebuild"
MenuCaption="&amp;Rebuild"
CaptureOutputWith="ProcessBuffer"
SaveOption="SaveWorkspaceFiles"
RunFromDir="%rw">
<Exec/>
</Target>
<Target
Name="Debug"
MenuCaption="&amp;Debug"
SaveOption="SaveNone"
RunFromDir="%rw">
<Exec/>
</Target>
<Target
Name="Execute"
MenuCaption="E&amp;xecute"
SaveOption="SaveNone"
RunFromDir="%rw">
<Exec CmdLine='"Holy Shit Aliens.exe"'/>
</Target>
</Menu>
</Config>
<CustomFolders>
<Folder
Name="Source Files"
Filters="*.c;*.C;*.cc;*.cpp;*.cp;*.cxx;*.prg;*.pas;*.dpr;*.asm;*.s;*.bas;*.java;*.cs;*.sc;*.e;*.cob;*.html;*.rc;*.tcl;*.py;*.pl"/>
<Folder
Name="Header Files"
Filters="*.h;*.H;*.hh;*.hpp;*.hxx;*.inc;*.sh;*.cpy;*.if"/>
<Folder
Name="Resource Files"
Filters="*.ico;*.cur;*.dlg"/>
<Folder
Name="Bitmaps"
Filters="*.bmp"/>
<Folder
Name="Other Files"
Filters="">
</Folder>
</CustomFolders>
<Files AutoFolders="DirectoryView">
<Folder Name="../">
<F
N="../Makefile"
Type="Makefile"/>
</Folder>
<F N="Character.cpp"/>
<F N="Character.h"/>
<F N="Control.h"/>
<F N="GameDisplay.cpp"/>
<F N="GameDisplay.h"/>
<F N="GameLogic.cpp"/>
<F N="GameLogic.h"/>
<F N="HUD.cpp"/>
<F N="HUD.h"/>
<F N="main.cpp"/>
<F N="main.h"/>
<F N="StarfieldBackground.cpp"/>
<F N="StarfieldBackground.h"/>
</Files>
</Project>

6
cpp/Holy Shit Aliens.vpw Normal file
View File

@@ -0,0 +1,6 @@
<!DOCTYPE Workspace SYSTEM "http://www.slickedit.com/dtd/vse/8.1/vpw.dtd">
<Workspace Version="8.1" VendorName="SlickEdit">
<Projects>
<Project File="Holy Shit Aliens.vpj"/>
</Projects>
</Workspace>

57
cpp/Holy Shit Aliens.vpwhist Executable file
View File

@@ -0,0 +1,57 @@
[Global]
CurrentProject=Holy Shit Aliens.vpj
[ProjectDates]
Holy Shit Aliens.vpj=20090912210534562
[TreeExpansion2]
- Holy Shit Aliens.vpj
- ..\
scroll:0
[State]
SCREEN: 1280 800 320 214 960 556 0 0 M 0 0 0 0 1006 540
CWD: ..\cpp
BUFFER: BN="..\gprof.log"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=1 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=Fundamental HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.182 CL=79 LE=0 CX=78 CY=6 WI=5 BI=23 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="StarfieldBackground.cpp"
BI: MA=1 74 1 TABS=1 5 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.2255 CL=9 LE=0 CX=8 CY=23 WI=5 BI=24 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="StarfieldBackground.h"
BI: MA=1 74 1 TABS=1 5 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.532 CL=1 LE=0 CX=0 CY=22 WI=5 BI=25 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="..\Makefile"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=Makefile HM=0 MF=32 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.1480 CL=19 LE=0 CX=18 CY=51 WI=5 BI=26 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="Character.cpp"
BI: MA=1 74 1 TABS=1 5 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.0 CL=1 LE=0 CX=0 CY=1 WI=5 BI=27 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="Character.h"
BI: MA=1 74 1 TABS=1 5 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.0 CL=1 LE=0 CX=0 CY=1 WI=5 BI=28 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="Control.h"
BI: MA=1 74 1 TABS=1 5 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.0 CL=1 LE=0 CX=0 CY=1 WI=5 BI=29 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="GameDisplay.cpp"
BI: MA=1 74 1 TABS=1 5 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.1761 CL=20 LE=0 CX=19 CY=63 WI=5 BI=30 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="GameLogic.cpp"
BI: MA=1 74 1 TABS=1 5 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.0 CL=1 LE=0 CX=0 CY=1 WI=5 BI=31 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="HUD.cpp"
BI: MA=1 74 1 TABS=1 5 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.0 CL=1 LE=0 CX=0 CY=1 WI=5 BI=32 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="main.cpp"
BI: MA=1 74 1 TABS=1 5 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=0 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.9433 CL=90 LE=0 CX=89 CY=32 WI=5 BI=33 HT=0 HN=0 HF=0 HC=4
WINDOW: 44 54 874 378 -1 -1 M WF=0 WT=1 "Terminal,6,0,1"
BUFFER: BN="main.cpp"
VIEW: LN=.9433 CL=90 LE=0 CX=89 CY=32 WI=126 BI=33 HT=0 HN=0 HF=0 HC=4
FILEHIST: 9
..\Makefile
Character.cpp
Character.h
Control.h
GameLogic.cpp
HUD.cpp
main.cpp
StarfieldBackground.cpp
GameDisplay.cpp

View File

@@ -0,0 +1,87 @@
[Global]
CurrentProject=Holy Shit Aliens.vpj
[ProjectDates]
Holy Shit Aliens.vpj=20090807083357000
[ActiveConfig]
Holy Shit Aliens.vpj=Release
[TreeExpansion2]
- Holy Shit Aliens.vpj
- ../backgrounds
- ../music
- ../sounds
- source
- ../sprites
scroll:0
[State]
SCREEN: 1440 900 0 27 1038 817 0 0 N 0 0 0 0 743 584
CWD: source/
BUFFER: BN="source/Animation.h"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=104 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.368 CL=92 LE=0 CX=92 CY=10 WI=5 BI=33 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Renderable.cpp"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=104 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.339 CL=2 LE=0 CX=2 CY=7 WI=5 BI=44 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/SpriteStrip.h"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.145 CL=1 LE=0 CX=1 CY=9 WI=5 BI=23 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="Makefile"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=Makefile HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.1615 CL=1 LE=0 CX=1 CY=15 WI=5 BI=27 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Renderable.h"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=104 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.-1 CL=1 LE=0 CX=1 CY=0 WI=5 BI=37 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Display.h"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=104 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.223 CL=16 LE=0 CX=16 CY=8 WI=5 BI=50 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/SpriteStrip.cpp"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.405 CL=11 LE=0 CX=11 CY=10 WI=5 BI=28 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Common.h"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.65 CL=23 LE=0 CX=23 CY=7 WI=5 BI=53 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Game.h"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.498 CL=28 LE=0 CX=28 CY=9 WI=5 BI=26 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Actor.h"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.1017 CL=8 LE=0 CX=8 CY=16 WI=5 BI=35 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/main.cpp"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.1787 CL=5 LE=0 CX=5 CY=13 WI=5 BI=29 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Actor.cpp"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.3883 CL=13 LE=0 CX=13 CY=10 WI=5 BI=32 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Animation.cpp"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.1148 CL=25 LE=0 CX=25 CY=1 WI=5 BI=24 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Display.cpp"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=104 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.0 CL=1 LE=0 CX=1 CY=1 WI=5 BI=6 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Game.cpp"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.2588 CL=11 LE=0 CX=11 CY=14 WI=5 BI=25 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Display2D.cpp"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.771 CL=24 LE=0 CX=24 CY=4 WI=5 BI=38 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="source/Display2D.h"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=C HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.530 CL=1 LE=0 CX=1 CY=12 WI=5 BI=45 HT=0 HN=0 HF=0 HC=4
BUFFER: BN="../../../branches/portal_bug_46/includes/zaius.php"
BI: MA=1 74 1 TABS=1 9 WWS=1 IWT=1 ST=0 IN=2 BW=0 US=32000 RO=0 SE=1 SN=0 BIN=0 MN=HTML HM=0 MF=8 TL=0 MLL=0 ASE=0 LNL=6 LCF=0 CAPS=0 E=0 ESBU2=-1
VIEW: LN=.0 CL=1 LE=0 CX=1 CY=1 WI=5 BI=41 HT=0 HN=0 HF=0 HC=4
WINDOW: 0 292 743 292 0 0 N WF=0 WT=2 "OEM Fixed Font,10,0,1"
BUFFER: BN="source/Display2D.cpp"
VIEW: LN=.1360 CL=17 LE=0 CX=17 CY=13 WI=127 BI=38 HT=0 HN=0 HF=0 HC=4
WINDOW: 0 0 743 292 0 0 N WF=0 WT=2 "OEM Fixed Font,10,0,1"
BUFFER: BN="source/Animation.cpp"
VIEW: LN=.678 CL=11 LE=0 CX=11 CY=3 WI=126 BI=24 HT=0 HN=0 HF=0 HC=4
FILEHIST: 9
source/Display.cpp
source/SpriteStrip.cpp
source/Common.h
source/Actor.h
source/main.cpp
source/Game.cpp
source/Actor.cpp
source/Animation.cpp
source/Display2D.cpp

BIN
cpp/Holy Shit Aliens.vtg Normal file

Binary file not shown.

133
cpp/StarfieldBackground.cpp Normal file
View File

@@ -0,0 +1,133 @@
#include "StarfieldBackground.h"
#include <SDL_gfxPrimitives.h>
#include <libgame/libgame.h>
StarfieldBackground::StarfieldBackground()
{
Actor::Actor();
this->lastTime = 0;
this->lockedFPS = 24;
}
StarfieldBackground::~StarfieldBackground()
{
if ( this->canvas != NULL ) {
delete this->canvas;
}
}
void StarfieldBackground::lockFPS(unsigned int fps)
{
this->lockedFPS = fps;
}
void StarfieldBackground::initStarfield(int w, int h)
{
Game &myGame = Game::NewSingleton();
// the entire purpose of this function is to ensure our temporary copy surface will
// have the same bit value and flags as the original image
Vector position;
Vector velocity;
SDL_Color color;
/*
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
int rmask = 0xff000000;
int gmask = 0x00ff0000;
int bmask = 0x0000ff00;
//int amask = 0x000000ff;
#else
int rmask = 0x000000ff;
int gmask = 0x0000ff00;
int bmask = 0x00ff0000;
//int amask = 0xff000000;
#endif
*/
//this->canvas = SDL_CreateRGBSurface(SDL_HWSURFACE, w, h, 32, rmask, gmask, bmask, 0);
this->canvas = myGame.getCanvas();
this->canvas->refcount += 1;
if ( this->canvas == NULL ) {
return;
}
for ( int i = 0; i < this->canvas->w/2 ; i++ ) {
position.x = (rand()%this->canvas->w)+1;
position.y = (rand()%this->canvas->h)+1;
position.z = 0;
velocity.x = 0;
velocity.y = 0;
if ( this->velocity.x > 0 ) {
velocity.x = (rand()%(int)this->velocity.x)+1;
}
if ( this->velocity.y > 0 ) {
velocity.y = (rand()%(int)this->velocity.y)+1;
}
velocity.z = 0;
color.r = (rand()%128)+127;
color.g = (rand()%128)+127;
color.b = (rand()%128)+127;
this->starpoints.push_back(position);
this->starcolors.push_back(color);
this->starvelocities.push_back(velocity);
}
}
SDL_Surface *StarfieldBackground::nextFrame()
{
std::vector<Vector>::iterator fieldIter;
std::vector<SDL_Color>::iterator colorIter;
//std::vector<Vector>::iterator velocityIter;
/*if ( (SDL_GetTicks() - this->lastTime) < (unsigned int) (1000 / this->lockedFPS) ) {
return;
} else {
this->lastTime = SDL_GetTicks();
}*/
//SDL_FillRect(this->canvas, NULL, 0x00000000);
fieldIter = this->starpoints.begin();
colorIter = this->starcolors.begin();
//velocityIter = this->starvelocities.begin();
while ( fieldIter != this->starpoints.end() ) {
pixelRGBA(this->canvas, (Sint16)(*fieldIter).x, (Sint16)(*fieldIter).y, (*colorIter).r, (*colorIter).g, (*colorIter).b, 255);
fieldIter++;
colorIter++;
}
return this->canvas;
}
void StarfieldBackground::update()
{
std::vector<Vector>::iterator fieldIter;
//std::vector<SDL_Color>::iterator colorIter;
std::vector<Vector>::iterator velocityIter;
if ( (SDL_GetTicks() - this->lastTime) < (unsigned int) (1000 / this->lockedFPS) ) {
return;
} else {
this->lastTime = SDL_GetTicks();
}
//SDL_FillRect(this->canvas, NULL, 0x00000000);
fieldIter = this->starpoints.begin();
//colorIter = this->starcolors.begin();
velocityIter = this->starvelocities.begin();
while ( fieldIter != this->starpoints.end() ) {
(*fieldIter).x += (*velocityIter).x;
(*fieldIter).y += (*velocityIter).y;
(*fieldIter).z += (*velocityIter).z;
if ( (*fieldIter).x > this->canvas->w ) {
(*fieldIter).x = 0;
}
if ( (*fieldIter).y > this->canvas->h ) {
(*fieldIter).y = 0;
}
//pixelRGBA(this->canvas, (*fieldIter).x, (*fieldIter).y, (*colorIter).r, (*colorIter).g, (*colorIter).b, 255);
fieldIter++;
//colorIter++;
velocityIter++;
}
return;
}

25
cpp/StarfieldBackground.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef __STARFIELDBACKGROUND_H__
#define __STARFIELDBACKGROUND_H__
#include <libgame/libgame.h>
class StarfieldBackground : public Actor
{
protected:
SDL_Surface *canvas;
unsigned int lockedFPS;
unsigned int lastTime;
std::vector<Vector> starpoints;
std::vector<Vector> starvelocities;
std::vector<SDL_Color> starcolors;
public:
StarfieldBackground();
~StarfieldBackground();
SDL_Surface *nextFrame();
void lockFPS(unsigned int fps);
void initStarfield(int w, int h);
void update();
};
#endif // __STARFIELDBACKGROUND_H__

36
cpp/logfile.txt Executable file
View File

@@ -0,0 +1,36 @@
Looping from 0 to 17 sprites...
Trying to load sprite strip from (index 0) file sprites/Enemy Fighter 1.png
Failed to load sprite strip from file sprites/Enemy Fighter 1.png
Trying to load sprite strip from (index 1) file sprites/Enemy Fighter 2.png
Failed to load sprite strip from file sprites/Enemy Fighter 2.png
Trying to load sprite strip from (index 2) file sprites/Enemy Fighter 3.png
Failed to load sprite strip from file sprites/Enemy Fighter 3.png
Trying to load sprite strip from (index 3) file sprites/Enemy Fighter 4.png
Failed to load sprite strip from file sprites/Enemy Fighter 4.png
Trying to load sprite strip from (index 4) file sprites/Enemy Laser Single.png
Failed to load sprite strip from file sprites/Enemy Laser Single.png
Trying to load sprite strip from (index 5) file sprites/Enemy Laser Double.png
Failed to load sprite strip from file sprites/Enemy Laser Double.png
Trying to load sprite strip from (index 6) file sprites/Player Ship 1.png
Failed to load sprite strip from file sprites/Player Ship 1.png
Trying to load sprite strip from (index 7) file sprites/Player Ship 2.png
Failed to load sprite strip from file sprites/Player Ship 2.png
Trying to load sprite strip from (index 8) file sprites/Player Ship Menu.png
Failed to load sprite strip from file sprites/Player Ship Menu.png
Trying to load sprite strip from (index 9) file sprites/Player Shield Hit.png
Failed to load sprite strip from file sprites/Player Shield Hit.png
Trying to load sprite strip from (index 10) file sprites/Powerup - Shield Recharge.png
Failed to load sprite strip from file sprites/Powerup - Shield Recharge.png
Trying to load sprite strip from (index 11) file sprites/Powerup - Spread Shot.png
Failed to load sprite strip from file sprites/Powerup - Spread Shot.png
Trying to load sprite strip from (index 12) file sprites/Powerup - Bigger Ship.png
Failed to load sprite strip from file sprites/Powerup - Bigger Ship.png
Trying to load sprite strip from (index 13) file sprites/Powerup - One Up.png
Failed to load sprite strip from file sprites/Powerup - One Up.png
Trying to load sprite strip from (index 14) file sprites/Star Destroyer 1.png
Failed to load sprite strip from file sprites/Star Destroyer 1.png
Trying to load sprite strip from (index 15) file sprites/Star Destroyer 2.png
Failed to load sprite strip from file sprites/Star Destroyer 2.png
Trying to load sprite strip from (index 16) file sprites/explosion.png
Failed to load sprite strip from file sprites/explosion.png
Exiting normally

884
cpp/main.cpp Normal file
View File

@@ -0,0 +1,884 @@
#include <libgame/libgame.h>
#include "main.h"
#include <iostream>
#include <cstdlib>
#include <stdlib.h>
#include <fstream>
// TODO:
//
// - add level clear screens
// - handle appearance of the boss dependent upon player score
// - get the game to start in fullscreen
//
// THE PROJECTILE/CHARACTER SUBCLASSING IS FUCKED. THE ORDER OF THE 'damage' ELEMENT AND OTHER
// ITEMS CAUSES UNEXPECTED RESULTS AS ITEMS SUCH AS PROJECTILES ARE TYPECAST AS A (Character *)
// AND PASSED AROUND THRU COLLISION FUNCTIONS. CHANGE THE ORDER THAT THE 'damage' ELEMENT IS DEFINED
// IN THE CHARACTER CLASS AND YOU'LL SEE THE LASERS START DOING WIERD SHIT AS A RESULT.
// keyed by difficulty level
// see generateEnemies() for how this is used
const int enemyWeights[][10] = {
{1, 1, 1, 1, 1, 2, 2, 2, 3, 3},
{1, 1, 1, 1, 2, 2, 2, 3, 3, 4},
{1, 1, 1, 2, 2, 2, 3, 3, 3, 4},
{1, 1, 2, 2, 2, 3, 3, 3, 4, 4} };
// keyed by difficulty level
// see generateEnemies() for how this is used
const int maxVisibleEnemies[][5] = {
// {TYPE1, TYPE2, TYPE3, TYPE4, BOSS}
{2, 1, 1, 1, 1},
{2, 2, 1, 1, 1},
{3, 2, 2, 1, 1},
{3, 3, 2, 2, 1} };
// keyed by difficulty level
int curVisibleEnemies[][5] = {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0} };
int loadSprites()
{
SpriteStrip *strip = NULL;
Game &myGame = Game::NewSingleton();
int failed = 0;
//std::cerr << "Looping from 0 to " << MAXSPRITES << " sprites...\n";
for ( int i = 0; i < MAXSPRITES ; i++ ) {
std::cerr .flush();
//std::cerr << "Trying to load sprite strip from (index " << i << ") file " << spriteStrips[i] << "\n";
strip = myGame.newSpriteStrip(spriteStrips[i]);
if ( strip == NULL ) {
//std::cerr << "Failed to allocate new sprite strip in memory.\n";
failed++;
continue ;
}
if ( strip->loadFromFile(spriteStrips[i], spriteStats[i][0], spriteStats[i][1], (Vector){0, 0, 0}) != 0 ) {
//std::cerr << "Failed to load sprite strip from file " << spriteStrips[i] << "\n";
delete strip;
failed++;
continue ;
}
//std::cerr << "Added sprite strip " << spriteStrips[i] << "(" << spriteStats[i][0] << "x" << spriteStats[i][1] << ") to memory\n";
}
// now do the same for the backgrounds
for ( int i = 0; i < MAXSCREENS ; i++ ) {
std::cerr .flush();
//std::cerr << "Trying to load sprite strip from (index " << i << ") file " << screenBackgrounds[i] << "\n";
strip = myGame.newSpriteStrip(screenBackgrounds[i]);
if ( strip == NULL ) {
//std::cerr << "Failed to allocate new sprite strip in memory.\n";
failed++;
continue ;
}
if ( strip->loadFromFile(screenBackgrounds[i], 0, 0, (Vector){0, 0, 0}) != 0 ) {
//std::cerr << "Failed to load sprite strip from file " << spriteStrips[i] << "\n";
failed++;
delete strip;
continue ;
}
//std::cerr << "Added sprite strip " << screenBackgrounds[i] << " (0x0) to memory\n";
}
//std::cerr << "returning with " << failed << " sprites failed to load.\n";
// init the enemy animations
myGame.newAnimation(ANIM_ENEMYFIGHTER1)->setStrip(myGame.getSpriteStrip(SPRITEFILE_ENEMYFIGHTER1), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_ENEMYFIGHTER2)->setStrip(myGame.getSpriteStrip(SPRITEFILE_ENEMYFIGHTER2), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_ENEMYFIGHTER3)->setStrip(myGame.getSpriteStrip(SPRITEFILE_ENEMYFIGHTER3), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_ENEMYFIGHTER4)->setStrip(myGame.getSpriteStrip(SPRITEFILE_ENEMYFIGHTER4), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_ENEMYDESTROYER1)->setStrip(myGame.getSpriteStrip(SPRITEFILE_ENEMYDESTROYER1), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_ENEMYDESTROYER2)->setStrip(myGame.getSpriteStrip(SPRITEFILE_ENEMYDESTROYER2), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_ENEMYLASERSINGLE)->setStrip(myGame.getSpriteStrip(SPRITEFILE_ENEMYLASER1), 0, 0, (Vector){0, 0, 0});
myGame.newAnimation(ANIM_ENEMYLASERDOUBLE)->setStrip(myGame.getSpriteStrip(SPRITEFILE_ENEMYLASER2), 0, 0, (Vector){0, 0, 0});
// init misc animations
myGame.newAnimation(ANIM_EXPLOSION)->setStrip(myGame.getSpriteStrip(SPRITEFILE_EXPLOSION), 12, 1, (Vector){0,0,0});
myGame.newAnimation(ANIM_PWUP_BIGSHIP)->setStrip(myGame.getSpriteStrip(SPRITEFILE_POWERUP_SHIP), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_PWUP_ONEUP)->setStrip(myGame.getSpriteStrip(SPRITEFILE_POWERUP_ONEUP), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_PWUP_SHIELD)->setStrip(myGame.getSpriteStrip(SPRITEFILE_POWERUP_SHIELD), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_PWUP_SPREADSHOT)->setStrip(myGame.getSpriteStrip(SPRITEFILE_POWERUP_SPREAD), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_PLAYERSPREAD1)->setStrip(myGame.getSpriteStrip(SPRITEFILE_PLAYERSPREAD1), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_PLAYERSPREAD3)->setStrip(myGame.getSpriteStrip(SPRITEFILE_PLAYERSPREAD3), 0, 0, (Vector){0,0,0});
return failed;
}
int initPlayers(Player *player1, Player *player2)
{
Animation *shipAnim = NULL;
Player *player;
Game &game = Game::NewSingleton();
GameOptions &opts = GameOptions::NewSingleton();
if ( player1 == NULL || player2 == NULL ) {
//std::cerr << "Player1 : " << player1 << " Player2 : " << player2 << "\n";
delete shipAnim;
return 1;
}
//std::cerr << "Setting sprite strip for player actors...\n";
if ( (shipAnim = game.newAnimation(ANIM_PLAYERDOUBLE)) == NULL ) {
return 1;
}
if ( shipAnim->setStrip(game.getSpriteStrip(SPRITEFILE_PLAYERSHIP2), 1) != 0 ) {
//std::cerr << "Couldn't set sprite strip for player animations\n";
return 1;
}
if ( (shipAnim = game.newAnimation(ANIM_PLAYERSINGLE)) == NULL ) {
return 1;
}
if ( shipAnim->setStrip(game.getSpriteStrip(SPRITEFILE_PLAYERSHIP1), 1) != 0 ) {
//std::cerr << "Couldn't set sprite strip for player animations\n";
return 1;
}
player = player1;
while ( player != NULL ) {
player->addAnimation(game.getAnimation(ANIM_PLAYERSINGLE), STATE_DEFAULT);
player->addState(STATE_NONE);
player->lives = 0;
player->score = 0;
player->setUserType(ACTOR_TEAM_PLAYER | ACTORTYPE_PLAYER | ACTORTYPE_NODELETE);
player->damage = 5;
player->weaponDamage = opts.playerBaseDamage;
player->projectileAnim = game.getAnimation(ANIM_PLAYERLASERSINGLE);
player->projectileSound = SOUNDFILE_PLAYERLASERSHOT;
player->deathSound = SOUNDFILE_EXPLOSION;
if ( player == player2 )
break;
player = player2;
}
player1->addAnimation(game.getAnimation(ANIM_EXPLOSION), STATE_DYING);
player2->addAnimation(game.getAnimation(ANIM_EXPLOSION), STATE_DYING);
player1->addAnimation(NULL, STATE_DEAD);
player2->addAnimation(NULL, STATE_DEAD);
player1->setPosition((Vector){250, 500, 0});
player2->setPosition((Vector){550, 500, 0});
player1->setState(STATE_NONE);
player2->setState(STATE_NONE);
return 0;
}
int setupStaticDisplay(Display2D *staticDisplay, std::string bgfile)
{
Actor *staticBackActor;
Animation *staticBackAnim;
Game &game = Game::NewSingleton();
if ( staticDisplay == NULL ) {
return 1;
}
staticBackActor = game.newActor(bgfile);
staticBackAnim = game.newAnimation(bgfile);
if ( staticBackActor == NULL ) {
return 1;
}
if ( staticBackAnim == NULL ) {
game.freeActor(bgfile);
return 1;
}
//staticDisplay->initVideo((Vector){0,0,0}, 800, 600, 32, SDL_SWSURFACE);
staticDisplay->shareCanvas(&(Game::NewSingleton()));
staticBackAnim->setStrip(game.getSpriteStrip(bgfile), 0);
staticBackActor->addAnimation(staticBackAnim, STATE_NONE);
staticBackActor->addState(STATE_NONE);
staticDisplay->addActor(staticBackActor, 0);
game.windows.push_back(staticDisplay);
return 0;
}
int setupGameDisplay(GameDisplay *gameDisplay)
{
StarfieldBackground *gameBackActor;
Game &game = Game::NewSingleton();
if ( gameDisplay == NULL ) {
return 1;
}
gameBackActor = new StarfieldBackground();
if ( gameBackActor == NULL ) {
return 1;
}
//std::cerr << "Scrolling background actor is at " << gameBackActor << "\n";
//gameDisplay->initVideo((Vector){0,0,0}, 800, 600, 32, SDL_SWSURFACE);
gameDisplay->shareCanvas(&(Game::NewSingleton()));
gameBackActor->setVelocity((Vector){0, 5, 0});
gameBackActor->initStarfield(800, 600);
gameBackActor->addState(STATE_NONE);
gameBackActor->lockFPS(24);
gameDisplay->addActor(gameBackActor, 0);
game.windows.push_back(gameDisplay);
game.addActor(gameBackActor, ACTOR_STARBACKGROUND);
return 0;
}
int configureOptionsMenu(MenuDisplay *menuDisplay)
{
Animation *menuAnimation;
Animation *pointerAnim;
Actor *menuBackground;
char joyName[128];
Game &myGame = Game::NewSingleton();
GameOptions &opts = GameOptions::NewSingleton();
int i = 0;
if ( pointerAnim == NULL ) {
return 1;
}
menuAnimation = myGame.newAnimation(ANIM_OPTIONMENU);
pointerAnim = myGame.newAnimation(ANIM_OPTIONPTR);
menuBackground = myGame.newActor(ACTOR_OPTMENUBACKGROUND);
if ( menuBackground == NULL ) {
myGame.freeAnimation(ANIM_OPTIONPTR);
return 1;
}
if ( menuAnimation == NULL ) {
myGame.freeAnimation(ANIM_OPTIONPTR);
myGame.freeActor(ACTOR_OPTMENUBACKGROUND);
return 1;
}
menuDisplay->initVideo((Vector){200,100,0}, 400, 400, 32, SDL_SWSURFACE);
menuAnimation->setStrip(myGame.getSpriteStrip(BACKGROUNDFILE_OPTIONS), 0);
pointerAnim->setStrip(myGame.getSpriteStrip(SPRITEFILE_PLAYERSHIP3), 0);
menuBackground->addAnimation(menuAnimation, STATE_NONE);
menuBackground->setPosition((Vector){0, 0, 0});
menuDisplay->addActor(menuBackground);
menuDisplay->setPointer(pointerAnim);
menuDisplay->setMenuOrigin((Vector){20, 20, 0} );
menuDisplay->setFont("arial", 20, (SDL_Color){0x2E,0x8F,0x2C,0}, (SDL_Color){0,0,0,0});
menuDisplay->setSpacing(20);
menuDisplay->addOption(GAMEOPT_DIFFICULTY, 0, 0, 0, 0, NULL);
menuDisplay->addSubOption(GAMEOPT_DIFFICULTY, DIFFICULTY_EASY);
menuDisplay->addSubOption(GAMEOPT_DIFFICULTY, DIFFICULTY_NORMAL);
menuDisplay->addSubOption(GAMEOPT_DIFFICULTY, DIFFICULTY_HARD);
menuDisplay->addSubOption(GAMEOPT_DIFFICULTY, DIFFICULTY_IMMORTAL);
menuDisplay->addOption(GAMEOPT_MUSIC, 0, 0, 0, 0, NULL);
menuDisplay->addSubOption(GAMEOPT_MUSIC, "ON");
menuDisplay->addSubOption(GAMEOPT_MUSIC, "OFF");
menuDisplay->addOption(GAMEOPT_SOUNDEFFECTS, 0, 0, 0, 0, NULL);
menuDisplay->addSubOption(GAMEOPT_SOUNDEFFECTS, "ON");
menuDisplay->addSubOption(GAMEOPT_SOUNDEFFECTS, "OFF");
menuDisplay->addOption(GAMEOPT_MUSICVOL, 0, 128, opts.musicVolume, 1, NULL);
menuDisplay->addOption(GAMEOPT_SOUNDVOL, 0, 128, opts.soundVolume, 1, NULL);
menuDisplay->addOption(GAMEOPT_P1CONTROL, 0, 0, 0, 0, NULL);
menuDisplay->addSubOption(GAMEOPT_P1CONTROL, CONTROLOPT_KEYBOARD);
for (i = 0; i < SDL_NumJoysticks() ; i++ ) {
memset((char *)&joyName, 128, 0);
sprintf((char *)&joyName, "J%d %s", i, SDL_JoystickName(i));
menuDisplay->addSubOption(GAMEOPT_P1CONTROL, std::string(joyName));
}
menuDisplay->addSubOption(GAMEOPT_P1CONTROL, CONTROLOPT_NONE);
menuDisplay->addOption(GAMEOPT_P2CONTROL, 0, 0, 0, 0, NULL);
menuDisplay->addSubOption(GAMEOPT_P2CONTROL, CONTROLOPT_NONE);
menuDisplay->addSubOption(GAMEOPT_P2CONTROL, CONTROLOPT_KEYBOARD);
for (i = 0; i < SDL_NumJoysticks() ; i++ ) {
memset((char *)&joyName, 128, 0);
sprintf((char *)&joyName, "J%d %s", i, SDL_JoystickName(i));
menuDisplay->addSubOption(GAMEOPT_P2CONTROL, std::string(joyName));
}
menuDisplay->setRelation(GAMEOPT_P2CONTROL, GAMEOPT_P1CONTROL);
menuDisplay->setRelation(GAMEOPT_P1CONTROL, GAMEOPT_P2CONTROL);
myGame.windows.push_back(menuDisplay);
return 0;
}
int configureTitleMenu(MenuDisplay *menuDisplay)
{
Animation *menuAnimation;
Animation *pointerAnim;
Actor *menuBackground;
Game &myGame = Game::NewSingleton();
if ( pointerAnim == NULL ) {
return 1;
}
menuAnimation = myGame.newAnimation(ANIM_TITLEMENU);
pointerAnim = myGame.newAnimation(ANIM_TITLEPTR);
menuBackground = myGame.newActor(ACTOR_TITLEBACKGROUND);
if ( menuBackground == NULL ) {
delete pointerAnim;
return 1;
}
if ( menuAnimation == NULL ) {
delete pointerAnim;
delete menuBackground;
return 1;
}
//menuDisplay->initVideo((Vector){0,0,0}, 800, 600, 32, SDL_SWSURFACE);
menuDisplay->shareCanvas(&(Game::NewSingleton()));
menuAnimation->setStrip(myGame.getSpriteStrip(BACKGROUNDFILE_MENU), 0);
pointerAnim->setStrip(myGame.getSpriteStrip(SPRITEFILE_PLAYERSHIP3), 0);
menuBackground->addAnimation(menuAnimation, STATE_NONE);
menuBackground->setPosition((Vector){0, 0, 0});
menuDisplay->addActor(menuBackground);
menuDisplay->setPointer(pointerAnim);
menuDisplay->setMenuOrigin((Vector){ 380, 150, 0} );
menuDisplay->setFont("arial", 30, (SDL_Color){0x2E,0x8F,0x2C,0}, (SDL_Color){0,0,0,0});
for (int i = 0; i < MAX_OPTS_TITLEMENU ; i++ ) {
//std::cerr << "Adding title menu option " << titleMenuOpts[i] << "\n";
menuDisplay->addOption(titleMenuOpts[i], 0, 0, 0, 0, NULL);
}
myGame.windows.push_back(menuDisplay);
return 0;
}
void checkPlayerInput(SDL_Event *event, int playerNum, Player *player, GameDisplay *gameDisplay)
{
GameOptions &opts = GameOptions::NewSingleton();
// FIXME: The static allocation of Animation objects is fucked. Have to dynamic EVERY SINGLE ONE.
// this one is GUARANTEED to be a loss at application exit.
ControlMap *controlMap = &opts.controlMaps[playerNum-1];
int joyNum = 0;
char tmpBuf[512];
memset((char *)&tmpBuf, 0x00, 512);
SDL_JoystickUpdate();
if ( controlMap == NULL || event == NULL ) {
//std::cerr << "NULL CONTROL MAP!\n";
return;
}
joyNum = SDL_JoystickIndex(controlMap->joystick);
//std::cerr << "Player " << playerNum << " has control type " << controlMap->controlType << "\n";
//sprintf((char *)&tmpBuf, "Current player state (pre): %d", player->getState() );
//std::cerr << tmpBuf << "\n";
if ( controlMap->controlType == CONTROL_TYPE_KEYBOARD ) {
if ( event->type == SDL_KEYUP ) {
if ( event->key.keysym.sym == controlMap->moveLeft ) {
player->removeState(STATE_MOVELEFT);
} else if ( event->key.keysym.sym == controlMap->moveRight ) {
player->removeState(STATE_MOVERIGHT);
} else if ( event->key.keysym.sym == controlMap->moveUp ) {
player->removeState(STATE_MOVEUP);
} else if ( event->key.keysym.sym == controlMap->moveDown ) {
player->removeState(STATE_MOVEDOWN);
} else if ( event->key.keysym.sym == controlMap->fire ) {
player->fireProjectile();
}
} else if ( event->type == SDL_KEYDOWN ) {
if ( event->key.keysym.sym == controlMap->moveLeft ) {
player->addState(STATE_MOVELEFT);
} else if ( event->key.keysym.sym == controlMap->moveRight ) {
player->addState(STATE_MOVERIGHT);
} else if ( event->key.keysym.sym == controlMap->moveUp ) {
player->addState(STATE_MOVEUP);
} else if ( event->key.keysym.sym == controlMap->moveDown ) {
player->addState(STATE_MOVEDOWN);
}
}
} else if ( controlMap->controlType == CONTROL_TYPE_JOYSTICK ) {
std::cerr << "Joystick event is " << (int)event->type << " (hat motion up is " << SDL_JOYHATMOTION << ")" << std::endl;
if ( event->type == SDL_JOYHATMOTION ) {
// OKAY you know what SCREW axis movements
// They suck suck SUCK
// just use the hat for this game
std::cerr << "Joystick event is for stick " << event->jhat.which << " but we're monitoring " << joyNum << std::endl;
if ( (event->type == SDL_JOYHATMOTION && event->jhat.which != joyNum) ) {
return;
}
std::cerr << "Joy hat value is : " << event->jhat.value << std::endl;
// the reason we also check axes 5 and 6 here is because some gamepads (like the
// logitech wingman this was developed with) map the joystick hat events to axes
// 5 and 6
if ( (event->jhat.value & controlMap->moveLeft) == controlMap->moveLeft) {
std::cerr << "Player is moving left\n";
player->addState(STATE_MOVELEFT);
} else {
player->removeState(STATE_MOVELEFT);
}
if ( (event->jhat.value & controlMap->moveRight) == controlMap->moveRight) {
std::cerr << "Player is moving right\n";
player->addState(STATE_MOVERIGHT);
} else {
player->removeState(STATE_MOVERIGHT);
}
if ( (event->jhat.value & controlMap->moveDown) == controlMap->moveDown) {
//std::cerr << "Player is moving up\n";
player->addState(STATE_MOVEDOWN);
} else {
player->removeState(STATE_MOVEDOWN);
}
if ( (event->jhat.value & controlMap->moveUp) == controlMap->moveUp) {
//std::cerr << "Player is moving down\n";
player->addState(STATE_MOVEUP);
} else {
player->removeState(STATE_MOVEUP);
}
} else if ( event->type == SDL_JOYBUTTONUP ) {
if ( event->jbutton.which == joyNum ) {
//std::cerr << "FIRING LASER\n";
player->fireProjectile();
}
}
}
//sprintf((char *)&tmpBuf, "Current player state (post): %d", player->getState() );
//std::cerr << tmpBuf << "\n";
}
void processInput(MenuDisplay *menuDisplay,
GameDisplay *gameDisplay,
Display2D *creditDisplay,
Display2D *helpDisplay,
Display2D *failDisplay,
MenuDisplay *optionDisplay,
Player *player1,
Player *player2,
HUDDisplay *hudDisplay1,
HUDDisplay *hudDisplay2)
{
Game &myGame = Game::NewSingleton();
GameStatus &gamestatus = GameStatus::NewSingleton();
SDL_Event nextEvent;
if ( gamestatus.status == GAMESTATE_OPTIONSCREEN ) {
if ( myGame.keyHeldDown(SDLK_LEFT) ) {
nextEvent.type = SDL_KEYDOWN;
nextEvent.key.keysym.sym = SDLK_LEFT;
nextEvent.key.state = SDL_PRESSED;
optionDisplay->handleEvent(&nextEvent);
}
if ( myGame.keyHeldDown(SDLK_RIGHT) ) {
nextEvent.type = SDL_KEYDOWN;
nextEvent.key.keysym.sym = SDLK_RIGHT;
nextEvent.key.state = SDL_PRESSED;
optionDisplay->handleEvent(&nextEvent);
}
}
while ( SDL_PollEvent(&nextEvent) != 0 ) {
//std::cerr << "Polling event from SDL queue ...\n";
switch (nextEvent.type) {
case SDL_KEYUP:
//std::cerr << "Keyup event received\n";
if ( nextEvent.key.state != SDL_RELEASED ) {
break;
}
if ( nextEvent.key.keysym.sym == SDLK_ESCAPE ) {
//std::cerr << gamestatus.status << "\n";
if ( gamestatus.status == GAMESTATE_CREDITSCREEN ||
gamestatus.status == GAMESTATE_HELPSCREEN ||
gamestatus.status == GAMESTATE_FAILSCREEN ) {
creditDisplay->setActive(0);
helpDisplay->setActive(0);
failDisplay->setActive(0);
gamestatus.status = GAMESTATE_TITLEMENU;
menuDisplay->setActive(1);
myGame.haltMusic();
myGame.playMusic(MUSICFILE_TITLESCREEN);
} else if ( gamestatus.status == GAMESTATE_OPTIONSCREEN ) {
optionDisplay->setActive(0);
//gamestatus.status = GAMESTATE_TITLEMENU;
} else if ( gamestatus.status == GAMESTATE_PLAYSINGLE || gamestatus.status == GAMESTATE_PLAYMULTI) {
gamestatus.status = GAMESTATE_TITLEMENU;
gameDisplay->setActive(0);
menuDisplay->setActive(1);
//std::cerr << "Clearing sounds...\n";
myGame.cleanSounds(1);
myGame.haltMusic();
myGame.playMusic(MUSICFILE_TITLESCREEN);
} else {
gamestatus.running = 0;
}
} else {
// processing keys per-gamestatus.status
if ( gamestatus.status == GAMESTATE_TITLEMENU ) {
menuDisplay->handleEvent(&nextEvent);
} else if ( gamestatus.status == GAMESTATE_OPTIONSCREEN) {
optionDisplay->handleEvent(&nextEvent);
}
}
case SDL_KEYDOWN:
if ( nextEvent.key.state != SDL_PRESSED ) {
break;
}
}
if ( gamestatus.status == GAMESTATE_PLAYSINGLE || gamestatus.status == GAMESTATE_PLAYMULTI ) {
checkPlayerInput(&nextEvent, 1, player1, gameDisplay);
checkPlayerInput(&nextEvent, 2, player2, gameDisplay);
}
}
}
void setControlMap(MenuOption *opt, Player *player, int playerNum)
{
GameOptions &opts = GameOptions::NewSingleton();
int joyNum;
char joyStr[2] = {'\0', '\0'};
ControlMap *controlMap = &opts.controlMaps[playerNum-1];
if ( opt == NULL ) {
return;
}
//std::cerr << "Setting player " << playerNum << "control scheme to " << opt->getStringValue() << "\n";
if ( opt->getStringValue() == CONTROLOPT_KEYBOARD ) {
//std::cerr << "Setting up keyboard control for player " << playerNum << "\n";
controlMap->controlType = CONTROL_TYPE_KEYBOARD;
controlMap->joystick = NULL;
controlMap->moveUp = CONTROL_KEY_MOVEUP;
controlMap->moveDown = CONTROL_KEY_MOVEDOWN;
controlMap->moveLeft = CONTROL_KEY_MOVELEFT;
controlMap->moveRight = CONTROL_KEY_MOVERIGHT;
controlMap->fire = CONTROL_KEY_FIRE;
//std::cerr << "Control is ready\n";
} else if ( opt->getStringValue() == CONTROLOPT_NONE ) {
controlMap->controlType = CONTROL_TYPE_NONE;
controlMap->joystick = NULL;
controlMap->moveUp = 0;
controlMap->moveDown = 0;
controlMap->moveLeft = 0;
controlMap->moveRight = 0;
controlMap->fire = 0;
} else if ( opt->getStringValue()[0] == 'J' ) {
//std::cerr << "Setting up joystick control for player " << playerNum << "\n";
joyStr[0] = opt->getStringValue()[1];
joyNum = atoi((char *)&joyStr);
if ( joyNum < SDL_NumJoysticks() ) {
if ( controlMap->joystick == NULL ) {
controlMap->joystick = SDL_JoystickOpen(joyNum);
if ( controlMap->joystick == NULL ) {
// shit..
std::cerr << "Failed opening joystick; re-setting this control to keyboard and hoping for the best.\n";
opt->name == CONTROLOPT_KEYBOARD;
setControlMap(opt, player, playerNum);
return;
}
std::cerr << "Successfully opened joystick " << joyNum << " " << opt->getStringValue() << "\n";
std::cerr << "Number of buttons " << SDL_JoystickNumButtons(controlMap->joystick) << "\n";
std::cerr << "Number of axes " << SDL_JoystickNumAxes(controlMap->joystick) << "\n";
}
controlMap->controlType = CONTROL_TYPE_JOYSTICK;
controlMap->moveUp = CONTROL_JS_MOVEUP;
controlMap->moveDown = CONTROL_JS_MOVEDOWN;
controlMap->moveLeft = CONTROL_JS_MOVELEFT;
controlMap->moveRight = CONTROL_JS_MOVERIGHT;
controlMap->fire = CONTROL_JS_FIRE;
controlMap->lastFireButtonState = 0;
//std::cerr << "Control is ready\n";
}
}
}
void processMenus(MenuDisplay *menuDisplay,
GameDisplay *gameDisplay,
Display2D *creditDisplay,
Display2D *helpDisplay,
Display2D *failDisplay,
MenuDisplay *optionDisplay,
Player *player1,
Player *player2,
HUDDisplay *hudDisplay1,
HUDDisplay *hudDisplay2)
{
Game &myGame = Game::NewSingleton();
GameStatus &gamestatus = GameStatus::NewSingleton();
GameOptions &opts = GameOptions::NewSingleton();
MenuOption *opt;
// this is mostly used to handle title menu option handling, not much else goes on here
if ( gamestatus.status == GAMESTATE_TITLEMENU ) {
// --------------- title screen menu processing ------------------------
if ( menuDisplay->isActive() == 0 ) {
opt = menuDisplay->getOption();
//std::cerr << opt->getStringValue() << "\n";
if ( opt != NULL && opt->getStringValue() == "1P START" ) {
menuDisplay->setActive(0);
gamestatus.status = GAMESTATE_PLAYSINGLE;
gameDisplay->setActive(1);
if ( opts.playMusic == 1 ) {
myGame.haltMusic();
myGame.playMusic(MUSICFILE_GAMESCREEN);
}
gamestatus.nextLevel(player1, NULL, 0);
player1->setPosition((Vector){350, 500, 0});
player1->setState(STATE_NONE);
gameDisplay->setHUDs(hudDisplay1, NULL);
if ( opts.playSound == 1 )
myGame.playSound(SOUNDFILE_PLAYERSTART);
player2->lives = -1;
} else if ( opt != NULL && opt->getStringValue() == "MP START" ) {
menuDisplay->setActive(0);
gamestatus.status = GAMESTATE_PLAYMULTI;
gameDisplay->setActive(1);
if ( opts.playMusic == 1 ) {
myGame.haltMusic();
myGame.playMusic(MUSICFILE_GAMESCREEN);
}
if ( opts.playSound == 1 )
myGame.playSound(SOUNDFILE_PLAYERSTART);
gameDisplay->setHUDs(hudDisplay1, hudDisplay2);
gamestatus.nextLevel(player1, player2, 0);
} else if ( opt != NULL && opt->getStringValue() == "CREDITS" ) {
menuDisplay->setActive(0);
gamestatus.status = GAMESTATE_CREDITSCREEN;
creditDisplay->setActive(1);
if ( opts.playMusic == 1 ) {
myGame.haltMusic();
myGame.playMusic(MUSICFILE_CREDITSCREEN);
}
} else if ( opt != NULL && opt->getStringValue() == "HELP" ) {
menuDisplay->setActive(0);
gamestatus.status = GAMESTATE_HELPSCREEN;
helpDisplay->setActive(1);
} else if ( opt != NULL && opt->getStringValue() == "OPTIONS" ) {
menuDisplay->setActive(1);
gamestatus.status = GAMESTATE_OPTIONSCREEN;
optionDisplay->setActive(1);
} else if ( opt != NULL && opt->getStringValue() == "QUIT" ) {
//std::cerr << "Quitting\n";
exit(0);
}
}
// we do this here instead of below, in the post-opt screen processing,
// so the default control maps are enforced even if they never enter the option screen
setControlMap(optionDisplay->getOption(GAMEOPT_P1CONTROL), player1, 1);
setControlMap(optionDisplay->getOption(GAMEOPT_P2CONTROL), player2, 2);
// ------------- OPTION SCREEN MENU PROCESSING -------------------------
} else if ( gamestatus.status == GAMESTATE_OPTIONSCREEN ) {
if ( optionDisplay->isActive() == 0 ) {
//std::cerr << "Trying to update options\n";
gamestatus.status = GAMESTATE_TITLEMENU;
// set music/sound/difficulty options
opt = optionDisplay->getOption(GAMEOPT_MUSIC);
if ( opt->getStringValue() == "OFF" ) {
myGame.haltMusic();
opts.playMusic = 0;
} else {
if ( opts.playMusic == 0 ) {
myGame.playMusic(MUSICFILE_TITLESCREEN);
}
opts.playMusic = 1;
}
opt = optionDisplay->getOption(GAMEOPT_SOUNDEFFECTS);
if ( opt->getStringValue() == "Off" ) {
opts.playSound = 0;
} else {
opts.playSound = 1;
}
opt = optionDisplay->getOption(GAMEOPT_DIFFICULTY);
if ( opt->getStringValue() == DIFFICULTY_EASY ) {
opts.difficultyLevel = 1;
} else if ( opt->getStringValue() == DIFFICULTY_NORMAL ) {
opts.difficultyLevel = 2;
} else if ( opt->getStringValue() == DIFFICULTY_HARD ) {
opts.difficultyLevel = 3;
} else if ( opt->getStringValue() == DIFFICULTY_IMMORTAL ) {
opts.difficultyLevel = 4;
}
opt = optionDisplay->getOption(GAMEOPT_MUSICVOL);
myGame.setMusicVolume(opt->getIntValue());
opt = optionDisplay->getOption(GAMEOPT_SOUNDVOL);
myGame.setSoundVolume(opt->getIntValue());
}
}
}
void generateEnemies(GameDisplay *display, Player *player1, Player *player2)
{
GameOptions &opts = GameOptions::NewSingleton();
GameStatus &status = GameStatus::NewSingleton();
Character *enemy = NULL;
Game &game = Game::NewSingleton();
char enemyName[64];
int enemyType = enemyWeights[opts.difficultyLevel-1][(rand()%10)+1];
//static Animation *enemyAnim = NULL;
if ( status.status != GAMESTATE_PLAYSINGLE && status.status != GAMESTATE_PLAYMULTI )
return;
if ( ((rand()%100)+1 < status.enemySpawnChance) &&
( SDL_GetTicks() - status.enemySpawnInterval) > status.enemyLastSpawned ) {
status.enemyLastSpawned = SDL_GetTicks();
enemy = new Character();
sprintf((char *)&enemyName, "ENEMY FIGHTER %d", enemyType);
enemy->addAnimation(game.getAnimation(std::string((char *)&enemyName)), STATE_DEFAULT);
enemy->addAnimation(game.getAnimation(ANIM_EXPLOSION), STATE_DYING);
enemy->addAnimation(NULL, STATE_DEAD);
enemy->setPosition((Vector){100+(rand()%600), 0, 0});
if ( enemyType == 4 ) {
enemy->setVelocity((Vector){status.enemyVelocity.y, status.enemyVelocity.y, 0});
enemy->addState(STATE_MOVERIGHT);
} else if ( enemyType == 3 ) {
enemy->setVelocity((Vector){status.enemyVelocity.y, status.enemyVelocity.y/2, 0});
} else
enemy->setVelocity((Vector){0, status.enemyVelocity.y, 0});
enemy->addState(STATE_MOVEDOWN);
// the math below yields us one of the four ACTORTYPE_ENEMYx defines.
enemy->setUserType(ACTOR_TEAM_ENEMY | ACTORTYPE_CHARACTER | (ENEMYTYPE_ENEMY1 << (enemyType-1)));
std::cerr << "Creating new enemy with userType " << enemy->getUserType() << " enemy type " << (ENEMYTYPE_ENEMY1 << (enemyType - 1)) << " and animation \"" << (char *)&enemyName << "\"\n";
enemy->damage = 50;
enemy->weaponDamage = 20;
enemy->health = 1;
std::cerr << "Getting enemy animation...\n";
if ( enemyType > 1 )
enemy->projectileAnim = game.getAnimation(ANIM_ENEMYLASERDOUBLE);
else
enemy->projectileAnim = game.getAnimation(ANIM_ENEMYLASERSINGLE);
enemy->projectileSound = SOUNDFILE_ENEMYLASERSHOT;
enemy->deathSound = SOUNDFILE_EXPLOSION;
enemy->score = 100 * enemyType;
enemy->target = player1;
std::cerr << "(SPAWN) curVisibleEnemies[" << opts.difficultyLevel-1 << "][" << enemyType-1 << "] = " << curVisibleEnemies[opts.difficultyLevel-1][enemyType-1] << "\n";
display->addActor(enemy, LAYER_SPRITE1);
display->colliders.push_back(enemy);
}
return;
}
int main(int argc, char *argv[])
{
// -- menu stuff
MenuDisplay menuDisplay;
GameDisplay &gameDisplay = GameDisplay::NewSingleton();
Display2D creditDisplay;
Display2D helpDisplay;
Display2D failDisplay;
MenuDisplay optionDisplay;
HUDDisplay hudDisplay1;
HUDDisplay hudDisplay2;
Actor *hudLivesActor;
Animation *hudLivesAnimation;
//unsigned int lastTimer = SDL_GetTicks();
// -- control stuff
//SDL_Event nextEvent;
// --- gamestate stuff
GameOptions &opts = GameOptions::NewSingleton();
GameStatus &gamestatus = GameStatus::NewSingleton();
Game &myGame = Game::NewSingleton();
std::vector<Character *> collidables;
Player player1;
Player player2;
std::ofstream logfile;
std::map<int, Display2D *> screenList;
myGame.initSDL();
myGame.initVideo(800, 600, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
srand(time(0));
TTF_Init();
FontRenderer &textengine = FontRenderer::NewSingleton();
textengine.loadFont("fonts/arialbd.ttf", "arial", 30);
textengine.loadFont("fonts/arial.ttf", "arial", 20);
if ( loadSprites() > 0 ) {
exit(1);
}
myGame.newAnimation(ANIM_PLAYERLASERSINGLE)->setStrip(myGame.getSpriteStrip(SPRITEFILE_PLAYERLASER1), 0, 0, (Vector){0,0,0});
myGame.newAnimation(ANIM_PLAYERLASERDOUBLE)->setStrip(myGame.getSpriteStrip(SPRITEFILE_PLAYERLASER2), 0, 0, (Vector){0,0,0});
if ( configureTitleMenu(&menuDisplay) == 1 )
exit(1);
if ( setupGameDisplay(&gameDisplay) == 1 )
exit(1);
if ( setupStaticDisplay(&creditDisplay, BACKGROUNDFILE_CREDITS) == 1 )
exit(1);
if ( setupStaticDisplay(&helpDisplay, BACKGROUNDFILE_HELP) == 1 )
exit(1);
if ( setupStaticDisplay(&failDisplay, BACKGROUNDFILE_FAIL) == 1 )
exit(1);
if ( configureOptionsMenu(&optionDisplay) == 1)
exit(1);
//gameDisplay.addActor(&player1, LAYER_SPRITE3);
//gameDisplay.addActor(&player2, LAYER_SPRITE3);
gameDisplay.setPlayers(&player1, &player2) ;
gameDisplay.colliders.push_back(&player1);
gameDisplay.colliders.push_back(&player2);
hudLivesActor = myGame.newActor(ACTOR_HUDLIVES);
hudLivesAnimation = myGame.newAnimation(ANIM_HUDLIVES);
hudLivesAnimation->setStrip(myGame.getSpriteStrip(SPRITEFILE_PLAYERSHIP3), 0, 0, (Vector){0,0,0});
hudLivesActor->addAnimation(hudLivesAnimation, STATE_NONE);
hudLivesActor->addState(STATE_NONE);
hudDisplay1.initVideo((Vector){0,0,0}, 120, 120, 32, SDL_SWSURFACE);
hudDisplay1.setLivesActor(hudLivesActor);
hudDisplay2.initVideo((Vector){800-120, 0, 0}, 120, 120, 32, SDL_SWSURFACE);
hudDisplay2.setLivesActor(hudLivesActor);
hudDisplay1.setTarget(&player1);
hudDisplay2.setTarget(&player2);
hudDisplay1.setText("PLAYER ONE");
hudDisplay2.setText("PLAYER TWO");
gamestatus.status = GAMESTATE_TITLEMENU;
menuDisplay.setActive(1);
gameDisplay.setActive(0);
creditDisplay.setActive(0);
failDisplay.setActive(0);
helpDisplay.setActive(0);
hudDisplay1.setActive(1);
hudDisplay2.setActive(1);
//myGame.playMusic(MUSICFILE_TITLESCREEN);
if ( initPlayers(&player1, &player2) != 0 ) {
//std::cerr << "I was unable to initialize the players. WTF?\n";
}
opts.musicVolume = 0;
opts.soundVolume = 0;
myGame.setMusicVolume(opts.musicVolume);
myGame.setSoundVolume(opts.soundVolume);
myGame.lockFPS(60);
//SDL_WM_GrabInput(SDL_GRAB_ON);
while ( gamestatus.running == 1 ) {
//opts.playSound = 0;
SDL_PumpEvents();
//std::cerr << "Menu display at " << &menuDisplay << " is active? " << menuDisplay.isActive() << "\n";
//std::cerr << "Game display at " << &gameDisplay << " is active? " << gameDisplay.isActive() << "\n";
//std::cerr << "Gamestate = " << GAMESTATE_TITLEMENU << " menuDisplay.isActive() " << menuDisplay.isActive() << "\n";
//std::cerr << "Game time : " << SDL_GetTicks() << "\n";
if ( player1.lives < 0 && player2.lives < 0 && gamestatus.status != GAMESTATE_FAILSCREEN) {
gamestatus.status = GAMESTATE_FAILSCREEN;
gameDisplay.setActive(0);
failDisplay.setActive(1);
//std::cerr << "Clearing sounds...\n";
myGame.cleanSounds(1);
myGame.haltMusic();
myGame.playMusic(MUSICFILE_FAILSCREEN);
player1.lives = player2.lives = 0;
}
processInput(&menuDisplay, &gameDisplay, &creditDisplay, &helpDisplay, &failDisplay,
&optionDisplay, &player1, &player2, &hudDisplay1, &hudDisplay2);
processMenus(&menuDisplay, &gameDisplay, &creditDisplay, &helpDisplay, &failDisplay,
&optionDisplay, &player1, &player2, &hudDisplay1, &hudDisplay2);
// bottom of event loop
gameDisplay.clampActor(&player1);
gameDisplay.clampActor(&player2);
generateEnemies(&gameDisplay, &player1, &player2);
gameDisplay.runCollisions();
myGame.update();
myGame.finishFrame();
}
exit(0);
}

82
cpp/main.h Executable file
View File

@@ -0,0 +1,82 @@
#ifndef __MAIN_H__
#define __MAIN_H__
#include "Common.h"
#define MAXSCREENS 6
#define MAXSPRITES 21
const char *screenBackgrounds[] = {
BACKGROUNDFILE_CREDITS,
BACKGROUNDFILE_FAIL,
BACKGROUNDFILE_HELP,
BACKGROUNDFILE_PLAIN,
BACKGROUNDFILE_MENU,
BACKGROUNDFILE_OPTIONS };
int spriteStats[][2] = {
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{110,110},
{0,0},
{0,0},
{0,0},
{0,0} };
const char *spriteStrips[] = {
SPRITEFILE_ENEMYFIGHTER1,
SPRITEFILE_ENEMYFIGHTER2,
SPRITEFILE_ENEMYFIGHTER3,
SPRITEFILE_ENEMYFIGHTER4,
SPRITEFILE_ENEMYLASER1,
SPRITEFILE_ENEMYLASER2,
SPRITEFILE_PLAYERSHIP1,
SPRITEFILE_PLAYERSHIP2,
SPRITEFILE_PLAYERSHIP3,
SPRITEFILE_PLAYERSHIELDHIT,
SPRITEFILE_POWERUP_SHIELD,
SPRITEFILE_POWERUP_SPREAD,
SPRITEFILE_POWERUP_SHIP,
SPRITEFILE_POWERUP_ONEUP,
SPRITEFILE_ENEMYDESTROYER1,
SPRITEFILE_ENEMYDESTROYER2,
SPRITEFILE_EXPLOSION,
SPRITEFILE_PLAYERLASER1,
SPRITEFILE_PLAYERLASER2,
SPRITEFILE_PLAYERSPREAD1,
SPRITEFILE_PLAYERSPREAD3 };
#define MAX_OPTS_TITLEMENU 6
const char *titleMenuOpts[] = {
"1P START",
"MP START",
"OPTIONS",
"CREDITS",
"HELP",
"QUIT"
};
#include <libgame/libgame.h>
#include "Character.h"
#include "HUD.h"
#include "StarfieldBackground.h"
#include "GameLogic.h"
#include "GameDisplay.h"
#endif

BIN
cpp/test.exe Executable file

Binary file not shown.

9534
cpp/tmplog Normal file

File diff suppressed because it is too large Load Diff