![]() |
раннер: процедурная генерация платформ различных типов
Здравствуйте!
Делаю раннер-скроллер с бесконечной картой. Бесконечность эту реализовал пока таким образом: - ГГ движется слева направо, но фактически остаётся на месте, т.к. все объекты движутся со скоростью "скорость ГГ*-1" - Платформы, оказавшиеся за левым краем экрана, убираются со сцены и из массива платформ - В кадре стоит проверка количества платформ в соответствующем массиве. Когда платформ становится меньше 12, за правым краем создаётся ещё 8. Учитывая то, что одновременно на экране видно только 9 платформ, этого достаточно, чтобы процесс удаления/создания не был виден Для генерации партий платформ по 8 штук я использую вектор со значениями uint, т.к. у каждой платформы есть свой тип, выраженный целым числом. Например, партия одинаковых платформ выглядит как [0,0,0,0,0,0,0,0]. При создании платформ через цикл я просто присваиваю им соответствующий тип из массива. Но позже типов становится больше и необходимо расставить их случайно, но с рядом ограничений. Например, когда типа всего 2: 0 и 1, необходимо, чтобы из 8 ячеек единицами было не более 6 и чтобы не больше 3х единиц подряд. Алгоритм создания такого массива я написал, хоть и получилась некрасивая простыня. Но теперь каждый раз, когда мне необходимо добавить очередную партию платформ, из-за этих рассчётов игра подтормаживает (это даже сейчас, когда у меня всего 2 типа, а что будет, когда их будет больше?..) Вопросы следующие: - Подскажите, пожалуйста, доходчивый ресурс, где можно почитать про алгоритмы создания случайных комбинаций с заданными ограничениями - мне ничего путного найти не удалось( - Если расставлять случайные числа по массивам заранее, это поможет избежать "тормозов", но тогда карта не будет бесконечной. В моём же случае каждый раз, когда добавляется новая партия платформ, происходят новые расчёты и появляются лаги. Может быть, есть какой-то лучший способ добиться "бесконечности" карты, кроме удаления и создания за пределами экрана на ходу? |
Во-первых, алгоритм создания платформ в данном случае требует реализацию пула, чтобы не тратить драгоценные тики на вызов конструктора.
Во-вторых, что за расчеты у вас такие, что дают лаги? Покажите код, уверен, Вам укажут на его слабые места. В-третьих, почему в массиве платформ хранятся типы платформ, а не ссылки на платформы? |
Цитата:
Там делов-то должно быть с гулькин нос. Можно попробовать заранее нагенерить паттернов. Правда, затрудняюсь сказать о затратах памяти и времени. |
Функция движения и удаления блоков, вызывается в кадре:
Код:
// UPDATE BLOCKSprivate var _waves:Vector.<Vector.<uint>>; //двухмерный вектор с числами Это нужно для того, чтобы при необходимости создать заново уже удалённые блоки (т.е. вернуться к какому-нибудь чекпойнту). За 1 раз создаётся 10 блоков - это и есть волна. Каждому из 10 блоков случайным образом (но с некоторыми ограничениями) присваивается определённый тип: Код:
// Создание волныКод:
// Создание блоков по указанному массиву вектора волнПро использование пула понял, пока читаю про него и пытаюсь понять, как им пользоваться. |
Ух, по хорошему всё это в классы, а не простыню. Очень много объявляется временных переменных, GC будет часто срабатывать, будут и тормоза. Дальше стоит сделать пул(гуглим, даж тут мои первые попытки найдутся) этих блоков, один раз в начале игры создали и всё. Убрать множество проверок помогут собственные событие(гуглим), но тут увы, только в классах писать (хотя как код перевалил за 800 строк, сами перейдёте на классы и всю игру перепишите и не раз).
Ну а вообще, сходу бы я написал логику типо такой: раз блоки ограничены изначально, то if (Math.random() > 0.5) vector.push(1) else vector.push(0) это к примеру, 3 и т.д. соответственно меняем условия (>0.33<0.66)- итого волны будут разные каждый раз. Дабы блоки не накладывались, есть множество вариантов, я бы сделал через событие, чтобы блок, который на сцене, сообщал сам, когда достаточно места для появления следующего. Ну а скорее всего, исключил бы вектор с типамы блоков изначально и просто бы в зависимости от условия, когда первый блок сообщает о возможности добавить следующий, рандомнобы выбирал что появится следом, меньше переменных - > меньше возни. Ну и обязательно создать пул для каждого типа блоков |
Цитата:
Цитата:
Цитата:
Цитата:
Итак, допустим, от тормозов из-за создания-удаления объектов я избавлюсь при помощи пула. Теперь, для создания пачки из 10 блоков мне необходим вектор uint с комбинацией случайных чисел, расстановка которых в этом векторе подчинена определённым правилам. Остаётся вопрос: 1. Каков наиболее оптимальный алгоритм такой расстановки? (Сейчас у меня алгоритм такой: присваиваем ячейке случайное число и проверяем уже созданные ячейки: если разрешение получено, оставляем в проверяемой ячейке выпавшее число, если нет - ставим по умолчанию 0) (Я думал ещё присваивать числа сразу всем ячейкам, а затем проверять всю комбинацию на выполнение условий, но ведь для этого всё равно придётся проверять каждую из них, поэтому лучше уж решать вопрос о том, можно ли оставлять в ячейке выпавшее число, сразу, при проверке данной ячейки) (Ещё думал на вариантом: в начале игры вычислить все возможные комбинации всех используемых чисел, затем отсортировать комбинации по различным критериям и распихать по соответствующим массивам, а затем при создании просто брать из массива произвольную комбинацию. К примеру, условия для блока типа 1 в пачке из 10 блоков такие: не больше 6 единиц, не занимать 1 и последнюю ячейки, не ставить 3 единицы подряд. С такими условиями у меня получится несколько комбинаций: [0,1,1,1,0,1,1,1,0,0], [0,0,1,0,0,1,0,1,1,0] и т.д. Я их всех заношу в вектор _combinations1:Vector.<Vector.<uint>>, а при создании выбираю случайную из них MyMath.random(0,_combinations1.length-1)) |
Всё печально.
Вместо того, что-бы двигать каждый блок по отдельности, проще двигать контейнер, содержащий все эти блоки и прочие элементы мира. А если подойти к делу профессионально, то двигаться должны герой в мире и камера, которая показывает какую то часть этого мира (Например героя). Во флеше нет класса камеры из коробки, но её совсем не сложно сделать самостоятельно, там от силы строк 100-200 кода. По сути, камера это конечная матрица трансформаций, на которую умножаются все дисплей объекты, перед отрисовкой на экране. Если с камерой совсем не понятно, то сделайте хотя бы контейнер для мира и двигайте его. (По сути это и будет примитивная камера) |
Цитата:
|
Поместите героя в этот же контейнер с блоками, пусть он там бегает, прыгает и сталкивается.
А теперь внимание! Чтоб герой всегда был на экране, двигаете контейнер с миром (в котором герой, блоки и всё остальное) вот так: Код AS3:
|
В теме задавалось сразу несколько вопросов, на большинство из которых я, благодаря советам откликнувшихся, нашёл ответы. Всем большое спасибо! Прошу модераторов закрыть тему - более конкретные вопросы лучше задам в отдельно созданных темах.
|
| Часовой пояс GMT +4, время: 01:43. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.