Game Logic & Mechanics

Game Loop

The game loop is the core of the game, responsible for updating the game state and rendering the game to the screen. The loop runs continuously, performing the following steps:

  1. Handle Input: Process player input, such as keyboard presses. This is done in the handleInput() function in Game.ts.
    // Game.ts
              handleInput(event: KeyboardEvent) {
                switch (event.key) {
                  case 'ArrowUp':
                    this.pacman.direction = Directions.Up;
                    break;
                  // ... other directions
                }
              }
              
  2. Update Game State: Update the position of the Pacman and the ghosts, and check for collisions. This is done in the update() function in Game.ts.
    // Game.ts
              update() {
                this.pacman.update();
                this.ghosts.forEach(ghost => ghost.update());
                this.checkCollisions();
              }
              
  3. Render: Draw the game state to the screen. This is done in the render() function in Game.ts.
    // Game.ts
              render() {
                this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
                this.pacman.draw(this.context);
                this.ghosts.forEach(ghost => ghost.draw(this.context));
                // ... other rendering logic
              }
              

Pacman Movement

Pacman moves in four directions: up, down, left, and right. Its movement is controlled by the player using the arrow keys. The update() function in Pacman.ts calculates the new position of Pacman based on its current direction and speed.

// Pacman.ts
          update() {
            switch (this.direction) {
              case Directions.Up:
                this.y -= this.speed;
                break;
              // ... other directions
            }
          }
          

Ghost AI

The ghosts have different AI behaviors:

  • Blinky (Red): Follows Pacman directly.
  • Pinky (Pink): Targets a position four squares ahead of Pacman.
  • Inky (Cyan): Targets a position twice the distance between Pacman and Blinky, offset by 2 squares.
  • Clyde (Orange): Follows Pacman when far away, but chases a corner when close.

The AI logic is implemented in the update() function of each ghost class (Blinky.ts, Pinky.ts, Inky.ts, Clyde.ts).

For example, the Blinky.ts class implements the following logic:

// Blinky.ts
          update() {
            const dx = this.pacman.x - this.x;
            const dy = this.pacman.y - this.y;
            this.direction = this.getDirection(dx, dy);
            // ... other logic
          }
          

Collisions

The game checks for collisions between Pacman and the ghosts, and between Pacman and the pellets. Collisions are handled in the checkCollisions() function in Game.ts.

// Game.ts
          checkCollisions() {
            if (this.pacman.collidesWith(this.ghosts)) {
              this.handlePacmanGhostCollision();
            }
            this.pellets.forEach(pellet => {
              if (this.pacman.collidesWith(pellet)) {
                this.handlePacmanPelletCollision(pellet);
              }
            });
          }
          

Game State

The game state is stored in the Game class in Game.ts. This includes information such as:

  • Pacman position and direction
  • Ghost positions and directions
  • Pellet positions
  • Score
  • Lives
  • Level

Game Over

The game ends when Pacman loses all his lives. The handlePacmanGhostCollision() function checks if Pacman has lost a life and updates the game state accordingly.

// Game.ts
          handlePacmanGhostCollision() {
            this.lives--;
            if (this.lives === 0) {
              this.gameOver = true;
            }
            // ... other logic
          }
          

Level Progression

The game progresses to the next level when all the pellets have been eaten. The handlePacmanPelletCollision() function checks if the player has eaten all the pellets and updates the game state accordingly.

// Game.ts
          handlePacmanPelletCollision(pellet) {
            this.score += pellet.points;
            this.pellets.splice(this.pellets.indexOf(pellet), 1);
            if (this.pellets.length === 0) {
              this.level++;
              // ... other logic
            }
          }