- PVSM.RU - https://www.pvsm.ru -
Чтобы хоть как-то разбавить тенденцию к 30строчникам решил написать достаточно завершенную и, в сравнении с 30lines, объемную реализацию классической игры Asteroids.
Я не буду меряться числом строк или символов кода, т.к. в нем есть [1] и достаточно нормальное оформление и даже комментарии.
Мир игры отрисовывается на canvas, все объекты мира унифицированы, а детектор коллизий использует попиксельный тест. Есть простая озвучка, жизни, godmod на первые секунды после появления, очки, растущая вместе с очками сложность и, конечно, разваливающиеся на куски астероиды :)
Попробовать можно тут [2]. Очень советую Chrome или хотя бы FF.
Для уменьшения объема логики все объекты мира сделаны универсальными, с минимальным разделением в зависимости от конкретного типа. Геометрия объектов хранится в списках вершин, прямо как раньше делали через glBegin(GL_LINES). Для корабля отводится две геометрии (обычная и с пламенем при разгоне) ради все той же унификации логики. Если поломать код, то можно сделать астероиды или пули в форме корабля, ну и т.п. Все точки в геометрии задаются в координатах [-1..1], а конкретные размеры получаются масштабированием на уровне отрисовки в canvas. И для любого размера астероида можно применить любую геометрию (вариантов астероидов несколько).
Каждый объект обладает группой характеристик:
Унификация значительно упростила обработку особых ситуаций, вроде заворачивания объекта при его уходе за границы экрана.
[{x:'x', W:W.w}, {x:'y', W:W.h}].forEach(function(_) {
var limit = (_.W>>1)+S.r, diff = _.W+2*S.r;
if (S[_.x] < -limit) {S[_.x] += diff}
else if (S[_.x] > limit) {S[_.x] -= diff}
});
Код можно еще сократить. Но имхо от станет менее понятным.
В одной из первых версий пробовал вариант с отображением объектов в две части, при частичном заходе за края (этакий Portal). Выглядело забавно, но мне показалось совсем не каноничным. Может стоит вернуть?
Дифференциация по типам выполняется лишь в логике обработки коллизий, чтобы понимать, что вообще с чем столкнулось. Сейчас учитываются столкновения астероидов в кораблем и пулями. Есть мысли о столкновении астероидов между собой, ну и, конечно, введение в игру НЛО.
Первоначальный вариант коллизий по оболочкам (bounding box через описанные окружности) показал несостоятельность, когда в случае, как на картинке справа, срабатывала коллизия. Это было недопустимо, так как лишала всего «драйва». Придумал два варианта решения: математический обсчет пересечения геометрии (любой объект представляется замкнутым набором отрезков) и попиксельное тестирование именно так, как отрисовывает движок браузера. Первый вариант, теоретически, менее ресурсоемок, но выбрал я второй.
Создается вторая canvas, на которую (только если тест оболочек подтвердил возможное пересечение) отрисовываются два проверяемых объекта, но в красно-зеленой цветовой гамме с активным блендингом на 50%. В итоге, в месте реального пересечения у нас появятся пиксели, имеющие и красную и зеленую компоненты. Очень просто, хоть и не эффективно.
Ну и некоторое уже более-менее «мясцо» напоследок:
Видно, что астероиды выводятся wireframe. Опять же ради толики каноничности.
Автор: AterCattus
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/48790
Ссылки в тексте:
[1] в нем есть: https://github.com/AterCattus/js-asteroids
[2] тут: http://ater.me/asteroids/
[3] Источник: http://habrahabr.ru/post/202888/
Нажмите здесь для печати.