#include "DarkGDK.h"
struct TPonto {
float X, Y;
};
char *cDiretorio = "objeto";
char *cOrigemNome = "ufo.bmp";
char *cOrigemTiroNome = "ufotiro.bmp";
const int cId_Origem = 10;
const int cId_OrigemTiro = 11;
const int cId_Vetor_Direcao = 12;
const int cId_Vetor_Direcao_Normalizado= 13;
const int cId_Vetor_Origem = 14;
const int cIntervalo = 500;
const float cTiroVelocidade = 10.0f;
bool gAtirou;
float gAngulo;
int gTiroInc= 0;
int gDecorrido, gDestinoX, gDestinoY, gOrigemTiroX, gOrigemTiroY, gOrigemX, gOrigemY;
void Rotacionar (int ADestinoX, int ADestinoY);
void Mostrar_Texto ()
{
char Balaio[256];
sprintf (Balaio, "Ponteiro (%d; %d) %d°", dbMouseX (), dbMouseY (), (int) gAngulo);
dbText (0, 0, Balaio);
}
void Mostrar_Tiro (void)
{
float X, Y;
if (gAtirou) {
X= gOrigemTiroX + dbXVector2 (cId_Vetor_Direcao_Normalizado)*cTiroVelocidade*gTiroInc;
Y= gOrigemTiroY + dbYVector2 (cId_Vetor_Direcao_Normalizado)*cTiroVelocidade*gTiroInc;
gTiroInc++;
dbSprite (cId_OrigemTiro, X, Y, 1);
if ((X < 0) || (X > dbScreenWidth ()) || (Y < 0) || (Y > dbScreenHeight ()))
gAtirou= false;
}
else if (dbTimer () - gDecorrido >= cIntervalo) {
gTiroInc = 0;
gAtirou = true;
gDecorrido= dbTimer ();
// Vetor_Direcao = Destino - Fonte
dbSetVector2 (cId_Vetor_Direcao, gDestinoX-gOrigemX, gDestinoY-gOrigemY);
dbNormalizeVector2 (cId_Vetor_Direcao_Normalizado, cId_Vetor_Direcao);
}
}
// Usando a fórmula: Angulo = ArcCos (ProdutoEscalar (A; B) / Modulo (A)*Modulo (B))
float OlharPara1 (TPonto APosicao, TPonto APosicaoOlhando, TPonto APosicaoDesejada)
{
float Angulo, Determinante, ModuloD, ModuloO;
dbSetVector2 (cId_Vetor_Origem, APosicaoOlhando.X-APosicao.X, APosicaoOlhando.Y-APosicao.Y);
dbSetVector2 (cId_Vetor_Direcao, APosicaoDesejada.X-APosicao.X, APosicaoDesejada.Y-APosicao.Y);
// Angulo entre vetores
ModuloD = dbLengthVector2 (cId_Vetor_Direcao);
ModuloO = dbLengthVector2 (cId_Vetor_Origem);
Angulo = dbACOS (dbDotProductVector2 (cId_Vetor_Origem, cId_Vetor_Direcao)/(ModuloD*ModuloO));
Determinante= dbXVector2 (cId_Vetor_Origem)*dbYVector2 (cId_Vetor_Direcao) - dbXVector2 (cId_Vetor_Direcao)*dbYVector2 (cId_Vetor_Origem);
if (Determinante < 0)
Angulo= 360-Angulo;
return Angulo;
}
// Usando a fórmula: Angulo = ArcTg (ProdutoEscalarPerpendicular (A; B) / ProdutoEscalar (A; B))
float OlharPara2 (TPonto APosicao, TPonto APosicaoOlhando, TPonto APosicaoDesejada)
{
float Angulo, PerpDot;
dbSetVector2 (cId_Vetor_Origem, APosicaoOlhando.X-APosicao.X, APosicaoOlhando.Y-APosicao.Y);
dbSetVector2 (cId_Vetor_Direcao, APosicaoDesejada.X-APosicao.X, APosicaoDesejada.Y-APosicao.Y);
// Angulo entre vetores
PerpDot= dbXVector2 (cId_Vetor_Origem)*dbYVector2 (cId_Vetor_Direcao) - dbXVector2 (cId_Vetor_Direcao)*dbYVector2 (cId_Vetor_Origem);
Angulo = dbATANFULL (PerpDot, dbDotProductVector2 (cId_Vetor_Origem, cId_Vetor_Direcao));
return Angulo;
}
// Usando a fórmula: Angulo = ArcTg (B.Y; B.X) - ArcTg (A.Y; A.X)
float OlharPara (TPonto APosicao, TPonto APosicaoOlhando, TPonto APosicaoDesejada)
{
float Angulo;
dbSetVector2 (cId_Vetor_Origem, APosicaoOlhando.X-APosicao.X, APosicaoOlhando.Y-APosicao.Y);
dbSetVector2 (cId_Vetor_Direcao, APosicaoDesejada.X-APosicao.X, APosicaoDesejada.Y-APosicao.Y);
// Angulo entre vetores
Angulo= dbATANFULL (dbYVector2 (cId_Vetor_Direcao), dbXVector2 (cId_Vetor_Direcao)) - dbATANFULL (dbYVector2 (cId_Vetor_Origem), dbXVector2 (cId_Vetor_Origem));
return Angulo;
}
void Reposicionar (void)
{
gDestinoX= dbMouseX ();
gDestinoY= dbMouseY ();
Rotacionar (gDestinoX, gDestinoY);
}
void Rotacionar (int ADestinoX, int ADestinoY)
{
TPonto Destino, Olhando, Posicao;
Destino.X= ADestinoX;
Destino.Y= ADestinoY;
Posicao.X= gOrigemX;
Posicao.Y= gOrigemY;
Olhando.X= Posicao.X;
Olhando.Y= dbScreenHeight (); // A nave está voltada pra baixo
gAngulo = OlharPara (Posicao, Olhando, Destino);
dbRotateSprite (cId_Origem, gAngulo);
}
void DarkGDK (void)
{
dbSyncOn ();
dbSyncRate (60);
SetCurrentDirectory (cDiretorio);
dbCreateAnimatedSprite (cId_Origem, cOrigemNome, 1, 1, cId_Origem);
dbCreateAnimatedSprite (cId_OrigemTiro, cOrigemTiroNome, 1, 1, cId_OrigemTiro);
dbSetSpritePriority (cId_Origem, 2);
dbMakeVector2 (cId_Vetor_Direcao);
dbMakeVector2 (cId_Vetor_Direcao_Normalizado);
dbMakeVector2 (cId_Vetor_Origem);
dbSprite (cId_Origem, dbScreenWidth () / 2, dbScreenHeight () / 2, 1);
dbOffsetSprite (cId_Origem, dbSpriteWidth (cId_Origem) / 2, dbSpriteHeight (cId_Origem) / 2);
gOrigemX = dbSpriteX (cId_Origem);
gOrigemY = dbSpriteY (cId_Origem);
gOrigemTiroX= gOrigemX - dbSpriteWidth (cId_OrigemTiro) / 2;
gOrigemTiroY= gOrigemY;
gDecorrido = dbTimer () - cIntervalo - 500;
while (LoopGDK () && !dbEscapeKey ()) {
Reposicionar ();
Mostrar_Tiro ();
Mostrar_Texto ();
dbSync ();
}
dbDeleteVector2 (cId_Vetor_Direcao);
dbDeleteVector2 (cId_Vetor_Direcao_Normalizado);
dbDeleteVector2 (cId_Vetor_Origem);
}
|