angulartypescriptfrontendweb-frameworks

Snake Game with Angular - Snake not spawning


I am in the first step of creating a snake which requires to: 1- create the game board 2- create the snake and the fruit 3- display the snake and the fruit o The problem is that the board is updated after the snake and the fruit are spawned but they are not displayed in the game board Note: 0 in a cell means it is empty, 1 means it is a snake body and 2 means it is a fruit

html -> gameboard component:

<div class="gameB">
    <div *ngFor="let i of board" class="row">
        <div *ngFor="let j of i" class="cell"
        [ngClass]="{'snake' : board[board.indexOf(i)][j] === 1, 'fruit': board[board.indexOf(i)][j] === 2}">
            {{ board[board.indexOf(i)][j] }}
        </div>
    </div>
</div>

TS -> gameboard component:

import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { NgModule } from '@angular/core';
import { Snake } from '../snake-iterface';


@Component({
  selector: 'app-game-board',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './game-board.component.html',
  styleUrl: './game-board.component.css'
})
export class GameBoardComponent implements OnInit{
  boardWidth:number = 20;
  boardHeight:number = 20;
  board:number[][] = [];
  snake:Snake = {} as Snake;
  fruit:number[] = [1,1];
  createBoard(){
    let temp:number[];
    for(let i = 0; i < this.boardHeight;i++){
      temp =[]
      for(let j = 0; j < this.boardWidth;j++){
        temp.push(0)
      }
      this.board.push(temp)
    }
  }
  spawnSnake():void{
    this.board[this.snake.headPositionY][this.snake.headPositionX] = 1;
  }
  updateBoard():void{
    for(let i = 0; i < this.boardHeight; i++){
      for(let j = 0; j < this.boardWidth;j++){
        if(this.snake.bodyPositions.includes([j, i]) ){
          this.board[i][j] = 1;
        }else if((j === this.fruit[0] && i == this.fruit[1])){
          this.board[i][j] = 2;
        }
      }
    }
  }


  ngOnInit(): void {
    this.createBoard()
    console.log("Before Snake creation", this.board)
    this.snake = {
      headPositionX: Math.floor(this.boardWidth / 2),
      headPositionY: Math.floor(this.boardHeight / 2),
      bodyPositions: [[Math.floor(this.boardWidth / 2), Math.floor(this.boardHeight / 2)]],
      length: 1,
      direction: 'right'
    };


    console.log("Before Spawn", this.board)
    this.spawnSnake()
    
    
    this.updateBoard()
    console.log("After Update 1", this.board)
    setTimeout(this.updateBoard, 1000)
    console.log("After Update 2", this.board)
  }

}

CSS -> gameboard component:


.gameB{
    margin: auto;
    padding:10px;
    display: flex;
    flex-direction: column;
    gap: 3px;
    background-color: black;
    width:fit-content;
}
.row{
    display: flex;
    flex-direction: row;
    gap: 3px;
}
.cell{
    width:20px;
    height:20px;
    background-color: grey;
}
.snake{
    background-color:red;
}
.fruit{
    background-color:purple;
}

Other Files:

HTML -> app component:

<app-game-board></app-game-board>

HTML -> index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>SnakeGame</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>

Note: first console log shows the snake and the fruit are added to the board before the update and before the snake is even created (how?????) second console and all other logs show the same result

Note:Using Angular 17

Please be precise in your answer as I am a begginer in Angular

I Tried changing the snake declaration from outside to inside of the ngOnInit but it still doesnt work


Solution

  • in game-board.component.html, you think that j is the index of the row but j is the content of the cell.

    then you just have to make that

    <div class="gameB">
        <div *ngFor="let i of board" class="row">
            <div
                *ngFor="let j of i"
                class="cell"
                [ngClass]="{'snake' : j === 1, 'fruit': j === 2}"
            >
                {{j}}
            </div>
        </div>
    </div>