Estoy tratando de hacer un minijuego muy simple en el que un personaje se mueva con teclas. Múltiples obstáculos te llegan por la derecha y tienes que esquivarlos.

El problema es que los obstáculos en la matriz myObstacles aparecen detrás de la imagen de fondo. ¿Por qué está haciendo eso y hay una solución fácil que me falta?

Avíseme si algo no está claro o si omití información. Primera vez que publico una pregunta aquí :)

var myGamePiece;
var myObstacles = [];
var myBackground;

function startGame() { 
    myGamePiece = new component(50, 50, "still.png", 10, 120, "image");
    myBackground = new component(1600, 400, "gamebkg.png", 0, 0, "background");
    myGameArea.start();
}


//board
var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 600;
        this.canvas.height = 600;
        this.context = this.canvas.getContext("2d");
        this.context.translate(0.5, 0.5);
        this.context.imageSmoothingQuality = "high";
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.frameNo = 0;
        this.interval = setInterval(updateGameArea, 20);
        //keys to move
        window.addEventListener('keydown', function (e) {
        myGameArea.key = e.keyCode;
        })
        window.addEventListener('keyup', function (e) {
        myGameArea.key = false;
        })
    },
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    },
    stop : function() {
        clearInterval(this.interval);
    }
}



function component(width, height, color, x, y, type) {
    this.type = type;
    if (type == "image" || type == "background") {
        this.image = new Image();
        this.image.src = color;
    }
    this.width = width;
    this.height = height;
    this.speedX = 0;
    this.speedY = 0;    
    this.x = x;
    this.y = y;    
    this.update = function() {
        ctx = myGameArea.context;
        if (type == "image" || type == "background") {
            ctx.drawImage(this.image, 
                this.x, 
                this.y,
                this.width, this.height);
        if (type == "background") {
            ctx.drawImage(this.image, 
                this.x + this.width, 
                this.y,
                this.width, this.height);
        }
        } else {
            ctx.fillStyle = color;
            ctx.fillRect(this.x, this.y, this.width, this.height);
        }
    }
    this.newPos = function() {
        this.x += this.speedX;
        this.y += this.speedY;
        if (this.type == "background") {
            if (this.x == -(this.width)) {
                this.x = 0;
            }
        }
    }    
    this.crashWith = function(otherobj) {
        var myleft = this.x;
        var myright = this.x + (this.width);
        var mytop = this.y;
        var mybottom = this.y + (this.height);
        var otherleft = otherobj.x;
        var otherright = otherobj.x + (otherobj.width);
        var othertop = otherobj.y;
        var otherbottom = otherobj.y + (otherobj.height);
        var crash = true;
    if ((mybottom < othertop) ||
        (mytop > otherbottom) ||
        (myright < otherleft) ||
        (myleft > otherright)) {
        crash = false;
    }
    return crash;
  }
}

function updateGameArea() {
   var x, y;
   for (i = 0; i < myObstacles.length; i += 1) {
        if (myGamePiece.crashWith(myObstacles[i])) {
            myGameArea.stop();
            return;
        }
    }

    myGameArea.clear();
    myGameArea.frameNo += 1;

    if (myGameArea.frameNo == 1 || everyinterval(150)) {
        x = myGameArea.canvas.width;
        y = myGameArea.canvas.height - 500;
        myObstacles.push(new component(30, 30, "feesh.png", x, y, "image"))
    }

    for (i = 0; i < myObstacles.length; i += 1) {
        myObstacles[i].x += -1;
        myObstacles[i].update();
    }

    myGamePiece.speedX = 0;
    myGamePiece.speedY = 0;
        if (myGameArea.key && myGameArea.key == 37) {myGamePiece.speedX = -5; }
        if (myGameArea.key && myGameArea.key == 39) {myGamePiece.speedX = 5; }
        if (myGameArea.key && myGameArea.key == 38) {myGamePiece.speedY = -5; }
        if (myGameArea.key && myGameArea.key == 40) {myGamePiece.speedY = 5; }
    myBackground.speedX = -1;
    myBackground.newPos();    
    myBackground.update();
    
    myGamePiece.newPos();    
    myGamePiece.update();
  
}

function everyinterval(n) {
    if ((myGameArea.frameNo / n) % 1 == 0) {return true;}
    return false;
}
1
pcmila 3 mar. 2021 a las 07:26

1 respuesta

La mejor respuesta

Sobre la base del comentario de @ AHaworth:

¡debe tener cuidado con el orden en que se dibujan las cosas!

El problema que veo en su código está en function updateGameArea() el fondo debe estar en la parte superior de las cosas que hace, vea mi solución a continuación.

var myGamePiece;
var myObstacles = [];
var myBackground;

function startGame() {
  myGamePiece = new component(50, 50, "red", 10, 60, "rect");
  myBackground = new component(1600, 400, "blue", 0, 0, "rect");
  myGameArea.start();
}

function updateGameArea() {
  myGameArea.clear();
  myGameArea.frameNo += 1;

  myBackground.speedX = -1;
  myBackground.newPos();
  myBackground.update();

  if (myGameArea.frameNo == 1 || everyinterval(150)) {    
    myObstacles.push(new component(30, 30, "pink", myGameArea.canvas.width, 50, "rect"))
  }
  for (i = 0; i < myObstacles.length; i += 1) {
    myObstacles[i].x += -0.5;
    myObstacles[i].update();
  }

  myGamePiece.speedX = 0;
  myGamePiece.speedY = 0;
  myGamePiece.newPos();
  myGamePiece.update();
}

//board
var myGameArea = {
  canvas: document.createElement("canvas"),
  start: function() {
    this.canvas.width = 400;
    this.canvas.height = 150;
    this.context = this.canvas.getContext("2d");
    document.body.insertBefore(this.canvas, document.body.childNodes[0]);
    this.frameNo = 0;
    this.interval = setInterval(updateGameArea, 20);    
  },
  clear: function() {
    this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
  }
}

function component(width, height, color, x, y, type) {
  this.width = width;
  this.height = height;
  this.speedX = 0;
  this.speedY = 0;
  this.x = x;
  this.y = y;
  this.update = function() {
    ctx = myGameArea.context;
    ctx.fillStyle = color;
    ctx.fillRect(this.x, this.y, this.width, this.height);
  }
  this.newPos = function() {
    this.x += this.speedX;
    this.y += this.speedY;   
  }
}

function everyinterval(n) {
  return ((myGameArea.frameNo / n) % 1 == 0)
}

startGame()

Reduje gran parte de su código para obtener un fragmento de trabajo, debe hacer lo mismo cuando publique una pregunta, eso lo ayudará a concentrarse en el error el 90% del tiempo, lo solucionará antes de publicar una pregunta y también ayudará a otros a depurar su código .

Si se lo toma en serio, use un motor de juego, hay muchos buenos de código abierto: https://github.com/collections/javascript-game-engines

0
Helder Sepulveda 3 mar. 2021 a las 16:39