Kill kill kill

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-13 21:03:34 +01:00
parent d4d5a84bc4
commit 2f66ba451a
4 changed files with 158 additions and 39 deletions

View File

@@ -307,9 +307,16 @@ class _WolfRendererState extends State<WolfRenderer>
}
// 5. Weapon
player.currentWeapon.update(elapsed.inMilliseconds);
// Update weapon animation and check for flash frame
bool shouldCheckHit = player.updateWeapon(elapsed.inMilliseconds);
if (pressedKeys.contains(LogicalKeyboardKey.controlLeft)) {
if (shouldCheckHit) {
_performRaycastAttack(elapsed);
}
// Input to trigger firing
if (pressedKeys.contains(LogicalKeyboardKey.controlLeft) &&
!_spaceWasPressed) {
player.fire(elapsed.inMilliseconds);
}
@@ -327,6 +334,64 @@ class _WolfRendererState extends State<WolfRenderer>
damageFlashOpacity = 0.5;
}
void _performRaycastAttack(Duration elapsed) {
Enemy? closestEnemy;
double minDistance = 15.0; // Maximum range of the gun
for (Entity entity in entities) {
if (entity is Enemy && entity.state != EntityState.dead) {
// 1. Calculate the angle from player to enemy
double dx = entity.x - player.x;
double dy = entity.y - player.y;
double angleToEnemy = math.atan2(dy, dx);
// 2. Check if that angle is close to our player's aiming angle
double angleDiff = player.angle - angleToEnemy;
while (angleDiff <= -math.pi) angleDiff += 2 * math.pi;
while (angleDiff > math.pi) angleDiff -= 2 * math.pi;
// 3. Simple bounding box check (approx 0.4 units wide)
double dist = math.sqrt(dx * dx + dy * dy);
double threshold =
0.2 / dist; // Smaller threshold as they get further away
if (angleDiff.abs() < threshold) {
// 4. Ensure there is no wall between you and the enemy
if (_hasLineOfSightToEnemy(entity, dist)) {
if (dist < minDistance) {
minDistance = dist;
closestEnemy = entity;
}
}
}
}
}
if (closestEnemy != null) {
closestEnemy.takeDamage(
player.currentWeapon.damage,
elapsed.inMilliseconds,
);
// If the shot was fatal, reward the player
if (closestEnemy.state == EntityState.dead) {
player.score += 100;
}
}
}
bool _hasLineOfSightToEnemy(Enemy enemy, double distance) {
double dirX = math.cos(player.angle);
double dirY = math.sin(player.angle);
for (double i = 0.5; i < distance; i += 0.2) {
int checkX = (player.x + dirX * i).toInt();
int checkY = (player.y + dirY * i).toInt();
if (!_isWalkable(checkX, checkY)) return false;
}
return true;
}
@override
Widget build(BuildContext context) {
if (_isLoading) {