Предисловие


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

Что нужно?


  • Средние знания С++(на нем и будем писать двигатель).
  • Базовые знания Lua (для описания игровой логики).

Как все устроено?


Вся игровая логика будет программироваться в файле, например — «main.lua». Движок будет читать этот файл и исполнять действия описанные в этом файле. Вывод графики будет с помощью SDL 2.0, физика — Box2D, аудио — OpenAl, скриптинг — Lua. IDE — Microsoft Visual Studio любой версии.

Нарисовал схему




Начинаем!


Сначала надо скачать:

  1. Lua
  2. SDL 2.0
  3. Box2D (надо будет скомпилировать самому)
  4. OpenAL

Скачайте и переместите все файлы в отдельную папку, например — «Engine SDK». Открываем MVS, создаем «пустое» консольное приложение, далее добавляем файл — «main.cpp».

Заполняем пока таким образом:

int main()
{
return 0;
}

Компилируем, если скомпилировалось, идем дальше. Жмем «Project > project properties». Выбираем «C/C++ > General» и добавляем дополнительные папки включения (указывайте путь где вы извлекли из архива Lua). Указываем путь к «include» Lua.



После этого заходим «Linker > General» и добавляем путь к либе.



Применяем и изменяем «main.cpp»

int main(int argc, char * argv[])
{
return 0;
}

Компилируем, идем дальше. Далее нам нужно создать отдельный заголовочный файл, в котором будет основная часть движка. Добавляем файл «Engine.h». И сразу заполняем его таким образом.

#include<iostream>
#include<lua.hpp>
#pragma comment(lib,"lua53") // на момент написания статьи версия Lua 5.3.
using namespace std;
class Lua
{
private:
	lua_State * lua_state;
public:
	void Init()  // инициализируем и подключаем модули.
	{
		lua_state = luaL_newstate();
		static const luaL_Reg lualibs[] =
		{
			{ "base", luaopen_base },
			{ "io", luaopen_io },
			{ "os",luaopen_os },
			{ "math",luaopen_math },
			{ "table",luaopen_table },
			{ "string",luaopen_string },
			{ "package",luaopen_package },
			{ NULL, NULL }
		};
		for (const luaL_Reg *lib = lualibs; lib->func != NULL; lib++)
		{
			luaL_requiref(lua_state, lib->name, lib->func, 1);
			lua_settop(lua_state, 0);
		}
	}
	void Open(const char*filename) // открываем файл с кодом (main.lua)
	{
		luaL_openlibs(lua_state);
		if (luaL_dofile(lua_state, filename))
		{
			const char*error = lua_tostring(lua_state, -1);
		}
	}
	void Close() // закрываем
	{
		lua_close(lua_state);
	}
	void Reg_int(int value, char*name) 
	{
		lua_pushinteger(lua_state, value);
		lua_setglobal(lua_state, name);
	}

	void Reg_double(double value, char*name)
	{
		lua_pushnumber(lua_state, value);
		lua_setglobal(lua_state, name);
	}

	void Reg_bool(bool value, char*name)
	{
		lua_pushboolean(lua_state, value);
		lua_setglobal(lua_state, name);
	}
	void Reg_string(char*value, char*name)
	{
		lua_pushstring(lua_state, value);
		lua_setglobal(lua_state, name);
	}
	void Reg_function(lua_CFunction value, const char*name) // регистр нашей функции
	{
		lua_pushcfunction(lua_state, value);
		lua_setglobal(lua_state, name);
	}
	int Get_int(int index) // берем числовой аргумент из функции
	{
		return (int)lua_tointeger(lua_state, index);
	}
	double Get_double(int index) 
	{
		return lua_tonumber(lua_state, index);
	}
	char* Get_string(int index)
	{
		return (char*)lua_tostring(lua_state, index);
	}
	bool Get_bool(int index)
	{
		return lua_toboolean(lua_state, index);
	}
	void Return_int(int value) // возвращаем числовое значение из функции
	{
		lua_pushinteger(lua_state, value);
	}
	void Return_double(double value)
	{
		lua_pushnumber(lua_state, value);
	}
	void Return_string(char*value)
	{
		lua_pushstring(lua_state, value);
	}
	void Return_bool(int value)
	{
		lua_pushboolean(lua_state, value);
	}
	int Call_load() // вызываем при старте
	{
		lua_getglobal(lua_state, "Load");
		lua_call(lua_state, 0, 1);
		return 0;
	}
	int Call_update() // вызываем пока работает приложения
	{
		lua_getglobal(lua_state, "Update");
		lua_call(lua_state, 0, 1);
		return 0;
	}
	int Call_draw()
	{
		lua_getglobal(lua_state, "Draw"); // вызываем после "Update"
		lua_call(lua_state, 0, 1);
		return 0;
	}
};
Lua lua;// lua экземпляр

Компилируем, если нет ошибок, идем дальше, если же есть, значит вы где- то накосячили. Изменяем «main.cpp»:

include "Engine.h"
int main(int argc, char * argv[])
{
lua.Init();
lua.Open("main.lua");
lua.Call_load();
lua.Close();
return 0;
}

Компилируем, если без ошибок, двигаемся дальше. Создаем в папке проекта текстовый файл «main.lua». Заполняем его так:

function Load()
print("Lua inited!")
end

function Update()

end

function Draw()

end

Компилируем, бросаем «lua5*.dll» в папку проекта, запускаем, и Оппа! В консоле вывело «Lua inited!». По сути мы написали простой Lua — интерпретатор. В второй части приступим к выводу графики.
Поделиться с друзьями
-->

Комментарии (17)


  1. NeonMercury
    02.06.2017 13:21
    +3

    Чем он будет отличаться от love2d? Будет ли LuaJIT? Почему не взяли luabind или toLua++?


    1. Wolf_Black
      02.06.2017 13:26

      :3


    1. Wolf_Black
      02.06.2017 13:28
      +1

      Будет отличатся своими функциями, наверное, суть в том, что бы показать основу, таким образом можно и 3D функции добавить, лишь рендер реализовать.
      А вопрос можно ассоциировать, как «Чем твой собственный „хелло, ворлд“ будет отличатся от чужого?»


  1. AWE64
    02.06.2017 14:45
    +4

    «Как нарисовать сову.jpg»


  1. Pinsky
    02.06.2017 14:53

    Думаю, раскопки этой репы подарят не меньшее удовольствие: https://github.com/antirez/load81

    P.S. что то последнее время каждый стремится написать свой Lua game engine. Pico8, Tic80 думаю к ним тоже идут.


  1. wikipro
    02.06.2017 19:28
    -2

    Что нужно для МАССОВОГО прикладного использования скриптового языка типа Lua в играх? Этот язык д.б. максимально простым для использования.
    Существует эмпирическое правило “Уменьшение сложности / порога вхождения в 2 раза увеличивает количество пользователей в 5-10 раз”.
    Каково типичное использование скриптового языка не программистом, а пользователем, (геймером, писателем торговых роботов, и т.п.)?
    Открыть готовый скрипт, попытается понять его попробовать исправить.
    Для быстрого и эффективного обучения желательно чтобы 70-80% изучаемого материала было известно. Т.о. новая информация эффективно связывается с уже усвоенными знаниями.
    Что для этого можно сделать? Основная масса не программистов плохо знает английский язык. Реально слов надо выучить 30-40 но это создаёт ненужный психологический входной барьер, препятствующий быстрому старту.
    Надо ли переводить Lua на русский язык? – Нет.
    Что сделала компания 1С написавшая самый популярный коммерческий язык программирования для не программистов? Она дополнила английские операторами их русскими синонимами.
    Программисты пишут на привычном Lua, если надо используют готовые чужие скрипты. Геймеры-школьники, писатели торговых роботов и прочие КулХакеры пишут так как им удобнее и проще и понятнее. Конвертор для Рус <-> Лат написать даже на Lua не проблема. Т.о. создаётся закрытая экосистема и лояльные пользователи. Условно назовём эту версию LuaPLUS
    Как это должно выглядеть для пользователя :


    1. В игре или приложении заменяется файл lua5.dll на lua5.dll (LuaPlus)
    2. После этого, как и раньше, работают все старые скрипты lua из примеры из интернета, но добавляется возможность в существующих и новых скриптах использовать русские имена переменных, функций и получать все сообщения об ошибках на русском.
    3. Всё!!!
      Что для этого надо сделать? необходимо добавить в исходники lua возможность использовать :
    4. русские имена переменных и функций
    5. русские ключевые слова (для упрощения нужно просто взять перевод 1С)
    6. сообщения об ошибках перевести на русский язык
    7. IDE с подсветкой синтаксиса, автодополнением и конвертором кода – РУС<->Лат
      Первая версия LuaPLUS реализующая эти возможности д.б. под Win7 чтобы дать возможность геймерам и писателям торговых роботов под QUIK (торговая система для фондового рынка) протестировать и оценить реализуемость идеи. Язык д.б. встроен в простенькую IDE типа SciTE или Notepad++ чтобы показать пользователям возможность подсветки синтаксиса и автодополнения
      Как можно монетизировать открытый GPL проект ?
    8. Для разработчика это – оказывать платные услуги по встраиванию своего продукта в чужие программы или просто переход на работу в компанию использующую его открытый продукт.
    9. Получение гранта на разработку
    10. Получение денег от краудсорсинга – если проект зацепит, скорей всего можно будет собрать какуюто сумму денег с разработчиков торговых роботов для QUIK и разработчиков игровых движков
      Собственно от Вас мне бы хотелось получить оценку идеи,
    11. насколько она технически реализуема
    12. насколько активно люди будут этим пользоваться
    13. какие и где могут быть сложности

    Я ищу специалистов которые помогут сделать LuaPLUS


    Что я могу сделать:


    1. Выполнить роль координатора и решать все орг. вопросы
    2. Переписать и протестировать все примеры скриптов
    3. Переписать учебники и туториалы по Lua на версии с использованием LuaPLUS
    4. Перевести все сообщения об ошибках на русский
    5. Выполнит всю прочую техническую работу которая потребуется.
      То я не могу сделать;
    6. Моих знаний и опыта не хватает чтобы разобраться и исходниках компилятор Lua, мне нужен специалист по компиляторами и Си который подскажет где и что надо подправить и перекомпилирует все правленые мной исходники, при необходимости исправив ошибки. На выхлопе надо получить dll ку и IDE SciTE для оценки идеи на практике.

    Меня интерсуют любые соображения кроме набивших оскомину, что русские ключевые слова программистам не нужны. LuaPLUS это не для программистов, это для конечных юзеров которые программистами не были и ими никогда не станут. Для них просто хорошё, а ещё проще ещё лучше.


    Есть небольшая сумма в 5 т.р. если кто то возьмётся …


    1. berez
      02.06.2017 20:18
      +3

      Конвертор для Рус <-> Лат написать даже на Lua не проблема. Т.о. создаётся закрытая экосистема и лояльные пользователи. Условно назовём эту версию LuaPLUS

      LuaPLUS — это если в язык добавить поддержку нелатиницы и выпустить локализации на нескольких языках.
      А то, что вы предлагаете, — это кривенькая русификация. Тогда уж давайте это чудо назовем LuaRUS.

      Что для этого надо сделать? необходимо добавить в исходники lua возможность использовать:
      русские имена переменных и функций

      1. В какой кодировке? UTF-8? Или windows-1251?
      2. Насколько я понимаю, для поддержки национальных кодировок достаточно подмандить парсер.

      Получение денег от краудсорсинга – если проект зацепит, скорей всего можно будет собрать какуюто сумму денег с разработчиков торговых роботов для QUIK и разработчиков игровых движков
      Собственно от Вас мне бы хотелось получить оценку идеи,

      «Осень, осень плёхо».
      Ну сами-то прикиньте на пальцах.
      Сколько там в луа зарезервированных слов? Десятка два (включая стандартную библиотеку)? Выучить их — абсолютно не проблема, кому надо — тот на бумажке напишет.
      Текст компьютерной программы все равно не похож на нормальный русский язык, даже если перевести все словеса на русский язык. Т.е. человеку все равно придется хоть как-то вникать в синтаксис языка.

      Что касается сообщений об ошибках — в луа они бывают весьма бестолковыми (следствие упрощенного синтаксиса). Человека, не знакомого с программированием, они только собьют с толку.

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

      Вы что же думаете, человек без опыта в программировании придет, откроет текст торгового плагина для QUIK, увидит там русские буквы и сразу же все поймет? И сразу же сможет написать свой похожий плагин? Это будет чудо.

      LuaPLUS это не для программистов, это для конечных юзеров которые программистами не были и ими никогда не станут.

      Тогда они не смогут сделать с модулем ничего осмысленного независимо от того, какие там в тексте слова — русские или английский.

      Для них просто хорошё, а ещё проще ещё лучше.

      Хорошё, значит… М-да.

      Давайте посмотрим, посмеемся:

      Исходный текст на луа (взят с какого-то онлайн-туториала):
      function square(iteratorMaxCount,currentNumber)
      
         if currentNumber<iteratorMaxCount
         then
            currentNumber = currentNumber+1
            return currentNumber, currentNumber*currentNumber
         end
      	
      end
      
      for i,n in square,3,0
      do
         print(i,n)
      end
      


      Теперь переведем его на русский:

      функция квадрат(итераторМаксКолич,текущийНомер)
      
         если текущийНомер<итераторМаксКолич
         тогда
            текущийНомер= текущийНомер+1
            возврат текущийНомер, текущийНомер*текущийНомер
         конец
      	
      конец
      
      для и,н в квадрат,3,0
      делай
         печать(и,н)
      конец
      


      Я б не сказал, что стало понятнее. Смешнее — да. Понятнее — нет.


    1. Pinsky
      05.06.2017 10:55

      Что я могу сделать:


      Ничего.

      Для интеграции Lua в си-шный проект требуются знания на уровне среднего php-разработчика.


    1. Azoh
      05.06.2017 11:08

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


  1. wikipro
    02.06.2017 22:09

    1. Я же писал LiaPLUS не для профессиональных программистов которым "И так понятно".
    2. Последний вариант для не программиста гораздо понятнее.
    3. код на английском тоже не похож на обычный английский язык.

    майкрософт упростил Xelix до MS DOS, язык программирования до BASIC, Aplle на чём деньги сделал ?? тенденция очевидна, чем проще тем денег больше ...


    чем обсуждать об ущербности ЯП с русскими операторами проще сделать и проверить на практике.


    1. RPG18
      04.06.2017 20:19

      чем обсуждать об ущербности ЯП с русскими операторами проще сделать и проверить на практике.

      Уже есть такой: vlang


  1. shuhray
    02.06.2017 23:17

    Подскажите, знатоки Lua. Сейчас хочу написать программу для интерактивных геометрических построений. Должно быть нарисовано окно с кнопками, ползунками, выпадающими меню и т.д., в котором буду что-то рисовать с помощью LuaGL. Чем лучше рисовать само окно? Есть wxLua, есть Iup, кто из них лучше или есть что-то ещё? Может, и кроме LuaGL есть что-нибудь ещё? Всё это должно работать с LuaJIT (при попытке приделать Iup были большие проблемы, пока создатель Iup не посоветовал переименовать lua51.dll в lua5.1.dll)


    1. Wolf_Black
      02.06.2017 23:18

      Я бы использовал си, чистый OpenGl и луа.


      1. alexeyknyshev
        03.06.2017 03:34

        Gui можно сделать на Qt, на qt-шный виджет можно риcовать из ogl
        Биндинги для qt https://github.com/torch/qtlua


    1. Lerg
      03.06.2017 16:22

      wxLua будет хорошим вариантом. Писать свою реализацию UI виджетов на OpenGL очень весело и увлекательно, но довольно трудозатратно.


      1. shuhray
        03.06.2017 21:03

        А есть ли по нему хорошие уроки?


  1. Lerg
    03.06.2017 16:23
    +1

    Больше Lua движков богу Lua движков! Жду продолжения.