2013-03-16 3 views
1

Я пишу проект класса (мы должны построить игру Frogger с использованием холста HTML5), и у меня есть множество объектов, которые помогут мне с разными вещами, такими как обнаружение столкновений, движение и т. Д. ,Значение объекта Javascript не получает правильное значение

Этот объект является одним из тех, кто здесь. Каждый вид содержит объект Frame, который содержит вызов функции hitTest, который проверяет, сталкивается ли его кадр с переданным в кадре. По какой-то причине this.lr сохраняет значение, которое первоначально было установлено в начале игры, и я не могу понять, почему он не обновляется на основе меняющейся исходной точки.

function Frame(origin, size) { 
    this.origin = utility.checkPoint(origin); 
    this.size = utility.checkSize(size); 
    var self = this; 

    this.lr = (function() { 
     return utility.checkPoint(new Point(self.origin.x + self.size.width, self.origin.y + self.size.height)); 
    }()); 

    this.tr = (function() { 
     return utility.checkPoint(new Point(self.origin.x + self.size.width, self.origin.y)); 
    }()); 

    this.ll = (function() { 
     return utility.checkPoint(new Point(self.origin.x, self.origin.y + self.size.height)); 
    }()); 

    /* Returns true if the two frames share any common pixels */ 

    this.hitTest = function (frame) { 
     var isInXBounds = function (p) { 
      return (p.x >= self.origin.x && p.x <= self.tr.x); 
     }; 

     var isInYBounds = function (p) { 
      return (p.y >= self.origin.y && p.y <= self.lr.y); 
     }; 

     var isContained = function (p) { 
      return (isInXBounds(p) && isInYBounds(p)); 
     }; 

     return isContained(frame.origin) || isContained(frame.tr) || isContained(frame.lr) || isContained(frame.ll); 
    }; 
} 

ответ

1

Вы сразу выполнение функции

this.lr = (function() { 
    return utility.checkPoint(new Point(self.origin.x + self.size.width, self.origin.y + self.size.height)); 
}()); 

В результате Л.Р. в настоящее время присваивается значение прямо на этом месте, и никогда не меняется.

То, что вы хотите, это просто:

this.lr = function() { 
    return utility.checkPoint(new Point(self.origin.x + self.size.width, self.origin.y + self.size.height)); 
}; 

Это определяет Л.Р. как метод, который можно назвать по мере необходимости в будущем.

+0

Так с помощью замыкания немедленно выполняет эту функцию? это не круто. Что произойдет, если я вызову Frame.lr в другом месте? Всегда ли оно возвращает только то, что первоначально было присвоено ему? Я чувствую, что это одна из тех неприятностей javascript – barndog

+0

@shadow - Это не помеха. Это просто, что вы используете неправильный шаблон для создания своего класса. –

+0

Хмм хорошо. Это нормально, что все мои объекты написаны с использованием шаблонов закрытия, если мои внутренние функции для этого объекта являются методами? – barndog

2

Это, как я хотел бы написать свой Frame класс:

Frame.prototype.lr = function() { 
    var x = this.origin.x + this.size.width; 
    var y = this.origin.y + this.size.height; 
    return utility.checkPoint(new Point(x, y)); 
}; 

Frame.prototype.tr = function() { 
    var x = this.origin.x + this.size.width; 
    return utility.checkPoint(new Point(x, this.origin.y)); 
}; 

Frame.prototype.ll = function() { 
    var y = this.origin.y + this.size.height; 
    return utility.checkPoint(new Point(this.origin.x, y)); 
}; 

Frame.prototype.isContained = function (point) { 
    var isInXBounds = point.x >= this.origin.x && point.x <= this.tr().x; 
    var isInYBounds = point.y >= this.origin.y && point.y <= this.lr().y; 
    return isInXBounds && isInYBounds; 
}; 

Frame.prototype.hitTest = function (frame) { 
    return this.isContained(frame.origin) || this.isContained(frame.tr) || 
      this.isContained(frame.lr) || this.isContained(frame.ll); 
}; 

function Frame(origin, size) { 
    this.origin = utility.checkPoint(origin); 
    this.size = utility.checkSize(size); 
} 

прототипичного наследство может быть довольно сложным для человека, который приходит от классического фона. Вот простое объяснение для прототипного наследования: https://stackoverflow.com/a/8096017/783743

Существует множество библиотек, которые помогают классическим программистам работать с JavaScript. Например, моя собственная библиотека augment. Вот как вы написали бы выше класс, используя augment:

var Frame = Object.augment(function() { 
    this.constructor = function (origin, size) { 
     this.origin = utility.checkPoint(origin); 
     this.size = utility.checkSize(size); 
    } 

    this.lr = function() { 
     var x = this.origin.x + this.size.width; 
     var y = this.origin.y + this.size.height; 
     return utility.checkPoint(new Point(x, y)); 
    }; 

    this.tr = function() { 
     var x = this.origin.x + this.size.width; 
     return utility.checkPoint(new Point(x, this.origin.y)); 
    }; 

    this.ll = function() { 
     var y = this.origin.y + this.size.height; 
     return utility.checkPoint(new Point(this.origin.x, y)); 
    }; 

    this.isContained = function (point) { 
     var isInXBounds = point.x >= this.origin.x && point.x <= this.tr().x; 
     var isInYBounds = point.y >= this.origin.y && point.y <= this.lr().y; 
     return isInXBounds && isInYBounds; 
    }; 

    this.hitTest = function (frame) { 
     return this.isContained(frame.origin) || this.isContained(frame.tr) || 
       this.isContained(frame.lr) || this.isContained(frame.ll); 
    }; 
}); 

Кроме того, поскольку вы хотите знать, что закрытие на самом деле я предлагаю вам прочитать следующий ответ: https://stackoverflow.com/a/12931785/783743

+0

Спасибо большое! Вам не нужно было проходить всю эту работу только для этого, но это здорово, что вы это сделали. Мне очень нравятся оба стиля написания объектов, но один из них действителен, чем другой, или может использоваться как взаимозаменяемо? – barndog

+0

Оба могут использоваться взаимозаменяемо, но я предпочитаю использовать второй метод. Библиотека «augment» небольшая, но имеет множество полезных функций. –

+0

О, я имел в виду образец прототипа против моей навязчивой идеи ... ха-ха, которая сразу же выполняет функцию. – barndog

Смежные вопросы