0

所以我一直在寻找我下载的游戏的脚本。我不确定的是Bullet(I)永远不会在脚本中实例化(即 var x = new Bullet)。不过,本教程将其称为构造函数。到底是怎么回事?

看起来 Bullet 构造函数正在接受一个参数并向其添加属性等。但是脚本中没有任何地方实例化过 Bullet - 所以它不可能吗?

var playerBullets = [];

    function Bullet(I) {
      I.active = true;
      I.xVelocity = 0;
      I.yVelocity = -I.speed;
      I.width = 3;
      I.height = 3;
      I.color = "#000";

      I.inBounds = function() {
        return I.x >= 0 && I.x <= CANVAS_WIDTH &&
          I.y >= 0 && I.y <= CANVAS_HEIGHT;
      };

      I.draw = function() {
        canvas.fillStyle = this.color;
        canvas.fillRect(this.x, this.y, this.width, this.height);
      };

      I.update = function() {
        I.x += I.xVelocity;
        I.y += I.yVelocity;

        I.active = I.active && I.inBounds();
      };

      I.explode = function() {
        this.active = false;
        // Extra Credit: Add an explosion graphic
      };

      return I;
    }

此代码稍后在脚本中使用,据我所知,这必须是使用 Bullet(I) 函数的脚本的相关部分?

playerBullets.forEach(function(bullet) {
    bullet.update();
});
4

3 回答 3

2

我个人不会将其称为通常意义上的构造函数,正如您正确指出的那样,您会像var myBullet = new Bullet().

然而,它确实通过使用 javascripts 松散类型能够在运行时向对象添加属性和方法来完成类似的“构造”和对象工作。这种方法可以像这样使用:

var myBullet = {}; // blank object
Bullet(myBullet);
// myBullet now has methods .draw, .active etc

我发现您下载的代码来自本教程Bullet,并且确实在 index.html 的第 167 行调用了该方法。它在玩家射击时配置子弹:

player.shoot = function() {
      Sound.play("shoot");

      var bulletPosition = this.midpoint();

      playerBullets.push(Bullet({ //<-- here
        speed: 5,
        x: bulletPosition.x,
        y: bulletPosition.y
      }));
    };
于 2013-05-30T09:43:12.950 回答
2

Bullet 似乎将一个(可能是空的)对象作为参数,然后将其转换为 Bullet“类”的对象(是的,我知道 javascript 没有类,但你知道我的意思)。我怀疑这样做的原因是为了确保对象被重用而不是被创建和销毁。这意味着更少的垃圾收集发生,因此游戏运行更流畅

于 2013-05-30T09:44:59.010 回答
1

看起来,它需要一个 - 可能 - 对象,即“I”,作为输入,并将东西附加到它并返回它。无需实例化 Bullet 本身。您只需要适当的 I(nput) 对象。充其量它应该被称为“构建器函数”之类的东西。

于 2013-05-30T09:43:39.037 回答