【问题标题】:jQuery object constructor - method recalling itselfjQuery 对象构造函数 - 调用自身的方法
【发布时间】:2014-06-22 04:53:03
【问题描述】:

我正在为学校构建一个 Jquery 游戏,我试图通过在函数末尾放置一个 setTimeout() 来让 create() 在运行该方法时重新调用它自己 (我使用 setTimeout 是因为 addEnemySpeed 是随机生成的,因此它每次都会更改)但它不起作用该方法仅从被调用到启动 (smallEnemy.create()) 运行一次但从不回忆自己?我希望这只是我的一个简单的疏忽?在此先感谢您的帮助。 干杯。

// OBSTACLE OBJECT CONSTRUCTOR //

function Obstacle(type, className, speed, startHealth, currentHealth, damageCause) {
  this.type = type;
  this.className = className;
  this.speed = speed;
  this.endX = -160;
  this.startHealth = startHealth;
  this.currentHealth = currentHealth;
  this.damageCause = damageCause;
  this.create = function(type, endX, speed) {
    type = this.type;
    endX = this.endX;
    speed = this.speed;
    var $obstacle = $('<div>');
    // if the obstacle is a enemy add enemies class
    if (type == 'smallEnemy' || type == 'bigEnemy') {
      $obstacle.addClass('enemies');
    }
    // add correct class name
    $obstacle.addClass(type);
    // add obstacle to playground
    $('#playGround').append($obstacle);
    // animate obstacle down x axis remove if hits destination
    $obstacle.transition({
      x: endX
    }, speed, 'linear', function() {
      $(this).remove();
    });
    setTimeout(this.create,addEnemySpeed);
  };
}

smallEnemy.create()

【问题讨论】:

  • 您希望this.create 重复多少次?
  • 首先,当this.createsetTimeout() 调用时,this 的值将不正确。你可以改用setTimeout(this.create.bind(this), addEnemySpeed)。
  • @AminJafari 我需要它继续不断地调用自己,直到我不再想要它为止。游戏在计时器上运行,并且一个大的 if else-if 语句控制它,例如:假设计时器在 100 到 80 之间,我将以随机速度创建一种类型的障碍物,那么如果计时器在 80 到 60 之间,我将创造另一种类型的障碍等等等等谢谢你的帮助
  • @jfriend00 谢谢!!这正是我想要的。
  • 既然您正在学习,您可能想知道如何使用原型、如何使用闭包以及this 是什么:stackoverflow.com/a/16063711/1641941

标签: javascript jquery methods prototype


【解决方案1】:

你试过这个吗:

function Obstacle(type, className, speed, startHealth, currentHealth, damageCause) {
  this.type = type;
  this.className = className;
  this.speed = speed;
  this.endX = -160;
  this.startHealth = startHealth;
  this.currentHealth = currentHealth;
  this.damageCause = damageCause;
  this.create = function(type, endX, speed) {
    type = this.type;
    endX = this.endX;
    speed = this.speed;
    var $obstacle = $('<div>');
    // if the obstacle is a enemy add enemies class
    if (type == 'smallEnemy' || type == 'bigEnemy') {
      $obstacle.addClass('enemies');
    }
    // add correct class name
    $obstacle.addClass(type);
    // add obstacle to playground
    $('#playGround').append($obstacle);
    // animate obstacle down x axis remove if hits destination
    $obstacle.transition({
      x: endX
    }, speed, 'linear', function() {
      $(this).remove();
    });
    var that=this; //this is how you can use "this" element in a function
    setTimeout(function(){that.create;},addEnemySpeed);
  };
}

smallEnemy.create()

【讨论】:

  • 你试过了吗?它不起作用,因为您仍然将函数作为引用传递,而不是作为闭包或绑定函数。以下答案解释了 this 在 JavaScript 中的含义以及如何使用原型:stackoverflow.com/a/16063711/1641941 您将其设置为 this,因此可能想要传递一个闭包,那么正确的代码是:setTimeout(function(){ that.create;},addEnemySpeed);
【解决方案2】:

这不是原型。相反,它是一个构造函数。当你创建一个新的障碍时,你会想打电话给var foo = new Obstacle(...);

function Obstacle(type, className, speed, startHealth, currentHealth, damageCause) {

  // private vars
  var timeout,
      endX = -160;

  // private methods
  function create(addEnemySpeed) {
    var $obstacle = $('<div>');

    // if the obstacle is a enemy add enemies class
    if (type == 'smallEnemy' || type == 'bigEnemy') {
      $obstacle.addClass('enemies');
    }

    // add correct class name
    $obstacle.addClass(type);

    // add obstacle to playground
    $('#playGround').append($obstacle);

    // animate obstacle down x axis remove if hits destination
    $obstacle.transition({x: endX}, speed, 'linear', function() {
      $(this).remove();
    });

    timeout = setTimeout(create, addEnemySpeed);
  }

  // I added this method so you can stop spawning this obstacle if you want
  function stop() {
    if (timeout) {
      clearTimeout(timeout);
      timeout = null;
    }
  }

  // public api (exports)
  this.type           = type;
  this.className      = className;
  this.speed          = speed;
  this.startHealth    = startHealth;
  this.currentHealth  = currentHealth;
  this.damageCause    = damageCause;

  this.create         = create;
  this.stop           = stop;
}

好的,让我们现在使用它

var smallEnemy = new Obstacle(...);

// Spawn a new enemy of this type ever 5 seconds
// Don't forget to pass addEnemySpeed
// (addEnemySpeed was undefined in your code)
smallEnemy.create(5000);

可选:当你想停止产卵时调用stop

smallEnemy.stop();

作为旁注,您可能需要考虑定义一些默认值并将对象传递给构造函数。这样你就不需要将 6 个有序的参数传递给构造函数(我认为这是相当多的)。

new Obstacle({type: "foo", speed: 100});

对未在对象中设置的任何键恢复默认值。如果这是您的选择,您会比我更清楚。只是想我会提到它。

【讨论】:

  • 非常感谢您的彻底回答,上个月刚开始使用 javascript/jquery,因此尝试尽可能多地接受这些帮助。肯定会接受您对默认值的建议,因为事实证明 6 个参数很难记住顺序,并且非常感谢 stop 方法的帮助。干杯。
猜你喜欢
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-02
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多