2013-09-20 4 views
0

В настоящее время я работаю над движком платформы, используя javascript и холст HTML5.Расширение javascript объекта

У меня есть объект, «платформа», которая выглядит примерно так ...

var platform = function(pid,px,py,pw,ph) { 
    //Some variables here... and then we have some functions  
    this.step = function() { 
    //Update/step events here 
    } 
    this.draw = function() { 
    //Drawing events here 
    } 
    //etc. 
} 

Функция шаг() имеет все расчеты для обнаружения столкновений в то время как функция Жеребьевка() рисует платформу.

Что я хочу сделать, это сделать еще один объект под названием movingPlatform. Это будет почти идентично текущей платформе, за исключением того, что этот движется.

Вместо копирования всех кодов обнаружения столкновений я хотел бы иметь возможность расширить movingPlatform с платформы ... и затем иметь возможность добавить дополнительный код в функцию step() на движущуюся платформу. хорошо ... двигаться.

Некоторая дополнительная информация ...

Когда игра загружается, он генерирует уровень, используя данные из файла CSV. У меня есть массив, платформы [], который хранит все платформы внутри него.

Так, чтобы создать платформу это выглядит так ...

platforms.push(new platform(i,data[1],data[2],data[3],data[4])); 

Я тогда сделать платформы выполнить их шаг и сделать событие во время основного этапа игры и рисовать события.

т.е.

for(var i=0; i<platforms.length; i++) { 
platforms[i].step(); 
} 

Любая помощь будет удивительным. Благодаря!

+1

Читайте о «наследовании прототипов» в JavaScript. – elclanrs

+0

По соглашению функции конструктора (т. Е. Те, которые вы называете «новыми») должны быть капитализированы. –

+0

@elclanrs Прототипирование этого, возможно, не может идти. По крайней мере, не в истинном стиле JS: 'var platform_instance = новая платформа (текстура, x, y, ширина, высота); MovingPlatform.prototype = platform_instance; var mPlatform = new MovingPlatform(); '. Все они будут иметь одинаковые текстуры, координаты и т. Д.Расширение прототипа объекта-конструктора, если вы можете гарантировать, что все соответствующие свойства объекта являются общедоступными, конечно, это отличная память. Но «наследование» посредством создания всех дочерних экземпляров совместно с прототипом одного родительского экземпляра здесь не помогает. – Norguard

ответ

2

Я бы использовал класс платформы как «базовый» объект для движущегося объекта платформы. Я бы сделал это через прототип, который является реализацией JavaScript объектно-ориентированного программирования.

Подробнее здесь How does JavaScript .prototype work? + еще много статей в Интернете

+0

Спасибо за рекомендацию и ссылку, я проверю это –

0

Вы можете использовать Javascript функциональность наследования прототип:

var baseItem = { 
    push: function(){alert('push');}, 
    pull: function(){alert('pull')} 
} 

var childItem = {} 
childItem.prototype = baseItem; 

childItem.push = function(){ 
    //call base function 
    childItem.prototype.push.call(this); 

    //do your custom stuff. 
    alert('I did it again.'); 
} 

childItem.push(); 

Fiddle

+0

Aha, спасибо за отличный пример, он неплохо очищает прототипы. –

+0

Или просто используйте прототип, который поставляется с функциями-конструкторами: http://stackoverflow.com/a/16063711/1641941 Литералы объектов не имеют прототипа, поэтому они не автоматически наследуют методы, которые вы не хотите переопределять, вызывая снова объявить все эти методы в Ребенке, чтобы вручную вызвать его родительский. Прототип функций конструктора также оптимизирован для поиска методов в большинстве JS-движков. – HMR

+0

@AndrewNatoli Нет, он не проясняет прототипирование, вы также можете определить наследование как 'childItem.santaclaus = baseItem' на самом деле; он не имеет ничего общего с объектом-прототипом, который имеет функции javascript. – HMR

0

Получение права наследования в JavaScript, несколько сложнее, если вам 'используется для языков на основе классов.

Если вы не используете много способов поведения, вам может быть проще просто создать некоторые общие методы, а затем сделать их доступными для объектов каждого типа платформы.

//Create constructors for each type 
var Platform = function(pid,px,py,pw,ph) { //By convention, constructors should start with an uppercase character 
    ... 
} 

var MovingPlatform = function() { 
    ... 
} 

//Create some reuseable methods 
var step = function() { 
    ... 
} 
var draw = function() { 
    ... 
} 
var move = function() { 
    ... 
} 

//Attach your methods to the prototypes for each constructor 
Platform.prototype.step = step; 
Platform.prototype.draw = draw; 

MovingPlatform.prototype.step = step; 
MovingPlatform.prototype.draw = draw; 
MovingPlatform.prototype.move = move; 

...etc 

Тем не менее, если вы хотите создать правильную цепочку наследования, есть множество статей, которые помогут вам: 1234

+0

Это похоже, что это лучший метод для того, что я пытаюсь сделать ... Я дам ему попробовать завтра, спасибо! –

+0

Обратите внимание, что этот подход обычно более подходит для ситуаций, когда вы хотите добавить базовый метод утилиты к группе типов объектов. В таких ситуациях, как ваша, где у вас есть иерархия типов, чище использовать правильную цепочку наследования, так что вам будет хорошо служить, чтобы время дочитать, как она работает. – ThinTim

+0

На самом деле я бы рекомендовал вам проигнорировать мой ответ и прочитать ссылки, приведенные в других ответах здесь, и в нижней части моего ответа, прежде чем принимать решение. Решение, которое я дал, будет работать и его легко понять, но его труднее расширить и поддерживать в будущем и не отражает логическую иерархию ваших объектов. – ThinTim

0

Вместо чистого наследования, здесь, я бы идти с прототипом-расширением, если вы не построите какую-то большую уродливую фабрику, просто ради того, чтобы сказать, что «MovingPlatform» унаследована от «Платформы» в чистом смысле, на самом деле это не так, как вы ожидали.

Есть несколько проблем (обман, для одного), но если ваши объекты полностью основаны на this, и вы в порядке с людьми, потенциально взломанными в консоли, тогда вам действительно нечего беспокоюсь о.

Во-первых, понять, что вы делаете внутри Platform:

var MyObject = function (a) { 
    this.property = a; 
    this.method = function (b) { this.property += b; }; 
}; 

Каждый раз, когда вы делаете новый MyObject, вы создаете новую версию функции .method.
То есть, если вы сделаете 10 000 из них, будет также 10 000 копий этой функции.
Иногда это очень хорошая и безопасная вещь.
Это также может быть очень медленная вещь.

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

... так:

MyObject = function (a) { 
    this.property = a; 
}; 
MyObject.prototype.method = function (b) { this.property += b; }; 

var o = new MyObject(1); 
o.method(2); 
o.property; //3 

Когда вы звоните new X, где X имеет свойства/методы по своему прототипу, те свойства/методы копируются на объект, во время его строительства.

Было бы так же, как происходит:

var method = function (b) { this.property += b; }, 
    o = new MyObject(1); 

o.method = method; 
o.method(2); 
o.property; // 3 

За исключением без дополнительной работы делать это самостоятельно, вручную.
Преимущества здесь в том, что каждый объект использует ту же функцию.
Они в основном передают функции доступ ко всему их this, и функция может делать с ней все, что захочет.

Там подвох:

var OtherObj = function (a, b) { 
    var private_property = b, 
     private_method = function() { return private_property; }; 

    this.public_property = a; 
    this.unshared_method = function() { var private_value = private_method(); return private_value; }; 
}; 

OtherObj.prototype.public_method = function() { 
    return private_property; 
}; 

var obj = new OtherObj(1, "hidden"); 

obj.public_property; // 1 
obj.unshared_method(); // "hidden" 
obj.public_method(); // err -- private_property doesn't exist 

Так если вы не имеете много вы заботитесь о пребывании частных, самый простой способ сделать это было бы сделать многоразовую функцию, которая полагается на this, который затем предоставить несколько прототипов через расширение.

// collision-handling 
var testCollision = function (target) { this./*...*/ }, 
    handleCollision = function (obj) { this./* ... */ }; 

// movement-handling 
var movePlatform = function (x, y, elapsed) { this.x += this.speed.x*elapsed; /*...*/ }; 
// not really the cleanest timestep implementation, but it'll do for examples 


var Platform = function (texture, x, y, w, h) { 
     this.x = x; 
     // ... 
    }, 
    MovingPlatform = function (texture, x, y, w, h, speedX, speedY, etc) { 
     this.etc = etc;//... 
    }; 


Platform.prototype.testCollision = testCollision; 
Platform.prototype.handleCollision = handleCollision; 

MovingPlatform.prototype. // both of the above, plus the movePlatform method 

Это очень много.
Именно поэтому функции в разных библиотеках будут clone или extend объектов.

var bunchOfComponents = { 
    a : function() { }, 
    b : 32, 
    c : { } 
}, 

myObj = {}; 

copy(myObj, bunchOfComponents); 

myObj.a(); 
myObj.b; //32 

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

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