Добавим в конфиг тетриса набор начальных координат для всех этих фигур:
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 комментариев