#include "DarkGDK.h"
struct TPonto {
float X, Y;
};
struct TVeiculo {
bool Atirou, Sinal;
float TiroVelocidade;
int Id, IdDirecao, IdTiro, Escala, TiroInc;
TPonto Tiro, TiroInicio;
};
const int cIdAdversarioExplosaoSom= 300;
const int cIdAdversarioTiroSom = 301;
const int cIdFundo = 400;
const int cIdNaveExplosaoSom = 500;
const int cIdNaveTiroSom = 501;
const int cIdVetorDirecao = 600;
const int cIdVetorOrigem = 601;
const int cIncNaveTiroY = 5;
const int cIncNaveX = 5;
const int cIncNaveY = 5;
const int cIntervalo = 3000;
const int cTamAdv = 50;
const int cXMin = cIncNaveX;
char *cAdversarioExplosaoSomNome= "Boom 1.wav";
char *cAdversarioNome = "ufo.bmp";
char *cAdversarioTiroNome = "ufotiro.bmp";
char *cAdversarioTiroSomNome = "rocket.wav";
char *cFundo = "Fundo640x480.bmp";
char *cNaveExplosaoSomNome = "Bomb near.wav";
char *cNaveNome = "nave.bmp";
char *cNaveTiroNome = "tiro.bmp";
char *cNaveTiroSomNome = "fire.wav";
bool gFoiAtingido= false;
int gAcertos= 0, gAngulo= 0, gAtingido= 0;
int gAlturaMaxAdv, gDecorrido, gLarguraMaxAdv, gLarguraTelaAdv, gYMin, gYMax, gYMaxAdv;
float gP0= 0;
TVeiculo gAdversario, gNave;
void Mostrar_Texto (char *ATexto);
float OlharPara (int APosicaoX, int APosicaoY, int AOlhandoX, int AOlhandoY, int ADestinoX, int ADestinoY);
void Atirar_Adversario (void)
{
if (!gAdversario.Atirou) {
dbShowSprite (gAdversario.IdTiro);
dbPlaySound (cIdAdversarioTiroSom);
gAdversario.Atirou = true;
gAdversario.TiroInc= 0;
}
}
void Atirar_Nave (void)
{
if (!gNave.Atirou) {
gNave.Atirou= true;
gNave.Tiro.X= dbSpriteX (gNave.Id) + (dbSpriteWidth (gNave.Id) / 2) - (dbSpriteWidth (gNave.IdTiro) / 2);
gNave.Tiro.Y= dbSpriteY (gNave.Id) - 15;
dbShowSprite (gNave.IdTiro);
dbPlaySound (cIdNaveTiroSom);
}
}
void DispararAoColidir_NaveTiroComAdversario (void)
{
gNave.Atirou= false;
dbHideSprite (gAdversario.Id);
dbPlaySound (cIdAdversarioExplosaoSom);
gAcertos++;
}
void DispararAoColidir_AdversarioTiroComNave (void)
{
gAdversario.Atirou= false;
gFoiAtingido = true;
dbPlaySound (cIdNaveExplosaoSom);
gAtingido++;
}
void Navegar (void)
{
if (dbUpKey ())
if (dbSpriteY (gNave.Id) - cIncNaveY >= gYMin)
dbSprite (gNave.Id, dbSpriteX (gNave.Id), dbSpriteY (gNave.Id) - cIncNaveY, 1);
if (dbDownKey ())
if (dbSpriteY (gNave.Id) + cIncNaveY <= gYMax)
dbSprite (gNave.Id, dbSpriteX (gNave.Id), dbSpriteY (gNave.Id) + cIncNaveY, 1);
if (dbKeyState (203) || dbKeyState (30)) // Movimentar nave pra esquerda <Seta esquerda>, <a>
if (dbSpriteX (gNave.Id) >= cXMin)
dbSprite (gNave.Id, dbSpriteX (gNave.Id) - cIncNaveX, dbSpriteY (gNave.Id), 1);
if (dbKeyState (205) || dbKeyState (32)) // Movimentar nave pra direita <Seta direita>, <d>
if (dbSpriteX (gNave.Id) <= dbScreenWidth () - dbSpriteWidth (gNave.Id) - cXMin)
dbSprite (gNave.Id, dbSpriteX (gNave.Id) + cIncNaveX, dbSpriteY (gNave.Id), 1);
if (dbKeyState (57)) // Atirar <Barra de espaço>
Atirar_Nave ();
}
// O oponente vai crescendo até cTamAdv%, daí atira. A seguir passa a encolher
void Mostrar_Adversario (void)
{
int XCentroNave;
if (gAdversario.Escala > 0) {
if (gAdversario.Escala == cTamAdv) {
// Atira e muda o sinal pra diminuir
if (dbSpriteVisible (gAdversario.Id))
Atirar_Adversario ();
gAdversario.Sinal= false;
gAdversario.Escala--;
}
else {
// Aumenta/diminui tamanho
dbStretchSprite (gAdversario.Id, gAdversario.Escala, gAdversario.Escala);
if (gAdversario.Sinal)
gAdversario.Escala++;
else
gAdversario.Escala--;
}
}
else if (dbTimer () - gDecorrido >= cIntervalo) {
// Mostra o oponente a cada 'gDecorrido' milisegundos
gDecorrido = dbTimer ();
gAdversario.Escala= 1;
gAdversario.Sinal = true;
dbSprite (gAdversario.Id, dbRND (gLarguraTelaAdv) + gLarguraMaxAdv, dbRND (gYMaxAdv) + gAlturaMaxAdv, 1);
dbOffsetSprite (gAdversario.Id, gLarguraMaxAdv/2, gAlturaMaxAdv/2);
gAdversario.TiroInicio.X= dbSpriteX (gAdversario.Id) - dbSpriteWidth (gAdversario.IdTiro) / 2;
gAdversario.TiroInicio.Y= dbSpriteY (gAdversario.Id);
XCentroNave = dbSpriteX (gNave.Id) + dbSpriteWidth (gNave.Id) / 2;
gAngulo = OlharPara (dbSpriteX (gAdversario.Id), dbSpriteY (gAdversario.Id), dbSpriteX (gAdversario.Id), dbSpriteY (gNave.Id), XCentroNave, dbSpriteY (gNave.Id));
// Vetor_Direcao = Destino - Fonte
dbSetVector2 (cIdVetorDirecao, XCentroNave - gAdversario.TiroInicio.X, dbSpriteY (gNave.Id) - gAdversario.TiroInicio.Y);
dbNormalizeVector2 (gAdversario.IdDirecao, cIdVetorDirecao);
dbShowSprite (gAdversario.Id);
dbRotateSprite (gAdversario.Id, gAngulo);
}
else
dbHideSprite (gAdversario.Id);
}
void Mostrar_AdversarioTiro (void)
{
float X, Y;
if (gAdversario.Atirou) {
// Mostra o tiro
X= gAdversario.TiroInicio.X + dbXVector2 (gAdversario.IdDirecao)*gAdversario.TiroVelocidade*gAdversario.TiroInc;
Y= gAdversario.TiroInicio.Y + dbYVector2 (gAdversario.IdDirecao)*gAdversario.TiroVelocidade*gAdversario.TiroInc;
gAdversario.TiroInc++;
dbSprite (gAdversario.IdTiro, X, Y, 1);
// Retira o tiro se ultrapassar a janela ou se bater na nave
if (Y > dbScreenHeight ())
gAdversario.Atirou= false;
else if (dbSpriteCollision (gAdversario.IdTiro, gNave.Id) && dbSpriteVisible (gNave.Id))
DispararAoColidir_AdversarioTiroComNave ();
if (!gAdversario.Atirou)
dbHideSprite (gAdversario.IdTiro);
}
}
void Mostrar_Fundo (void)
{
const float cPVelocidade= 10.0f;
int A, L;
gP0+= 0.25f*cPVelocidade;
if (gP0 > dbScreenHeight ())
gP0= 0;
dbSprite (cIdFundo, 0, gP0, cIdFundo);
dbSprite (cIdFundo+1, 0, gP0-dbScreenHeight (), cIdFundo);
}
void Mostrar_NaveTiro (void)
{
if (gNave.Atirou) {
if (gNave.Tiro.Y <= 0)
gNave.Atirou= false;
else if (dbSpriteCollision (gNave.IdTiro, gAdversario.Id) && dbSpriteVisible (gAdversario.Id))
DispararAoColidir_NaveTiroComAdversario ();
else {
dbSprite (gNave.IdTiro, gNave.Tiro.X, gNave.Tiro.Y, 1);
gNave.Tiro.Y= gNave.Tiro.Y - cIncNaveTiroY*gNave.TiroVelocidade;
}
if (!gNave.Atirou)
dbHideSprite (gNave.IdTiro);
}
}
void Mostrar_Texto (char *ATexto)
{
char Balaio[256];
if (ATexto != "")
dbSetWindowTitle (ATexto);
else {
sprintf (Balaio, "Oponentes: %d; Nave: %d", gAcertos, gAtingido);
dbSetWindowTitle (Balaio);
}
}
float OlharPara (TPonto APosicao, TPonto APosicaoOlhando, TPonto APosicaoDesejada)
{
float Angulo, Determinante, ModuloD, ModuloO;
dbSetVector2 (cIdVetorDirecao, APosicaoDesejada.X-APosicao.X, APosicaoDesejada.Y-APosicao.Y);
dbSetVector2 (cIdVetorOrigem, APosicaoOlhando.X-APosicao.X, APosicaoOlhando.Y-APosicao.Y);
// Ângulo entre vetores
ModuloD = dbLengthVector2 (cIdVetorDirecao);
ModuloO = dbLengthVector2 (cIdVetorOrigem);
Angulo = dbACOS (dbDotProductVector2 (cIdVetorOrigem, cIdVetorDirecao)/(ModuloD*ModuloO));
Determinante= dbXVector2 (cIdVetorOrigem)*dbYVector2 (cIdVetorDirecao) - dbXVector2 (cIdVetorDirecao)*dbYVector2 (cIdVetorOrigem);
if (Determinante < 0)
Angulo= 360-Angulo;
return Angulo;
}
float OlharPara (int APosicaoX, int APosicaoY, int AOlhandoX, int AOlhandoY, int ADestinoX, int ADestinoY)
{
TPonto Destino, Olhando, Posicao;
Destino.X= ADestinoX;
Destino.Y= ADestinoY;
Posicao.X= APosicaoX;
Posicao.Y= APosicaoY;
Olhando.X= AOlhandoX;
Olhando.Y= AOlhandoY;
return OlharPara (Posicao, Olhando, Destino);
}
void DarkGDK (void)
{
dbSetDisplayMode (640, 480, 32);
dbAutoCamOff ();
dbSyncOn ();
dbSyncRate (60);
dbSetImageColorKey (1, 100, 120);
SetCurrentDirectory ("objeto");
gNave.Atirou = false;
gNave.Id = 10;
gNave.IdTiro = 11;
gNave.TiroVelocidade = 2.0f;
gAdversario.Atirou = false;
gAdversario.Escala = 0;
gAdversario.Id = 20;
gAdversario.IdTiro = 21;
gAdversario.IdDirecao = 22;
gAdversario.Sinal = true;
gAdversario.TiroInc = 0;
gAdversario.TiroVelocidade= 5.0f;
dbCreateAnimatedSprite (gNave.Id, cNaveNome, 1, 1, gNave.Id);
dbCreateAnimatedSprite (gNave.IdTiro, cNaveTiroNome, 1, 1, gNave.IdTiro);
dbCreateAnimatedSprite (gAdversario.Id, cAdversarioNome, 1, 1, gAdversario.Id);
dbCreateAnimatedSprite (gAdversario.IdTiro, cAdversarioTiroNome, 1, 1, gAdversario.IdTiro);
dbLoadImage (cFundo, cIdFundo);
gAlturaMaxAdv = dbSpriteHeight (gAdversario.Id);
gLarguraMaxAdv = dbSpriteWidth (gAdversario.Id);
gLarguraTelaAdv= dbScreenWidth () - 2*gLarguraMaxAdv;
dbStretchSprite (gNave.Id, 50, 50);
dbStretchSprite (gNave.IdTiro, 50, 50);
dbStretchSprite (gAdversario.IdTiro, 50, 50);
dbSetSpritePriority (gNave.Id, 3);
dbSetSpritePriority (gNave.IdTiro, 3);
dbSetSpritePriority (gAdversario.Id, 3);
dbSetSpritePriority (gAdversario.IdTiro, 3);
dbLoadSound (cNaveTiroSomNome, cIdNaveTiroSom);
dbLoadSound (cNaveExplosaoSomNome, cIdNaveExplosaoSom);
dbLoadSound (cAdversarioTiroSomNome, cIdAdversarioTiroSom);
dbLoadSound (cAdversarioExplosaoSomNome, cIdAdversarioExplosaoSom);
dbMakeVector2 (cIdVetorDirecao);
dbMakeVector2 (cIdVetorOrigem);
dbMakeVector2 (gAdversario.IdDirecao);
gYMax = dbScreenHeight () - dbSpriteHeight (gNave.Id) - 2;
gYMaxAdv= dbScreenHeight () / 2;
gYMin = gYMaxAdv + gAlturaMaxAdv*2;
dbSprite (gNave.Id, (dbScreenWidth ()-dbSpriteWidth (gNave.Id))/2, gYMax, 1);
gDecorrido= dbTimer () - cIntervalo - 500;
while (LoopGDK () && !dbEscapeKey ()) {
Mostrar_Fundo ();
Navegar ();
Mostrar_NaveTiro ();
Mostrar_AdversarioTiro ();
Mostrar_Adversario ();
Mostrar_Texto ("");
if (gFoiAtingido)
Mostrar_Texto ("FOI ATINGIDO!!!");
dbSync ();
if (gFoiAtingido) {
dbWait (2000);
gFoiAtingido= false;
}
}
dbDeleteVector2 (cIdVetorDirecao);
dbDeleteVector2 (cIdVetorOrigem);
dbDeleteVector2 (gAdversario.IdDirecao);
}
|