0

I am in the process of building a Jquery game for school and I am trying to get create() to recall its self when the method is ran by putting a setTimeout() at the end of the function (I am using setTimeout because addEnemySpeed is a random generated so it changes everytime) but it is not working the method only runs once from being called to initiate (smallEnemy.create()) but never recalls itself? I am hoping this is just a simple oversight on my part?? THANKS in advance for the help. CHEERS.

// 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()
VinceBrown
  • 95
  • 1
  • 14
  • how many times do you want `this.create` to be repeated? – Amin Jafari Jun 22 '14 at 04:56
  • For starters, the `this` value won't be correct when `this.create` is called by `setTimeout()`. You can use `setTimeout(this.create.bind(this)`, addEnemySpeed) instead. – jfriend00 Jun 22 '14 at 05:00
  • @AminJafari I need it to keep on continually calling itself until i do not want it to anymore. The game runs on a timer and one big if else-if statement controls it so ex: say if the timer is between 100 and 80 I will be creating one type of obstacle at a random speed then if the timer is between 80 and 60 I will be creating another type of obstacle and so on and so on Thanks for the help – VinceBrown Jun 22 '14 at 05:04
  • Since you're learning you may want to know about how to use prototype, how to use closures and what `this` is: http://stackoverflow.com/a/16063711/1641941 – HMR Jun 22 '14 at 06:04

2 Answers2

2

have you tried this:

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()
Amin Jafari
  • 7,157
  • 2
  • 18
  • 43
  • 1
    Have you tried it? it would not work as you're still passing the function as a reference, not as a closure or bound function. The following answer explains what `this` is in JavaScript and how to use prototype: http://stackoverflow.com/a/16063711/1641941 You're setting that to `this` so probably want to pass a closure, then the correct code would be: setTimeout(function(){that.create;},addEnemySpeed); – HMR Jun 22 '14 at 06:01
0

This isn't a prototype. Rather, it's a constructor. When you create a new obstacle, you will want to call 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;
}

Ok let's put it to use now

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);

Optional: Call stop when you want to stop spawning

smallEnemy.stop();

As a side note, you might want consider defining some defaults and passing an object to the constructor. This way you don't need to pass 6 ordered arguments to the constructor (which I think is quite a bit).

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

Fall back on defaults for any keys that aren't set in the object. You'll know better than me if this is an option for you. Just thought I'd mention it.

maček
  • 76,434
  • 37
  • 167
  • 198
  • thank you very much for the thorough answer,just started javascript/jquery last month so trying to take in as much as possible and answers like these help. Definitely going to take your advice on the defaults because 6 arguments was proving to be tedious to remember order, and really appreciate the help with the stop method. Cheers. – VinceBrown Jun 22 '14 at 05:39