16 марта 2010 в 17:51
Урок по созданию простой 2D игры в HGE
В данном уроке вы создадите простую 2д игру, цель заключается в сборе монет.
Надеюсь вы уже знаете как создавать проект на основе движка HGE.
Необходимые файлы
Вот описание необходимые файлы для этого проекта. Поместите их все в каталоге с .exe файлом. Ссылка на скачивание будет в конце урока.
bg.jpg" alt="Фото" /><
<
<
// main.cpp
#include <windows.h>
#include <hge.h>
#include <hgeresource.h>
#include <hgesprite.h>
#include <hgeanim.h>
#include <hgefont.h>
#include <hgeparticle.h>
HGE *hge = 0;
hgeResourceManager* myRes;
bool done = false;
bool FrameFunc()
{
return done;
}
int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int)
{
hge = hgeCreate(HGE_VERSION);
hge->System_SetState(HGE_WINDOWED, true);
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
if(hge->System_Initiate())
{
myRes = new hgeResourceManager("resource.res");
hge->System_Start();
}
else
{
MessageBox(NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
}
delete myRes;
hge->System_Shutdown();
hge->Release();
return 0;
}
Теперь создадим скрипт ресурсов
Texture background
{
filename=bg.jpg" alt="Фото" />
}
Sprite bgSprite
{
texture=background
rect=0, 0, 512, 512
}
Texture sheet
{
filename=sheet.png
}
Animation coin
{
texture=sheet
rect=0, 0, 32, 32
frames=5
fps=8.0
mode=FORWARD,LOOP
}
Font font1
{
filename=font1.fnt
}
Sound coinSound
{
filename=coin.ogg
}
Sprite sparkles
{
texture=sheet
rect=0, 40, 32, 32
blendmode=ALPHAADD
}
Particle coinCollected
{
filename=particle.psi
sprite=sparkles
fps=50.0
}
Инициализация содержимого
В верхней части программы добавляем максимальное количество монет
# DEFINE MAXCOINS 100
Потом размещаем следующее:
hgeSprite* bgSprite; hgeAnimation* coinAnim; hgeFont* font1; HCHANNEL chan[2]; HEFFECT coinSound; hgeParticleSystemInfo sparkles; hgeParticleManager *particleManager; float mouseX, mouseY; //координаты курсора мыши int collected = 0; //сколько монет уже собрали
Затем необходима структура для обработки монет, объявляем одну следующим образом:
struct Coin
{
bool exists; //монета еще не подобрана?
hgeRect loc; //позиция монеты
};
Coin coins[MAXCOINS];
Теперь В WinMain, добавьте следующее:
hge->Random_Seed(0);
bgSprite = myRes->GetSprite("bgSprite");
coinAnim = myRes->GetAnimation("coin");
coinAnim->Play(); //запускаем начальную анимацию
font1 = myRes->GetFont("font1");
coinSound = myRes->GetEffect("click");
sparkles = myRes->GetParticleSystem("sparkles")->info;
particleManager= new hgeParticleManager();
Теперь создаем все монеты в случаных местах:
for(int i=0; i<MAXCOINS; i++)
{
float randX, randY;
coins[i].exists=true;
randX = hge->Random_Float(0, 770);
randY = hge->Random_Float(0, 570);
coins[i].loc = hgeRect(randX, randY, randX+32, randY+32);
}
Не забудьте удалить менджер частиц когда программа завершается.
delete particleManager;
Теперь WinMain выглядит так:
int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int)
{
hge = hgeCreate(HGE_VERSION);
hge->System_SetState(HGE_WINDOWED, true);
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
hge->System_SetState(HGE_HIDEMOUSE, false);
hge->System_SetState(HGE_TITLE, "Coin Collector");
if(hge->System_Initiate())
{
myRes = new hgeResourceManager("resource.res");
hge->Random_Seed(0);
bgSprite = myRes->GetSprite("bgSprite");
coinAnim = myRes->GetAnimation("coin");
coinAnim->Play(); //start playback of animation
font1 = myRes->GetFont("font1");
coinSound = myRes->GetEffect("coinSound");
sparkles = myRes->GetParticleSystem("coinCollected")->info;
particleManager= new hgeParticleManager();
//initialize all coins
for(int i=0; i<MAXCOINS; i++)
{
float randX, randY;
coins[i].exists=true;
randX = hge->Random_Float(0, 770);
randY = hge->Random_Float(0, 570);
coins[i].loc = hgeRect(randX, randY, randX+32, randY+32);
}
hge->System_Start();
}
else
{
MessageBox(NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);
}
if(myRes)
{
delete myRes;
}
if(particleManager)
{
delete particleManager;
}
hge->System_Shutdown();
hge->Release();
return 0;
}
Обновление и функции ввода
В FrameFunc добавляем:
hge->Input_GetMousePos(&mouseX, &mouseY); //получаем позицию курсора float dt=hge->Timer_GetDelta(); //Возвращает время, прошедшее с последнего вызова функуии кадра в секундах. coinAnim->Update(dt); //обновляем анимацию particleManager->Update(dt); //обновляем систему частиц
Сбор монет
//проверяем нажата ли левая кнопка мыши на монете
if(hge->Input_GetKey()==HGEK_LBUTTON)
{
for(int i=0; i<MAXCOINS; i++)
{
//проверяем все монеты
if(coins[i].exists && coins[i].loc.TestPoint(mouseX, mouseY))
{
//курсор над этой монетой?
chan[1] = hge->Effect_Play(coinSound); //если да запускаем звук
particleManager->SpawnPS(&sparkles, mouseX, mouseY); //запускаем систему частиц
coins[i].exists = false;
collected++;
}
}
}
Rendering - рисуем результат на экран
hge->Gfx_BeginScene(); hge->Gfx_Clear(0); //очищаем и заполняем экран черным цветом bgSprite->RenderStretch(0, 0, 800, 600); //рендерим фон
Теперь рисуем все монеты, которые не собраны
for(int i=0; i<MAXCOINS; i++)
{
if(coins[i].exists)
{
coinAnim->RenderStretch(coins[i].loc.x1, coins[i].loc.y1, coins[i].loc.x2, coins[i].loc.y2);
}
}
Рисуем информацию о собранных монетах
font1->SetScale(1.0); font1->SetColor(ARGB(255,0,0,0)); font1->printf(5, 5, "Coins collected: %d", collected);
И завершаем рисованием частиц и вывод на экран
particleManager->Render(); //render all particles hge->Gfx_EndScene();
Теперь FrameFunc выглядит так
bool FrameFunc()
{
hge->Input_GetMousePos(&mouseX, &mouseY);
float dt=hge->Timer_GetDelta();
coinAnim->Update(dt);
particleManager->Update(dt);
if(hge->Input_GetKey()==HGEK_LBUTTON)
{
for(int i=0; i<MAXCOINS; i++)
{
if(coins[i].exists && coins[i].loc.TestPoint(mouseX, mouseY))
{
chan[1] = hge->Effect_Play(coinSound);
particleManager->SpawnPS(&sparkles, mouseX, mouseY);
coins[i].exists = false;
collected++;
}
}
}
hge->Gfx_BeginScene();
hge->Gfx_Clear(0); /
bgSprite->RenderStretch(0, 0, 800, 600);
//render all coins
for(int i=0; i<MAXCOINS; i++)
{
if(coins[i].exists) coinAnim->RenderStretch(coins[i].loc.x1, coins[i].loc.y1, coins[i].loc.x2, coins[i].loc.y2);
}
font1->SetScale(1.0); //set text size to normal
font1->SetColor(ARGB(255,0,0,0)); /
font1->printf(5, 5, "Coins collected: %d", collected);
particleManager->Render();
hge->Gfx_EndScene();
return done;
}
3 ноября 2012 в 22:49
Автор, спасибо тебе за урок. Все понятно расписано, буду ждать новых уроков
17 июля 2015 в 23:56
Поправьте пожалуйста статью. Материал хороший, в одном небольшом проекте столько всего используется. Но из-за поплывшего оформления читать очень неудобно.
авторизуйтесь
или войдите через