226 lines
3.4 KiB
C++
226 lines
3.4 KiB
C++
#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
|
|
);
|
|
}
|
|
}
|