304 lines
9.7 KiB
C++
304 lines
9.7 KiB
C++
|
|
#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;
|
||
|
|
}
|
||
|
|
}
|