HGE tutorial 02 学习笔记及摘录

Tutorial 02 - Using input, sound and rendering

To render something we will need a hgeQuad structure. Quad is the basic primitive in HGE used for rendering graphics. Quad contains 4 vertices, numbered 0 to 3 clockwise. 

Also we'll need a handle for the sound effect.

hgeQuad quad;

HEFFECT snd;

Here go some "gameplay" variables and constants that we will use for our show.

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

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

Now we create the function that will play collision sound with parameters based on sprite position and speed.

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);
}

Now to the frame function. First, we need to know the time elapsed since last call of frame function to adjust our animation speeds to the current frame rate. We obtain it by calling the Timer_GetDelta function.

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

Now we process the key presses. We use here Input_GetKeyState function to monitor the keys state. To catch the key clicks you may use Input_GetKeyfunction.

  
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;

Now we do some movement calculations and collision detection specific to our example:

  
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();}

Now we have updated the screen coordinates for our sprite and we should update the quad's vertices to reflect the changes.

  
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;

We've done with updating and should return false to continue execution.

  return false;
}

Now to the rendering part. We are going to set up a separate function which will be called by HGE when the application window should be redrawn.

bool RenderFunc()
{

To start rendering we call the Gfx_BeginScene function. Then we clear the screen with a call to Gfx_Clear and render the sprite with Gfx_RenderQuad. Finally we finish rendering and update the screen, calling the Gfx_EndScenefunction.

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

  return false;
}

The rendering function should always return false

Now let's see the changes in WinMain function. In this tutorial we set some more system states before HGE initiating. First, we should specify our rendering function. We also turn on the log file support and specify the desired video mode more explicitly:

  hge->System_SetState(HGE_LOGFILE, "hge_tut02.log");
  hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
  hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
  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);

When HGE is initiated we need to load a texture that holds graphics and a sound effect:

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

Now we should set up the hgeQuad structure that we will use for rendering. The quad's texture is already set up, now we set the blending mode and fill in the vertices array with the desired values. 

We don't use z-buffer in this example, so the z-order of vertices is ignored here, and we set it to an arbitrary value in range from 0.0 to 1.0, just to be sure. The format of a vertex color DWORD is 0xAARRGGBB. 

The texture coordinates tx and ty for each vertex define the part of the texture to be rendered with this quad. The values are in range 0.0 to 1.0. 0,0 means top left corner and 1,1 - bottom right corner of the texture. Here we have a 128x128 texture and we want to use a 32x32 square part of it starting at 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; 

Now we're ready to start the game loop with the System_Start function. When the frame function returns true and the game loop is finished we should free the loaded texture and the sound effect:

 
   hge->System_Start();

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

The rest of shutdown process is identical to the one demonstrated inTutorial 01

The complete source code with detailed comments for this tutorial you may find in the folder tutorials\tutorial02. The required media files you'll find in the folder tutorials\precompiled.



源码

/*
** Haaf's Game Engine 1.8
** Copyright (C) 2003-2007, Relish Games
** hge.relishgames.com
**
** hge_tut02 - Using input, sound and rendering
*/


// Copy the files "particles.png" and "menu.wav"
// from the folder "precompiled" to the folder with
// executable file. Also copy hge.dll and bass.dll
// to the same folder.


#include "..\..\include\hge.h"

HGE *hge=0;

// Quad is the basic primitive in HGE
// used for rendering graphics.
// Quad contains 4 vertices, numbered
// 0 to 3 clockwise.
hgeQuad quad;

// Handle for a sound effect
HEFFECT snd;

// Some "gameplay" variables and constants
float x=100.0f, y=100.0f;
float dx=0.0f, dy=0.0f;

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

// This function plays collision sound with
// parameters based on sprite position and speed
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);
}

bool FrameFunc()
{
	// Get the time elapsed since last call of FrameFunc().
	// This will help us to synchronize on different
	// machines and video modes.
	float dt=hge->Timer_GetDelta();

	// Process keys
	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;

	// Do some movement calculations and collision detection	
	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();}

	// Set up quad's screen coordinates
	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;

	// Continue execution
	return false;
}

// This function will be called by HGE when
// the application window should be redrawn.
// Put your rendering code here.
bool RenderFunc()
{
	// Begin rendering quads.
	// This function must be called
	// before any actual rendering.
	hge->Gfx_BeginScene();

	// Clear screen with black color
	hge->Gfx_Clear(0);

	// Render quads here. This time just
	// one of them will serve our needs.
	hge->Gfx_RenderQuad(&quad);

	// End rendering and update the screen
	hge->Gfx_EndScene();

	// RenderFunc should always return false
	return false;
}


int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	// Get HGE interface
	hge = hgeCreate(HGE_VERSION);

	// Set up log file, frame function, render function and window title
	hge->System_SetState(HGE_LOGFILE, "hge_tut02.log");
	hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
	hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
	hge->System_SetState(HGE_TITLE, "HGE Tutorial 02 - Using input, sound and rendering");

	// Set up video mode
	hge->System_SetState(HGE_WINDOWED, true);
	hge->System_SetState(HGE_SCREENWIDTH, 800);
	hge->System_SetState(HGE_SCREENHEIGHT, 600);
	hge->System_SetState(HGE_SCREENBPP, 32);

	if(hge->System_Initiate())
	{
		// Load sound and texture
		snd=hge->Effect_Load("menu.wav");
		quad.tex=hge->Texture_Load("particles.png");
		if(!snd || !quad.tex)
		{
			// If one of the data files is not found, display
			// an error message and shutdown.
			MessageBox(NULL, "Can't load MENU.WAV or PARTICLES.PNG", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
			hge->System_Shutdown();
			hge->Release();
			return 0;
		}

		// Set up quad which we will use for rendering sprite
		quad.blend=BLEND_ALPHAADD | BLEND_COLORMUL | BLEND_ZWRITE;

		for(int i=0;i<4;i++)
		{
			// Set up z-coordinate of vertices
			quad.v[i].z=0.5f;
			// Set up color. The format of DWORD col is 0xAARRGGBB
			quad.v[i].col=0xFFFFA000;
		
		}

		// Set up quad's texture coordinates.
		// 0,0 means top left corner and 1,1 -
		// bottom right corner of the texture.
		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; 
		/*自己添加测试用例quad 4个纹理坐标 构成一个矩形选中一个纹理图案
                quad.v[0].tx=0.75; quad.v[0].ty=0.5; 
		quad.v[1].tx=1; quad.v[1].ty=0.5; 
		quad.v[2].tx=1; quad.v[2].ty=0.75; 
		quad.v[3].tx=0.75; quad.v[3].ty=0.75; 
		
		quad.v[0].tx=0; quad.v[0].ty=0; //能显示出所有的纹理坐标
		quad.v[1].tx=1; quad.v[1].ty=0; 
		quad.v[2].tx=1; quad.v[2].ty=1; 
		quad.v[3].tx=0; quad.v[3].ty=1; */
		// Let's rock now!
		hge->System_Start();

		// Free loaded texture and sound
		hge->Texture_Free(quad.tex);
		hge->Effect_Free(snd);
	}
	else MessageBox(NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);

	// Clean up and shutdown
	hge->System_Shutdown();
	hge->Release();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值