Комментарии 27
Самое забавное во всем этом, что редактор, который бы позволил делать также карты можно написать самому за один вечер. Только для каждого квадратика хранить не несколько байт с цветом, а данные у вдобном для программы виде и любом количестве.
Подобный подход сам использовал. И не однократно, но он подходит разве что для прототипирования. Для левел-дизайнера это котироватьяс не будет вообще никак, так как тут даже украшательства нельзя воткнуть самому. А усложнение уровня путем создания нескольких картинок, вообще сделает для дизайнера это адским испытанием.
Но за статью всёравно спасибо, почитать интересно.
Подобный подход сам использовал. И не однократно, но он подходит разве что для прототипирования. Для левел-дизайнера это котироватьяс не будет вообще никак, так как тут даже украшательства нельзя воткнуть самому. А усложнение уровня путем создания нескольких картинок, вообще сделает для дизайнера это адским испытанием.
Но за статью всёравно спасибо, почитать интересно.
Есть редактор Tiled — бесплатный, открытый, кроссплатформенный.
www.mapeditor.org/
www.mapeditor.org/
Мм, ну я надеюсь все эти манипуляции хотя бы не в рантайме при загрузке уровня происходят?
Про какие манипуляции идет речь? Применение шума + фильтр — в рантайме в шейдере, а, например, размытие по Гауссу — при загрузке
А это разве не жутко медленно? Особенно применение полноэкранного тяжелого шейдера в рантайме. Не лучше бы это всё делать при сборке ресурсов игры и хранить итоговую текстуру?
Ну раз уж уровни в Paint'е делаются, почему бы данные в риалтайм не процессить? Только хардкор! :)
вообще не медленно, игра выдает 60 кадров даже на iphone 4. Если заготовить при сборке, то подводные водоросли уже не анимировать, на поверхности воды волны будут статичными, а памяти на такую текстуру потребуется примерно в 1165 раз больше (если я правильно посчитал)
Ну водоросли можно отдельным шейдером анимировать — вряд ли разница будет заметна. Аргумент насчет веса текстур я еще могу понять, но по крайней мере итоговую текстуру можно было бы отрендерить в статичную текстуру при загрузке и не напрягать GPU лишний раз. Оно-то может 60 фпс и выдает, но и батарею кушать будет больше, чем при пре-рендере
если софтварно писать эти фильтры, то скорее всего медленно будет, а через шейдеры очень быстро, они параллелятся очень хорошо.
Ну, понятно что реалтайм оно выдюжит. Другое дело, что это совершенно неоправданная растрата ресурсов, что важно для мобильного устройства.
UPD: Ну и никто не мешает воспользоваться рендером в текстуру и отрисовать быстро через шейдер.
UPD: Ну и никто не мешает воспользоваться рендером в текстуру и отрисовать быстро через шейдер.
Так, мне эти разговоры про рендер заранее надоели.
Возьмем самый маленький уровень (он же 1-й)
Его размер 47х33 тайла
На экран попадает ровно 15 тайлов по горизонтали (на айпаде), рендеринг произвожу в текстуру 1024х768
Т.е. один тайл занимает примерно 1024/15=68.3 пиксела (примерно 70) в ширину, а он еще и квадратный, т.е. 70х70
Т.о. чтобы сохранить пиксельность уровня нужно заготовить заранее под него текстуру 3290х2310
Теперь возьмем самый большой уровень 91х196. Для него уже потребуется текстура 6370х13720, тогда как на моем айпаде 4 максимальный размер текстур 4096х4096. Как вариант, можно разбить эту текстуру на много маленьких (1024х1024 например) так, чтобы все они покрывали уровень. Один фиг, большой уровень потребует 6370х13720х4=350М
Даже если все это таки сделать, шейдер уровня будет нетривиальный (не, не просто так взять выборку из текстуры и поместить на экран). Нужно произвести смешивание со скайбоксом, На участке, где вода (а её кстати где хранить в большой текстуре, она ведь пересекается с бекграундом, альфаканал уже занят под маску скайбокса) произвести искажений бэка и водорослей и «замутнить» бэк (типа толща воды). А как сделать выплывание рыбок из-за земли, но поверх бэка? (бэк и земля ведь не отдельно хранятся, а в большой текстуре) Обрезать? Как? Хранить землю и бэк таки в разный текстурах? Ладно, тогда 700М.
Оно того стоит? Тогда как я с помощью шейдера рендерю нужный мне кусок уровня с 60фпс
update: только что вспомнил, разрешение маски уровня апается в два раза, поэтому умножаем память еще в 4 раза
Возьмем самый маленький уровень (он же 1-й)
Его размер 47х33 тайла
На экран попадает ровно 15 тайлов по горизонтали (на айпаде), рендеринг произвожу в текстуру 1024х768
Т.е. один тайл занимает примерно 1024/15=68.3 пиксела (примерно 70) в ширину, а он еще и квадратный, т.е. 70х70
Т.о. чтобы сохранить пиксельность уровня нужно заготовить заранее под него текстуру 3290х2310
Теперь возьмем самый большой уровень 91х196. Для него уже потребуется текстура 6370х13720, тогда как на моем айпаде 4 максимальный размер текстур 4096х4096. Как вариант, можно разбить эту текстуру на много маленьких (1024х1024 например) так, чтобы все они покрывали уровень. Один фиг, большой уровень потребует 6370х13720х4=350М
Даже если все это таки сделать, шейдер уровня будет нетривиальный (не, не просто так взять выборку из текстуры и поместить на экран). Нужно произвести смешивание со скайбоксом, На участке, где вода (а её кстати где хранить в большой текстуре, она ведь пересекается с бекграундом, альфаканал уже занят под маску скайбокса) произвести искажений бэка и водорослей и «замутнить» бэк (типа толща воды). А как сделать выплывание рыбок из-за земли, но поверх бэка? (бэк и земля ведь не отдельно хранятся, а в большой текстуре) Обрезать? Как? Хранить землю и бэк таки в разный текстурах? Ладно, тогда 700М.
Оно того стоит? Тогда как я с помощью шейдера рендерю нужный мне кусок уровня с 60фпс
update: только что вспомнил, разрешение маски уровня апается в два раза, поэтому умножаем память еще в 4 раза
Это все напомнило мне детство.
Помн лет в одинадцать (примерно 1991 год) написал какую-то простенькую леталку-стрелялку на компилируемом бейсике на писюке.
Но Писюки тогда были не очень доступны. Я ходил в какой-то институт где работали знакомые, игрался за машинкой с зелено-черным монитором (черно-белые были только у крутых). Никаких жестких дисков — только дискеты. Комп с жестким диском на 20мегабайт был только один и к нему меня не пускали.
В общем доступ был ограничен, экран одноцветный… А дома стоит Спектрум. Цветной.
Портировал код один в один благо диалекты бейсков не сильно различались.
Но восьмибитный проц да интерпретируемый бейсик сделали задачу неосуществимой. Мои полностью рандомные горы на писюках требовали солидной задержки, а тут двигались столь медленно, что играть было нереально.
Альтернатива портирования всей игры на ассемблер меня не привлекала, хоть я ассемблер и знал и писал на нем небольшие куски для усиления. Вариант выноса только блока рисования гор тоже не помог — я вызывал системную процедуру рисования линий, и это все равно было медленно.
Тогда я решил «испортить» качество гор заменив их на четыре вида спрайтов — полностью твердый, полностью воздух и два варианта наклона — влево и вправо. Вывод таких «символов» с перегруженным шрифтом оказался заметно быстрее, плюс ширина блока сократилась в восемь раз (ширина символа).
В результате такой оптимизации (первой в моей жизни) я смог остаться в рамках бейсика и получить приемлимую производительность (даже задержку ввел небольшую).
Вот забавно — сейчас можно рендерить по живому не заморачиваясь о производительности, а тогда приходилось выкручиваться и рендерить по живому потому что места для заранее сгенеренных текстур тупо не было. Магнитофоны были слишком медленными, а дисководы были не у всех…
Помн лет в одинадцать (примерно 1991 год) написал какую-то простенькую леталку-стрелялку на компилируемом бейсике на писюке.
Но Писюки тогда были не очень доступны. Я ходил в какой-то институт где работали знакомые, игрался за машинкой с зелено-черным монитором (черно-белые были только у крутых). Никаких жестких дисков — только дискеты. Комп с жестким диском на 20мегабайт был только один и к нему меня не пускали.
В общем доступ был ограничен, экран одноцветный… А дома стоит Спектрум. Цветной.
Портировал код один в один благо диалекты бейсков не сильно различались.
Но восьмибитный проц да интерпретируемый бейсик сделали задачу неосуществимой. Мои полностью рандомные горы на писюках требовали солидной задержки, а тут двигались столь медленно, что играть было нереально.
Альтернатива портирования всей игры на ассемблер меня не привлекала, хоть я ассемблер и знал и писал на нем небольшие куски для усиления. Вариант выноса только блока рисования гор тоже не помог — я вызывал системную процедуру рисования линий, и это все равно было медленно.
Тогда я решил «испортить» качество гор заменив их на четыре вида спрайтов — полностью твердый, полностью воздух и два варианта наклона — влево и вправо. Вывод таких «символов» с перегруженным шрифтом оказался заметно быстрее, плюс ширина блока сократилась в восемь раз (ширина символа).
В результате такой оптимизации (первой в моей жизни) я смог остаться в рамках бейсика и получить приемлимую производительность (даже задержку ввел небольшую).
Вот забавно — сейчас можно рендерить по живому не заморачиваясь о производительности, а тогда приходилось выкручиваться и рендерить по живому потому что места для заранее сгенеренных текстур тупо не было. Магнитофоны были слишком медленными, а дисководы были не у всех…
В 11 лет знали asm и basic… кошмарно подумать, что вы знаете и делаете сейчас. Я-то думал, что более-менее разбираться в С в 13 лет было уже очень круто.
Это вообще вопрос времени. Сейчас люди в 20-25 лет знать не знают что такое ассемблер и с трудом пишут на С. Им подавай высокий уровень. Джаву или шарп.
А вот когда я писал свои первые программки (бесполезные до дури, разумеется, в шесть мои-то лет), ничего кроме встроенного в commodore64 бейсика попросту не было. А все почему, потому что в 89м году были другие средства разработки, нежели сейчас :)
А вот когда я писал свои первые программки (бесполезные до дури, разумеется, в шесть мои-то лет), ничего кроме встроенного в commodore64 бейсика попросту не было. А все почему, потому что в 89м году были другие средства разработки, нежели сейчас :)
Вы правы, все не от возраста зависит, а от окружения… у меня, например, с 1994 года был 386-й, я на нем, конечно же, играл, хотя отец иногда показывал мне простые программки. Потом, в 2000 году, дома появился современный комп, я на нем снова играл. Но в 2001, в кризис доткомов, отец потерял работу и пришлось снова вернутсья на 386-й. Игры типа Wolfenstein после Unreal и Starcraft уже не катили, хотя Prehistoric я прошел целиком без сейвов, вот и не осталось другого выхода как открыть K & R и начать что-то программировать потиху. Сначала скринсейверы, потом простые игры, а потом… купили новый комп и я увлекся 3d, а в программирование вернулся только на первых курсах института. Не знаю зачем вас этим гружу… что-то вспомнилось.
Это только так кажется что страшно.
А на самом деле тогда просто время такое было.
Впервые я увидел компьютер в девять лет, когда пришел в лабораторию к деду. Дед был доцент на кафедре ВОЛС и они там вечно что-то изобретали, испытывали, рассчитывали… Машинка называлась СМ1800. Характеристики ее я не помню, но там были два пятидюймовых дисковода с маленькой ёмкостью (что-то вроде 90кб) и монитор… монитор был текстовый. Т.е. от системного блока размером с приличную тумбочку шел не аналоговый сигнал а текстовый, и в мониторе уже был свой контроллер который всё это превращал в аналоговый сигнал для трубки.
За компом сидел сын дедушкиного коллеги. Пацан был на три года меня старше и с умным видом писал что-то на бейсике.
Писал он как оказалось примитивнейшую игрушку — в консоли запрашивается твое имя, тебе говорят «Привет *юзернейм*!», тебя спрашивают мол хочешь ли ты поиграть, если да, то компьютер загадывает число (взятое из констант ибо ГСЧ или не было или пацан о нем не знал), ну и так далее… В общем обычная лапша из print input if goto
Поскольку логика «игры» была очевидна, тем более что парниша периодически тестировал, то значение этих трех-пяти команд понять было не сложно. Строки нумерованы… В общем когда парниша вышел в туалет я не удержался и сел за комп. Написал буквально три строчки с еще одним вопросом. Когда парень пришел проворчал с минутку мол он мне не разрешал, но код одобрил и пошел писать дальше… Вот реально ведь ничего сложного — как обезьяна повторил чужие действия.
Ну а дальше имея уже какой-то опыт прочитать книжку и разобраться в синтаксисе было не сложно.
Использование ассемблера в то время тоже было неизбежным, поскольку на спектруме фактически было только два языка — системный встроеннный бейсик и ассемблер. Да были еще паскали да фортраны, но в реальности на таких малых мощностях машины (48кб ОЗУ из которых часть забирает видеопамять и система, 16кб ПЗУ, восьмибитный проц на пару мегагерц, магнитофон вместо дисковода) использовать их было не особенно реально — компилятор/интерпретатор, исходник, бинарник… при этом бейсик никто не отменял он ведь часть ОС… В общем вариантов особо не было. Поэтому графика писалась на асме.
Ну как писалась — брались примеры из книжек и допиливались до своих нужд… Да на писюках был паскаль (я как-то с паскаля начинал). Но там опять таки с библиотеками было довольно туго. Интернета тогда еще не было, поэтому если в моем окружении библиотек не было значит их для меня не было. Зато были книги. И в книгах было прекрасно написано через какие прерывания и каким образом можно получить те фичи которых не было в стандартных библиотеках. Например хотелось использовать SVGA-режимы которые уже были в моем компьютере (чуть позже чем в 91-ом) но в стандартных библиотеках доступен был только VGA. Пришлось писать в паскале небольшие включения ассемблера…
Но на самом деле в ассемблере нет ничего такого страшного.
Это только кажется что сложно.
А когда ты уже умеешь писать лапшу на бейсике то изучить ассемблер не сложно.
По сути там что? Пару команд условных/безусловных переходов, копирование в регистр/из регистра сложения/вычитания всякие…
Для человека который привык к лапше классического бейсика (с нумерациями строк) в принципе ничего сложного — просто лишаешься небольшого количества синтаксического сахара и вынужден часть механической работы делать сам (планировать память, исправлять адреса переходов изменяя место в памяти, отлаживать в уме или на листочке полученный код и т.п.), но тут много думать не нужно — просто внимательным быть и всё. Ну и если хочешь чтоб код был достаточно шустрым то нужно грамотно планировать память, особенно регистры. Но опять таки — ну нет тут ничего сложного, да и в небольшом куске кода можно и поговнокодить даже по тем меркам.
Вот что по настоящему было сложно так это всё это забыть.
Да, да, забыть!
Я помню свои эмоции когда я впервые столкнулся с языком без goto. Я думал что с меня издеваются, и не понимал как вообще можно жить без прямых переходов. И это я к тому времени уже писал на процедурном диалекте бейсика.
Так же самом помню как я сильно возмущался спустя много лет после этого когда в пхп вернули GOTO. Я то помню как это все выглядит, и как сложно было эту лапшу выбить из меня…
Так что как по мне так Си в 13 лет знать это круче чем ассемблер в 11. И главное полезнее :)
А на самом деле тогда просто время такое было.
Впервые я увидел компьютер в девять лет, когда пришел в лабораторию к деду. Дед был доцент на кафедре ВОЛС и они там вечно что-то изобретали, испытывали, рассчитывали… Машинка называлась СМ1800. Характеристики ее я не помню, но там были два пятидюймовых дисковода с маленькой ёмкостью (что-то вроде 90кб) и монитор… монитор был текстовый. Т.е. от системного блока размером с приличную тумбочку шел не аналоговый сигнал а текстовый, и в мониторе уже был свой контроллер который всё это превращал в аналоговый сигнал для трубки.
За компом сидел сын дедушкиного коллеги. Пацан был на три года меня старше и с умным видом писал что-то на бейсике.
Писал он как оказалось примитивнейшую игрушку — в консоли запрашивается твое имя, тебе говорят «Привет *юзернейм*!», тебя спрашивают мол хочешь ли ты поиграть, если да, то компьютер загадывает число (взятое из констант ибо ГСЧ или не было или пацан о нем не знал), ну и так далее… В общем обычная лапша из print input if goto
Поскольку логика «игры» была очевидна, тем более что парниша периодически тестировал, то значение этих трех-пяти команд понять было не сложно. Строки нумерованы… В общем когда парниша вышел в туалет я не удержался и сел за комп. Написал буквально три строчки с еще одним вопросом. Когда парень пришел проворчал с минутку мол он мне не разрешал, но код одобрил и пошел писать дальше… Вот реально ведь ничего сложного — как обезьяна повторил чужие действия.
Ну а дальше имея уже какой-то опыт прочитать книжку и разобраться в синтаксисе было не сложно.
Использование ассемблера в то время тоже было неизбежным, поскольку на спектруме фактически было только два языка — системный встроеннный бейсик и ассемблер. Да были еще паскали да фортраны, но в реальности на таких малых мощностях машины (48кб ОЗУ из которых часть забирает видеопамять и система, 16кб ПЗУ, восьмибитный проц на пару мегагерц, магнитофон вместо дисковода) использовать их было не особенно реально — компилятор/интерпретатор, исходник, бинарник… при этом бейсик никто не отменял он ведь часть ОС… В общем вариантов особо не было. Поэтому графика писалась на асме.
Ну как писалась — брались примеры из книжек и допиливались до своих нужд… Да на писюках был паскаль (я как-то с паскаля начинал). Но там опять таки с библиотеками было довольно туго. Интернета тогда еще не было, поэтому если в моем окружении библиотек не было значит их для меня не было. Зато были книги. И в книгах было прекрасно написано через какие прерывания и каким образом можно получить те фичи которых не было в стандартных библиотеках. Например хотелось использовать SVGA-режимы которые уже были в моем компьютере (чуть позже чем в 91-ом) но в стандартных библиотеках доступен был только VGA. Пришлось писать в паскале небольшие включения ассемблера…
Но на самом деле в ассемблере нет ничего такого страшного.
Это только кажется что сложно.
А когда ты уже умеешь писать лапшу на бейсике то изучить ассемблер не сложно.
По сути там что? Пару команд условных/безусловных переходов, копирование в регистр/из регистра сложения/вычитания всякие…
Для человека который привык к лапше классического бейсика (с нумерациями строк) в принципе ничего сложного — просто лишаешься небольшого количества синтаксического сахара и вынужден часть механической работы делать сам (планировать память, исправлять адреса переходов изменяя место в памяти, отлаживать в уме или на листочке полученный код и т.п.), но тут много думать не нужно — просто внимательным быть и всё. Ну и если хочешь чтоб код был достаточно шустрым то нужно грамотно планировать память, особенно регистры. Но опять таки — ну нет тут ничего сложного, да и в небольшом куске кода можно и поговнокодить даже по тем меркам.
Вот что по настоящему было сложно так это всё это забыть.
Да, да, забыть!
Я помню свои эмоции когда я впервые столкнулся с языком без goto. Я думал что с меня издеваются, и не понимал как вообще можно жить без прямых переходов. И это я к тому времени уже писал на процедурном диалекте бейсика.
Так же самом помню как я сильно возмущался спустя много лет после этого когда в пхп вернули GOTO. Я то помню как это все выглядит, и как сложно было эту лапшу выбить из меня…
Так что как по мне так Си в 13 лет знать это круче чем ассемблер в 11. И главное полезнее :)
Вспоминаю, как рисовал уровни для Tux Racer в фотошопе. Изображения являлись картами уровней, вид сверху. На каждый уровень было, кажется, по три картинки: на одной изображался рельеф (яркостью оттенков серого), на другой — тип поверхности, на третьей — объекты.
UPD Вот, нашел, как это выглядело: tuxracer.fubaby.com/articles.php?ArticleID=1
UPD Вот, нашел, как это выглядело: tuxracer.fubaby.com/articles.php?ArticleID=1
Я раньше обожал делать подобные прототипы каких-то топологий, но еще смешне: на текстовых файлах.
То есть рисуется символьное поле, например 40х25, а символ = состояние либо категория
Насколько помню, так прототипировали и описывали движение погрузчиков на складе и т.п. :)
То есть рисуется символьное поле, например 40х25, а символ = состояние либо категория
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XX 8 XXXXXXXXXXX XXXX 4 XXXXXXXX XXX * XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Насколько помню, так прототипировали и описывали движение погрузчиков на складе и т.п. :)
Спасибо за статью, вы на пути генерации процедурных карт). Поделитесь информацией насчет анимированных шумов, может какую-то ссылку дадите? Я так понимаю, что анимировать шум можно увеличив его размерность, т.е. изменять поверхность полны смещаясь по двумерному массиву. Проблемка пока в анимации 2d структур, поскольку 3d текстуру нельзя передать в шейдер на ios. В общем за любую информацию по этой части заранее спасибо.
И еще вопрос по части производительности. Воду я так понимаю вы воду рисуете фрагментным шейдером, или что-то недопоняла? У меня самый простецкий шейдер на iphone4 кладет fps ниже 30, если его на весь экран применять. Хотя там по сути совсем маленькая псевдо-анимация шума:
noisevec = texture2D(uTexture0, Position.xy);
noisevec = texture2D(uTexture0, vec2 (Position.x+noisevec[1], Position.y-noisevec[3]+Offset));
Как вариант только отключать retina на 4-ке.
И еще вопрос по части производительности. Воду я так понимаю вы воду рисуете фрагментным шейдером, или что-то недопоняла? У меня самый простецкий шейдер на iphone4 кладет fps ниже 30, если его на весь экран применять. Хотя там по сути совсем маленькая псевдо-анимация шума:
noisevec = texture2D(uTexture0, Position.xy);
noisevec = texture2D(uTexture0, vec2 (Position.x+noisevec[1], Position.y-noisevec[3]+Offset));
Как вариант только отключать retina на 4-ке.
Поделитесь информацией насчет анимированных шумов, может какую-то ссылку дадите?
Текстура шума у меня одна и она двухмерная, перед рендерингом воды есть отдельный рендер в текстуру 256х256, там-то как раз и создается анимация, а так же в эту текстуру рендерится реактивная струя (чтобы водоросли искажались на её фоне и для создания всплеска воды при выпрыгивании/нырянии). Анимация делается одной шумовой текстурой: производятся 4 выборки из неё с разными коэфами текстурных коорд (которые зависят от времени), эти выборки суммируются.
Воду я так понимаю вы воду рисуете фрагментным шейдером
да, вода рендерится в текстуру 256х256, отсюда нет просадки фпс, а качество не страдает, т.к. там нет мелких деталей
Я так понимаю, фрагментый шейдер вызывается по количеству точек на экране, и размер текстуры тут не имеет особого значения. Поэтому у меня пока получается, что если изображение на пол-экрана то fps падает, вне зависимости от детальности прорисовки. Наверное, я что-то не так понимаю. Вы opengl 2 используете?
Игра не «PixelJunk™ Shooter» случайно?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Использование Paint в качестве редактора уровней