Добавим в конфиг тетриса набор начальных координат для всех этих фигур:
var Tetris = {
config: {
// ...
figureTypes: {
I: [
[[-3,5]],
[[-2,5]],
[[-1,5]],
[[ 0,5]]
],
J: [
[[-2,6]],
[[-1,6]],
[[0,5],[0,6]]
],
L: [
[[-2,5]],
[[-1,5]],
[[0,5],[0,6]]
],
O: [
[[-1,5],[-1,5]],
[[ 0,5], [0,6]]
],
S: [
[[-1,6],[-1,7]],
[[0,5], [0,6]]
],
T: [
[[-1,5],[-1,6],[-1,7]],
[[0,6]]
],
Z: [
[[-1,4],[-1,5]],
[[0,5], [0,6]]
]
}
},
// ...
}В методе создания фигуры будем брать случайную фигуру из набораfigure: {
// ...
create: function() {
this.coords = this.getRandomFigure();
},
// ...
}Метод getRandomFigure будет возвращать координаты случайно выбранной фигурыfigure: {
// ...
getRandomFigure: function() {
var keys = Object.keys(Tetris.config.figureTypes);
var randKey = Math.floor(Math.random() * keys.length);
return Tetris.config.figureTypes[keys[randKey]];
},
// ...
}Так как у нас есть высокие фигуры и отрицательные координаты могут продержаться дольше одного тика, могут возникнуть ошибки при попытке проверить блок с отрицательной координатой на пустоту.Чтобы избежать этой ошибки, допишем проверку в методе touched
touched: function() {
var contact = false;
Tetris.each(this.coords, function(i,j){
var figureRow = Tetris.figure.coords[i][j][0];
// Здесь (figureRow >= 0)
if (figureRow >= 0 && Tetris.pitch.bricks[figureRow + 1] == undefined) {
contact = true;
}
});
if (contact) {
return contact;
}
Tetris.each(this.coords, function(i,j){
var figureRow = Tetris.figure.coords[i][j][0];
var figureCol = Tetris.figure.coords[i][j][1];
// И здесь (figureRow >= 0)
if (figureRow >= 0 && Tetris.pitch.bricks[figureRow + 1][figureCol]) {
contact = true;
}
});
if (contact) {
return contact;
}
return false;
}Когда я запустил этот код, сначала обрадовался — фигурки начали падать, появлялись разные фигурки, их соприкосновения обрабатывались корректно, но где-то на середине процесс останавливался (хотя тики продолжали идти).
И тут я вспомнил, что в JavaScript объекты, в отличие от остальных типов (строк, чисел и пр.) передаются в функцию по ссылке. Соответственно, меняя координаты фигуры, мы меняли их в объекте Tetris.config.figureTypes. И при создании новой фигуры координаты ей присваивались не из конфига, а новые, изменённые. В итоге, фигура появлялась поверх предыдущей с таким же типом.
Выхода из такой ситуации я знаю два. Первый — это склонировать объект, а второй — превратить объект в функцию, которая будет возвращать нужное значение.
Я выбрал второй вариант. Получилось немного монструозно — из-за того, что я хотел сохранить силуэт фигур в конфиге, но работает исправно.
// ...
figureTypes: {
I: function() {
return [
[[-3,5]],
[[-2,5]],
[[-1,5]],
[[ 0,5]]
];
},
J: function() {
return [
[[-2,6]],
[[-1,6]],
[[0,5],[0,6]]
];
},
L: function() {
return [
[[-2,5]],
[[-1,5]],
[[0,5],[0,6]]
];
},
O: function() {
return [
[[-1,5],[-1,6]],
[[ 0,5], [0,6]]
];
},
S: function() {
return [
[[-1,6],[-1,7]],
[[0,5], [0,6]]
];
},
T: function() {
return [
[[-1,5],[-1,6],[-1,7]],
[[0,6]]
];
},
Z: function() {
return [
[[-1,4],[-1,5]],
[[0,5], [0,6]]
];
}
}
// ...Вот итоговый код этого урока: http://jsfiddle.net/ilyautkin/aavju3jd/13/
Объектная
0 комментариев