416 lines
6.0 KiB
C++
416 lines
6.0 KiB
C++
#include "raylib.h"
|
|
#include <cmath>
|
|
|
|
extern Vector3 playerPosition;
|
|
extern bool IsSolidAt(Vector3 position, float radius);
|
|
|
|
const int NPC_COUNT = 12;
|
|
|
|
Vector3 enemyPosition[NPC_COUNT] =
|
|
{
|
|
{ -72.0f, 1.0f, -72.0f },
|
|
{ 72.0f, 1.0f, -72.0f },
|
|
{ -72.0f, 1.0f, 72.0f },
|
|
{ 72.0f, 1.0f, 72.0f },
|
|
|
|
{ -48.0f, 1.0f, -36.0f },
|
|
{ 48.0f, 1.0f, -36.0f },
|
|
{ -48.0f, 1.0f, 36.0f },
|
|
{ 48.0f, 1.0f, 36.0f },
|
|
|
|
{ -28.0f, 1.0f, -68.0f },
|
|
{ 28.0f, 1.0f, -68.0f },
|
|
{ -28.0f, 1.0f, 68.0f },
|
|
{ 28.0f, 1.0f, 68.0f }
|
|
};
|
|
|
|
float enemyWalkTime[NPC_COUNT] = {};
|
|
float enemyStunTime[NPC_COUNT] = {};
|
|
float enemySpin[NPC_COUNT] = {};
|
|
|
|
const float enemySpeed = 2.4f;
|
|
const float enemyStunDuration = 2.5f;
|
|
|
|
bool enemyMoving[NPC_COUNT] = {};
|
|
|
|
void MoveEnemyWithCollision(
|
|
int index,
|
|
float moveX,
|
|
float moveZ
|
|
)
|
|
{
|
|
Vector3 nextX = enemyPosition[index];
|
|
|
|
nextX.x += moveX;
|
|
|
|
if (!IsSolidAt(nextX, 0.45f))
|
|
enemyPosition[index].x = nextX.x;
|
|
|
|
Vector3 nextZ = enemyPosition[index];
|
|
|
|
nextZ.z += moveZ;
|
|
|
|
if (!IsSolidAt(nextZ, 0.45f))
|
|
enemyPosition[index].z = nextZ.z;
|
|
}
|
|
|
|
void UpdateEnemy(float deltaTime)
|
|
{
|
|
for (int i = 0; i < NPC_COUNT; i++)
|
|
{
|
|
float dx =
|
|
playerPosition.x -
|
|
enemyPosition[i].x;
|
|
|
|
float dz =
|
|
playerPosition.z -
|
|
enemyPosition[i].z;
|
|
|
|
float distance =
|
|
std::sqrt(
|
|
dx * dx +
|
|
dz * dz
|
|
);
|
|
|
|
// =========================================
|
|
// MAREADO
|
|
// =========================================
|
|
|
|
if (enemyStunTime[i] > 0.0f)
|
|
{
|
|
enemyStunTime[i] -= deltaTime;
|
|
enemySpin[i] += deltaTime * 18.0f;
|
|
|
|
enemyMoving[i] = false;
|
|
|
|
if (enemyStunTime[i] < 0.0f)
|
|
enemyStunTime[i] = 0.0f;
|
|
|
|
continue;
|
|
}
|
|
|
|
// =========================================
|
|
// EMPUJAR JUGADOR
|
|
// =========================================
|
|
|
|
if (distance > 0.001f &&
|
|
distance < 1.5f)
|
|
{
|
|
float pushX =
|
|
(dx / distance) *
|
|
10.0f *
|
|
deltaTime;
|
|
|
|
float pushZ =
|
|
(dz / distance) *
|
|
10.0f *
|
|
deltaTime;
|
|
|
|
Vector3 next = playerPosition;
|
|
|
|
next.x += pushX;
|
|
next.z += pushZ;
|
|
|
|
if (!IsSolidAt(next, 0.45f))
|
|
playerPosition = next;
|
|
}
|
|
|
|
// =========================================
|
|
// SEGUIR JUGADOR
|
|
// =========================================
|
|
|
|
if (distance > 1.8f)
|
|
{
|
|
dx /= distance;
|
|
dz /= distance;
|
|
|
|
MoveEnemyWithCollision(
|
|
i,
|
|
dx * enemySpeed * deltaTime,
|
|
dz * enemySpeed * deltaTime
|
|
);
|
|
|
|
enemyWalkTime[i] +=
|
|
deltaTime * 9.0f;
|
|
|
|
enemyMoving[i] = true;
|
|
}
|
|
else
|
|
{
|
|
enemyMoving[i] = false;
|
|
enemyWalkTime[i] = 0.0f;
|
|
}
|
|
}
|
|
|
|
// =========================================
|
|
// CLICK DERECHO
|
|
// =========================================
|
|
|
|
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT))
|
|
{
|
|
for (int i = 0; i < NPC_COUNT; i++)
|
|
{
|
|
float dx =
|
|
enemyPosition[i].x -
|
|
playerPosition.x;
|
|
|
|
float dz =
|
|
enemyPosition[i].z -
|
|
playerPosition.z;
|
|
|
|
float distance =
|
|
std::sqrt(
|
|
dx * dx +
|
|
dz * dz
|
|
);
|
|
|
|
if (distance < 4.0f &&
|
|
distance > 0.001f)
|
|
{
|
|
dx /= distance;
|
|
dz /= distance;
|
|
|
|
MoveEnemyWithCollision(
|
|
i,
|
|
dx * 3.5f,
|
|
dz * 3.5f
|
|
);
|
|
|
|
enemyStunTime[i] =
|
|
enemyStunDuration;
|
|
|
|
enemySpin[i] = 0.0f;
|
|
enemyWalkTime[i] = 0.0f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TeleportEnemyNearPlayer(
|
|
int index,
|
|
float yaw
|
|
)
|
|
{
|
|
if (index < 0 ||
|
|
index >= NPC_COUNT)
|
|
return;
|
|
|
|
// =========================================
|
|
// CONSERVAR LA DISTANCIA ACTUAL
|
|
// =========================================
|
|
|
|
float dx =
|
|
enemyPosition[index].x -
|
|
playerPosition.x;
|
|
|
|
float dz =
|
|
enemyPosition[index].z -
|
|
playerPosition.z;
|
|
|
|
float oldDistance =
|
|
std::sqrt(
|
|
dx * dx +
|
|
dz * dz
|
|
);
|
|
|
|
if (oldDistance < 3.0f)
|
|
oldDistance = 3.0f;
|
|
|
|
// =========================================
|
|
// BUSCAR OTRA DIRECCIÓN
|
|
// =========================================
|
|
|
|
float baseAngle =
|
|
std::atan2(
|
|
dz,
|
|
dx
|
|
);
|
|
|
|
for (int attempt = 0; attempt < 16; attempt++)
|
|
{
|
|
float angle =
|
|
baseAngle +
|
|
PI +
|
|
attempt * 0.4f;
|
|
|
|
Vector3 newPosition =
|
|
{
|
|
playerPosition.x +
|
|
std::cos(angle) * oldDistance,
|
|
|
|
1.0f,
|
|
|
|
playerPosition.z +
|
|
std::sin(angle) * oldDistance
|
|
};
|
|
|
|
if (!IsSolidAt(newPosition, 0.45f))
|
|
{
|
|
enemyPosition[index] =
|
|
newPosition;
|
|
|
|
enemyStunTime[index] = 0.0f;
|
|
enemySpin[index] = 0.0f;
|
|
enemyWalkTime[index] = 0.0f;
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
int CheckEnemyHit(Vector3 bulletPosition)
|
|
{
|
|
for (int i = 0; i < NPC_COUNT; i++)
|
|
{
|
|
float hitX =
|
|
bulletPosition.x -
|
|
enemyPosition[i].x;
|
|
|
|
float hitY =
|
|
bulletPosition.y -
|
|
1.2f;
|
|
|
|
float hitZ =
|
|
bulletPosition.z -
|
|
enemyPosition[i].z;
|
|
|
|
float distance =
|
|
std::sqrt(
|
|
hitX * hitX +
|
|
hitY * hitY +
|
|
hitZ * hitZ
|
|
);
|
|
|
|
if (distance < 0.8f)
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void DrawEnemy()
|
|
{
|
|
for (int i = 0; i < NPC_COUNT; i++)
|
|
{
|
|
float legMove = 0.0f;
|
|
float armMove = 0.0f;
|
|
|
|
if (enemyMoving[i])
|
|
{
|
|
legMove =
|
|
std::sin(enemyWalkTime[i]) *
|
|
0.18f;
|
|
|
|
armMove =
|
|
std::sin(enemyWalkTime[i]) *
|
|
0.25f;
|
|
}
|
|
|
|
float spinX = 0.0f;
|
|
float spinZ = 0.0f;
|
|
|
|
if (enemyStunTime[i] > 0.0f)
|
|
{
|
|
spinX =
|
|
std::sin(enemySpin[i]) *
|
|
0.25f;
|
|
|
|
spinZ =
|
|
std::cos(enemySpin[i]) *
|
|
0.25f;
|
|
}
|
|
|
|
DrawCube(
|
|
{
|
|
enemyPosition[i].x -
|
|
0.22f +
|
|
spinX,
|
|
|
|
0.45f,
|
|
|
|
enemyPosition[i].z +
|
|
legMove +
|
|
spinZ
|
|
},
|
|
0.25f,
|
|
0.9f,
|
|
0.25f,
|
|
DARKGRAY
|
|
);
|
|
|
|
DrawCube(
|
|
{
|
|
enemyPosition[i].x +
|
|
0.22f -
|
|
spinX,
|
|
|
|
0.45f,
|
|
|
|
enemyPosition[i].z -
|
|
legMove -
|
|
spinZ
|
|
},
|
|
0.25f,
|
|
0.9f,
|
|
0.25f,
|
|
DARKGRAY
|
|
);
|
|
|
|
DrawCube(
|
|
{
|
|
enemyPosition[i].x,
|
|
1.25f,
|
|
enemyPosition[i].z
|
|
},
|
|
0.8f,
|
|
1.0f,
|
|
0.45f,
|
|
BLUE
|
|
);
|
|
|
|
DrawSphere(
|
|
{
|
|
enemyPosition[i].x + spinX,
|
|
2.05f,
|
|
enemyPosition[i].z + spinZ
|
|
},
|
|
0.38f,
|
|
BEIGE
|
|
);
|
|
|
|
DrawCube(
|
|
{
|
|
enemyPosition[i].x -
|
|
0.55f +
|
|
spinX,
|
|
|
|
1.25f + armMove,
|
|
|
|
enemyPosition[i].z +
|
|
spinZ
|
|
},
|
|
0.18f,
|
|
0.75f,
|
|
0.18f,
|
|
BLUE
|
|
);
|
|
|
|
DrawCube(
|
|
{
|
|
enemyPosition[i].x +
|
|
0.55f -
|
|
spinX,
|
|
|
|
1.25f - armMove,
|
|
|
|
enemyPosition[i].z -
|
|
spinZ
|
|
},
|
|
0.18f,
|
|
0.75f,
|
|
0.18f,
|
|
BLUE
|
|
);
|
|
}
|
|
}
|