Tutorial 07 - Thousand of Hares

This tutorial shows HGE rendering power and usage of various blending modes.

        

Creation of sprites

We will skip all the technical stuff now and dive right into the action. First we should create and initialize a couple of sprites, used for "game objects" and background rendering. Note how the background sprite is created from a tiny 64x64 tile and tinted at the bottom:

HTEXTURE tex, bgtex;
hgeSprite *spr, *bgspr;

tex=hge->Texture_Load("zazaka.png");
spr=new hgeSprite(tex,0,0,64,64);
spr->SetHotSpot(32,32);

bgtex=hge->Texture_Load("bg2.png");
bgspr=new hgeSprite(bgtex,0,0,800,600);
bgspr->SetBlendMode(BLEND_COLORADD | BLEND_ALPHABLEND);
bgspr->SetColor(0xFF000000,0);
bgspr->SetColor(0xFF000000,1);
bgspr->SetColor(0xFF000040,2);
bgspr->SetColor(0xFF000040,3);

Initializing game objects array

Now we should create an array, holding properties of our "game objects" and fill it with random values:

#define MAX_OBJECTS 2000

struct sprObject
{
  float x,y;
  float dx,dy;
  float scale,rot;
  float dscale,drot;
  DWORD color;
};

sprObject*  pObjects;
int         nObjects;

pObjects=new sprObject[MAX_OBJECTS];
nObjects=1000;

for(i=0; i<MAX_OBJECTS; i++)
{
  pObjects[i].x=hge->Random_Float(0,SCREEN_WIDTH);
  pObjects[i].y=hge->Random_Float(0,SCREEN_HEIGHT);
  pObjects[i].dx=hge->Random_Float(-200,200);
  pObjects[i].dy=hge->Random_Float(-200,200);
  pObjects[i].scale=hge->Random_Float(0.5f,2.0f);
  pObjects[i].dscale=hge->Random_Float(-1.0f,1.0f);
  pObjects[i].rot=hge->Random_Float(0,M_PI*2);
  pObjects[i].drot=hge->Random_Float(-1.0f,1.0f);
}

Changing blending mode

SetBlend function takes an integer from range 0..4 and adjusts blending mode of the game object sprite and colors within game objects array:

void SetBlend(int blend)
{
  static int sprBlend[5]=
  {
    BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE,
    BLEND_COLORADD | BLEND_ALPHABLEND | BLEND_NOZWRITE,
    BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE,
    BLEND_COLORMUL | BLEND_ALPHAADD   | BLEND_NOZWRITE,
    BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE
  };

  static DWORD sprColors[5][5]=
  {
    {0xFFFFFFFF, 0xFFFFE080, 0xFF80A0FF, 0xFFA0FF80, 0xFFFF80A0},
    {0xFF000000, 0xFF303000, 0xFF000060, 0xFF006000, 0xFF600000},
    {0x80FFFFFF, 0x80FFE080, 0x8080A0FF, 0x80A0FF80, 0x80FF80A0},
    {0x80FFFFFF, 0x80FFE080, 0x8080A0FF, 0x80A0FF80, 0x80FF80A0},
    {0x40202020, 0x40302010, 0x40102030, 0x40203010, 0x40102030}
  };

  if(blend>4) blend=0;
  nBlend=blend;

  spr->SetBlendMode(sprBlend[blend]);

  for(int i=0;i<MAX_OBJECTS;i++)
    { pObjects[i].color=sprColors[blend][hge->Random_Int(0,4)]; }
}

Updating the scene

In the FrameFunc we iterate through our game objects array and calculate their new positions:

  for(i=0; i<nObjects; i++)
  {
    pObjects[i].x+=pObjects[i].dx*dt;
    if(pObjects[i].x>SCREEN_WIDTH || pObjects[i].x<0)
      { pObjects[i].dx=-pObjects[i].dx; }

    pObjects[i].y+=pObjects[i].dy*dt;
    if(pObjects[i].y>SCREEN_HEIGHT || pObjects[i].y<0)
      { pObjects[i].dy=-pObjects[i].dy; }

    pObjects[i].scale+=pObjects[i].dscale*dt;
    if(pObjects[i].scale>2 || pObjects[i].scale<0.5)
      { pObjects[i].dscale=-pObjects[i].dscale; }

    pObjects[i].rot+=pObjects[i].drot*dt;
  }

Rendering the scene

In the RenderFunc we iterate through our game objects array and and render them to the screen:

  hge->Gfx_BeginScene();
  bgspr->Render(0,0);
	
  for(i=0; i<nObjects; i++)
  {
    spr->SetColor(pObjects[i].color); 
    spr->RenderEx(pObjects[i].x, pObjects[i].y,
                  pObjects[i].rot, pObjects[i].scale);
  }

  hge->Gfx_EndScene();

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

Use UP and DOWN arrow keys to adjust number of game objects, SPACE to change blending mode and ESC to exit.