Home > OS >  Javascript canvas game enemys: solution not found
Javascript canvas game enemys: solution not found

Time:07-17

So, i am just making a javascript canvas only game. I know game engines like Godot but its just more like a challenge for me, thats why i choose javascript. The first thing i did was coding the enemies.

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");



var x = 0;
var y = 0;
var x_add = 2;
var y_add = 2;

animate();

function animate(){
    draw();
    setTimeout(animate, 10);
};

function draw(){
    ctx.clearRect(0,0,1500, 500);
    //draw_enemy(0, 0, "green", 30, 30);
    draw_enemy(900, 100, "red", 40, 50);
};

function draw_enemy(start_x, start_y, fill, w, h){
    if(x   w   start_x == 1000){
        x_add = -2;
    }
    if(y   h   start_y == 500){
        y_add = -2;
    }
    if(y    start_y == 0){
        y_add = 2;
    }
    if(x   start_x == 0){
        x_add = 2;
    }
    x  = x_add;
    y  = y_add;
    ctx.fillStyle = fill;
    ctx.fillRect(x   start_x, y   start_y, w, h);
};
<!DOCTYPE html>
<html>
    <head>
        <title>local storage test</title>
        <style>
        </style>
    </head>
    <body>
        <div style="text-align: center">
            <canvas id="canvas" width="1000" height="500" style="border: 1px solid black; padding: 5 px">
            </canvas>
        </div>        
        <script src="script.js">
        </script>
    </body>
</html>

So i made a function for creating enemies. If i have one enemy spawned, everything works fine. But if i include 2 or more enemies, They all move the same and their movement is random. I think i know what the problem in my code is but i dont know how to do fix it. I think that the problem is, that if enemy 1 touches the border, x_add changes. But if then the function for enemy 2 is executed, it doesnt touches the border, but still, the x_add var is the same like the variable from enemy 1. So how can i make variables for every enemy, maybe with an enemy array? Or should i make an else statement, if the enemy doesnt touch the border? But then how i know in which direction the enemy was going before? Can smb explain how i can fix it? thx

CodePudding user response:

Using a class for this is the best option. A class allows you to create multiple instances of the same object while allowing each instance to be individually controlled.

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

let enemies = [];

class Enemy {
  constructor(c) {
    this.x = 50   Math.random() * canvas.width;
    this.y = 50   Math.random() * canvas.height;
    this.w = 40;
    this.h = 50;
    this.c = c;
    this.vx = 2;
    this.vy = 2;
  }
  draw() {
    ctx.fillStyle = this.c;
    ctx.fillRect(this.x, this.y, this.w, this.h);
  }
  update() {
    if (this.x   this.w >= canvas.width) {
      this.vx = -2;
    }
    if (this.y   this.h >= canvas.height) {
      this.vy = -2;
    }
    if (this.y <= 0) {
      this.vy = 2;
    }
    if (this.x <= 0) {
      this.vx = 2;
    }
    this.x  = this.vx;
    this.y  = this.vy;
    this.draw()
  }
}

function createEnemies() {
  for (let i=0; i < 5; i  ) {
    enemies.push(new Enemy('red'))
  }
}
createEnemies()

enemies.push(new Enemy('green'))
enemies.push(new Enemy('blue'))

/*
There may be times where you want to pass in specific values for the properties for each individual enemy. i.e. color, x, y, health, defense, etc
*/

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  enemies.forEach(e => e.update())  
}

/*
forEach is the same as saying...

for (let i = 0; i < enemies.length; i  ) {
  enemies[i].update()
}

...but shorter and cleaner
*/

function animate() {
  draw();
  setTimeout(animate, 10);
}
animate()

//suggest using requestAnimationFrame() instead of setTimeout
<canvas id="canvas" width="1000" height="500" style="border: 1px solid black; padding: 5 px">
</canvas>

A couple things to keep in mind. For this example you will want to push all of your objects to an array and draw/update them in a loop in the animate function. You can also choose to pass in any of the property values i.e. you want certain enemies to have a specific color. Or maybe you want each enemy to start at a specific location then pass the x and y value to the constructor.

I also recommend using canvas.width and canvas.height over the actual numerical size.

  • Related