Nivel TALAN
This commit is contained in:
1 parent
f9f1c5c3ec
commit
95a1231c63
7 files changed
+1349
-3204
No files matched your search
BIN
Binary file not shown.
@@ -1,36 +1,8 @@
|
|||||||
# Disable raylib examples/games and include FetchContent
|
find_package(PkgConfig REQUIRED)
|
||||||
set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
|
||||||
set(BUILD_GAMES OFF CACHE BOOL "" FORCE)
|
|
||||||
include(FetchContent)
|
|
||||||
|
|
||||||
# Declare and make raylib available
|
pkg_check_modules(RAYLIB REQUIRED IMPORTED_TARGET raylib)
|
||||||
FetchContent_Declare(
|
|
||||||
raylib
|
add_exe_module(
|
||||||
GIT_REPOSITORY "https://github.com/raysan5/raylib.git"
|
A4B1
|
||||||
GIT_TAG "master"
|
DEPENDS PkgConfig::RAYLIB
|
||||||
GIT_PROGRESS TRUE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 2. Descargar Pugixml (Lector de XML/SVG)
|
|
||||||
FetchContent_Declare(
|
|
||||||
pugixml
|
|
||||||
GIT_REPOSITORY "https://github.com/zeux/pugixml.git"
|
|
||||||
GIT_TAG "v1.14" # Versión estable
|
|
||||||
GIT_PROGRESS TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
# 1. Save the local PLATFORM variable
|
|
||||||
set(ORIGINAL_PLATFORM "${PLATFORM}")
|
|
||||||
|
|
||||||
# 2. Override the local variable to "Desktop" (This shadows the cache and hides "linux" from raylib)
|
|
||||||
set(PLATFORM "Desktop")
|
|
||||||
|
|
||||||
# 3. Configure raylib
|
|
||||||
FetchContent_MakeAvailable(raylib pugixml)
|
|
||||||
|
|
||||||
# 4. Restore your project's local PLATFORM variable back to "linux"
|
|
||||||
set(PLATFORM "${ORIGINAL_PLATFORM}")
|
|
||||||
|
|
||||||
|
|
||||||
add_exe_module(pacman OUTPUT_NAME "Pacman")
|
|
||||||
target_link_libraries(pacman PRIVATE raylib pugixml)
|
|
||||||
@@ -0,0 +1,415 @@
|
|||||||
|
#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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,457 @@
|
|||||||
|
#include "raylib.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
struct Wall
|
||||||
|
{
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Furniture
|
||||||
|
{
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 size;
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int MAZE_W = 41;
|
||||||
|
static const int MAZE_H = 41;
|
||||||
|
static const float CELL = 4.0f;
|
||||||
|
|
||||||
|
static bool maze[MAZE_H][MAZE_W];
|
||||||
|
static std::vector<Wall> walls;
|
||||||
|
static std::vector<Furniture> furniture;
|
||||||
|
|
||||||
|
extern Vector3 playerPosition;
|
||||||
|
extern Camera3D GetPlayerCamera();
|
||||||
|
|
||||||
|
extern void UpdatePlayer(float deltaTime);
|
||||||
|
extern void UpdateEnemy(float deltaTime);
|
||||||
|
extern void UpdateWeapons(float deltaTime);
|
||||||
|
|
||||||
|
extern void DrawEnemy();
|
||||||
|
extern void DrawBullets();
|
||||||
|
extern void DrawPlayerWeapon();
|
||||||
|
|
||||||
|
bool IsSolidAt(Vector3 position, float radius)
|
||||||
|
{
|
||||||
|
for (const Wall& wall : walls)
|
||||||
|
{
|
||||||
|
if (position.x >= wall.position.x - wall.size.x / 2.0f - radius &&
|
||||||
|
position.x <= wall.position.x + wall.size.x / 2.0f + radius &&
|
||||||
|
position.z >= wall.position.z - wall.size.z / 2.0f - radius &&
|
||||||
|
position.z <= wall.position.z + wall.size.z / 2.0f + radius)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Furniture& object : furniture)
|
||||||
|
{
|
||||||
|
if (position.x >= object.position.x - object.size.x / 2.0f - radius &&
|
||||||
|
position.x <= object.position.x + object.size.x / 2.0f + radius &&
|
||||||
|
position.z >= object.position.z - object.size.z / 2.0f - radius &&
|
||||||
|
position.z <= object.position.z + object.size.z / 2.0f + radius)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Vector3 CellToWorld(int x, int z)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
(x - MAZE_W / 2) * CELL,
|
||||||
|
0.0f,
|
||||||
|
(z - MAZE_H / 2) * CELL
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateMaze()
|
||||||
|
{
|
||||||
|
for (int z = 0; z < MAZE_H; z++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < MAZE_W; x++)
|
||||||
|
{
|
||||||
|
maze[z][x] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Vector2> stack;
|
||||||
|
stack.push_back({1, 1});
|
||||||
|
maze[1][1] = false;
|
||||||
|
|
||||||
|
std::mt19937 rng(12345);
|
||||||
|
|
||||||
|
const int dirs[4][2] =
|
||||||
|
{
|
||||||
|
{ 2, 0 },
|
||||||
|
{-2, 0 },
|
||||||
|
{ 0, 2 },
|
||||||
|
{ 0,-2 }
|
||||||
|
};
|
||||||
|
|
||||||
|
while (!stack.empty())
|
||||||
|
{
|
||||||
|
Vector2 current = stack.back();
|
||||||
|
|
||||||
|
std::vector<int> available;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
int nx = (int)current.x + dirs[i][0];
|
||||||
|
int nz = (int)current.y + dirs[i][1];
|
||||||
|
|
||||||
|
if (nx > 0 && nx < MAZE_W - 1 &&
|
||||||
|
nz > 0 && nz < MAZE_H - 1 &&
|
||||||
|
maze[nz][nx])
|
||||||
|
{
|
||||||
|
available.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (available.empty())
|
||||||
|
{
|
||||||
|
stack.pop_back();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int d = available[rng() % available.size()];
|
||||||
|
|
||||||
|
int nx = (int)current.x + dirs[d][0];
|
||||||
|
int nz = (int)current.y + dirs[d][1];
|
||||||
|
|
||||||
|
maze[((int)current.y + nz) / 2]
|
||||||
|
[((int)current.x + nx) / 2] = false;
|
||||||
|
|
||||||
|
maze[nz][nx] = false;
|
||||||
|
|
||||||
|
stack.push_back({(float)nx, (float)nz});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int z = 3; z < MAZE_H - 3; z += 6)
|
||||||
|
{
|
||||||
|
for (int x = 3; x < MAZE_W - 3; x += 6)
|
||||||
|
{
|
||||||
|
maze[z][x] = false;
|
||||||
|
|
||||||
|
if (x + 1 < MAZE_W - 1)
|
||||||
|
maze[z][x + 1] = false;
|
||||||
|
|
||||||
|
if (x > 1)
|
||||||
|
maze[z][x - 1] = false;
|
||||||
|
|
||||||
|
if (z + 1 < MAZE_H - 1)
|
||||||
|
maze[z + 1][x] = false;
|
||||||
|
|
||||||
|
if (z > 1)
|
||||||
|
maze[z - 1][x] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BuildWalls()
|
||||||
|
{
|
||||||
|
walls.clear();
|
||||||
|
|
||||||
|
for (int z = 0; z < MAZE_H; z++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < MAZE_W; x++)
|
||||||
|
{
|
||||||
|
if (!maze[z][x])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vector3 p = CellToWorld(x, z);
|
||||||
|
|
||||||
|
walls.push_back({
|
||||||
|
{p.x, 1.5f, p.z},
|
||||||
|
{CELL, 3.0f, CELL}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateFurniture()
|
||||||
|
{
|
||||||
|
furniture.clear();
|
||||||
|
|
||||||
|
for (int z = 2; z < MAZE_H - 2; z++)
|
||||||
|
{
|
||||||
|
for (int x = 2; x < MAZE_W - 2; x++)
|
||||||
|
{
|
||||||
|
if (maze[z][x])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((x * 13 + z * 7) % 17 != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (x <= 4 && z <= 4)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vector3 p = CellToWorld(x, z);
|
||||||
|
|
||||||
|
Furniture object;
|
||||||
|
object.type = (x * 3 + z * 5) % 5;
|
||||||
|
|
||||||
|
switch (object.type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
object.position = {p.x, 0.8f, p.z};
|
||||||
|
object.size = {2.4f, 1.6f, 2.4f};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
object.position = {p.x, 0.75f, p.z};
|
||||||
|
object.size = {1.5f, 1.5f, 1.5f};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
object.position = {p.x, 1.35f, p.z};
|
||||||
|
object.size = {1.8f, 2.7f, 1.0f};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
object.position = {p.x, 0.4f, p.z};
|
||||||
|
object.size = {2.5f, 0.8f, 0.8f};
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
object.position = {p.x, 0.6f, p.z};
|
||||||
|
object.size = {2.0f, 1.2f, 1.2f};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsSolidAt(object.position, 0.2f))
|
||||||
|
furniture.push_back(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawFloor()
|
||||||
|
{
|
||||||
|
for (int z = 0; z < MAZE_H; z++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < MAZE_W; x++)
|
||||||
|
{
|
||||||
|
if (maze[z][x])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vector3 p = CellToWorld(x, z);
|
||||||
|
|
||||||
|
int shade = 108 + ((x * 17 + z * 11) % 9);
|
||||||
|
|
||||||
|
Color color = {
|
||||||
|
(unsigned char)shade,
|
||||||
|
(unsigned char)shade,
|
||||||
|
(unsigned char)(shade + 1),
|
||||||
|
255
|
||||||
|
};
|
||||||
|
|
||||||
|
DrawCube(
|
||||||
|
{p.x, -0.06f, p.z},
|
||||||
|
CELL + 0.16f,
|
||||||
|
0.12f,
|
||||||
|
CELL + 0.16f,
|
||||||
|
color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawWalls()
|
||||||
|
{
|
||||||
|
for (const Wall& wall : walls)
|
||||||
|
{
|
||||||
|
DrawCube(
|
||||||
|
wall.position,
|
||||||
|
wall.size.x,
|
||||||
|
wall.size.y,
|
||||||
|
wall.size.z,
|
||||||
|
{52, 82, 116, 255}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawCeiling()
|
||||||
|
{
|
||||||
|
for (int z = 0; z < MAZE_H; z++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < MAZE_W; x++)
|
||||||
|
{
|
||||||
|
if (maze[z][x])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vector3 p = CellToWorld(x, z);
|
||||||
|
|
||||||
|
bool lightZone =
|
||||||
|
((x * 3 + z * 7) % 11 == 0);
|
||||||
|
|
||||||
|
Color ceilingColor =
|
||||||
|
lightZone
|
||||||
|
? Color{155, 155, 155, 255}
|
||||||
|
: Color{70, 70, 70, 255};
|
||||||
|
|
||||||
|
DrawCube(
|
||||||
|
{p.x, 3.12f, p.z},
|
||||||
|
CELL + 0.16f,
|
||||||
|
0.16f,
|
||||||
|
CELL + 0.16f,
|
||||||
|
ceilingColor
|
||||||
|
);
|
||||||
|
|
||||||
|
if (lightZone)
|
||||||
|
{
|
||||||
|
DrawCube(
|
||||||
|
{p.x, 3.01f, p.z},
|
||||||
|
1.3f,
|
||||||
|
0.04f,
|
||||||
|
0.7f,
|
||||||
|
RAYWHITE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawFurniture()
|
||||||
|
{
|
||||||
|
for (const Furniture& object : furniture)
|
||||||
|
{
|
||||||
|
Color color;
|
||||||
|
|
||||||
|
switch (object.type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
color = {75, 75, 75, 255};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
color = {100, 82, 65, 255};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
color = {62, 62, 68, 255};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
color = {84, 70, 55, 255};
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
color = {90, 90, 90, 255};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawCube(
|
||||||
|
object.position,
|
||||||
|
object.size.x,
|
||||||
|
object.size.y,
|
||||||
|
object.size.z,
|
||||||
|
color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawHUD()
|
||||||
|
{
|
||||||
|
DrawRectangle(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
300,
|
||||||
|
70,
|
||||||
|
{0, 0, 0, 100}
|
||||||
|
);
|
||||||
|
|
||||||
|
DrawText(
|
||||||
|
"NIVEL: TALAN-TALAN",
|
||||||
|
15,
|
||||||
|
12,
|
||||||
|
20,
|
||||||
|
RAYWHITE
|
||||||
|
);
|
||||||
|
|
||||||
|
DrawText(
|
||||||
|
"WASD MOVER",
|
||||||
|
15,
|
||||||
|
39,
|
||||||
|
15,
|
||||||
|
LIGHTGRAY
|
||||||
|
);
|
||||||
|
|
||||||
|
int centerX = GetScreenWidth() / 2;
|
||||||
|
int centerY = GetScreenHeight() / 2;
|
||||||
|
|
||||||
|
DrawLine(
|
||||||
|
centerX - 8,
|
||||||
|
centerY,
|
||||||
|
centerX + 8,
|
||||||
|
centerY,
|
||||||
|
RAYWHITE
|
||||||
|
);
|
||||||
|
|
||||||
|
DrawLine(
|
||||||
|
centerX,
|
||||||
|
centerY - 8,
|
||||||
|
centerX,
|
||||||
|
centerY + 8,
|
||||||
|
RAYWHITE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunGame()
|
||||||
|
{
|
||||||
|
InitWindow(
|
||||||
|
1366,
|
||||||
|
768,
|
||||||
|
"A4B1 - Nivel Talan-Talan"
|
||||||
|
);
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
DisableCursor();
|
||||||
|
|
||||||
|
GenerateMaze();
|
||||||
|
BuildWalls();
|
||||||
|
GenerateFurniture();
|
||||||
|
|
||||||
|
while (!WindowShouldClose())
|
||||||
|
{
|
||||||
|
float deltaTime = GetFrameTime();
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_F11))
|
||||||
|
{
|
||||||
|
ToggleFullscreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdatePlayer(deltaTime);
|
||||||
|
UpdateEnemy(deltaTime);
|
||||||
|
UpdateWeapons(deltaTime);
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground({25, 25, 28, 255});
|
||||||
|
|
||||||
|
BeginMode3D(GetPlayerCamera());
|
||||||
|
|
||||||
|
DrawFloor();
|
||||||
|
DrawWalls();
|
||||||
|
DrawCeiling();
|
||||||
|
DrawFurniture();
|
||||||
|
|
||||||
|
DrawEnemy();
|
||||||
|
DrawBullets();
|
||||||
|
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
|
DrawPlayerWeapon();
|
||||||
|
DrawHUD();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
EnableCursor();
|
||||||
|
CloseWindow();
|
||||||
|
}
|
||||||
+4
-3170
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,242 @@
|
|||||||
|
#include "raylib.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
extern bool IsSolidAt(Vector3 position, float radius);
|
||||||
|
|
||||||
|
Vector3 playerPosition = {-76.0f, 1.0f, -76.0f};
|
||||||
|
|
||||||
|
float verticalVelocity = 0.0f;
|
||||||
|
float playerYaw = 0.0f;
|
||||||
|
float playerPitch = 0.0f;
|
||||||
|
|
||||||
|
float weaponBobTime = 0.0f;
|
||||||
|
float weaponShootTime = 0.0f;
|
||||||
|
|
||||||
|
const float moveSpeed = 7.0f;
|
||||||
|
const float jumpForce = 9.0f;
|
||||||
|
const float gravity = 20.0f;
|
||||||
|
|
||||||
|
static const float PLAYER_RADIUS = 0.45f;
|
||||||
|
static const float PLAYER_GROUND_Y = 1.0f;
|
||||||
|
static const float PLAYER_HEAD_Y = 2.0f;
|
||||||
|
static const float CEILING_Y = 3.0f;
|
||||||
|
|
||||||
|
Camera3D GetPlayerCamera()
|
||||||
|
{
|
||||||
|
Camera3D camera = {};
|
||||||
|
|
||||||
|
camera.position = playerPosition;
|
||||||
|
|
||||||
|
Vector3 forward =
|
||||||
|
{
|
||||||
|
cosf(playerPitch) * cosf(playerYaw),
|
||||||
|
sinf(playerPitch),
|
||||||
|
cosf(playerPitch) * sinf(playerYaw)
|
||||||
|
};
|
||||||
|
|
||||||
|
camera.target =
|
||||||
|
{
|
||||||
|
camera.position.x + forward.x,
|
||||||
|
camera.position.y + forward.y,
|
||||||
|
camera.position.z + forward.z
|
||||||
|
};
|
||||||
|
|
||||||
|
camera.up = {0.0f, 1.0f, 0.0f};
|
||||||
|
camera.fovy = 75.0f;
|
||||||
|
camera.projection = CAMERA_PERSPECTIVE;
|
||||||
|
|
||||||
|
return camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MovePlayer(Vector3 movement)
|
||||||
|
{
|
||||||
|
// X separado de Z para poder deslizarse por las paredes.
|
||||||
|
Vector3 nextX = playerPosition;
|
||||||
|
nextX.x += movement.x;
|
||||||
|
|
||||||
|
if (!IsSolidAt(nextX, PLAYER_RADIUS))
|
||||||
|
{
|
||||||
|
playerPosition.x = nextX.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 nextZ = playerPosition;
|
||||||
|
nextZ.z += movement.z;
|
||||||
|
|
||||||
|
if (!IsSolidAt(nextZ, PLAYER_RADIUS))
|
||||||
|
{
|
||||||
|
playerPosition.z = nextZ.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdatePlayer(float deltaTime)
|
||||||
|
{
|
||||||
|
Vector2 mouse = GetMouseDelta();
|
||||||
|
|
||||||
|
playerYaw += mouse.x * 0.003f;
|
||||||
|
playerPitch -= mouse.y * 0.003f;
|
||||||
|
|
||||||
|
if (playerPitch > 1.45f)
|
||||||
|
playerPitch = 1.45f;
|
||||||
|
|
||||||
|
if (playerPitch < -1.45f)
|
||||||
|
playerPitch = -1.45f;
|
||||||
|
|
||||||
|
Vector3 movement = {0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
Vector3 forward =
|
||||||
|
{
|
||||||
|
cosf(playerYaw),
|
||||||
|
0.0f,
|
||||||
|
sinf(playerYaw)
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector3 right =
|
||||||
|
{
|
||||||
|
-sinf(playerYaw),
|
||||||
|
0.0f,
|
||||||
|
cosf(playerYaw)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (IsKeyDown(KEY_W))
|
||||||
|
{
|
||||||
|
movement.x += forward.x;
|
||||||
|
movement.z += forward.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyDown(KEY_S))
|
||||||
|
{
|
||||||
|
movement.x -= forward.x;
|
||||||
|
movement.z -= forward.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyDown(KEY_D))
|
||||||
|
{
|
||||||
|
movement.x += right.x;
|
||||||
|
movement.z += right.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyDown(KEY_A))
|
||||||
|
{
|
||||||
|
movement.x -= right.x;
|
||||||
|
movement.z -= right.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
float movementLength =
|
||||||
|
sqrtf(
|
||||||
|
movement.x * movement.x +
|
||||||
|
movement.z * movement.z
|
||||||
|
);
|
||||||
|
|
||||||
|
if (movementLength > 0.0f)
|
||||||
|
{
|
||||||
|
movement.x /= movementLength;
|
||||||
|
movement.z /= movementLength;
|
||||||
|
|
||||||
|
MovePlayer({
|
||||||
|
movement.x * moveSpeed * deltaTime,
|
||||||
|
0.0f,
|
||||||
|
movement.z * moveSpeed * deltaTime
|
||||||
|
});
|
||||||
|
|
||||||
|
weaponBobTime += deltaTime * 10.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool grounded =
|
||||||
|
playerPosition.y <= PLAYER_GROUND_Y + 0.001f;
|
||||||
|
|
||||||
|
if (grounded)
|
||||||
|
{
|
||||||
|
playerPosition.y = PLAYER_GROUND_Y;
|
||||||
|
verticalVelocity = 0.0f;
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_SPACE))
|
||||||
|
{
|
||||||
|
verticalVelocity = jumpForce;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalVelocity -= gravity * deltaTime;
|
||||||
|
|
||||||
|
playerPosition.y +=
|
||||||
|
verticalVelocity * deltaTime;
|
||||||
|
|
||||||
|
if (playerPosition.y < PLAYER_GROUND_Y)
|
||||||
|
{
|
||||||
|
playerPosition.y = PLAYER_GROUND_Y;
|
||||||
|
verticalVelocity = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Colisión con el techo.
|
||||||
|
if (playerPosition.y + PLAYER_HEAD_Y > CEILING_Y)
|
||||||
|
{
|
||||||
|
playerPosition.y =
|
||||||
|
CEILING_Y - PLAYER_HEAD_Y;
|
||||||
|
|
||||||
|
if (verticalVelocity > 0.0f)
|
||||||
|
verticalVelocity = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weaponShootTime > 0.0f)
|
||||||
|
weaponShootTime -= deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawPlayerWeapon()
|
||||||
|
{
|
||||||
|
float bobX = 0.0f;
|
||||||
|
float bobY = 0.0f;
|
||||||
|
|
||||||
|
bobX = sinf(weaponBobTime) * 5.0f;
|
||||||
|
bobY = fabsf(cosf(weaponBobTime)) * 4.0f;
|
||||||
|
|
||||||
|
if (weaponShootTime > 0.0f)
|
||||||
|
{
|
||||||
|
bobX += GetRandomValue(-4, 4);
|
||||||
|
bobY += GetRandomValue(-5, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
int w = GetScreenWidth();
|
||||||
|
int h = GetScreenHeight();
|
||||||
|
|
||||||
|
float x = w * 0.76f + bobX;
|
||||||
|
float y = h * 0.68f + bobY;
|
||||||
|
|
||||||
|
DrawRectangle(
|
||||||
|
(int)x,
|
||||||
|
(int)y,
|
||||||
|
190,
|
||||||
|
95,
|
||||||
|
DARKGRAY
|
||||||
|
);
|
||||||
|
|
||||||
|
DrawRectangle(
|
||||||
|
(int)x + 55,
|
||||||
|
(int)y - 35,
|
||||||
|
80,
|
||||||
|
55,
|
||||||
|
GRAY
|
||||||
|
);
|
||||||
|
|
||||||
|
DrawRectangle(
|
||||||
|
(int)x + 72,
|
||||||
|
(int)y - 62,
|
||||||
|
45,
|
||||||
|
40,
|
||||||
|
BLACK
|
||||||
|
);
|
||||||
|
|
||||||
|
DrawRectangle(
|
||||||
|
(int)x + 20,
|
||||||
|
(int)y + 30,
|
||||||
|
45,
|
||||||
|
65,
|
||||||
|
BLACK
|
||||||
|
);
|
||||||
|
|
||||||
|
DrawRectangle(
|
||||||
|
(int)x + 120,
|
||||||
|
(int)y + 15,
|
||||||
|
65,
|
||||||
|
35,
|
||||||
|
BLACK
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
#include "raylib.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
extern Camera3D GetPlayerCamera();
|
||||||
|
extern Vector3 playerPosition;
|
||||||
|
extern float playerYaw;
|
||||||
|
extern float weaponShootTime;
|
||||||
|
|
||||||
|
extern int CheckEnemyHit(Vector3 bulletPosition);
|
||||||
|
extern void TeleportEnemyNearPlayer(int index, float yaw);
|
||||||
|
extern bool IsSolidAt(Vector3 position, float radius);
|
||||||
|
|
||||||
|
struct Bullet
|
||||||
|
{
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 direction;
|
||||||
|
float speed;
|
||||||
|
bool active;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int MAX_BULLETS = 100;
|
||||||
|
|
||||||
|
static Bullet bullets[MAX_BULLETS];
|
||||||
|
|
||||||
|
static Vector3 GetForward()
|
||||||
|
{
|
||||||
|
Vector3 forward =
|
||||||
|
{
|
||||||
|
cosf(playerYaw),
|
||||||
|
0.0f,
|
||||||
|
sinf(playerYaw)
|
||||||
|
};
|
||||||
|
|
||||||
|
return forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SpawnBullet(
|
||||||
|
Vector3 start,
|
||||||
|
Vector3 direction
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_BULLETS; i++)
|
||||||
|
{
|
||||||
|
if (!bullets[i].active)
|
||||||
|
{
|
||||||
|
bullets[i].position = start;
|
||||||
|
bullets[i].direction = direction;
|
||||||
|
bullets[i].speed = 35.0f;
|
||||||
|
bullets[i].active = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateWeapons(float deltaTime)
|
||||||
|
{
|
||||||
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
|
||||||
|
{
|
||||||
|
Camera3D camera = GetPlayerCamera();
|
||||||
|
|
||||||
|
Vector3 forward =
|
||||||
|
{
|
||||||
|
camera.target.x - camera.position.x,
|
||||||
|
camera.target.y - camera.position.y,
|
||||||
|
camera.target.z - camera.position.z
|
||||||
|
};
|
||||||
|
|
||||||
|
float length =
|
||||||
|
sqrtf(
|
||||||
|
forward.x * forward.x +
|
||||||
|
forward.y * forward.y +
|
||||||
|
forward.z * forward.z
|
||||||
|
);
|
||||||
|
|
||||||
|
if (length > 0.001f)
|
||||||
|
{
|
||||||
|
forward.x /= length;
|
||||||
|
forward.y /= length;
|
||||||
|
forward.z /= length;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 right =
|
||||||
|
{
|
||||||
|
-sinf(playerYaw),
|
||||||
|
0.0f,
|
||||||
|
cosf(playerYaw)
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector3 start =
|
||||||
|
{
|
||||||
|
camera.position.x + forward.x * 0.7f,
|
||||||
|
camera.position.y + forward.y * 0.7f,
|
||||||
|
camera.position.z + forward.z * 0.7f
|
||||||
|
};
|
||||||
|
|
||||||
|
const float spread = 0.07f;
|
||||||
|
|
||||||
|
SpawnBullet(
|
||||||
|
start,
|
||||||
|
{
|
||||||
|
forward.x,
|
||||||
|
forward.y,
|
||||||
|
forward.z
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
SpawnBullet(
|
||||||
|
start,
|
||||||
|
{
|
||||||
|
forward.x + right.x * spread,
|
||||||
|
forward.y,
|
||||||
|
forward.z + right.z * spread
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
SpawnBullet(
|
||||||
|
start,
|
||||||
|
{
|
||||||
|
forward.x - right.x * spread,
|
||||||
|
forward.y,
|
||||||
|
forward.z - right.z * spread
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
SpawnBullet(
|
||||||
|
start,
|
||||||
|
{
|
||||||
|
forward.x + right.x * spread * 2.0f,
|
||||||
|
forward.y,
|
||||||
|
forward.z + right.z * spread * 2.0f
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
SpawnBullet(
|
||||||
|
start,
|
||||||
|
{
|
||||||
|
forward.x - right.x * spread * 2.0f,
|
||||||
|
forward.y,
|
||||||
|
forward.z - right.z * spread * 2.0f
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
weaponShootTime = 0.12f;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_BULLETS; i++)
|
||||||
|
{
|
||||||
|
if (!bullets[i].active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vector3 movement =
|
||||||
|
{
|
||||||
|
bullets[i].direction.x *
|
||||||
|
bullets[i].speed * deltaTime,
|
||||||
|
|
||||||
|
bullets[i].direction.y *
|
||||||
|
bullets[i].speed * deltaTime,
|
||||||
|
|
||||||
|
bullets[i].direction.z *
|
||||||
|
bullets[i].speed * deltaTime
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector3 nextPosition =
|
||||||
|
{
|
||||||
|
bullets[i].position.x + movement.x,
|
||||||
|
bullets[i].position.y + movement.y,
|
||||||
|
bullets[i].position.z + movement.z
|
||||||
|
};
|
||||||
|
|
||||||
|
// Las balas chocan con paredes y muebles.
|
||||||
|
if (IsSolidAt(nextPosition, 0.08f))
|
||||||
|
{
|
||||||
|
bullets[i].active = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bullets[i].position = nextPosition;
|
||||||
|
|
||||||
|
int hitNPC =
|
||||||
|
CheckEnemyHit(bullets[i].position);
|
||||||
|
|
||||||
|
if (hitNPC >= 0)
|
||||||
|
{
|
||||||
|
TeleportEnemyNearPlayer(
|
||||||
|
hitNPC,
|
||||||
|
playerYaw
|
||||||
|
);
|
||||||
|
|
||||||
|
bullets[i].active = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dx =
|
||||||
|
bullets[i].position.x -
|
||||||
|
playerPosition.x;
|
||||||
|
|
||||||
|
float dz =
|
||||||
|
bullets[i].position.z -
|
||||||
|
playerPosition.z;
|
||||||
|
|
||||||
|
float distance =
|
||||||
|
sqrtf(dx * dx + dz * dz);
|
||||||
|
|
||||||
|
if (distance > 200.0f)
|
||||||
|
{
|
||||||
|
bullets[i].active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawBullets()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_BULLETS; i++)
|
||||||
|
{
|
||||||
|
if (!bullets[i].active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DrawSphere(
|
||||||
|
bullets[i].position,
|
||||||
|
0.10f,
|
||||||
|
YELLOW
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user