我正在学习 freeCodeCamp 的关于飞翔小鸟游戏的教程 https://www.youtube.com/watch?v=pufKO5EG8nc
但我通过课堂来了解更多相关信息。
问题是,图像无法加载,而在视频中加载正常。
我在谷歌上搜索并了解了 onload 事件,并在那里实现了它,但仍然没有任何问题,控制台中也没有错误消息。
即使没有 onload 事件,为什么视频的图像会加载,而我的却没有? >:(
我的 HTML 代码:
<canvas id="canvas" width="512" height="512">
</canvas>
我的 JS 代码:
const canvas = document.querySelector("#canvas");
class Game {
constructor(c) {
this.c = c; //canvas
this.ctx = c.getContext("2d"); // context
this.sprites = 5;
this.loadedSprites = 0;
this.player = new Image(); // define images
this.bg = new Image();
this.fg = new Image();
this.north = new Image();
this.south = new Image();
this.pX = 10; // player starting location
this.pY = 150;
// set sprite locations and load.
this.player.src = "images/crab.png";
this.player.onload = this.draw;
this.bg.src = "images/bg.png";
this.bg.onload = this.draw;
this.fg.src = "images/fg.png";
this.fg.onload = this.draw;
this.north.src = "images/obstacle.png";
this.gap = 80;
this.constant = this.north.height + this.gap;
this.north.onload = this.draw;
this.south.src = "images/obstacle.png";
this.south.onload = this.draw;
}
//draw images
draw() {
this.loadedSprites += 1;
if (this.loadedSprites >= this.sprites) {
this.ctx.drawImage(this.bg, 0, 0);
this.ctx.drawImage(this.north, 100, 0);
this.ctx.drawImage(this.south, 0, 0 + this.constant);
this.ctx.drawImage(this.fg, 0, this.c.height - this.fg.height);
this.ctx.drawImage(this.player, this.pX, this.pY);
}
}
}
let game = new Game(canvas);
答案 0 :(得分:0)
您的问题与范围有关——它指的是变量、对象和函数的可访问性——以及this关键字的含义取决于实际范围.
为了更好地理解,让我们看一下下面的例子:
class Game {
constructor() {
console.log("Game constructor:", this);
this.player = new Image();
this.player.onload = this.draw;
this.player.src = "https://picsum.photos/200/300";
}
draw() {
console.log("draw:", this);
}
}
let game = new Game();
如果您点击“运行代码片段”,您应该会在控制台中看到以下输出:
Game constructor: {}
draw: <img src="https://picsum.photos/200/300"></img>
如您所见,对 draw()
内的 this 的调用不再指同一事物。在第一种情况下,它是 Game 的对象实例(用大括号表示),在第二种情况下,它是 HTMLImageElement 的实例。
所以你的代码失败了,因为:
this.loadedSprites += 1;
if (this.loadedSprites >= this.sprites) {
不要引用 Game 类的私有变量 loadedSprites
和 sprites
- 事实上它根本不引用任何东西,因为它只是在 draw 函数的范围内未定义,因此 {{1} } 永远不会增加。
一种解决方法是使用新属性将 Game 类的上下文传递给每个 Image 实例,例如loadedSprites
。
.reference
并在 draw() 中使用它,例如:
this.player = new Image();
this.player.reference = this;
this.player.onload = this.draw;
以下是基于您的代码的完整示例:
draw() {
this.reference.loadedSprites += 1;
}
const canvas = document.querySelector("#canvas");
class Game {
constructor(c) {
this.c = c; //canvas
this.ctx = c.getContext("2d"); // context
this.sprites = 5;
this.loadedSprites = 0;
this.player = new Image(); // define images
this.player.reference = this;
this.bg = new Image();
this.bg.reference = this;
this.fg = new Image();
this.fg.reference = this;
this.north = new Image();
this.north.reference = this;
this.south = new Image();
this.south.reference = this;
this.pX = 10; // player starting location
this.pY = 150;
// set sprite locations and load.
this.player.onload = this.draw;
this.player.src = "https://picsum.photos/id/237/20/20";
this.bg.onload = this.draw;
this.bg.src = "https://picsum.photos/id/22/20/20";
this.fg.onload = this.draw;
this.fg.src = "https://picsum.photos/id/30/20/20";
this.gap = 80;
this.constant = this.north.height + this.gap;
this.north.onload = this.draw;
this.north.src = "https://picsum.photos/id/37/20/20";
this.south.onload = this.draw;
this.south.src = "https://picsum.photos/id/137/20/20";
}
//draw images
draw() {
let ref = this.reference;
ref.loadedSprites += 1;
if (ref.loadedSprites >= ref.sprites) {
ref.ctx.drawImage(ref.bg, 0, 0);
ref.ctx.drawImage(ref.north, 100, 0);
ref.ctx.drawImage(ref.south, 0, 0 + ref.constant);
ref.ctx.drawImage(ref.fg, 0, ref.c.height - ref.fg.height);
ref.ctx.drawImage(ref.player, ref.pX, ref.pY);
}
}
}
let game = new Game(canvas);