Пример 02 - Использование ввода, звука и рендеринга

Для того, чтобы что-нибудь вывести, нам понадобится структура hgeQuad. Четырехугольники - простейший примитив используемый для рендеринга в HGE. Четырехугольник содержит 4 вершины, пронумерованные от 0 до 3 по часовой стрелке.

Так же нам понадобится идентификатор звукового эффекта.

hgeQuad quad;

HEFFECT snd;

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

float x=100.0f, y=100.0f;
float dx=0.0f, dy=0.0f;

const float speed=90;
const float friction=0.98f;

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

void boom() {
  int pan=int((x-400)/4);
  float pitch=(dx*dx+dy*dy)*0.0005f+0.2f;
  hge->Effect_PlayEx(snd,100,pan,pitch);
}

Теперь перейдем к функции кадра. Сначала, нам надо узнать, сколько прошло времени с последнего вызова функции кадра, для выравнивания скорости анимации по текущей частоте кадров. Чтобы узнать это время, вызываем функцию Timer_GetDelta.

bool FrameFunc()
{
  float dt=hge->Timer_GetDelta();

Теперь обработаем назатие клавиш. Мы используем функцию Input_GetKeyState для определения состояния клавиш. Чтобы обработать нажатие кнопок мыши, можно воспользоваться функцией Input_GetKey.

  if (hge->Input_GetKeyState(HGEK_ESCAPE)) return true;
  if (hge->Input_GetKeyState(HGEK_LEFT)) dx-=speed*dt;
  if (hge->Input_GetKeyState(HGEK_RIGHT)) dx+=speed*dt;
  if (hge->Input_GetKeyState(HGEK_UP)) dy-=speed*dt;
  if (hge->Input_GetKeyState(HGEK_DOWN)) dy+=speed*dt;

Теперь проведем кое-каие расчеты перемещения и определения столкновения, специфичные для нашего примера:

  dx*=friction; dy*=friction; x+=dx; y+=dy;
  if(x>784) {x=784-(x-784);dx=-dx;boom();}
  if(x<16) {x=16+16-x;dx=-dx;boom();}
  if(y>584) {y=584-(y-584);dy=-dy;boom();}
  if(y<16) {y=16+16-y;dy=-dy;boom();}

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

  quad.v[0].x=x-16; quad.v[0].y=y-16;
  quad.v[1].x=x+16; quad.v[1].y=y-16;
  quad.v[2].x=x+16; quad.v[2].y=y+16;
  quad.v[3].x=x-16; quad.v[3].y=y+16;

Теперь мы готовы нарисовать наш спрайт. Чтобы начать вывод вызовем функцию Gfx_BeginScene. Затем мы очищаем экран вызовом Gfx_Clear и рисуем спрайт с помощью вызовом Gfx_RenderQuad. Наконец мы заканчиваем вывод и обновление экрана, вызывая функцию Gfx_EndScene.

  hge->Gfx_BeginScene();
  hge->Gfx_Clear(0);
  hge->Gfx_RenderQuad(&quad);
  hge->Gfx_EndScene();

  return false;
}

Теперь посмотрим изменения в функции WinMain. В этом примере мы установим больше переменных HGE до инициализации. Включим файл протокола и укажем видео режим:

  hge->System_SetState(HGE_LOGFILE, "hge_tut02.log");
  hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
  hge->System_SetState(HGE_TITLE,
           "HGE Tutorial 02 - Using input, sound and rendering");

  hge->System_SetState(HGE_FPS, 100);
  hge->System_SetState(HGE_WINDOWED, true);
  hge->System_SetState(HGE_SCREENWIDTH, 800);
  hge->System_SetState(HGE_SCREENHEIGHT, 600);
  hge->System_SetState(HGE_SCREENBPP, 32);

Когда HGE инициализирован, нужно загрузить текстуру, которая содержит графику и звуковой эффект:

    snd=hge->Effect_Load("menu.wav");
    quad.tex=hge->Texture_Load("particles.png");

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

Мы не используем z-буфер в этом примере, так что значения z игнорируются, и мы установим их в произвольное значение от 0.0 до 1.0, просто на всякий случай. Вормат цвета вершин DWORD - 0xAARRGGBB.

Координаты текстуры tx и ty для каждой вершины определяют ту часть текстуры, которая будет отображена в четырехугольнике. Значени принадлежат промежутку от 0.0 до 1.0. 0,0 означает левый верхний угол 1,1 - нижний правый угол текстуры. У нас текстура размерами 128x128 и мы зотим использовать часть размером 32x32 начиная с 96,64.

    quad.blend=BLEND_ALPHAADD | BLEND_COLORMUL | BLEND_ZWRITE;

    for(int i=0;i<4;i++)
    {
      quad.v[i].z=0.5f;
      quad.v[i].col=0xFFFFA000;
    }

    quad.v[0].tx=96.0/128.0; quad.v[0].ty=64.0/128.0;
    quad.v[1].tx=128.0/128.0; quad.v[1].ty=64.0/128.0;
    quad.v[2].tx=128.0/128.0; quad.v[2].ty=96.0/128.0;
    quad.v[3].tx=96.0/128.0; quad.v[3].ty=96.0/128.0;

Теперь мы готовы начать игровой цикл при помоши вызова System_Start. Когда функция кадра возвращает true и игровой цикл заканчивается, загруженная текстура и звуковой эффект должны быть удалены:

    hge->System_Start();

    hge->Texture_Free(quad.tex);
    hge->Effect_Free(snd);

Остальной процесс завершения аналогичен тому, что был в Примере 01.

Полный код с детальными коментариями для этого урока можно найти в директории tutorials\tutorial02. Требуемые медиа файлы можно найти в директории tutorials\precompiled.