bugfix> javascript > 投稿

Repl.itを使用してJavascriptでゲームを作成しようとしていますが、数秒ごとにプレーヤーの画像がちらつきます。なぜこれが起こっているのか理解できませんか?いくつかの画像をキャンバスに読み込んでいますが、追加するとちらつきが始まりました animate() 機能し、画像の変更を開始しました。誰かがこれを説明できますか? (このWebサイトにアクセスして、ちらつきを確認し、ゲームもプレイしてください。https://advanced-chrome-dino-game.isaacroot.repl.co/)私のコード:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var ground_size = 75;
var up = false;
var game_over = false;
const start_speed = 8;
var score = 0;
function randBetween(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min);
}
class Player {
  constructor(x_pos) {
    this.color = "black";
    this.image = "dino_1.png"
    this.img = new Image();
    this.width = 120;
    this.height = 120;
    this.x = x_pos;
    this.y = c.height - ground_size - this.height;
    this.speed = 0;
    this.jump_power = 22.5;
    this._gravity = 1;
    this.an_time = 7;
    this.an_count = 0;
  }
  ground_height() {
    return c.height - ground_size - this.height;
  }
  on_ground() {
    if (this.y == this.ground_height()) {
      return true;
    } else {
      return false;
    }
  }
  jump() {
    if (this.on_ground()) {
      this.speed = this.jump_power;
      this.image = "dino_jump.png";
    }
  }
  gravity() {
    this.speed -= this._gravity;
  }
  animate() {
    if (this.an_count <= 0) {
      if (this.image == "dino_1.png") {
        this.image = "dino_2.png";
      } else {
        if (this.image == "dino_2.png") {
          this.image = "dino_1.png"
        }
      }
      this.an_count = this.an_time;
    } else {
      this.an_count -= 1;
    }
  }
  react() {
    this.y -= this.speed
    if (this.y > this.ground_height()) {
      this.y = this.ground_height();
      this.speed = 0;
    }
    if (this.on_ground() && this.image == "dino_jump.png") {
      this.image = "dino_1.png"
    }
  }
  rect() {
    return [this.x, this.y, this.width, this.height]
  }
}
class Obstacle {
  constructor(x_pos, speed) {
    this.color = "red";
    this.img = new Image();
    this.img.src = "cactus_big.png";
    this.width = 52 * 1.5;
    this.height = 75 * 1.5;
    this.x = x_pos;
    this.y = c.height - ground_size - this.height;
    this.speed = speed;
  }
  ground_height() {
    return c.height - ground_size - this.height;
  }
  on_ground() {
    if (this.y == this.ground_height()) {
      return true;
    } else {
      return false;
    }
  }
  react() {
    if (this.x <= 0 - this.width) {
      this.x = randBetween(c.width, c.width + 500);
    }
    this.x -= this.speed;
  }
  rect() {
    return [this.x, this.y, this.width, this.height]
  }
}
player = new Player(75);
obstacle1 = new Obstacle(c.width, start_speed);
function inRect(rect1, rect2) {
  var rect1_left = rect1[0];
  var rect1_right = rect1[0] + rect1[2];
  var rect1_top = rect1[1];
  var rect1_bottom = rect1[1] + rect1[3];
  var rect2_left = rect2[0];
  var rect2_right = rect2[0] + rect2[2];
  var rect2_top = rect2[1];
  var rect2_bottom = rect2[1] + rect2[3];
  var horizontal = false;
  var vertical = false;
  if (rect1_right > rect2_left && rect2_right > rect1_left) {
    horizontal = true;
  }
  if (rect1_bottom > rect2_top && rect2_bottom > rect1_top) {
    vertical = true;
  }
  return (vertical && horizontal);
}
function draw() {
  ctx.beginPath();
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, c.width, c.height);
  ctx.fillStyle = "#4b4b4b";
  ctx.fillRect(0, c.height - ground_size, c.width, c.height);
  ctx.fillStyle = player.color;
  // ctx.fillRect(player.x, player.y, player.width, player.height);
  player.img.src = player.image;
  ctx.drawImage(player.img, player.x, player.y, player.width, player.height)
  ctx.fillStyle = obstacle1.color;
  // ctx.fillRect(obstacle1.x, obstacle1.y, obstacle1.width, obstacle1.height);
  ctx.drawImage(obstacle1.img, obstacle1.x, obstacle1.y, obstacle1.width, obstacle1.height)
  ctx.fillStyle = "black";
  ctx.font = "30px Arial";
  ctx.fillText("Score: " + Math.round(score / 25).toString(), 20, 50);
  if (game_over) {
    ctx.font = "80px Arial";
  }
  ctx.stroke();
}
document.addEventListener('keydown', (event) => {
  if (event.key == 'ArrowUp' || event.key == 'Spacebar') {
    up = true;
  } else if (event.key == 'ArrowDown') {
    //pass
  }
});
document.addEventListener('keyup', (eventt) => {
  if (eventt.key == 'ArrowUp') {
    up = false;
  } else if (event.key == 'ArrowDown') {
    //pass
  }
});
function update_speed() {
  obstacle1.speed += 0.001;
}
function run() {
  if (up == true) {
    player.jump()
  }
  player.gravity();
  player.react();
  player.animate();
  obstacle1.react();
  if (inRect(player.rect(), obstacle1.rect())) {
    game_over = true
  }
  score += obstacle1.speed
  draw();
  update_speed();
  if (game_over == false) {
    requestAnimationFrame(run);
  }
}
run();

回答 2 件
  • コードを確認したところ、毎回画像をに読み込んでいることがわかりました。 player.img 変数。

    function createImage(path){
      let image = new Image();
      image.src = path;
      return image;
    }
    var images = {
      dino:[
        createImage("dino_1.png"),
        createImage("dino_2.png"),
        createImage("dino_jump.png")
      ],
      cactus:createImage("cactus_big.png")
    }
    
    

    ここで私のコードを使用する場合は、代わりにそれらの画像を使用するようにコードを変更する必要があります。これで、描画するたびに画像が読み込まれるようになりました。このように、すべての画像が保存され、ちらつきがなくなり、試してみました。

  • さて、あなたがしなければならないのは、画像をプリロードして、index.htmlが次のようになるようにすることだけです。

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <title>Block Runner</title>
        <link href="style.css" rel="stylesheet" type="text/css" />
        <link rel="preload" href="cactus_big.png" as="image">
        <link rel="preload" href="dino_1.png" as="image">
        <link rel="preload" href="dino_2.png" as="image">
        <link rel="preload" href="dino_jump.png" as="image">
        <link rel="preload" href="ground.png" as="image">
      </head>
      <body>
        <canvas id="myCanvas" width="900" height="600" style="border:0px solid #d3d3d3;">
            Your browser does not support the HTML5 canvas tag.</canvas>
        <script src="script.js"></script>
      </body>
    </html>
    
    

    ちらつかないようにする必要があります。

あなたの答え