ParTizan написал:
ставьте ограничения на графику музыку…
тут в основном кодеры сидят и соревнуются в НАПИСАНИИ игр, и ограничения едины на все( в данном конкурсе 5мб) хочешь на графику, хочешь на музыку, а хочешь урезай свои dll
Ох не могу! Хотю спать!))) Лан завтра постараюсь долепить до обеда)) Попробовал сделать пускалку на Qt, и оказалось, что если брать последний КюТ под винду, да ещё с вебкитом то минимальные либы будут весить около 70Мб((
А так мой танчик ужо ездит по хтмл канвасу, ударяется во вражеский штаб... Но больше там ничего нет - только штаб и танк))) На завтра остались враги, местность (наверно буду генерить), выстрелы.. Кстати я тайлсет сам малевал в гимпе, вот такой получился:
Shirson
Можешь подсказать, но до конца конкурса я вряд ли внедрю это — работы непочатый край) Не факт, что вообще смогу сдать, ибо могу кодить только вечерами, по 3 часа.
Катастрофа!! Пишу из маршрутки с смартфона на остатке батареи и интернета, читай из горящего танка.. Срочно пришлсь ехать в другой город.. Надеюсь у родителей жены есть интернет...
Ок.
Буду писать на примере демоновского скриншота, дальше можно подровнять под персональные требования.
В чём суть идеи - генерится несколько опорных точек ландшафта, между которыми интерполируется остальная поверхность. Для экстраполяции подойдёт косинусная интерполяция, как компромисс между линейной (простой, но грубой) и кубической (красотульной, но навёрнутой).
У Демона экран 64х40 кусочка земли. Выбираем количество опорных точек - эти точки будут задавать места гребней и спадов волн. Понятно, что нужно брать количество опорных точек, на которое делится 64 (это 2, 4, 8, 16, 32 ). Если взять слишком малое число, получится слишком много пиков/ямок и это будет уже сейсмограмма землятресения. Если взять слишком большое число, будет плавная волна, бесполезная для игры.
Основываясь на скриншоте и собственной ректальной чуйке, напрашивается число точек в 8 штук :) Тут стоит внести уточнение. Т.к. точки нужны для интерполяции, то они должны охватывать весь объём ландшафта. А у нас пока вот так:
Шаг 1: Создать массив из 9 элементов, чтобы хранить опорные точки( или сделать это прямо в игровом массиве - дело ваше.)
Нужно сгенерить 9 случайных чисел, которые зададут относительный разлёт высот. Диаппазон разлёта будет определять насколько крутые склоны будут получаться. На скриншоте разлёт составляет 20 квадративок грунта.
Шаг 2: Значит генерим 9 случайных значений 0..19 и записываем из в массив опорных точек.
Теперь определим, на какой высоте от нижней части экрана они будут находиться. На скришоте - 8 квадратиков. Это толщина породы под нашими "волнами".
Шаг 3: Берём выбранную толщину породы и прибавляем к каждой опорной точке из массива (при оптимизации можно объеденить этот и предыдущий шаг)
Теперь нужно высчитать остальные столбики грунта, лежащие между нашими опорными точками Для этого нам понадобится функция интерполяции. Что такое интерполяция? Это нахождение значений между двумя, уже заданными.
Например:
Красные точки - заданные значения, линии между ними - интерполяция
Линейная
Косинусная
Несмотря на то, что это жутко звучит, ничего страшного в ней нет :)
Пишем функцию:
function Cosine_Interpolate(a, b, x)
ft = x * 3.1415927
f = (1 - cos(ft)) * 0.5
return a*(1-f) + b*f
end
Как это работает?
a и b это высоты соседних точек, между которыми мы генерим ландшафт.
х задаёт относительное положение нужной нам токи. Если он равен 0, то получим а. Если 1, то получим b. Всё что между - то что нам нужно.
Шаг 4: Интерполируем значения в игровой массив:
for Point = 0 to 7 // У нас 9 опорных точек, но цикл до 8й, потому что в цикле мы обратимся к +1й
..a = PointsArray[Point]
..b = PointsArray[Point+1]
..for x = 0 to 7 // для каждого столбика земли
....CosIn = Cosine_Interpolate(a, b, x/8)
....GameArray[a * 8 + x] = integer( CosIn )
..end
end
Тадаааа! :)
Сосбвенно всё. Количество опорных точек, высоты и разлёт следует подбирать индивидуально. Оптимизация и причёсывание кода (вроде уборки магических чисел из кода) на вашей совести, я писал как можно нагляднее.
P.S. Более ужасного и бесполезного тега [cоdе] я и не припомню, если честно. Начиная от обрезания пробелов и заканчивая размерами фрейма. У нас он получше, вроде был, не?
Shirson вот тебе делать нечего! Но спасибо:) В принципе, я ожидал что-то завязанное на интерполяции, это распространенный метод. И ты его хорошо и понятно преподнес
У меня был вариант нагенерить ландшафт, используя синус/косинус, меняя амплитуду и период от шага в шагу, но отказался. Думал про опорные точки, но не хватило ума придумать другую интерполяцию кроме линейной. Про косинусную интерполяцию не знал, взял на заметку, очень классно получается :)
Красивый сгенеренный ландшафт не успеваю, тестирую ИИ и возникла проблема...
Начну издалека.
Первая версии ИИ просто целилась в игрока и стреляла напрямую. Было очень глупо в условиях-то горной местности :)
Вторая версия находила самую высокую точку между собой и игроком и пыталась ее перебросить. Все было классно, пока между игроком и противником не оставалась довольно ровная площадка. ИИ упорно стрелял на облет высоты в один тайл с малой силой. Было грустно.
Третья версия учла недостатки... нагло вырвалась из под контроля, и за 3-6 ходов сносит танк игрока вчистую, учитывая ландшафт и прочее. Все было бы классно, если бы я сам не понимал, как у меня получилось сделать его таким эффективным, прямо колдунство какое-то...
Со мною такое впервые, я вообще не очень спец по ИИ. Надо его ухудшать как-то, разброс что ли более эффективным сделать... Придется нарушить заповедь «Работает — не трогай!».
Вижу, уже две работы сданы. Молодцы, ребята, мне б вашу скорость...
Вопрос — учитывая, что сроки короткие, штрафы увеличены, сколько будет длиться голосование?
Daemon
Это очевидная ситуация. У меня была выпускная квалификационная работа, тоже танки(плоские, походовые, вид сверху).
Компьютер просто считал угол и силу выстрела и мог стрелять со 100% точностью. Пришлось специально добавить разброс.
Причем можно сделать как случайность попал/не попал, так и точность.
То есть, например при 30% разброс - 3 клетки, остальные 70% - разброс 8 клеток.
Shirson написал:
Подсказать как на раз-два генерить подобные, но красивые ландшафты, без особых заморочек?
Shirson написал: Шаг 1: Шаг 2: Шаг 3: Шаг 4:
Тадаааа! :)
Ничего не имею против генерации с помощью интерполяции (у неё свои и значительные преимущества), но назвать её генерацией на раз-два язык не поворачивается.
Вот пример генерации на раз-два:
Раз - генерим массив случайных чисел:
const unsigned int size = 64;
const unsigned int max = 40;
int a[size + 2];
for( unsigned int i = 0; i < size+2; ++i )
a[i] = rand() % max;
Два - делаем блур:
int result[size];
for( unsigned int i = 0; i < size; ++i )
result[i] = (a[i] + a[i+1] + a[i+2]) / 3;
Если блур сделать дважды, то получаем что-то похожее на это:
Все остальное по вкусу и потребностям. Например 250 точек, 10-кратный блур с радиусом 2 место 1:
Daemon написал:
У меня был вариант нагенерить ландшафт, используя синус/косинус, меняя амплитуду и период от шага в шагу, но отказался.
Думаю вполне рабочий вариант. Т.е. как разложение в ряд Фурье, только случайные коэффициенты. Должны получится замечательные ландшафты.
Фух.. Я снова в игре! Shirson, спасибо, за Cosine_Interpolate! Тоже не знал. Блин она мне когда-то так бы пригодилась.. Но, думаю, ещё пригодится.
Я сейчас тоже занят генерацией карты только для BattleCity-like игры. Решил на этот раз использовать только хардкор - только эвристику))) Скоро выложу скрин, что получается..
Mefistofel
Одно дело, когда угол и сила выстрела вычисляются по четко выведенной формуле, которая дает 100% результат. Другое дело, как в моем случае, почти от балды составленный алгоритм с вручную подобранными весами для учета факторов, который неожиданно дает хороший результат.
Вообще я погорячился, бывают ситуации ,когда ИИ все же тупит. Тут уже ничего не исправишь. На ум приходит алгоритм с обратной связью, как наиболее реалистичный - выстрелил, оценил точку падения (дальше игрока, ближе игрока), изменил силу/угол, но уже не успею, ибо сегодня времени на кодинг не будет, надеюсь, что хоть успею собрать архив по правилам.