You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Canvas上绘制数组中的多个实体?我的僵尸列表绘制失败

解决ZombieList对象无法全部绘制的问题

我帮你排查了代码里的几个关键问题,咱们一步步来修复:

代码里的核心问题

  • 你在Zombie构造函数里误用了全局的ZombieY变量,而不是实例自己的this.y,这会导致所有僵尸共享同一个Y坐标,移动的时候也会一起动,完全失去了每个僵尸的独立性。
  • 绘制僵尸时,你把X坐标写死成了200,没有使用每个僵尸实例的this.x,就算创建了多个僵尸,它们也会叠在一起显示。
  • 你创建了zombieList数组,但没有在动画循环里遍历这个数组,调用每个僵尸的Update()和Draw()方法——这直接导致这些僵尸根本没被渲染出来。

修正后的完整代码

// 初始化僵尸图片
var FatZombieWikki = new Image();
FatZombieWikki.src = "FatZombieWikki.png";

// 修正后的Zombie构造函数
var Zombie = function(x, y) {
  this.x = x;
  this.y = y; // 使用实例自己的y属性,而不是全局变量
  
  this.Draw = function(ctx) {
    // 使用当前实例的x和y作为绘制坐标
    ctx.drawImage(FatZombieWikki, this.x, this.y, 50, 50);
  }
  
  this.Update = function(){
    // 更新当前实例的y值,每个僵尸独立移动
    if(this.y < 900) {
      this.y += 0.5;
    }
  }
}

// 创建僵尸列表
var zombieList = [];
for (var i = 0; i < 10; i++) {
  // 修正多余的逗号,给每个僵尸不同的初始x坐标
  zombieList.push(new Zombie(40 * i, 100));
}

// 获取canvas上下文(假设你的canvas元素id是"gameCanvas")
var canvas = document.getElementById("gameCanvas");
var ctx = canvas.getContext("2d");

// 动画循环,负责更新和绘制所有僵尸
function gameLoop() {
  // 先清空画布,避免僵尸移动留下残影
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  // 遍历zombieList,逐个更新和绘制僵尸
  zombieList.forEach(function(zombie) {
    zombie.Update();
    zombie.Draw(ctx);
  });
  
  // 循环调用动画帧
  requestAnimationFrame(gameLoop);
}

// 启动游戏循环
gameLoop();

关键改动说明

  1. 实例化属性替代全局变量:把ZombieY全部换成this.y,让每个僵尸拥有自己的位置状态,独立移动和显示。
  2. 动态绘制坐标:绘制时使用this.x和this.y,确保每个僵尸在各自的初始位置生成。
  3. 添加动画循环:通过requestAnimationFrame创建游戏循环,遍历zombieList来更新和绘制每一个僵尸,这是让所有僵尸显示出来的核心步骤。
  4. 修正语法错误:去掉了构造函数调用时多余的逗号,避免潜在的语法问题。

内容的提问来源于stack exchange,提问作者wille771

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:22:00