Сегодня: Вторник, 19.03.2024, 10:33 (МСК)| Здравствуйте, Гость| Мой профиль | Регистрация | Вход | RSS

Популярно об ИИ.
Третий сезон

Спецэффекты в Cinema4D

Эргономика компьютерных клавиатур

Google Chrome. Таким должен быть браузер

Adobe Audition 3. Лучшая в 2010-м
Главная » РАЗРАБОТКА КОМПЬЮТЕРНЫХ ИГР

Lua для игр и не только. Часть 1

01.08.2010


Если вы не любите кошек, значит, вы не умеете их готовить.

Если что-то должно быть сделано, то нужно это сделать качественно. О языке Lua написать должно, потому как он сопровождает мировые технологии топ-класса, а насчет качества… не хочется уподобляться быстрому обзору в стиле «я знаю Lua» или «Lua как явление с точки зрения профи», а объяснить суть процессов, связанных с этим языком, так чтобы было понятно, и вы смогли бы на нем программировать. Причем для начального освоения вам понадобится немногое: скачать последнюю версию языка и бесплатную программу в 1,2 Мб, плюс уделить немного времени. 

Эпиграф к этой статье очень хорошо может быть отнесен к прекрасному и своеобразному Lua. Для многих Lua — это свободно распространяемый далеко не всем понятный язык программирования бразильского происхождения, причем серьезно меняющийся. Но его нельзя не любить, он уникален и широко используется в высокопроизводительных мультиплатформенных разработках, в том числе и в компьютерных играх топ-класса (World of Warcraft и т.д.). 

Эту серию материалов можно назвать продолжением популярной в прошлом году «Разработка компьютерных игр» и ответвлением от «Популярно об ИИ» (искусственный интеллект очень часто пишется на Lua и вскоре вы поймете почему). Изучение Lua можно рекомендовать всем, кто связан с разработкой ПО на современном уровне (при разном уровне подготовки), язык достаточно необычен и очень интересен, синтаксис прост. Lua по изначальной своей концепции является встраиваемым языком, то есть может внедренно работать в рамках низкоуровневых API. Основное предназначение — написание сценариев и обработка сложных данных, хотя… не только. Изначально Lua и был придуман как язык расширения для включения в программы-хозяева, написанные на С, но может использоваться и автономно. 

Lua.org является лабораторией подразделения компьютерных наук при Папском Католическом Университете (Pontifical Catholic University) Рио-де-Жанейро. Авторы проекта — R. Ierusalimschy, L. H. de Figueiredo и W. Celes. По-португальски слово «lua» обозначает «Луна».


Намек на принадлежность



Функциональную принадлежность того или иного языка при первом знакомстве обычно легко определить по имеющимся в нем типам данных. В Lua их восемь: nil (неопределенный), boolean (логический), number (числовой), string (строковый), function (функция), userdata (пользовательские данные, получаемые из внешнего API), thread (поток), table (таблицы, а по существу, единственный механизм структурирования данных). Все это подробно мы обсудим позже. Сложно? На самом деле только на первоначальном уровне понимания основной концепции. То есть, это перечисление будет понятным для опытных программистов, а начинающим достаточно просто принять эту информацию к сведению, потом мы все хорошо и полно расшифруем. Также в языке предусмотрена автоматизация работы с памятью (мусороуборщик) и так далее. 


Для чего нужен Lua?


Обычно дилемма в программировании всегда одна: как совместить высокую производительность кода с продуктивностью и скоростью разработки. Первое нам предлагают низкоуровневые компилируемые языки типа С/С++, второе — интерпретируемые или языки сценариев. Причем иногда хочется просто отделять «котлеты от мух», а точнее — компилируемый код от сценариев.
С этим столкнулись практически все области программирования, а наиболее остро такая проблема стала перед разработчиками компьютерных игр. Специфика создания этой продукции заключается в том, что спектр задач велик, но решать их нужно оперативно. Можно, конечно, ждать у моря погоды, когда кто-то решит все за вас, но это — время. Поэтому такой достаточно слабо известный широкому кругу обывателей язык Lua стал неким технологическим ноу-хау в отрасли. 

Суть его заключается в том, что он является встраиваемым, высокоуровневым и data-oriented, то есть, предназначенным для обработки сложных данных. Приложения, включающие Lua, представляют собой комбинацию компилируемого кода и Lua-сценариев. Компилируемый код может при необходимости заняться железом, и, в то же время, может вызывать Lua-сценарии для обработки сложных данных. Эти сценарии могут писаться и модифицироваться независимо от компилируемого кода.  

Ситуация выгодна и тем, что сценарии обладают своего рода переносимостью. То есть, например, при переводе игры/программы на другую платформу вам нужно менять только компилируемую часть. 


С чего лучше начать первое знакомство?


Для первого знакомства и предварительного изучения синтаксиса рекомендуется скачать русифицированную версию программы SciTE (1,2 Мб), в которой мы и начнем работать. Это универсальный текстовый редактор/компилятор для Windows/OSX, поддерживающий синтаксис более 70 языков программирования, благодаря использованию лексеров (lexer) — программных модулей для анализа и обработки конкретного языка программирования. Лексеры подобны плагинам, и пишутся, в основном, независимыми разработчиками. SciTE удобен для изучения тем, что он имеет встроенную полноценную версию Lua, и мало того, сам базируется на Lua-сценариях, а в Help’е к нему вы найдете ничто иное как перевод родной документации к последней версии этого языка. Кстати, самый качественный перевод из всех существующих в рунете. 


Программа SciTE

Помимо этого последние версии языка Lua (на момент написания материала 5.1.4) можно скачать с сайта www.lua.org, что пригодится нам потом. В поставку включена простая хост-программа lua, которая использует библиотеку Lua и представляет из себя полную и автономную реализацию интерпретатора языка, а также компилятор luac. Lua является свободно распространяемым программным средством, поэтому предоставляется без каких либо гарантий в соответствии с лицензией. 

Информации по Lua в интернете достаточно много, в том числе и русскоязычной. Хотя описания старых версий абсолютно не актуальны, Lua сильно меняется. Англоязычный сегмент также велик, причем очень часто советуют обратиться к книге соавтора проекта Роберто Иерусалимского (Roberto Ierusalimschy) «Программирование на Lua», второе издание (Programming in Lua (Second Edition)). Как мы уже сказали, от версии к версии язык претерпевает существенные изменения, и не только сам язык, но и его концептуальные основы (например, два года назад оперировали ключевым понятием тэгов (tag), использовали множество функций, которых сейчас нет, вернее, все видоизменено, и это произошло за два года!). То есть нужно, как говорится, держать нос по ветру, поскольку специфики очень много. Есть и сложности с первоначальным освоением, потому как большинство описаний и руководств носит формальный характер, чего мы попытаемся в данной серии избежать. Поэтому начнем со SciTE и автономного использования Lua. После переключимся на более сложный уровень.

Если есть необходимость использования другого компилятора для языка Lua, в том числе и под другие ОС (Linux i386, BSD i386 (FreeBSD, NetBSD или OpenBSD), Mac OS X на Intel’ах, Solaris x86 (только GCC, не SunCC), MinGW (Win32), Cygwin, POSIX на x86, Generic x86), то можно рекомендовать LuaJIT (Lua Just-In-Time Compiler), который есть по адресу http://luajit.org/.


Общие данные


Lua — типичный процедурный язык (библиотека его функций написана на подмножестве ANSI C и C++), он может компилироваться без всяких модификаций на всех известных платформах, имеющих компилятор ANSI C. В данном случае мы уже немного забежим вперед и скажем, что работа с функциями Lua не сильно отличается от работы с обычными С-библиотеками, причем часто само понятие «функции Lua» приравнивают к макросам, что действительно так, по поведению они схожи. Как мы уже отметили, Lua является встраиваемым, то есть интегрируемым, и в этом случае для функционирования кода на нем написанного, нужна хост-программа. Ей, в свою очередь доступно ряд функций на С для связи с Lua. Все функции API, связанные типы и константы объявлены в файле заголовка lua.h (также хорошо описаны в документации). 

Все инструкции в Lua выполнены в глобальной среде. В ее рамках позволяется запускать части кода, написанные на Lua, модифицировать переменные Lua и регистрировать С-функции для использования непосредственно в коде Lua. Эта среда будет инициализирована обращением lua_newstate и сохранится до обращения lua_close или до завершения ведущей программы. Глобальная среда может управляться Lua-кодом или ведущей программой, которая может читать и писать глобальные переменные, используя функции API из библиотеки, которая предоставлена Lua. Все переменные в Lua являются глобальными, если отдельно не указано, что они локальны. Дальнейшие тонкости рассмотрим в процессе, а сейчас начнем с основ. 


Hello, world!


Запускаем SciTE, ничего не меняем, просто создаем новый файл, который у вас по умолчанию обозначится как Untitled.txt. Вводим в него строку:

print("Hello, world, from ",_VERSION,"!\n")

Поскольку у нас не обозначена принадлежность этого файла к чему-либо, ведь расширение *.txt ни о чем не говорит, команда «Tools -> Выполнить» (или F5) ни к чему не приведет. Пересохраняем файл под новым именем, например, Hello.lua (расширение *.lua является типичным для файлов сценариев, написанных на этом языке). Теперь нажимаем F5 и в окне вывода видим результат:

Hello, world, from Lua 5.1!

При этом отметим, что print() является базовой функцией Lua, она удобна для быстрого отображения значения и обычно используется для отладки. Она не очень удобна для отформатированного вывода, для которого уместнее использовать string.format().
Немного расширим наш пример с использованием функции, форматирующей строку:

function printf(...)
 print(string.format(...))
end
printf("Hello from %s on %s\n",_VERSION,os.date())

По нажатии F5 выдается результат:

Hello from Lua 5.1 on 04/14/09 10:19:53

Теперь прокомментируем, вернее, расскажем о котах и их приготовлении:). Синтаксис языка поначалу не совсем привычен, особенно для тех, кто привык к ECMA-262 (С++ подобное семейство языков сценариев, куда входит JavaScript, ActionScript и т.п.). Чем-то Lua близок к С (не С++), хотя все здесь перемешано. К тому же синтаксис Lua довольно свободен и очень часто одно и то же выражение можно записать по-разному.

Для первоначального изучения лексики, синтаксиса и семантики языка лучше порекомендовать использовать SciTE и программирование на Lua в автономном режиме (что мы и начали делать), пройдя стандартный путь от Hello, world! до сложных вычислений. Впрочем, много тонкостей вы можете узнать и сейчас. 


Синтаксис


М-да, а начнем мы с веселого, которое для многих просто пробегается глазами, но тут важно. В переводе документации по Lua для SciTE есть, пожалуй, единственная, но очень досадная и коварная ошибка (в англоязычной документации она отсутствует). Итак, короткие комментарии помечаются двойным дефисом «--», что соответствует С-шному «//». Для ввода длинных комментариев вместо С-варианта «/*…*/» предполагается в простейшем случае «--[[…]]». Обратите внимание на то, что квадратная скобка двойная, а не одинарная, как опрометчиво указано в русскоязычном переводе документации. Причем эта ошибка фатальна, и часто можно увидеть как начинающие программисты, просто не захотев разобраться с ситуацией, пользуются короткими комментариями, считая вариант с длинными — глюком. А как быть, когда нужно оперативно отключить большую часть кода?

Так вот, на самом деле Lua гораздо умнее. Двойными квадратными скобками обозначается уровень вложенности строки. В варианте [[…]] мы имеем нулевой уровень вложенности, а все последующие указываются с помощью количества знаков «=» между открывающимися или закрывающимися квадратными скобками. Например, четвертый уровень вложенности обозначается как [====[…]====] (четыре символа «=» при открытии и закрытии). С длинными комментариями такой вариант работает даже лучше, чем в варианте С с его «/*…*/», потому как можно делать множество уровней этих самых комментариев. 

Почему это так важно? Дело в том, что вложенность строк может распространяться не только на комментарии, но и при работе с литеральными строками (в том числе как вариант замены некоторых С-подобных escape-поледовательностей). Например, нам нужно вывести вариант в двух строках:

apple
117"

Синтаксис С в данном случае также будет работать, то есть, мы запишем:

a = ’apple\n117"’ 
print(a)

… и получим необходимое. «\n» — это перевод на новую строку. Можно использовать и двойные кавычки используя «\”» (символ двойной кавычки):

a = "apple\n117\"" 

Можно использовать и ASCII-код, в котором, например: символ «a» — это 97, «1» — 049, символ перевода строки — 10:

a = "\97pple\10\049\0497\”"

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

a = [=[apple
117"]=]

Все. Необходимый результат будет выведен. Причем такая ситуация с вложениями на разных уровнях во многих вариантах бывает весьма актуальной. То есть, литеральную строку мы открываем/закрываем на одном уровне, комментарий делаем на другом и так далее.

Опытный программист, не работавший с Lua, внимательно посмотрев на то, что написано, заметил, что по завершении любой из операций напрочь отсутствует «;», вызывающий особую любовь у представителей других языков. В качестве разделителя может выступать обыкновенный пробел или переход на другую строку, хотя, что интересно, если по привычке вы напишете точку с запятой, то сообщения об ошибке не появится. То есть применение этого разделителя факультативно, хотя иногда и уместно. Пустого оператора в языке нет, поэтому выражение ';;' не допустимо.

А еще опытный программист, взглянув на обозначение комментария, скажет, что в Lua отсутствует декремент, который в С++ и ему подобных записывается как «--». Это действительно так, в Lua нет операций ++, --, +=, -=, *=, /=. И это не единственные перлы с упрощением, о многом вы узнаете во второй части материала.


Промежуточное завершение


Lua — один из самых интересных современных языков. Его применение простирается не только на компьютерные игры, хотя стоит отметить, что последние являются представителями самого сложного сегмента программирования. Вашего покорного слугу в свое время Lua удивил по классическим правилам шоу-бизнеса: сначала ошарашил, а потом озадачил. 

Причем, изучая новации в Microsoft Visual Studio и в языках с ней связанных, можно увидеть схожее движение в сторону интегрирования высоко и низкоуровневых подходов (то же «многоязыковое программирование»), при котором один язык расширяет возможности другого. Такое же мы можем наблюдать во взаимодействии Lua и C API. Хотя последний вариант по современным меркам — высший пилотаж. 




Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Ассоциация боевых роботов
Рекомендуем...
Новости

Разделы

Опросы

Какой язык программирования вы считаете наиболее актуальным сегодня?
Всего ответов: 329

Друзья

3D-кино






Найти на сайте:








Об авторе       Контакты      Вопрос-ответ        Хостинг от uCoz