@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user