Начало работы с игровым движком Rungine

Game development
Sandbox
Runner Engine (сокращенно Rungine) — это новый 2D/3D движок для создания игр и мультимедийных приложений. Он обладает гибким набором инструментов, которые способны помочь разработчику увеличить скорость разработки, но они пока находятся в доработке. В состав движка входят: Core (ядро с собственным набором утилит), GUI, Graphic2D. В данный момент Runner Engine поддерживает только DirectX9. Идет работа над поддержкой OpenGL. В дальнейшем планируется продолжить работу над поддержкой DirectX10 и DirectX11.

Поддерживаемая платформа: Windows

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

Инициализация:

Первым шагом необходимо подключить dll движка:
#include "..\..\RunnerEngine\Runner.h"
#pragma comment(lib, "../../Bin/Runner.lib")


Объявляем девайс:
RDevice rdevice;
//Для инициализации необходимо вызвать метод Create:
if(!rdevice.Create(800, 600, Mode::Windowed, API::Direct3D9)) {
   return 0;
}


Весь рабочий цикл осуществляется следующим образом:
//рисуем, пока окно не закрыто
while(rdevice.EnterMsgLoop(true)) {
   rdevice.Clear();//очищаем поверхность окна
   //начало рисования графики
   if(rdevice.BeginScene()) {
        //рисуем картинку внутри окна
        rdevice.EndScene();//конец рисования
        rdevice.Present();//отображаем все нарисованное
   }
}

Все. Инициализацией мы разобрались. Теперь можно вывести на экран картинку или нарисовать изображение.


Hello, Runner
Hello, Runner — это первый пример из Rungine SDK. Он показывает, как инициализировать Rungine и нарисовать простейшее изображение.

Исходный код с описанием:
//Подключаем движок:
#include "..\..\RunnerEngine\Runner.h"
#pragma comment(lib, "../../Bin/Runner.lib")
String MediaDir = "../Media/HelloRunner/";
RDevice rdevice;//объявление устройста для работы всего движка
Picture im;//обычное изображение
RFont font;
int WINAPI WinMain(
                                  HINSTANCE hinstance,
                                   HINSTANCE prevInstance,
                                   PSTR cmdLine,
                                   int showCmd) {
  RFile f;
  //стандартные настройки:
  int width = 800;
  int height = 600;
  bool mode = Mode::Windowed;
  int api = API::Direct3D9;
  //проверяем наличие изображения:
if(!FileUtility::FileExists(MediaDir + "../Samples.dat"))
  //если его нет, значит приложение запущенно из Visual Studio:
  MediaDir = "../" + MediaDir;
  /*
     Читаем настройки длины, высоты, типа приложения
     (оконное/полноэкранное) и используемого API:
   */
   if(f.OpenRead((MediaDir + "../Samples.dat").ToChar())) {
       f.Read(&width,sizeof(width));
       f.Read(&height,sizeof(height));
       f.Read(&mode,sizeof(mode));
       f.Read(&api,sizeof(api));
       f.Close();
   }
   //инициализируем Runner Engine и создаем
   //окно размером WidthхHeight пикселей:
   if(!rdevice.Create(width, height, mode, api)) {
      return 0;
   }
   //Создание системного шрифта Tahoma 10 кегля
   font.Create(&rdevice, Fonts::Tahoma); 
   //создаем im, загружам картинку RunnerBackground.tga:
   im.Create(&rdevice, MediaDir + "RunnerBackground.tga");
   //изменение заголовка окна:
   Window::SetTitle("Runner Engine. Tutorial: Hellow World");
   //рисуем, пока окно не закрыто
   while(rdevice.EnterMsgLoop(true)) {
      //true для того, что бы при неактивном окне фпс падал, с целью
     //экономии ресурсов
     rdevice.Clear();//очищаем поверхность окна
     //начало рисования графики
     if(rdevice.BeginScene()) {
        //рисуем картинку внутри окна
        im.Draw(0,0,Window::GetWidth(),Window::GetHeight(),
        Colors::White);
        //Вывод текста:
        font.Begin();
        font.Draw2DText(10,10,"Press ESC to exit",Colors::White);
        font.Draw2DText(10,25,String("FPS: ") + rdevice.GetFPS(),
        Colors::White);
        font.End();
        rdevice.EndScene();//конец рисования
        rdevice.Present();//отображаем все нарисованное
     }
     //проверка нажатия на клавишу ESC:
     if(Keyboard::GetKey(KEY_ESCAPE)) {
        Window::Destroy();//завершаем работу приложения
     }
  }
   return 0;
}
//для того что бы взять hWnd окна: Window::GetHWND();



Запущенный пример выглядит следующим образом:
image

Gears:
Gears — это пример простейшей анимации на примере двух взаимосвязанных шестеренок

#include "..\..\RunnerEngine\Runner.h"
#pragma comment(lib, "../../Bin/Runner.lib")
String MediaDir = "../Media/Gears/";
RDevice rdevice;//объявление устройста для работы всего движка
//Изображения шестренок:
Picture Gear1;//нижняя шестеренка
Picture Gear2;//верхняя шестеренка
Picture Symbol;//название движка
RFont font;
//количесво зубчиков у первой и второй шестеренок:
int g1_count = 12;
int g2_count = 12;
float angle = 0.0f;//угол поворота шестеренок в радианах
bool Create() {
  RFile f;
  //стандартные настройки:
  int width = 800;
  int height = 600;
  bool mode = Mode::Windowed;
  int api = API::Direct3D9; 
  //проверяем наличие изображения:
  if(!FileUtility::FileExists(MediaDir + "../Samples.dat"))
      //если его нет, значит приложение запущенно из Visual Studio:
      MediaDir = "../" + MediaDir;
      /*Читаем настройки длины, высоты, типа приложения
        (оконное/полноэкранное) и используемого API: */
  if(f.OpenRead((MediaDir + "../Samples.dat").ToChar())) {
    f.Read(&width,sizeof(width));
    f.Read(&height,sizeof(height));
    f.Read(&mode,sizeof(mode));
    f.Read(&api,sizeof(api));
    f.Close();
  }
  //инициализируем Runner Engine и создаем  
  //окно размером WidthхHeight пикселей:
  if(!rdevice.Create(width, height, mode, api)) {
   return false;
  }
  rdevice.SetTexFilter(TexFilter::ANISOTROPIC,TexFilter::ANISOTROPIC,16);
  //Создание системного шрифта Tahoma 10 кегля
  font.Create(&rdevice, Fonts::Tahoma);
  //загружам текстуры:
  Gear1.Create(&rdevice, MediaDir + "Gear1.dds");
  Gear2.Create(&rdevice, MediaDir + "Gear2.dds");
  Symbol.Create(&rdevice, MediaDir + "Symbol.tga");
  return true;
}
void UpdateFPS() {
  //старое значение fps(колво кадров в секунду):
  static int old_fps = 0;
  //взятие нового значения fps:
  int new_fps = rdevice.GetFPS();
  if(old_fps != new_fps) {
    //название заголовка окна:
    Window::SetTitle(String("Runner Engine. Tutorial 2: Gears ")+ new_fps +" fps");
    old_fps = new_fps;
  }
}
void Render() {
  //рисуем, пока окно не закрыто:
  while(rdevice.EnterMsgLoop()) {
    UpdateFPS();
    /*угол поворота большой шестеренки зависит от пройденного
          интервала времени, а не количества кадров:*/
    angle += rdevice.GetElapsedTime()/500.0f;
    /*
          т.к. шестеренки могут быть разными, у первой g1_count зубчиков, а у
          второй g2_count, то они должны вращаться с разной скоростью, т.е.
          например, вторая шестеренка должна вращаться в g2_count/g1_count раз
          быстрее первой и в противоположную сторону.
          т.е. угол поворота второй шестеренки вычисляется следующим
          образом:*/
    float angle2 = -(g2_count/g1_count)*angle;
    /*Теперь ее вращение шестеренки зависит от первой шестеренки.
            Таким образом можно строить целые цепи взаимосвязанных шестеренок.*/
    rdevice.Clear(Colors::System::Background);//очищаем поверхность окна
    rdevice.SetTexWithAlphaChanel(1);//разрешаем альфа каналы
    //начало рисования графики
    if(rdevice.BeginScene()) {
      //координаты расчитаны на разрешение 800х600, но работает
      //одинакого при любых разрешениях благодаря умнажения их
      //на коэффициент соотношения текущего разрешения к разрешению
      //800х600:
      float kx = (float)Window::GetWidth()/800;
      float ky = (float)Window::GetHeight()/600;
      int x = 170;//*kx;
      int y = 70;//*ky;
      //размеры расчитываются аналогичным образом:
      int sx = INT(297.0f*kx);
      int sy = INT(297.0f*ky);
      //где 297 это длина и ширина изображений шестеренок в икселах,
      //для разрешения экрана 800x600
      //рисование шестеренок:
      Gear1.Draw(INT((x - 40)*kx), INT((y + 170)*ky),sx,sy, angle);
      Gear2.Draw(INT((x + 150)*kx), INT((y - 40)*ky),sx,sy, angle2);
      //вычисляем размер надписи с учетом разрешения:
      Point Size = Symbol.GetSize()*Window::GetWidth()/2300;
      Symbol.Draw(Window::GetWidth() - Size.x, Window::GetHeight() –
      Size.y, Size.x, Size.y);
      //Вывод текста:
      font.Begin();
      font.Draw2DText(10,10,"Press ESC to exit",Colors::White);
      font.Draw2DText(10,25,String("FPS: ") +
      rdevice.GetFPS(),Colors::White);
      font.End();
      rdevice.EndScene();//конец рисования
      rdevice.Present();//отображаем все нарисованное
    }
    //проверка нажатия на клавишу ESC:
    if(Keyboard::GetKey(KEY_ESCAPE)) {
      Window::Destroy();//завершаем работу приложения
    }
  }
}

int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd) {
  if(Create()) {
    Render();
    return 0;
  }
}


Запущенный пример выглядит следующим образом:
image
Tags:2d3d3d-графикаgamedevgame enginegame development2d графикаигровой движокигровая индустрияrungine
Hubs: Game development
+17
3.3k 27
Comments 43

Popular right now

Профессия Product Manager
March 3, 2021108,500 ₽Нетология
Python для анализа данных
March 3, 202124,900 ₽SkillFactory
Профессия Data Scientist
March 3, 2021162,000 ₽SkillFactory
Специализация Data Science
March 3, 2021114,000 ₽SkillFactory
Python для веб-разработки
March 5, 202159,400 ₽SkillFactory

Top of the last 24 hours