In this section, you’ll learn how to implement basic artificial intelligence (AI) for enemies in your Phaser games. We’ll cover common enemy behaviors, how to structure enemy logic, and how to make your game more engaging by adding dynamic challenges for the player.


  1. What is AI in Games?

Game AI refers to the logic that controls non-player characters (NPCs) or enemies, making them behave in ways that challenge or interact with the player. In Phaser, AI is typically implemented using JavaScript code that updates enemy actions each frame.

Common Enemy Behaviors

Behavior Type Description Example
Patrol Move back and forth between two points Guard walking along a platform
Chase Follow the player when in range Enemy runs towards the player
Flee Move away from the player Enemy escapes when approached
Attack Perform an action when close to the player Enemy shoots or jumps at player
Idle/Wait Stay still or perform simple animations Enemy stands guard

  1. Structuring Enemy Logic

To keep your code organized, it’s best to encapsulate enemy behavior in a class or a Phaser group. This allows you to manage multiple enemies and their states efficiently.

Example: Basic Enemy Class

class Enemy extends Phaser.Physics.Arcade.Sprite {
    constructor(scene, x, y, texture) {
        super(scene, x, y, texture);
        scene.add.existing(this);
        scene.physics.add.existing(this);

        this.speed = 100;
        this.direction = 1; // 1 = right, -1 = left
        this.patrolDistance = 200;
        this.startX = x;
    }

    update() {
        // Patrol logic: move back and forth
        this.setVelocityX(this.speed * this.direction);

        if (Math.abs(this.x - this.startX) > this.patrolDistance) {
            this.direction *= -1; // Change direction
            this.flipX = !this.flipX; // Flip sprite
        }
    }
}

Explanation:

  • The Enemy class extends Phaser’s Sprite and adds physics.
  • The enemy moves left and right between two points (patrolDistance).
  • When the enemy reaches the patrol limit, it turns around.

  1. Implementing Enemy Behaviors

A. Patrol Behavior

Patrol is the simplest AI. The enemy moves between two points.

// In your scene's update method:
enemies.children.iterate(function(enemy) {
    enemy.update();
});

B. Chase Behavior

To make an enemy chase the player:

class ChasingEnemy extends Enemy {
    constructor(scene, x, y, texture, player) {
        super(scene, x, y, texture);
        this.player = player;
        this.chaseRange = 150;
    }

    update() {
        const distance = Phaser.Math.Distance.Between(this.x, this.y, this.player.x, this.player.y);

        if (distance < this.chaseRange) {
            // Move towards player
            this.scene.physics.moveToObject(this, this.player, this.speed);
            this.flipX = this.player.x < this.x;
        } else {
            // Patrol if player is not close
            super.update();
        }
    }
}

Explanation:

  • The enemy checks the distance to the player.
  • If the player is within chaseRange, the enemy moves towards the player.
  • Otherwise, it resumes patrolling.

  1. Practical Exercise

Exercise: Create a Patrolling and Chasing Enemy

Task:

  1. Create a new enemy that patrols between two points.
  2. If the player comes within 100 pixels, the enemy should chase the player.
  3. When the player leaves the range, the enemy resumes patrolling.

Starter Code:

// Assume 'player' is your player sprite and 'scene' is your Phaser scene

class SmartEnemy extends Phaser.Physics.Arcade.Sprite {
    constructor(scene, x, y, texture, player) {
        super(scene, x, y, texture);
        scene.add.existing(this);
        scene.physics.add.existing(this);

        this.player = player;
        this.speed = 100;
        this.direction = 1;
        this.patrolDistance = 150;
        this.startX = x;
        this.chaseRange = 100;
    }

    update() {
        // TODO: Implement patrol and chase logic
    }
}

// In your scene's update method:
enemy.update();

Solution:

update() {
    const distance = Phaser.Math.Distance.Between(this.x, this.y, this.player.x, this.player.y);

    if (distance < this.chaseRange) {
        // Chase the player
        this.scene.physics.moveToObject(this, this.player, this.speed);
        this.flipX = this.player.x < this.x;
    } else {
        // Patrol
        this.setVelocityX(this.speed * this.direction);

        if (Math.abs(this.x - this.startX) > this.patrolDistance) {
            this.direction *= -1;
            this.flipX = !this.flipX;
        }
    }
}

Common Mistakes & Tips:

  • Forgetting to call update(): Make sure you call enemy.update() in your scene’s update method.
  • Not resetting velocity: If you use moveToObject, ensure you stop the enemy when needed (e.g., when the player is out of range).
  • Sprite flipping: Use flipX to make the enemy face the correct direction.

  1. Expanding Enemy AI

You can add more complexity by:

  • Giving enemies different states (patrol, chase, attack, idle).
  • Using timers to delay actions.
  • Adding attack animations or projectiles.
  • Making enemies avoid obstacles or each other.

Example: Enemy State Table

State Trigger Condition Action
Patrol Player out of range Move between two points
Chase Player in range Move towards player
Attack Player very close Perform attack animation
Idle No player, no patrol Stand still or play idle anim

  1. Summary

  • Game AI makes your games more dynamic and challenging.
  • Start with simple behaviors like patrol and chase.
  • Use classes to encapsulate enemy logic for scalability.
  • Combine behaviors and states for more advanced AI.

Next Steps:
In the next section, you’ll learn about deploying and optimizing your game, ensuring your AI and other features run smoothly for all players.

© Copyright 2024. All rights reserved