Unity 5 создание меню для игры. Создание легкого меню или азы Unity скриптинга. Вызов метода StartGame, когда игрок нажимает на кнопку

Где-то неделю назад один из моих подписчиков попросил меня рассказать о CSS спрайтах , что это такое вообще и с чем их едят. Поэтому сегодня я решил написать эту статью, в которой расскажу, что такое CSS спрайты и где их используют .

CSS спрайт - это комбинированное изображение, в котором находится много различных картинок, и с помощью свойства background-position мы выставляем нужную картинку в нужном месте. Допустим, у нас есть кнопка, и эта кнопка меняет свой вид при наведении на неё курсора мыши. Можно сделать, например, 2 картинки и затем подставлять в качестве фона кнопки ту или иную картинку. Но недостаток данного способа очевиден: в 2 раза больше файлов, примерно в 2 раза больше размер, следовательно, в 2 раза больше время загрузки, чем 1 изображение. И вот техника CSS спрайтов позволяет создать всего лишь одну картинку, в которой будут сразу 2 фона кнопки.

Чтобы стало понятнее, давайте решим эту задачу. У нас имеется изображение, допустим, высотой 20 пикселей и шириной 100 пикселей. Кнопка имеет ширину 50 пикселей и высоту 20 пикселей. В одной картинке мы помещаем изображения обоих состояний (друг за другом). HTML-код будет таким:

Кнопка

И CSS-код :

A {
background: url("button.jpg") no-repeat left top; // Фон кнопки
display: block; // Сделать блочным элементом
height: 20px; // Высота кнопки
width: 50px; // Ширина кнопки
text-decoration: none; // Убрать черту подчёркивания
}
a:hover {
background-position: right top; // Меняем позицию фона, чтобы было смещение изображения
}

Вот таким хитрым образом можно в одной картинке хранить множество изображений. Подчеркну, что именно множество изображений, а не только 2 . Иногда чуть ли не весь сайт состоит из одной картинки, в которой находятся все используемые изображения. Не считаю, что это очень хорошо, но зато будет минимальное количество файлов изображений и минимальный размер загружаемой страницы, что всегда хорошо.

Слово спрайт (англ. sprite - фея, призрак) впервые было использовано мультипликаторами Диснея в несколько ином качестве, мультипликаторы для более быстрого и удобного создания и "оживления" мульт героев сначала рисовали все фазы их движения на прозрачных плёнках, а затем накладывали эти плёнки на основной фон - сцену, и получали кадры мультика, тем самым экономя время, деньги и нервы художников.. эти самые плёнки они и называли спрайтами.

Потом термин спрайт внедрился в компьютерную графику и особо широкое распространение получил в компьютерных играх - но это тоже не совсем то о чем я хочу Вам поведать.. Сегодня я хочу Вам рассказать о так называемых CSS-спрайтах..

Итак, под спрайтами в CSS принято называть одно изображение, которое состоит из нескольких "частей", которые показываются как бы по отдельности в зависимости от действий пользователя..

Что слишком много слов.. покажу пример..

Это спрайт который присутствует на каждой странице данного сайта:

Просто в "спокойном" состоянии Вам показывается одна его часть, а при наведении курсора другая.

Как это сделать? На самом деле все достаточно просто.

В данном примере для блока с фиксированными размерами мы в качестве фона загружаем "двойное" изображение, но так как сам блок из за присвоенных ему размеров ровно в два раза меньше по высоте чем картинка, то браузер показывает лишь первую "часть" фонового изображения, а при наведении курсора срабатывает псевдокласс :hover с свойством background-position которое сдвигает фон вверх, на нужное расстояние, тем самым показывая вторую часть картинки.

Ладно, оставим мой логотип в покое, тем более что я Вам немного слукавил.. сделаем, что-то более полезное для Вас, например вот такую кнопку:

Открываем значит фотошоп и рисуем в нём примерно такой рисунок:

Здесь главное не ошибиться с размерами! вторая часть изображения, где наша кнопка активна, должна быть точно таких же размеров, как и первая часть рисунка, иначе потом, при наведении курсора, все будет "скакать". Лучше всего сначала нарисовать одну часть картинки, потом скопировать её, прогнать через фильтры, что то дорисовать и склеить два изображения в одно.. впрочем, уроки фотошопа не моя стихия..

Итак, у нас получилась "двойная" картинка 175 на 80 пикселей, запомним эти размеры и начнём писать код.

Он у меня получился таким.. смотрим результат и читаем комментарии в коде:




CSS спрайты



Такое вот меню получилось:




Кнопка 1
Кнопка 2
Кнопка 3
Кнопка 4

Думаю, многие читатели задаются вопросом: "А зачем вообще нужны эти спрайты если тоже самое можно сделать с помощью двух отдельных картинок, где одна фон для просто ссылки, а вторая для ссылки с :hover , при этом, не сражаясь с фотошопом и не высчитывая координаты фона для CSS??"

Во-первых: Скорость загрузки изображений увеличивается в разы!! Несмотря на то что "двойная" картинка весит столько же, сколько и две отдельно взятых маленьких "одинарных", загрузка одной большой картинки происходит быстрее, так как браузером не создаются дополнительные HTTP запросы серверу.

Помните, когда я Вам показывал свой логотип-спрайт, говорил что слукавил? Так вот моё лукавство заключается в том, что данная картинка содержит в себе не две логических части изображения, а восемнадцать!!

И полностью она выглядит так:

То есть практически вся графика, которую Вы видите на этом сайте, на самом деле приходит к Вам в виде одного единственного изображения! CSS файл показывать не буду, я его сам боюсь..)),

Так вот HTTP запросы.. если бы изображений вместо одного было 18ть то диалог браузера с сервером выглядел бы примерно так:

Браузер : Здравствуй Сервер! я тут от тебя же, по моему запросу, получаю HTML и CSS документы, так вот в них указано, что у тебя в папке "графика".. должна лежать картинка с названием: "картинка1" скинь а?
Сервер : Привет Браузер, давненько не виделись, сейчас посмотрю.. ага есть у меня такая картинка! Лови!!
Браузер : Спасибо, поймал! Но мне еще нужна "картинка2" в той же папке..
Сервер : Да и такая есть.. отправляю..
Браузер : Загрузил.. но тут еще "картинка3" указана.
Сервер : И не спится же тебе! Держи свою картинку!!
Браузер : Спасибо! Да мне уже саму если честно надоело, но мой пользователь хочет догрузить страницу полностью.. короче у тебя там еще "картинка4" должна быть..
Сервер : Ты меня начинаешь напрягать! На свою картинку!!
Браузер : Извини, но я же не виноват, что здесь столько изображений!!! Нужна "картинка5"!
Сервер : У меня от тебя уже процессор кипит!! Заколебал!! Забирай свою картинку!!
... ... ...

Дальнейший диалог озвучивать не буду, ибо дальше идет нецензурная брань..

К чему вся эта болтовня между сервером и браузером (клиентом) на которую уходит уйма времени и трафика, к тому же нагружает сервер при большом количестве посетителей сайта, если гораздо быстрее и экономичнее сделать один HTTP запрос и получить все 18 картинок в одном пакете!!

Во-вторых: Загрузка второго изображения при использовании псевдокласса :hover происходит лишь только в тот момент когда пользователь навел курсор на ссылку с первым изображением. Если это небольшое изображение типа кнопки из примера выше, то ничего особо страшного не произойдёт - вторая картинка быстро подгрузится и пользователь ничего не заметит.. а если это большая картинка по весу и размеру?? Тогда пользователь будет наблюдать, как она загружается, хотя он психологически был готов к быстрой смене изображений! Еще один плюс спрайтам! … хотя, если честно, одновременно это и минус.. минус в том случае если пользователь в течении сессии так и не навел курсор.. картинка загрузилась, но так ему и не пригодилась.. но поверьте эта "жертва трафика" оправдывает себя практически всегда!

Ну и в-третьих: Как бы Вам это не показалось странным, но это удобно!! Удобно в коде указывать путь к одному и тому же изображению, удобно его править в фотошопе, к примеру, сделать весь сайт поярче или потемнее работая с одним единственном рисунком, удобно хранить, удобно загружать на сервер, да даже в CSS работать с большим спрайтом удобно! - хотя для этого и нужны определённые навыки и привычка..

Ладно, решайте сами использовать спрайты или нет.. а моё дело маленькое, просто так сказать довести информацию до Вашего сведения.. возникнут дополнительные вопросы жду Вас на

Введение

Для начала нужно разобраться, что же такое спрайт. Вот такое описание я нашел в книге Андрэ Ла Мота:

" Знаете, есть такой газированный напиток... Снова шучу. На самом деле спрайты - это маленькие объектики, которые находятся на игровом поле и могут двигаться. Этот термин прижился с легкой руки программистов фирмы Atari и Apple в середине 70-х годов. Спрайты - это персонажи в играх для ПК, которые могут без труда перемещаться по экрану, изменять цвет и размер "

И так, спрайт это персонаж игры. Не углубляясь в дебри программирования, могу сказать что спрайт это массив из цветов - для простаты представим его как BMP файл или TBitmap, тем более что, этот формат поддерживаемый windows и не содержащий компрессии.

Что нам нужно от спрайта - заставить его появляться на экране и образовывать анимацию. Анимация это не только смена координаты спрайта, но и изменение самой картинки. Следовательно спрайт может иметь не одно изображение, а несколько. Смена их и приводит к анимации.

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

Не правда ли есть разница, и довольно заметная. При выводе на экран использовался один и тот же рисунок, но все зависит от способа выведения спрайта.

1-й способ (маг в белом квадрате) основан на простом копировании одной области памяти в другую.

2-й способ (маг на фоне) то же копирование, но интеллектуальное. Копирование происходит по следующему алгоритму: Если цвет копируемого элементы матрицы (область памяти) соответствует значению цвета Transparent Color, то копирования не происходит, переходим к следующему элементу.

3-й способ так же основан на копирование области памяти, но с применением логических операций - маски.

Спрайты c готовой маской

Способов вывести спрайт на поверхность экрана много. Рассмотрим один из них. Это способ, когда отдельно рисуется спрайт и отдельно маска. Для этого нам понадобится сам спрайт, его маска и буфер.

Спрайт
Маска спрайта

И спрайт и маска должны иметь одинаковый размер, в данном примере 50x50. Для чего нужна маска? Она нужна для того, чтобы при выводе спрайта не затиралось изображение, которое находится под ним. Маску можно заготовить отдельно в BMP файле - более быстрый способ, а можно рассчитать программно.Спрайт и маску помещаем в TBitmap.

Wizard:=Tbitmap.Create; Wizard.Loadfromfile("spr1.bmp"); // Bitmap для спрайта WizardMask:=Tbitmap.Create; WizardMask.Loadfromfile("spr2.bmp"); // Bitmap для маски

Ну вот, у нас есть спрайт, маска и нам это вывести его на экран. Для этого существует функция Win32Api:

BitBlt (param_1,X1,Y1,dX1,dY1,param_2,X2,Y2,param_3);

  • Param_1 - Handle на поверхность куда выводить.
  • X1,Y1 - Смещение от начала координат.
  • dX1,dY1 - Размер выводимого изображения.
  • Param_2 - Handle откуда брать.
  • X2,Y2 - Размер выводимого изображения.
  • Param_3 - Параметры копирования.

Для нашего случая:

BitBlt (Buffer.Canvas.Handle,X,Y,50,50, WizardMask.Canvas.Handle,0,0,SrcPaint); BitBlt (Buffer.Canvas.Handle,X,Y,50,50, Wizard.Canvas.Handle,0,0,SrcAnd);

  • SrcPaint - Копировать только белое.
  • SrcAnd - Копировать все кроме белого.

Сначала выводим маску с параметром SrcPaint, а затем в тоже место (координаты X,Y) сам спрайт с параметром SrcAnd.

Осталось рассмотреть зачем же нужен буфер. При выводе одного спрайта вы не почувствуете мелькания изображения, но когда их будет 100-200 это будет заметно. По этому все спрайты копируются в буфер - это Tbitmap размером с экран или окно, короче изменяемой области. Вот как окончательно будет выглядеть фрагмент программы:

Var Wizard, WizardMask,Buffer:Tbitmap; X,Y:integer; ... Wizard:=Tbitmap.Create; Wizard.Loadfromfile("spr1.bmp"); WizardMask:=Tbitmap.Create; WizardMask.Loadfromfile("spr2.bmp"); // Копируем маску в буфер BitBlt(Buffer.Canvas.Handle,X,Y,50,50, Buffer:=Tbitmap.Create; : WizardMask.Canvas.Handle,0,0,SrcPaint); // Копируем спрайт в буфер BitBlt(Buffer.Canvas.Handle,X,Y,50,50, Wizard.Canvas.Handle,0,0,SrcAnd); ... // Перемещаем буфер на форму BitBlt(Form1.Canvas.Handle,0,0,320,240, // Buffer.Canvas.Handle,0,0,SrcCopy);

Флаг SrcCopy означает копирование без изменения, аналогичен простому перемещению одного участка памяти в другой.

Не нужно думать, что готовая маска это прошлое компьютерных игр. В любом случае, маска создается, только иногда это делается программно, а иногда заготавливается в виде отдельного файла. Какой вариант лучше, нужно смотреть по конкретному примеру.

Я не буду расписывать все параметры BitBlt, если интересно смотрите сами в Delphi Help. Ну вот и все. Напоследок исходники и картина творчества.

Cпрайты c программной маской - Transparent

Другой метод вывода спрайтов - методом программной маски. Этот способ, немного медленнее, но не требует возни с изготовлением масок. Это не значит, что маски вообще нет. Маска присутствует и создается в памяти.

Для счастливых обладателей Windows NT подойдет способ, который используется в самой ОС. Это функция MaskBlt. Судя по ее названию, она позволяет выводить растры используя битовые маски.

Привиду пример на спрайтах из игры Эпоха Империй I. Наша задача, как и во всех предыдущих примерах, вывести спрайт с Transparent Color (по русски плохо звучит). В игре он черный.


var Sprite,Mask:TBitmap; begin Sprite:=TBitmap.Create; Sprite.LoadFromFile("G0100219.bmp"); Mask:=TBitmap.Create; Mask.LoadFromFile("G0100219.bmp"); Mask.Mask(clBlack); // Создание маски // Преобразование в маску, после этого получится Bitmap, представленный // на Рис 2 MaskBlt(Form1.Canvas.Handle, 10,10, Sprite.Width, Sprite.Height, Sprite.Canvas.Handle,0,0,Mask.MaskHandle,0,0,SRCPAINT); // После вызова этой функции, экран выглядит как на рисунке 3. BitBlt(Form1.Canvas.Handle, 10, 10, Sprite.Width, Sprite.Height, Sprite.Canvas.Handle,0,0, SRCPAINT); end;

С Windows NT все понятно, но как быть в других ОС? (Хотя возможно, эта функция появится(-лась) в Windows 2000 и Windows Me). Использовать библиотеки сторонних разработчиков. Если они поставляются с исходным кодом, то вы можете перенести необходимые вам процедуры в собственный модуль.

Я нашел самую быструю библиотеку для работы с графикой - Media Library Component Version 1.93 . В примере используется только часть ее. Нам понадобится только одна процедура:

DrawBitmapTransparent (param_1,X,Y,param_2,param_3);

  • param_1 - Canvas, куда копировать
  • X,Y - Смещение
  • param_2 - TBitmap, что копировать.
  • param_3 - TColor, цвет Transparent - этот цвет не будет копироваться

Применение только данной библиотеки не принципиально. Практически в любом наборе VCL компонентов от сторониих производителей есть процедуры или функции для вывода Bitmap с использованием цвета прозрачности. Такие процедуры есть в библиотеке RXLib, LMD Tools, Cool Control и многих других.

Для нашего примера: DrawBitmapTransparent(Buffer.Canvas,WizardX,WizardY,Wizard,clRed); Спрайт должен выглядеть так:

Небольшое замечание по поводу Transparent. Цвет надо выбирать такой, которого нет на самом спрайте, иначе неизбежны "дырки" в изображении. Лучше всего такой: #00FF00 - ярко зеленый, но можно использовать черный или белый.

В предыдущей главе "Работа спрайта c готовой маской" я подвесил передвижение спрайта на таймер:

Procedure TForm1.Timer1Timer(Sender: TObject); begin ... // тело цикла end.

Да cпособ хорош, но не так быстродейственен. Есть еще пара вариантов:

1. Создать поток TThread - в примере разобран именно он.
2. "Подвесить" на IDL

Рассмотрим сначала второй способ т.к. он наименее прогрессивен:) Пишем такую процедуру:

Procedure TForm1.Tic(Sender: TObject; var Done: Boolean); begin ... // Сюда заносим, что надо исполнять. ... Done:= false; end;

И еще немного:

Procedure TForm1.FormCreate(Sender: TObject); begin ... Application.OnIdle:= Tic; end;

Способ быстрее в 1-2 раз чем таймер, но не лишен недостатков. Не буду объяснять почему. Первый способ самый оптимальный для игры, как самой сложной так и простой. Реализуется он с помощью потоков. В игре их можно создать несколько - один для обработки графики, другой для AI, третий для музыки и т.д. У каждого потока свой приоритет, но высший только у одного. При работе с несколькими потоками не забывайте их "прибивать" при выходе из программы.

Сначала заводим новый класс:

TGameRead=class(TThread) // класс для таймера игры protected procedure Execute;override; // Запуск procedure Tic; // Один тик программы end;

Потом переменную:

Var ... T1:TGameRead; ...

Описываем процедуры класса:

Procedure TGameRead.execute; begin repeat synchronize(Tic); until Terminated end; procedure TGameRead.Tic; begin ... // Тут пишем все как в TTimer - OnTime ... end;

В событии Form1.Create инициализируем поток, и задаем приоритет. Расписывать все приоритеты не буду, читайте Delphi Help ...и не забываем убрать за собой:

T1:=TGameRead.Create(false); // Создаем поток T1.Priority:=TpHighest; // Ставим приоритет... procedure TForm1.FormDestroy(Sender: TObject); begin T1.Suspend;// Приостановим T1.Free; // и прибьем end;

Ну вот и все. Ах да, вас наверное заинтересовала строчка FPS. Так это тоже самое, что выдает Quake на запрос "showframerate" или что-то такого плана - количество кадров в секунду. Делается это так: заводится переменная:

Var G:integer; ...

При каждом вызове потока Tic, она увеличивается на единицу:

Procedure TGameRead.Tic; begin ... Inc(G); // Увеличиваем значение G end;

Создаем таймер с интервалом 1000 - это 1 секунда, и в событии OnTime выводим значение G в метку. В значении G будет количество вызовов процедуры DoSome за 1 секунду:

Procedure TForm1.Timer1Timer(Sender: TObject); begin label1.caption:="FPS:"+IntToStr(G); G:=0; // Обнуляем G end;

На моем средненьком Pentium AMD 233 c Intel 740 8M - выдает 90-100 кадров в секунду, при окне 360X360. Для начала неплохо! Исходники , картинка перед вами.

P.S. У вас может возникнуть вопрос - почему передвижение спрайта за мышкой. Ответ: наименьшие затраты на писанину тест программы, при неплохом разнообразии движения.

Использование внешних процедур для Transparent вывода спрайтов, хорошо но есть несколько минусов данного способа:

во первых эти процедуры не слишком оптимизированы - их основное предназначение вывод простеньких элементов приложения, таких как иконок, картинок кнопок и т.д. Хотя это не относится к некоторым библиотекам, код которых на 90% состоит из ассемблера.

во вторых хранить выводимое изображение нужно в bmp файле, хотя подойдет и любой другой, не применяющий компрессию с потерей (Jpeg) . Если картинок более 1-й, а при нормальной анимации их набирается порядка 150-200 на один юнит, то сложно получать именно нужный участок файла.

Приведу пример.

В bmp файле содержатся 8 картинок - 64x64 пикселя. Нужно получить доступ к 6-й картинке (на рисунке помечена розовым квадратом)- ее координаты будут 128,64

Чтобы получить следующий кадр анимации, нужно снова ко номеру кадра считать координаты: Не совсем удобно. Все эти проблемы можно решить используя TImageList.

Использование TImageList

Используя этот компонент можно не думать о координатах картинки, цвете прозрачности - он решает сразу две проблемы.

Разберем что нужно сделать, для вывода спрайта с использованием TImageList. Во первых нужно загрузить набор спрайтов TImageList, для этого лучше всего использовать команду:

TImageList.AddMasked(Image: TBitmap; MaskColor: TColor): Integer;

Первый параметр - это Bitmap, второй Transparent Color - цвет прозрачности. Если Вам не нужно использовать цвет прозрачности, то нужно использовать процедуру Add. После загрузки всех картинок, можно приступать к их выводу на экран. Для этого существует процедура:

Procedure TImageList.Draw(Canvas: TCanvas; X, Y, Index: Integer);

Первый параметр Canvas на который будет произведена отрисовка, второй и третий координаты для вывода X и Y а четвертый индекс или порядковый номер выводимого изображения.

Для примера:

ImageList1.Draw(Canvas,0,0,6);

BitBlt(Canvas.Handle,0,0,64,64,Bitmap_Mask.Canvas.Handle,128,64,SrcPaint); - маска BitBlt(Canvas.Handle,0,0,64,64,Bitmap.Canvas.Handle,128,64,SrcAnd; - спрайт

ImageList1.Draw(Canvas,0,0,6);

Тот же самое, но с использованием BitBlt:

BitBlt(Canvas.Handle,0,0,64,64,Bitmap_Mask.Canvas.Handle,128,64,SrcPaint); - маска BitBlt(Canvas.Handle,0,0,64,64,Bitmap.Canvas.Handle,128,64,SrcAnd; - спрайт

Думаю пояснять нет нужды, что использовать TImageList лучше, и проще. Пример работы с TImageList описан в файле. Там показана анимация персонажа из игры WarCraft и Warlord III. Я так и не разобрался как работает механизм отрисовки в TImageList. Мои раскопки привели к такой функции:

Function ImageList_Draw(ImageList: HImageList; Index: Integer; Dest: HDC; X, Y: Integer; Style: UINT): Bool; stdcall;

Function ImageList_DrawEx(ImageList: HImageList; Index: Integer; Dest: HDC; X, Y, DX, DY: Integer; Bk, Fg: TColorRef; Style: Cardinal): Bool; stdcall;

HImageList - Handle на TImageList.

Так как вызывается экспортируемая процедура, находящаяся в библиотеке Comctl32.dll то остается не понятным, какие алгоритмы используются при выводе изображения. Могу только сказать, что при добавлении нового изображения, добавляется как изображение так и маска.

Я заинтересовался данным вопросом и продолжал копать стандартные библиотеки Windows и компоненты. Возможно информация по данным вопросам содержится во многочисленных SDK, выпускаемых Microsoft. В компоненте TFastDIB я наткнулся на процедуру Draw:

Procedure TFastDIB.MaskDraw(fDC,x,y:Integer;c:TFColor); begin TransBlt(fDC,x,y,Width,Height,hDC,0,0,Width,Height,PDWord(@c)^); end;

Естественно меня заинтересовала процедура TransBlt и вот что я нашел:

Function TransBlt(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11:DWord):BOOL; stdcall; ... function CreateDIB; external "gdi32.dll" name "CreateDIBSection"; function TransBlt; external "msimg32.dll" name "TransparentBlt"; function AlphaBlt; external "msimg32.dll" name "AlphaBlend";

Мне захотелось посмотреть, а что еще может библиотека "msimg32.dll" и вот полный список:

  • AlphaBlend
  • GradientFill
  • TransparentBlt
  • DllInitialize
  • vSetDdrawflag

Все, хватит, а то некоторые читатели и так ничего не поняли. Но для интересующихся скажу - не все процедуры и функции описаны в Delphi, многое не документировано.

Использование Direct X

Чем плохи рассмотренные выше методы вывода спрайтов - они медленные. Хочу подчеркнуть, что для каждой программы нужно выбирать свои методы написания. Конкретное задание требует своих средств исполнения. То что Microsoft написал библиотеку Direct X не значит что тут же нужно писать всю графику используя ее.

Приведу пример. Самая популярная игра для Windows - Quake II, Warcraft, Diablo - нет САПЕР и ПАСЬЯНС. Можете не верить, но это факт. В первую категорию играют ограниченный контингент людей в последнюю играли ВСЕ. Я это говорю к тому, что если вы пишите графическое приложение, то нужно ориентироваться на его потребности и выбирать соответствующие технологию зависимости от них. Какие это потребности:

необходимость вывода большого количества часто сменяющихся изображений
большой объем графической информации
аппаратная поддержка
максимальное быстродействие

Используя Direct X можно получит все вышеперечисленное. Набор этих библиотек, изначально разрабатывался как средство для работы с графикой. Что было, когда писали под DOS: строили в участке памяти (back buffer) какое то изображение или копировали туда спрайты, а потом перемещали этот back buffer в область "экранной" памяти. Сразу отрисовывался весь экран. С приходом Windows, переместить участок памяти в экранную область не возможно. Приходится использовать Canvas, Handle.

DirectX позволяет решить все эти проблемы. Вы можете подготавливать изображение на так называемой поверхности, и потом FLIP и вся поверхность становится видимой - копируется в экранную область видеопамяти. Должен заметить, что алгоритм работы ничуть не меняется.

С появлением DirectX появились и аппаратные поддержки таких необходимых вещей как: Trancparent Color и Bit blitting.

Термин бит-блиттинг означает процесс перемещения группы битов (образа) из одного места экрана в другое или памяти. В играх на ПК нас интересует перемещение образа из области хранения вне экрана в область видеобуфера. Кто интересуется аппаратными возможностями своей видео карты, то их можно узнать достав Microsoft DirectX CPL. В ней можно просмотреть, какие функции в видео карте реализуются аппаратно, а какие програмно.

Итак процесс работы таков, загружаете спрайты на поверхность (ISurface) затем нужно вызвать процедуру BLT или BLTFAST, потом поменять буферную и видимую поверхность командой FLIP и все.

В начале раздела я написал Direct X, но я несколько обманул Вас. Я расскажу как выводить спрайты с помощью Direct X, но с использованием набора VCL компонентов DelphiX . Я это делаю по той простой причине, что если я напишу пример используя стандартные модули DirectX то их некоторые не поймут, отчаяться и бросят программировать вообще:) Согласитесь не все сразу поймут, что делает данная процедура, хотя она всего лишь меняет поверхности.

Var hRet: HRESULT; begin Result:= False; while True do begin hRet:= FDDSPrimary.Flip(nil, 0); if hRet = DD_OK then Break else if hRet = DDERR_SURFACELOST then begin hRet:= RestoreAll; if hRet <> DD_OK then Exit; end else if hRet <> DDERR_WASSTILLDRAWING then Exit; end; Result:= True; end;

По этому я и решил использовать . Писать с помощью него очень просто. Нам потребуется всего два компонента. Первый TDXDraw - если объяснить коротко, то это аналог TCanvas. Еще один компонент это TDXImageList - прямой аналог TImageList, единственно все элементы являются TDIB и не содержат ни каких масок.

, Как добавить врагов , Контроллер врагов .
5. Простейшая игра (3) : Система частиц , Добавление звуков , Создание текста на экране , Публикация .
6. Трехмерный платформер. (в процессе создания)

2. Интерфейс программы

Начнём с простого – с внешнего вида программы. Нельзя просто так взять и создать что-то в программе, если вы видите её в первый раз. Для начала нужно всё осмотреть, привыкнуть к расположению окон, оценить количество всевозможных менюшек и кнопок. Для этого можно выделить немного времени и самостоятельно попытаться что-нибудь сделать в программе, а можно ознакомиться со всем интерфейсом под нашим руководством.

Это нужно, чтобы появилось чувство комфорта в программе, чтобы уже чисто интуитивно знать расположение всех инструментов, и больше никогда не заострять на этом внимания. (Ближайший пример: в автомобиле при первом опыте вождения нужно больше обращать внимание, не на то, какие знаки на дороге, а то, как вы держите руль и с какой силой нажимаете на педали. А в дальнейшем про такие мелочи даже и не вспоминают, они выполняются на автомате, чисто интуитивно).

(Если эта тема не интересна, вы замечаете, что начинаете быстро утомляться при чтении, то можете пропустить целый раздел «Интерфейс», и сразу перейти к разделу «3. Создание простейшей игры ». Многим трудно даётся теория, гораздо эффективнее получается обучение сразу на практике. В 3-ей главе вы сразу же будете видеть результат своей работы, и обучение начнет приносить положительные эмоции. Но чтобы всё осознать, вам придётся периодически возвращаться ко второму разделу).

Ну а мы продолжаем.

Общий вид

Рабочее окно Unity разбито на 6 взаимосвязанных областей. (По умолчанию в Unity включается вид «Default» или «Tall». Если у вас другой вид рабочего окна, то можете переключить его в меню «Layout» в верхнем правом углу окна).



Перечень всех рабочих областей окна Unity:


1. Main menu
(Главное меню)
Строчка текста сверху, где располагаются все команды , доступные в программе. Многие команды продублированы кнопками и меню в рабочих областях, поэтому главное меню не обязательно использовать.
2. Project View
(Обзор проекта)
Список, в котором показаны все используемые файлы в игре: файл сцены, файл программного кода, графические и аудиофайлы.
3. Hierarchy
(Иерархия)
Список, где перечислены все объекты , добавленные на сцену. Здесь можно работать с объектами, копировать их, переименовывать, удалять.
4. Scene
(Сцена)
Область, где отображается игровой мир или игровая сцена. Здесь мы можем добавлять новые объекты, перетаскивать их, менять вид.
5. Game
(Игра)
Область предпросмотра, где видно, как сцена будет выглядеть в игре . Здесь можно настраивать различные настройки экрана и видеорежима.
6. Inspector
(Инспектор)
Список, состоящий из нескольких различных по виду разделов. Показывает все свойства выбранного объекта : размеры, модели, текстуры, скрипты.

Подробнее о каждой области будет описано ниже.

2.1. Главное меню (Main menu)


Главное меню Unity3D стандартно располагается в верхнем левом углу окна. Здесь есть обычные команды, типа «сохранить», «загрузить», но есть и уникальные для этой программы строчки.


В главном меню содержатся вообще все команды программы, а в основных областях окна они лишь дублируются. Таким образом, чтобы рассмотреть все значения и переводы команд, нужно знать Юнити досконально, поэтому все команды главного меню мы рассмотрим подробно чуть позже на отдельной странице.

2.2. Обзор проекта (Project View)


Каждый проект содержит папку «Assets». Содержимое этой папки представлено в области «Project View». Это ресурсы игры: файлы-скрипты, 3D-модели, текстуры, аудиофайлы, префабы (объекты, которые можно клонировать).


(Перемещение файлов можно выполнять в папке и через стандартный Проводник Windows, щёлкнув правой кнопкой мыши по нему и выбрав «Reveal in Exlorer». Но при перемещении ресурсов в Проводнике Windows будут потеряны все ссылки между объектами. Лучше всегда перемещать файлы внутри проекта только в «Project View»).


Добавить новый ресурс в проект можно двумя способами:

Перетащить файл из Проводника в Project View.

Команда «Assets» > «Import New Assets».


Проекты игры состоят из одного или нескольких файлов сцены. Каждая отдельная сцена – это отдельный уровень игры. Сцены так же хранятся в папке «Assets» и отображаются в «Project View».


Некоторые игровые ресурсы не являются файлами, и создаются непосредственно в Unity. Для создания ресурса используется выпадающее меню «Create» в «Project View» или (ПКМ) > «Create».

Меню «Create» позволяет добавлять в проект скрипты, префабы, папки и прочее. Любой ресурс или папку можно переименовать, нажав «F2» или сделав два клика по имени. Если зажать «Alt», то при раскрытии директории будут раскрыты и все поддиректории.

2.3. Иерархия (Hierarchy)


Иерархия содержит все объекты (GameObject) открытой сцены. Объекты, добавляемые в сцену или удаляемые из неё, отображаются или наоборот перестают отображаться в Hierarchy.


Наследование (Parenting). В иерархии Unity объектам можно задавать наследование. Любой объект может быть дочерним по отношению к другому. Дочерний объект будет двигаться и вращаться вместе с родителем. Для создания дочерней связи достаточно перетащить объект на «родителя» в Hierarchy.

2.4. Сцена (Scene View)


Игровая сцена используется для расстановки объектов на уровне (окружение, персонажи, камеры, системы частиц и прочее). Сцена может являться игровым уровнем, главным меню, заставкой.


В 2D режиме управление интуитивно понятно. В 3D режиме есть множество приёмов для перемещения по сцене:

* Зажатый ПКМ активирует режим свободного полёта.

* Перемещаться можно клавишами WASD на манер игры в жанре FPS.

* Выберите объект в списке иерархии и нажмите «F». Вид сцены будет центрирован и масштабирован по выбранному объекту.

* При зажатом Alt, ЛКМ будет крутить камеру вокруг текущей точки опоры.

* При зажатом Alt, СКМ будет перемещать камеру.

* При зажатом Alt, ПКМ будет масштабировать вид сцены.

* Альтернативный режим перемещений - клавиша Q.

2.5. Игровой вид (Game View) Сайт сайт


Game View - предпросмотр игры (рендер из игровой камеры).

В расположении окон по умолчанию «Игровой вид» отсутствует, для его включения нужно выбрать вкладку «Game» над игровой сценой. В других режима окон «Игровой вид» занимает своё отдельное место.


Три кнопки в верхней части окна Юнити отвечают за управление предпросмотром игры: «Play», «Pause» и «Step». (Все изменения, произведённые во время предпросмотра, сбрасываются при выходе из него. Исключением являются изменения в префабах).


Game View Control Bar

Первое выпадающее меню в «Game View» - это контроль пропорций изображения (Aspect Drop-down). На некоторых дисплеях это соотношение отличается от стандартного 4:3 (например, на широкоформатных мониторах - 16:10).

Кнопка «Gizmos» включает отображение контейнеров гизмо в «Game View».

Последняя кнопка - «Stats». Она показывает статистку рендеринга (Rendering Statistics), полезную при оптимизации.

2.6. Инспектор (Inspector)


GameObject – это любой объект в игре. Следует понимать, что сам по себе объект ничего не делает. Ему требуются специальные свойства, прежде чем он станет персонажем, окружением или визуальным эффектом.

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


Перечень объектов содержится в области «Hierarchy». Если в списке иерархии мы выберем любой объект, то в области «Inspector» (Инспектор) отобразятся все свойства этого конкретного объекта. Здесь же можно редактировать все эти свойства или добавлять новые.


Объект может содержать в себе такие типы компонентов: расположение в пространстве (Transform), меши (meshes), скрипты (scripts), звуки, ИС (Lights) и другие элементы.

Status Bar

Строка состояния (Status Bar) расположена в нижней части окна редактора. Она отображает ошибки компиляции и логи дебага. Если возникают проблемы с игрой, стоит заглянуть в строку состояния. Двойное нажатие на неё вызовет окно консоли (Console), в котором отображаются все ошибки.

2.7. Настройка рабочего окна

Можно настраивать расположение (Layout) секторов, перетаскивая их за закладки. Если перетащить закладку в область закладок уже существующего окна, то она будет добавлена к присутствующим там закладкам. Также можно прикрепить сектор к краю экрана или краю другого сектора.

Сектор может быть пристыкован к одной из сторон существующего окна.

Закладки могут открепляться от главного окна редактора и включаться в состав плавающего окна редактора. Плавающее окно может содержать сектора и закладки так же, как и главное окно.

Плавающее окно редактор похоже на главное окно, но не имеет панели инструментов (Toolbar).

Когда расположение секторов задано, его можно сохранить и загрузить в нужный момент через выпадающее меню Layout (Save и Load).

Полностью настроенное расположение секторов.

В любое время можно правым кликом по закладке вызвать меню с дополнительными возможностями, такими как максимизация сектора или добавление новых закладок.

Достижение "Почётный читатель сайт"
Понравилась статья? В благодарность можно поставить лайк через любую социальную сеть. Для вас это - один клик, для нас - очередной шаг вверх в рейтинге игровых сайтов.
Достижение "Почётный спонсор сайт"
Для особо щедрых есть возможность перевести деньги на счет сайта. В этом случае вы можете повлиять на выбор новой темы для статьи или прохождения.
money.yandex.ru/to/410011922382680