1311 lines
26 KiB
C++
1311 lines
26 KiB
C++
#include "raylib.h"
|
|
#include <cmath>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
|
|
struct Bala
|
|
{
|
|
Vector2 posicion;
|
|
Vector2 direccion;
|
|
float velocidad;
|
|
int equipo;
|
|
int rebotes;
|
|
bool activa;
|
|
};
|
|
|
|
struct Municion
|
|
{
|
|
Vector2 posicion;
|
|
bool activa;
|
|
};
|
|
|
|
struct Entidad
|
|
{
|
|
Vector2 posicion;
|
|
Vector2 velocidad;
|
|
Vector2 direccion;
|
|
float radio;
|
|
float vida;
|
|
float vidaMaxima;
|
|
int equipo;
|
|
bool jugador;
|
|
bool viva;
|
|
int municion;
|
|
float tiempoDisparo;
|
|
};
|
|
|
|
struct Pared
|
|
{
|
|
Rectangle rectangulo;
|
|
};
|
|
|
|
const float MUNDO_ANCHO = 1000.0f;
|
|
const float MUNDO_ALTO = 650.0f;
|
|
const float BORDE = 35.0f;
|
|
|
|
const float RADIO_JUGADOR = 18.0f;
|
|
const float RADIO_ENEMIGO = 20.0f;
|
|
|
|
const float VELOCIDAD_JUGADOR = 300.0f;
|
|
const float VELOCIDAD_IA = 175.0f;
|
|
|
|
const float VELOCIDAD_BALA = 720.0f;
|
|
const float DAÑO_BALA = 25.0f;
|
|
|
|
const float RADIO_VISION = 235.0f;
|
|
|
|
float Limitar(float valor, float minimo, float maximo)
|
|
{
|
|
if (valor < minimo)
|
|
return minimo;
|
|
|
|
if (valor > maximo)
|
|
return maximo;
|
|
|
|
return valor;
|
|
}
|
|
|
|
Vector2 Normalizar(Vector2 v)
|
|
{
|
|
float largo = sqrtf(v.x * v.x + v.y * v.y);
|
|
|
|
if (largo <= 0.0001f)
|
|
return {0.0f, 0.0f};
|
|
|
|
return {
|
|
v.x / largo,
|
|
v.y / largo
|
|
};
|
|
}
|
|
|
|
float Distancia(Vector2 a, Vector2 b)
|
|
{
|
|
float x = a.x - b.x;
|
|
float y = a.y - b.y;
|
|
|
|
return sqrtf(x * x + y * y);
|
|
}
|
|
|
|
bool CirculoCirculo(
|
|
Vector2 a,
|
|
float radioA,
|
|
Vector2 b,
|
|
float radioB)
|
|
{
|
|
return Distancia(a, b) < radioA + radioB;
|
|
}
|
|
|
|
bool CirculoRectangulo(
|
|
Vector2 centro,
|
|
float radio,
|
|
Rectangle rect)
|
|
{
|
|
float puntoX = Limitar(
|
|
centro.x,
|
|
rect.x,
|
|
rect.x + rect.width
|
|
);
|
|
|
|
float puntoY = Limitar(
|
|
centro.y,
|
|
rect.y,
|
|
rect.y + rect.height
|
|
);
|
|
|
|
float dx = centro.x - puntoX;
|
|
float dy = centro.y - puntoY;
|
|
|
|
return dx * dx + dy * dy < radio * radio;
|
|
}
|
|
|
|
void RebotarBorde(Entidad& entidad)
|
|
{
|
|
float izquierda = BORDE + entidad.radio;
|
|
float derecha = MUNDO_ANCHO - BORDE - entidad.radio;
|
|
float arriba = BORDE + entidad.radio;
|
|
float abajo = MUNDO_ALTO - BORDE - entidad.radio;
|
|
|
|
if (entidad.posicion.x < izquierda)
|
|
{
|
|
entidad.posicion.x = izquierda;
|
|
entidad.velocidad.x = fabsf(entidad.velocidad.x);
|
|
}
|
|
|
|
if (entidad.posicion.x > derecha)
|
|
{
|
|
entidad.posicion.x = derecha;
|
|
entidad.velocidad.x = -fabsf(entidad.velocidad.x);
|
|
}
|
|
|
|
if (entidad.posicion.y < arriba)
|
|
{
|
|
entidad.posicion.y = arriba;
|
|
entidad.velocidad.y = fabsf(entidad.velocidad.y);
|
|
}
|
|
|
|
if (entidad.posicion.y > abajo)
|
|
{
|
|
entidad.posicion.y = abajo;
|
|
entidad.velocidad.y = -fabsf(entidad.velocidad.y);
|
|
}
|
|
}
|
|
|
|
void RebotarPared(
|
|
Entidad& entidad,
|
|
const std::vector<Pared>& paredes)
|
|
{
|
|
for (const Pared& pared : paredes)
|
|
{
|
|
if (!CirculoRectangulo(
|
|
entidad.posicion,
|
|
entidad.radio,
|
|
pared.rectangulo))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
float izquierda = pared.rectangulo.x;
|
|
float derecha = pared.rectangulo.x +
|
|
pared.rectangulo.width;
|
|
|
|
float arriba = pared.rectangulo.y;
|
|
float abajo = pared.rectangulo.y +
|
|
pared.rectangulo.height;
|
|
|
|
float dIzquierda =
|
|
fabsf(entidad.posicion.x - izquierda);
|
|
|
|
float dDerecha =
|
|
fabsf(entidad.posicion.x - derecha);
|
|
|
|
float dArriba =
|
|
fabsf(entidad.posicion.y - arriba);
|
|
|
|
float dAbajo =
|
|
fabsf(entidad.posicion.y - abajo);
|
|
|
|
float menor = std::min(
|
|
std::min(dIzquierda, dDerecha),
|
|
std::min(dArriba, dAbajo)
|
|
);
|
|
|
|
if (menor == dIzquierda)
|
|
{
|
|
entidad.posicion.x =
|
|
izquierda - entidad.radio;
|
|
|
|
entidad.velocidad.x =
|
|
-fabsf(entidad.velocidad.x);
|
|
}
|
|
else if (menor == dDerecha)
|
|
{
|
|
entidad.posicion.x =
|
|
derecha + entidad.radio;
|
|
|
|
entidad.velocidad.x =
|
|
fabsf(entidad.velocidad.x);
|
|
}
|
|
else if (menor == dArriba)
|
|
{
|
|
entidad.posicion.y =
|
|
arriba - entidad.radio;
|
|
|
|
entidad.velocidad.y =
|
|
-fabsf(entidad.velocidad.y);
|
|
}
|
|
else
|
|
{
|
|
entidad.posicion.y =
|
|
abajo + entidad.radio;
|
|
|
|
entidad.velocidad.y =
|
|
fabsf(entidad.velocidad.y);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool TocarPared(
|
|
Vector2 posicion,
|
|
const std::vector<Pared>& paredes)
|
|
{
|
|
for (const Pared& pared : paredes)
|
|
{
|
|
if (CheckCollisionPointRec(
|
|
posicion,
|
|
pared.rectangulo))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void MoverBala(
|
|
Bala& bala,
|
|
float dt,
|
|
const std::vector<Pared>& paredes)
|
|
{
|
|
if (!bala.activa)
|
|
return;
|
|
|
|
Vector2 siguiente = {
|
|
bala.posicion.x +
|
|
bala.direccion.x *
|
|
bala.velocidad *
|
|
dt,
|
|
|
|
bala.posicion.y +
|
|
bala.direccion.y *
|
|
bala.velocidad *
|
|
dt
|
|
};
|
|
|
|
bool golpeo = false;
|
|
|
|
if (siguiente.x < BORDE)
|
|
{
|
|
siguiente.x = BORDE;
|
|
|
|
if (bala.rebotes == 0)
|
|
{
|
|
bala.direccion.x *= -1.0f;
|
|
bala.rebotes++;
|
|
}
|
|
else
|
|
{
|
|
bala.activa = false;
|
|
}
|
|
|
|
golpeo = true;
|
|
}
|
|
|
|
if (siguiente.x > MUNDO_ANCHO - BORDE)
|
|
{
|
|
siguiente.x = MUNDO_ANCHO - BORDE;
|
|
|
|
if (bala.rebotes == 0)
|
|
{
|
|
bala.direccion.x *= -1.0f;
|
|
bala.rebotes++;
|
|
}
|
|
else
|
|
{
|
|
bala.activa = false;
|
|
}
|
|
|
|
golpeo = true;
|
|
}
|
|
|
|
if (siguiente.y < BORDE)
|
|
{
|
|
siguiente.y = BORDE;
|
|
|
|
if (bala.rebotes == 0)
|
|
{
|
|
bala.direccion.y *= -1.0f;
|
|
bala.rebotes++;
|
|
}
|
|
else
|
|
{
|
|
bala.activa = false;
|
|
}
|
|
|
|
golpeo = true;
|
|
}
|
|
|
|
if (siguiente.y > MUNDO_ALTO - BORDE)
|
|
{
|
|
siguiente.y = MUNDO_ALTO - BORDE;
|
|
|
|
if (bala.rebotes == 0)
|
|
{
|
|
bala.direccion.y *= -1.0f;
|
|
bala.rebotes++;
|
|
}
|
|
else
|
|
{
|
|
bala.activa = false;
|
|
}
|
|
|
|
golpeo = true;
|
|
}
|
|
|
|
if (!bala.activa)
|
|
return;
|
|
|
|
if (!golpeo)
|
|
{
|
|
for (const Pared& pared : paredes)
|
|
{
|
|
if (!CheckCollisionPointRec(
|
|
siguiente,
|
|
pared.rectangulo))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (bala.rebotes == 0)
|
|
{
|
|
float izquierda = pared.rectangulo.x;
|
|
float derecha =
|
|
pared.rectangulo.x +
|
|
pared.rectangulo.width;
|
|
|
|
float arriba = pared.rectangulo.y;
|
|
float abajo =
|
|
pared.rectangulo.y +
|
|
pared.rectangulo.height;
|
|
|
|
float dxIzquierda =
|
|
fabsf(siguiente.x - izquierda);
|
|
|
|
float dxDerecha =
|
|
fabsf(siguiente.x - derecha);
|
|
|
|
float dyArriba =
|
|
fabsf(siguiente.y - arriba);
|
|
|
|
float dyAbajo =
|
|
fabsf(siguiente.y - abajo);
|
|
|
|
float menorX =
|
|
std::min(dxIzquierda, dxDerecha);
|
|
|
|
float menorY =
|
|
std::min(dyArriba, dyAbajo);
|
|
|
|
if (menorX < menorY)
|
|
bala.direccion.x *= -1.0f;
|
|
else
|
|
bala.direccion.y *= -1.0f;
|
|
|
|
bala.rebotes++;
|
|
|
|
siguiente.x +=
|
|
bala.direccion.x * 3.0f;
|
|
|
|
siguiente.y +=
|
|
bala.direccion.y * 3.0f;
|
|
}
|
|
else
|
|
{
|
|
bala.activa = false;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bala.activa)
|
|
bala.posicion = siguiente;
|
|
}
|
|
|
|
int BuscarObjetivo(
|
|
int indice,
|
|
const std::vector<Entidad>& entidades)
|
|
{
|
|
int objetivo = -1;
|
|
float menorDistancia = 999999.0f;
|
|
|
|
for (int i = 0;
|
|
i < (int)entidades.size();
|
|
i++)
|
|
{
|
|
if (i == indice)
|
|
continue;
|
|
|
|
if (!entidades[i].viva)
|
|
continue;
|
|
|
|
if (entidades[i].equipo ==
|
|
entidades[indice].equipo)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
float distancia =
|
|
Distancia(
|
|
entidades[indice].posicion,
|
|
entidades[i].posicion
|
|
);
|
|
|
|
if (distancia < menorDistancia)
|
|
{
|
|
menorDistancia = distancia;
|
|
objetivo = i;
|
|
}
|
|
}
|
|
|
|
return objetivo;
|
|
}
|
|
|
|
void Disparar(
|
|
Entidad& entidad,
|
|
std::vector<Bala>& balas)
|
|
{
|
|
if (!entidad.viva)
|
|
return;
|
|
|
|
if (entidad.municion <= 0)
|
|
return;
|
|
|
|
Bala bala;
|
|
|
|
bala.posicion = {
|
|
entidad.posicion.x +
|
|
entidad.direccion.x * 27.0f,
|
|
|
|
entidad.posicion.y +
|
|
entidad.direccion.y * 27.0f
|
|
};
|
|
|
|
bala.direccion =
|
|
Normalizar(entidad.direccion);
|
|
|
|
bala.velocidad =
|
|
VELOCIDAD_BALA;
|
|
|
|
bala.equipo =
|
|
entidad.equipo;
|
|
|
|
bala.rebotes = 0;
|
|
bala.activa = true;
|
|
|
|
balas.push_back(bala);
|
|
|
|
entidad.municion--;
|
|
}
|
|
|
|
bool HayMunicion(
|
|
const std::vector<Municion>& municiones)
|
|
{
|
|
for (const Municion& municion : municiones)
|
|
{
|
|
if (municion.activa)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CrearMunicion(
|
|
std::vector<Municion>& municiones,
|
|
const std::vector<Pared>& paredes,
|
|
const std::vector<Entidad>& entidades)
|
|
{
|
|
if ((int)municiones.size() >= 2)
|
|
return;
|
|
|
|
Vector2 posicion;
|
|
|
|
bool valida = false;
|
|
|
|
for (int intento = 0;
|
|
intento < 100 && !valida;
|
|
intento++)
|
|
{
|
|
posicion = {
|
|
(float)GetRandomValue(
|
|
(int)BORDE + 25,
|
|
(int)MUNDO_ANCHO -
|
|
(int)BORDE - 25
|
|
),
|
|
|
|
(float)GetRandomValue(
|
|
(int)BORDE + 25,
|
|
(int)MUNDO_ALTO -
|
|
(int)BORDE - 25
|
|
)
|
|
};
|
|
|
|
valida =
|
|
!TocarPared(
|
|
posicion,
|
|
paredes
|
|
);
|
|
|
|
if (!valida)
|
|
continue;
|
|
|
|
valida = false;
|
|
}
|
|
|
|
if (!valida)
|
|
return;
|
|
|
|
for (const Entidad& entidad : entidades)
|
|
{
|
|
if (!entidad.viva)
|
|
continue;
|
|
|
|
if (Distancia(
|
|
posicion,
|
|
entidad.posicion) < 100.0f)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
municiones.push_back({
|
|
posicion,
|
|
true
|
|
});
|
|
}
|
|
|
|
void DibujarEntidad(
|
|
const Entidad& entidad,
|
|
float escalaX,
|
|
float escalaY,
|
|
float escala)
|
|
{
|
|
if (!entidad.viva)
|
|
return;
|
|
|
|
Vector2 posicion = {
|
|
entidad.posicion.x * escalaX,
|
|
entidad.posicion.y * escalaY
|
|
};
|
|
|
|
Color color =
|
|
entidad.equipo == 0
|
|
? BLUE
|
|
: RED;
|
|
|
|
DrawCircleV(
|
|
posicion,
|
|
entidad.radio * escala,
|
|
color
|
|
);
|
|
|
|
Vector2 direccion = {
|
|
posicion.x +
|
|
entidad.direccion.x *
|
|
25.0f *
|
|
escala,
|
|
|
|
posicion.y +
|
|
entidad.direccion.y *
|
|
25.0f *
|
|
escala
|
|
};
|
|
|
|
DrawLineEx(
|
|
posicion,
|
|
direccion,
|
|
3.0f * escala,
|
|
WHITE
|
|
);
|
|
|
|
float vidaAncho =
|
|
42.0f * escala;
|
|
|
|
float vidaAlto =
|
|
5.0f * escala;
|
|
|
|
float vidaX =
|
|
posicion.x -
|
|
vidaAncho * 0.5f;
|
|
|
|
float vidaY =
|
|
posicion.y -
|
|
entidad.radio * escala -
|
|
13.0f * escala;
|
|
|
|
DrawRectangle(
|
|
(int)vidaX,
|
|
(int)vidaY,
|
|
(int)vidaAncho,
|
|
(int)vidaAlto,
|
|
DARKGRAY
|
|
);
|
|
|
|
DrawRectangle(
|
|
(int)vidaX,
|
|
(int)vidaY,
|
|
(int)(
|
|
vidaAncho *
|
|
(entidad.vida /
|
|
entidad.vidaMaxima)
|
|
),
|
|
(int)vidaAlto,
|
|
GREEN
|
|
);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
SetConfigFlags(
|
|
FLAG_WINDOW_RESIZABLE |
|
|
FLAG_VSYNC_HINT
|
|
);
|
|
|
|
InitWindow(
|
|
1100,
|
|
750,
|
|
"A4B1 0.1"
|
|
);
|
|
|
|
SetTargetFPS(120);
|
|
|
|
SetRandomSeed(
|
|
(unsigned int)GetTime()
|
|
);
|
|
|
|
std::vector<Pared> paredes = {
|
|
{{280.0f, 150.0f, 180.0f, 14.0f}},
|
|
{{540.0f, 150.0f, 180.0f, 14.0f}},
|
|
{{280.0f, 486.0f, 180.0f, 14.0f}},
|
|
{{540.0f, 486.0f, 180.0f, 14.0f}},
|
|
{{240.0f, 230.0f, 14.0f, 150.0f}},
|
|
{{746.0f, 230.0f, 14.0f, 150.0f}},
|
|
{{450.0f, 245.0f, 100.0f, 14.0f}},
|
|
{{450.0f, 391.0f, 100.0f, 14.0f}}
|
|
};
|
|
|
|
std::vector<Entidad> entidades = {
|
|
{
|
|
{220.0f, 325.0f},
|
|
{0.0f, 0.0f},
|
|
{1.0f, 0.0f},
|
|
RADIO_JUGADOR,
|
|
100.0f,
|
|
100.0f,
|
|
0,
|
|
true,
|
|
true,
|
|
5,
|
|
0.0f
|
|
},
|
|
|
|
{
|
|
{180.0f, 500.0f},
|
|
{0.0f, 0.0f},
|
|
{1.0f, 0.0f},
|
|
RADIO_ENEMIGO,
|
|
100.0f,
|
|
100.0f,
|
|
0,
|
|
false,
|
|
true,
|
|
5,
|
|
0.0f
|
|
},
|
|
|
|
{
|
|
{780.0f, 180.0f},
|
|
{0.0f, 0.0f},
|
|
{-1.0f, 0.0f},
|
|
RADIO_ENEMIGO,
|
|
100.0f,
|
|
100.0f,
|
|
1,
|
|
false,
|
|
true,
|
|
5,
|
|
0.0f
|
|
},
|
|
|
|
{
|
|
{780.0f, 470.0f},
|
|
{0.0f, 0.0f},
|
|
{-1.0f, 0.0f},
|
|
RADIO_ENEMIGO,
|
|
100.0f,
|
|
100.0f,
|
|
1,
|
|
false,
|
|
true,
|
|
5,
|
|
0.0f
|
|
}
|
|
};
|
|
|
|
std::vector<Bala> balas;
|
|
std::vector<Municion> municiones;
|
|
|
|
float tiempoAparicionMunicion = 0.0f;
|
|
int impactos = 0;
|
|
|
|
while (!WindowShouldClose())
|
|
{
|
|
float dt = GetFrameTime();
|
|
|
|
if (IsKeyPressed(KEY_F11))
|
|
ToggleFullscreen();
|
|
|
|
int anchoPantalla =
|
|
GetScreenWidth();
|
|
|
|
int altoPantalla =
|
|
GetScreenHeight();
|
|
|
|
float escalaX =
|
|
anchoPantalla /
|
|
MUNDO_ANCHO;
|
|
|
|
float escalaY =
|
|
altoPantalla /
|
|
MUNDO_ALTO;
|
|
|
|
float escala =
|
|
std::min(
|
|
escalaX,
|
|
escalaY
|
|
);
|
|
|
|
Entidad& jugador =
|
|
entidades[0];
|
|
|
|
Vector2 movimiento = {
|
|
0.0f,
|
|
0.0f
|
|
};
|
|
|
|
if (IsKeyDown(KEY_W))
|
|
movimiento.y -= 1.0f;
|
|
|
|
if (IsKeyDown(KEY_S))
|
|
movimiento.y += 1.0f;
|
|
|
|
if (IsKeyDown(KEY_A))
|
|
movimiento.x -= 1.0f;
|
|
|
|
if (IsKeyDown(KEY_D))
|
|
movimiento.x += 1.0f;
|
|
|
|
movimiento =
|
|
Normalizar(movimiento);
|
|
|
|
if (movimiento.x != 0.0f ||
|
|
movimiento.y != 0.0f)
|
|
{
|
|
jugador.direccion =
|
|
movimiento;
|
|
}
|
|
|
|
jugador.velocidad = {
|
|
movimiento.x *
|
|
VELOCIDAD_JUGADOR,
|
|
|
|
movimiento.y *
|
|
VELOCIDAD_JUGADOR
|
|
};
|
|
|
|
if (jugador.viva)
|
|
{
|
|
jugador.posicion.x +=
|
|
jugador.velocidad.x *
|
|
dt;
|
|
|
|
jugador.posicion.y +=
|
|
jugador.velocidad.y *
|
|
dt;
|
|
|
|
RebotarBorde(jugador);
|
|
RebotarPared(
|
|
jugador,
|
|
paredes
|
|
);
|
|
}
|
|
|
|
jugador.tiempoDisparo -= dt;
|
|
|
|
if (jugador.viva &&
|
|
IsKeyPressed(KEY_SPACE) &&
|
|
jugador.tiempoDisparo <= 0.0f)
|
|
{
|
|
if (jugador.municion > 0)
|
|
{
|
|
Disparar(
|
|
jugador,
|
|
balas
|
|
);
|
|
|
|
jugador.tiempoDisparo =
|
|
0.18f;
|
|
}
|
|
}
|
|
|
|
for (int i = 1;
|
|
i < (int)entidades.size();
|
|
i++)
|
|
{
|
|
Entidad& entidad =
|
|
entidades[i];
|
|
|
|
if (!entidad.viva)
|
|
continue;
|
|
|
|
int objetivo =
|
|
BuscarObjetivo(
|
|
i,
|
|
entidades
|
|
);
|
|
|
|
if (objetivo >= 0)
|
|
{
|
|
Vector2 direccion =
|
|
Normalizar({
|
|
entidades[objetivo].posicion.x -
|
|
entidad.posicion.x,
|
|
|
|
entidades[objetivo].posicion.y -
|
|
entidad.posicion.y
|
|
});
|
|
|
|
entidad.direccion =
|
|
direccion;
|
|
|
|
float distancia =
|
|
Distancia(
|
|
entidad.posicion,
|
|
entidades[objetivo].posicion
|
|
);
|
|
|
|
Vector2 movimientoIA =
|
|
direccion;
|
|
|
|
if (distancia < 250.0f)
|
|
{
|
|
movimientoIA = {
|
|
-direccion.y,
|
|
direccion.x
|
|
};
|
|
}
|
|
|
|
entidad.velocidad = {
|
|
movimientoIA.x *
|
|
VELOCIDAD_IA,
|
|
|
|
movimientoIA.y *
|
|
VELOCIDAD_IA
|
|
};
|
|
|
|
entidad.tiempoDisparo -= dt;
|
|
|
|
if (entidad.tiempoDisparo <= 0.0f &&
|
|
entidad.municion > 0)
|
|
{
|
|
Disparar(
|
|
entidad,
|
|
balas
|
|
);
|
|
|
|
entidad.tiempoDisparo =
|
|
0.75f;
|
|
}
|
|
}
|
|
|
|
entidad.posicion.x +=
|
|
entidad.velocidad.x *
|
|
dt;
|
|
|
|
entidad.posicion.y +=
|
|
entidad.velocidad.y *
|
|
dt;
|
|
|
|
RebotarBorde(
|
|
entidad
|
|
);
|
|
|
|
RebotarPared(
|
|
entidad,
|
|
paredes
|
|
);
|
|
}
|
|
|
|
for (Bala& bala : balas)
|
|
{
|
|
if (!bala.activa)
|
|
continue;
|
|
|
|
MoverBala(
|
|
bala,
|
|
dt,
|
|
paredes
|
|
);
|
|
|
|
if (!bala.activa)
|
|
continue;
|
|
|
|
for (int i = 0;
|
|
i < (int)entidades.size();
|
|
i++)
|
|
{
|
|
Entidad& entidad =
|
|
entidades[i];
|
|
|
|
if (!entidad.viva)
|
|
continue;
|
|
|
|
if (entidad.equipo ==
|
|
bala.equipo)
|
|
continue;
|
|
|
|
if (!CirculoCirculo(
|
|
bala.posicion,
|
|
6.0f,
|
|
entidad.posicion,
|
|
entidad.radio))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
entidad.vida -=
|
|
DAÑO_BALA;
|
|
|
|
impactos++;
|
|
|
|
Vector2 empuje =
|
|
bala.direccion;
|
|
|
|
entidad.posicion.x +=
|
|
empuje.x * 10.0f;
|
|
|
|
entidad.posicion.y +=
|
|
empuje.y * 10.0f;
|
|
|
|
if (entidad.vida <= 0.0f)
|
|
{
|
|
entidad.vida = 0.0f;
|
|
entidad.viva = false;
|
|
entidad.velocidad = {
|
|
0.0f,
|
|
0.0f
|
|
};
|
|
}
|
|
|
|
bala.activa = false;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
balas.erase(
|
|
std::remove_if(
|
|
balas.begin(),
|
|
balas.end(),
|
|
[](const Bala& bala)
|
|
{
|
|
return !bala.activa;
|
|
}
|
|
),
|
|
balas.end()
|
|
);
|
|
|
|
tiempoAparicionMunicion -=
|
|
dt;
|
|
|
|
if (tiempoAparicionMunicion <= 0.0f)
|
|
{
|
|
CrearMunicion(
|
|
municiones,
|
|
paredes,
|
|
entidades
|
|
);
|
|
|
|
tiempoAparicionMunicion =
|
|
4.0f;
|
|
}
|
|
|
|
for (Municion& municion :
|
|
municiones)
|
|
{
|
|
if (!municion.activa)
|
|
continue;
|
|
|
|
if (!jugador.viva)
|
|
continue;
|
|
|
|
if (Distancia(
|
|
jugador.posicion,
|
|
municion.posicion
|
|
) < 28.0f)
|
|
{
|
|
jugador.municion += 5;
|
|
municion.activa = false;
|
|
}
|
|
}
|
|
|
|
municiones.erase(
|
|
std::remove_if(
|
|
municiones.begin(),
|
|
municiones.end(),
|
|
[](const Municion& municion)
|
|
{
|
|
return !municion.activa;
|
|
}
|
|
),
|
|
municiones.end()
|
|
);
|
|
|
|
BeginDrawing();
|
|
|
|
ClearBackground({
|
|
0,
|
|
0,
|
|
0,
|
|
255
|
|
});
|
|
|
|
Vector2 jugadorPantalla = {
|
|
jugador.posicion.x *
|
|
escalaX,
|
|
|
|
jugador.posicion.y *
|
|
escalaY
|
|
};
|
|
|
|
for (const Pared& pared :
|
|
paredes)
|
|
{
|
|
Vector2 centro = {
|
|
pared.rectangulo.x +
|
|
pared.rectangulo.width *
|
|
0.5f,
|
|
|
|
pared.rectangulo.y +
|
|
pared.rectangulo.height *
|
|
0.5f
|
|
};
|
|
|
|
if (Distancia(
|
|
centro,
|
|
jugador.posicion
|
|
) > RADIO_VISION + 180.0f)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Rectangle r = {
|
|
pared.rectangulo.x *
|
|
escalaX,
|
|
|
|
pared.rectangulo.y *
|
|
escalaY,
|
|
|
|
pared.rectangulo.width *
|
|
escalaX,
|
|
|
|
pared.rectangulo.height *
|
|
escalaY
|
|
};
|
|
|
|
DrawRectangleRounded(
|
|
r,
|
|
0.3f,
|
|
8,
|
|
{
|
|
45,
|
|
45,
|
|
52,
|
|
255
|
|
}
|
|
);
|
|
|
|
DrawRectangleRoundedLines(
|
|
r,
|
|
0.3f,
|
|
8,
|
|
{
|
|
120,
|
|
120,
|
|
130,
|
|
255
|
|
}
|
|
);
|
|
}
|
|
|
|
Rectangle borde = {
|
|
BORDE * escalaX,
|
|
BORDE * escalaY,
|
|
|
|
(MUNDO_ANCHO -
|
|
BORDE * 2.0f) *
|
|
escalaX,
|
|
|
|
(MUNDO_ALTO -
|
|
BORDE * 2.0f) *
|
|
escalaY
|
|
};
|
|
|
|
if (Distancia(
|
|
jugador.posicion,
|
|
{
|
|
MUNDO_ANCHO * 0.5f,
|
|
MUNDO_ALTO * 0.5f
|
|
}
|
|
) < RADIO_VISION + 500.0f)
|
|
{
|
|
DrawRectangleRoundedLines(
|
|
borde,
|
|
0.08f,
|
|
16,
|
|
WHITE
|
|
);
|
|
}
|
|
|
|
for (const Municion& municion :
|
|
municiones)
|
|
{
|
|
if (!municion.activa)
|
|
continue;
|
|
|
|
if (Distancia(
|
|
jugador.posicion,
|
|
municion.posicion
|
|
) > RADIO_VISION)
|
|
continue;
|
|
|
|
Vector2 posicion = {
|
|
municion.posicion.x *
|
|
escalaX,
|
|
|
|
municion.posicion.y *
|
|
escalaY
|
|
};
|
|
|
|
DrawRectangle(
|
|
(int)posicion.x - 9,
|
|
(int)posicion.y - 9,
|
|
18,
|
|
18,
|
|
YELLOW
|
|
);
|
|
|
|
DrawText(
|
|
"+5",
|
|
(int)posicion.x - 8,
|
|
(int)posicion.y - 7,
|
|
14,
|
|
BLACK
|
|
);
|
|
}
|
|
|
|
for (const Bala& bala :
|
|
balas)
|
|
{
|
|
if (!bala.activa)
|
|
continue;
|
|
|
|
if (Distancia(
|
|
jugador.posicion,
|
|
bala.posicion
|
|
) > RADIO_VISION)
|
|
continue;
|
|
|
|
Vector2 posicion = {
|
|
bala.posicion.x *
|
|
escalaX,
|
|
|
|
bala.posicion.y *
|
|
escalaY
|
|
};
|
|
|
|
Color color =
|
|
bala.equipo == 0
|
|
? BLUE
|
|
: RED;
|
|
|
|
DrawCircleV(
|
|
posicion,
|
|
5.0f * escala,
|
|
color
|
|
);
|
|
}
|
|
|
|
for (const Entidad& entidad :
|
|
entidades)
|
|
{
|
|
if (!entidad.viva)
|
|
continue;
|
|
|
|
if (Distancia(
|
|
jugador.posicion,
|
|
entidad.posicion
|
|
) > RADIO_VISION)
|
|
continue;
|
|
|
|
DibujarEntidad(
|
|
entidad,
|
|
escalaX,
|
|
escalaY,
|
|
escala
|
|
);
|
|
}
|
|
|
|
DrawCircle(
|
|
(int)jugadorPantalla.x,
|
|
(int)jugadorPantalla.y,
|
|
RADIO_VISION * escala,
|
|
Fade(BLACK, 0.0f)
|
|
);
|
|
|
|
DrawRectangle(
|
|
15,
|
|
15,
|
|
270,
|
|
145,
|
|
Fade(BLACK, 0.75f)
|
|
);
|
|
|
|
DrawText(
|
|
TextFormat(
|
|
"VIDA: %d",
|
|
(int)jugador.vida
|
|
),
|
|
28,
|
|
25,
|
|
22,
|
|
WHITE
|
|
);
|
|
|
|
DrawText(
|
|
TextFormat(
|
|
"BALAS: %d",
|
|
jugador.municion
|
|
),
|
|
28,
|
|
53,
|
|
22,
|
|
YELLOW
|
|
);
|
|
|
|
DrawText(
|
|
TextFormat(
|
|
"IMPACTOS: %d",
|
|
impactos
|
|
),
|
|
28,
|
|
81,
|
|
19,
|
|
WHITE
|
|
);
|
|
|
|
DrawText(
|
|
TextFormat(
|
|
"FPS: %d",
|
|
GetFPS()
|
|
),
|
|
28,
|
|
107,
|
|
18,
|
|
GREEN
|
|
);
|
|
|
|
DrawText(
|
|
"AZUL 2 VS ROJO 2",
|
|
28,
|
|
132,
|
|
16,
|
|
LIGHTGRAY
|
|
);
|
|
|
|
EndDrawing();
|
|
}
|
|
|
|
CloseWindow();
|
|
|
|
return 0;
|
|
} |