Реализация больших миров. Основы генерации

другие уроки, мануалы, советы по Construct 2

Сообщение Реализация больших миров. Основы генерации
» 27 май 2014, 00:59

Изображение

Пробовали создать мир размером 80000х80000 пикселей полностью покрытый травкой? Скорее всего игра будет хорошенько подтормаживать и бесить этим игроков. Я же вам расскажу о методе создания больших миров (80000х80000 это цифра, которую смог осилить мой не самый мощный комп) с размером лэйаута в 640х480 пикселей.

Примечание: текст этого урока рассчитан на пользователей, знающих что такое вкладка событий и как создать новое событие (event). Для тех, кто не совсем уверен в своих способностях находить вкладку событий я дополнительно прилагаю 40 фоток. Надеюсь, так поймут все.

В чем фишка?

Мы создадим уникальный мир (простейшая генерация) который будет существовать только в массиве. И частичка этого мира будет отображаться игроку.

И так.

Разберем механику нашей игры. У нас есть двумерный массив (координаты X и Y), где X - номер клетки в ряду, а Y - в столбце. Значением каждой клетки будет номер объекта, который должен быть на этом месте. Пример: мы хотим чтоб в клетке 2:2 у нас находился стремный листочек, а вокруг него были пустые клетки.
Изображение

Пусть номер объекта "листочек" будет 1, а пустоты 0. Тогда значения в клетках будут выглядеть так:
Изображение


Далее, эти значения будут обрабатываться и отображаться перед пользователем.
Надеюсь, идея мира в массиве понятна.

Перейдем к созданию.


Открываем пустой проект. (если что-то не понятно, текст сопровождается картинами)
Изображение

Создаем новый Sprite.
Изображение


Изменяем его размеры до 32х32. Там еще есть выбор куда установить центр картинки. Можете, конечно, нажать верхний левый угол, но у меня оно все равно не работает.
Изображение


Если у вас тоже - идем в параметры центра (origin) и устанавливаем центр в 0:0.
Изображение


Заливаем наш квадратик зеленым цветом. Ок. Закрываем редактор изображения.

В верхем баре открываем вторую вкладку (view) и включаем сетку.
Изображение


Теперь заполняем видимый при запуске участок зелеными квадратиками. (по желанию можно в меню справа указать размеры холста 640х480, тогда не будет путаницы между видимой частью холста и общей. Я это сделать забыл и все мои 40 фоток остались с бОльшим холстом)

Изображение


Бооольше, боольше квадратиков. И не вылазим за рамки "видимого участка", это не красиво.

Изображение


Славно. А вы молодцы. :acute: Рассказываю зачем мы это сделали. Помните пример с уродским листиком? Клетка массива несла только ID изображаемого объекта. Но надо же нарисовать этот объект, не так ли? Именно этим и займутся наши квадратики. Они будут придавать цифрам в массивах графический облик.

Идем дальше. Создадим новый объект Array.

Изображение


Только что вы создали наш будущий мир. Чуть изменим параметры массива. (меню справа) Пусть размеры Х и У будут 300 на 300. (а значит и наш мир будет размером 300 на 300 клеток)

Изображение


Добавим еще два объекта. Function и Keyboard.
Изображение

Изображение


Прекрасно. Перейдем во вкладку событий и создадим 2 переменные: scrolx и scroly. (P.S. Да, я в курсе что scroll с двумя L, но создать scrollx или scrolly у вас не получится)
Изображение


По желанию можно создать группу событий Control. Я, например, создал. Пусть хоть в уроке у меня не будет код, где черт ногу сломает.
Дальнейший план таков. Мы должны сделать управление над миром. Пускай при нажатии стрелочек на клавиатуре мир передвигается в том же направление на 1 клетку. Как это осуществить? При нажатии, например, на право переменная scrolx будет увеличиваться на 32, т.е. на 1 клетку. Наши Спрайты, зеленые квадратики, будут учитывать это передвижение и показывать объект, который в массиве находится на 1 клетку правее. Если сейчас не особо понятно, возможно, дальше станет понятнее.
В группе Control создадим новое событие "При нажатии на левую стрелочку". Keyboard -> Key is down->Right arrow.

Изображение

К этому условию добавим еще одно - каждую 0.1 секунды. Рассказываю зачем. Пока что у нас программа будет просто фиксировать зажатие, а значит события будут происходить каждый тик (1/60 секунды). Мы же не хотим сдвигаться за секунду на 60 клеток? Нет, это очень быстро. Для этого и добавляем событие-контроллер "every 0.1 sec". Теперь за секунды мы будем сдвигаться всего на 10 клеток.

Изображение

Изображение


Получаем такого красавчика:

Изображение



К этому условию создадим событие Add to scrolx 32 (добавить 32 к scrolx).

Изображение


Вот:

Изображение


Копируем это событие. В копии меняем стрелку на левую и вместо Add to - Subtract from. (Вычесть)

Изображение


Повторяем это для верхней и нижней стрелок. Только теперь если зажата клавиша вверх - вычитаем из scrolY 32, вниз - добавляем.

Изображение


Под группой Control создаем новое событие. Function -> On function -> "step"
Изображение

Изображение


Далее уже интереснее. Нам надо вывести занения массива в графической форме. Если мы еще не двигались стрелками (scolx=scroly=0), то квадрат 0:0 будет отображать значение 0:0 из массива, 1:0-1:0 и т.д. Но как из этой кучи квадратиков получить их номер? Просто! Помните размер наших квадртов? Именно, 32. Теперь разделим их координаты на 32 и мы получим порядковый номер. Посмотрите сами: вершина верхнего левого квадрата находится в 0:0. Делим на 32 получим 0:0. Второй квадрат в ряду находится в 32:0. Делим на 32, получаем 1:0. И так для каждого квадрата. Хорошо. Но как будет отображаться движение? Допустим, мы сдвинулись на квадрат вправо (scrolx=32). Тогда мы просто добавим к кооринате X каждого квадрата по scrolx, т.е. по 32. Верхний левый квадрат находится в 0:0, но если прибавим 32 то получим 32:0. Делим на 32 получаем 1:0 - порядковый номер второго квадрата до движения. Т.е. первый квадрат уже будет изображать значение второй клетки массива. Аналогично и с движениями вверх/вниз.
Как это будет выглядеть? Создаем новый action к условию с функцией. Sprite -> set frame ->Array.At(floor((sprite.X+scrolx)/32), floor((sprite.Y+scroly)/32))
Где Array.At(X,Y) - значение в X,Y. floor - округление (на всяких пожарный). Т.е. floor((sprite.X+scrolx)/32) и есть то, о чем мы говорили. Мы прибавляем к координате X scrolx и делим на 32. Округяем это занчение.
Изображение

Изображение


Теперь добавим ко всем событиям движения (нажатия стрелок) вызов фунцкции "step".
Изображение


И еще одно событие. Делаем так, чтоб кадры анимации квадратиков не изменялись. On start===>sprite: set animation speed 0.
Изображение


Еще раз разберем что мы сделали. Отныне каждый квадрат будет устанавливать себе тот кадр анимации, который указан в массиве (то, что в самом начале я назвал номером объекта). Но надо же нарисовать эти кадры. Идем опять в графический редактор Sprite-а (нашего квадратика) и играем с панелью анимации.

Изображение


Дублируем первый кадр три раза.

Изображение


Во втором кадре берем карандаш и рисуем убожество в виде травы. (на картинке квадратик приближен)

Изображение


Точно так же и с третьим кадром.

Изображение


В четвертом кадре рисуем не менее уродское деревце. бррр...

Изображение


Выходим из редактора. И идем назад в редактор событий. Создадим простейшую генерацию уникального мира. От start of layout создаем подсобытие.

Изображение


Условие: Для каждой клетки массива XY (Array->For each element->XY)

Изображение
Изображение


Событие: Array->Set XY-> X: Array.CurX Y: Array.CurY value: choose(0,1,2,3)
Изображение


Т.е. программа проработает каждую клетку массива и присвоит ей случайное значение 0, 1, 2 или 3.

Все. Смотрим что у нас получилось
Изображение


Запускаем. Делаем движение... йес)

Изображение


Исходник прилагается.

ishod.capx
(177.75 КБ) Скачиваний: 229


P.S. почему размеры 300 на 300? я же говорил о 80 тысячах... Да пожалуйста, размер поля 80к - это 25000 клеток. Ставьте на здоровье размер массива 2500:2500.
P.P.S. так уж и быть, дарю вам свои рисунки травы и дерева. Даже коммерческое использование разрешаю.
Последний раз редактировалось Matt 30 май 2014, 21:31, всего редактировалось 2 раз(а).
Аватара пользователя

Участник
Сообщений: 34
Я тут с 03 окт 2012
Репутация 24 [ ? ]

Сообщение Реализация больших миров. Основы генерации
» 29 май 2014, 17:47

урок, вроде неплохой. однако печалит то, что вы, видимо, его сами-то не читали - много очепяток в тексте.
Аватара пользователя

Администратор
Сообщений: 2406
Я тут с 06 сен 2012
Откуда: Санкт-Петербург, Южно-Сахалинск
Skype: sirg1987
Репутация 268 [ ? ]

Сообщение Реализация больших миров. Основы генерации
» 29 май 2014, 20:17

Отличный урок. Понятно и с юмором.
Аватара пользователя

Участник
Сообщений: 10
Я тут с 09 авг 2013
Репутация 0 [ ? ]

Сообщение Реализация больших миров. Основы генерации
» 30 май 2014, 01:04

Фуф, хоть кто-то прокомментировал) а то уже в голову стали лезть злобные мысли самому себе написать, мол, молодец, чувак, не зря старался.
Sir_G, завтра все перепроверю. Я пока дописал текст и вставил все 40 фоток (чтоб их) чертовски вымотался и пошел спать так и не перепроверив. Исправлюсь.
Lezvie, йе, пасибище огромное за отзыв)
Аватара пользователя

Участник
Сообщений: 34
Я тут с 03 окт 2012
Репутация 24 [ ? ]

Сообщение Реализация больших миров. Основы генерации
» 30 май 2014, 10:11

Маааааленький минус: можно выйти за пределы поля + во время старта отображается пустое поле.(всё это легко исправить)
P.S. А можно сгенерировать массив только один раз? А выкрвырять сгенерированный массив? А сделать так, чтобы массив был в интернете?
Аватара пользователя

Модератор
Сообщений: 2153
Я тут с 11 окт 2013
Откуда: Челябинск
Двиг: С2
Лицензия: Pirate
VK: night_silent
Репутация 223 [ ? ]

Сообщение Реализация больших миров. Основы генерации
» 03 июн 2014, 07:42

endermAH писал(а):А можно сгенерировать массив только один раз?

Эм...так при старте уровня генерируй да и все.
endermAH писал(а):А выкрвырять сгенерированный массив?

"выкрвырять"
"выкрвырять"
"выкрвырять"

ЧТО???
endermAH писал(а):А сделать так, чтобы массив был в интернете?

Это как?
Аватара пользователя

Игродел
Сообщений: 2229
Я тут с 22 авг 2013
Репутация 450 [ ? ]

Сообщение Реализация больших миров. Основы генерации
» 03 июн 2014, 11:44

rokstars писал(а):Эм...так при старте уровня генерируй да и все.

Я к тому, что чтоб при любом запуске игры загружался один и тот же мир.
rokstars писал(а):Это как?

И чтобы этот мир лежал в интернете
Аватара пользователя

Модератор
Сообщений: 2153
Я тут с 11 окт 2013
Откуда: Челябинск
Двиг: С2
Лицензия: Pirate
VK: night_silent
Репутация 223 [ ? ]

Сообщение Реализация больших миров. Основы генерации
» 03 июн 2014, 12:11

endermAH писал(а):И чтобы этот мир лежал в интернете

Загрузка текста из файла на DropBox.
Сохранение массива в файл можно сделать так. Но это для PC.
Для Android'a скорее всего надо делать БД (Базу Данных). За основу взять "Онлайн таблица рекордов ". Только поле будет одно (может, 2 или 3, в зависимости от того что нужно). Записываем в это поле массив (Array.AsJSON), и когда надо считываем в массив функцией load.
Аватара пользователя

Игродел
Сообщений: 2229
Я тут с 22 авг 2013
Репутация 450 [ ? ]

Сообщение Реализация больших миров. Основы генерации
» 05 июн 2014, 01:03

А как сделать чтобы движущиеся объекты в массиве отображались?
Аватара пользователя

Участник
Сообщений: 10
Я тут с 09 авг 2013
Репутация 0 [ ? ]

Сообщение Реализация больших миров. Основы генерации
» 05 июн 2014, 09:08

А мне урок понравился !
ставлю + в карму ибо с юмором и по делу :yes:
Аватара пользователя

Участник
Сообщений: 20
Я тут с 06 янв 2014
Репутация 1 [ ? ]



Вернуться в Другие уроки по Construct 2

Сейчас эту тему просматривают

Зарегистрированные пользователи: нет зарегистрированных пользователей

Наверх