Enemy does not fire according to his tick rate

Hello everyone,
In recent days, I’ve been seeing why my enemies are firing only one shot against my player, given that I basically copied my player’s shot code to the enemies.
The best part of this that makes me laugh is the fact that if the player is in constant jumping, the enemies shoot at him (only one shot)

imagem
imagem

How the code works:

  • If the player reaches a distance from the enemy (<= 200), the enemies start firing at him, with a tickrate of 100
  • They fire at the side of the player’s player (not fully functional).

imagem
imagem

Game code:

update(time,delta) {
if (this.rambo.alive == true) {
  this.checkInputs(time); // Rambo Inputs
  this.enemiesMovementAndFire(time, this.rambo); // Enemies Movement and Fire
}

//Passage to SecondScene
if (this.rambo.x >= this.map.widthInPixels) {
  this.scene.stop();
  this.scene.start('SecondScene', {
    rambo: this.rambo
  });
}
  }

  enemiesMovementAndFire(time, rambo) {
Phaser.Actions.Call(this.enemiesGroup.getChildren(), function (enemy) {
  enemy.movement();
  if (enemy.x - this.rambo.x <= 200 && enemy.y == this.rambo.y) {
    enemy.fire(time, rambo);
  }
}, this);
  }

Enemy Class:

import Bullets from './Bullets.js';
export default class Enemy extends Phaser.Physics.Arcade.Sprite {
    constructor(scene, x, y) {
        super(scene, x, y, 'enemy');
        this.scene = scene;

       
        this.nextTick = 0;
        this.bullets = this.scene.physics.add.group({
            classType: Bullets,
            key: "bullet"
        });

        scene.add.existing(this);
        scene.physics.add.existing(this);
        scene.physics.world.enable(this);

        this.fminX = x - 20;
        this.frightX = x + 20;
        this.setFrame(0);
        this.setGravityY(300);
        this.direction = "right";
        this.lives = 3;
    }


    movement() {
        switch (this.direction) {
            case "left":
                // Walk Left
                if (this.x > this.fminX) {
                    this.setVelocityX(-45);
                    this.anims.play("enemy-" + this.direction, true);
                } else {
                    // Left Bounderies Reached, change direction
                    this.direction = "right";
                }
                break;
            case "right":
                // Walk Right
                if (this.x < this.frightX) {
                    this.setVelocityX(45);
                    this.anims.play("enemy-" + this.direction, true); 
                } else {
                    // Right Bounderies Reached, change direction
                    this.direction = "left";
                }
                break;
        }
    }
    
    fire(time) {
        // The function tracks the time between "tics" and the current time of the game
        // Game time is always up to date. the next tic will only be if it is less than the game time
        if (time > this.nextTick) {
            var bullet = this.bullets.get();
            if (this.direction === "right") {
                if (bullet) {
                    bullet.fire(this.x + 7, this.y + 5, 250, 0);
                }
            } else {
                // Shoot Left
                if (bullet) {
                    bullet.fire(this.x - 7, this.y + 5, -250, 0);
                }
            }
        }
        //tickFreq é a frequencia em ms com a qual o evento poderá acontecer
        var tickFreq = 100;
        this.nextTick = time + tickFreq;
    }
}

There are two logical errors in the core from the screenshots, both related to the proximity check. For the X position check, it should work normally when the player is to the left of the enemy (because enemy.x - this.rambo.x will be positive), but it will always be true if the player is to the right. You should take the absolute value (using Math.abs) of the expression before comparing it to 200. Given the current firing code, you should also set enemy.direction accordingly. The second problem is caused by your Y check - the enemy will only fire if the player is at the same Y position as the enemy, which will not be the case when they jump. You should use a proximity check similar to the one used when checking the X position.

image

I made these modifications mentioned, but the problems persists, the enemy does not fire according to his given tickrate, or better yet, he shoots randomly.
If I reduce their tickrate, basically my player, he will get with a bullet laser dying instantly.
Given that my player fires every 100ms, I wanted them to fire every 250ms, but it does not work.

Right, there’s another mistake I didn’t see earlier. You call the fire method on your enemy every frame. At the end of the method, you adjust the next tick regardless of whether you’re currently on a tick. Moving the two lines of code which set this.nextTick into the if statement should make the calls more consistent.

1 Like