Ir al contenido

publicidad
publicidad

Foto

Curso MM: 15 Creando fondos para los sprites


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
No hay respuestas en este tema

#1

Escrito 18 agosto 2009 - 22:01

Creando fondos para los sprites

En ésta hora se crea una clase Background. Tipos de fondos: sólidos, imagen, animados y con scroll (éste último no se desarrolla en el libro). En realidad serán dos clases, una para fondos sólidos y con imagen; y otra que será un fondo animado con estrellas.

Creando una clase de fondo básico

Esta clase estará dentro de la clase Background, que puede ser utilizada para crear fondos sólidos o con una imagen.

[code:1]class Background
{
protected:
// Member Variables
int m_iWidth, m_iHeight; //ancho y alto.
COLORREF m_crColor; //color.
Bitmap* m_pBitmap; //puntero a una imagen.

public:
// Constructor(s)/Destructor
Background(int iWidth, int iHeight, COLORREF crColor);
Background(Bitmap* pBitmap);
virtual ~Background();

// General Methods
virtual void Update();
virtual void Draw(HDC hDC);

// Accessor Methods
int GetWidth() { return m_iWidth; };
int GetHeight() { return m_iHeight; };
};[/code]

El método Update() aquí está vacío, no es necesario actualizar nada. En el caso de los fondos animados derivaremos la clase de ésta y podremos usar la función Update() para algo.

Veamos los constructores:

[code:1]Background::Background(int iWidth, int iHeight, COLORREF crColor)
{
// Initialize the member variables
m_iWidth = iWidth;
m_iHeight = iHeight;
m_crColor = crColor;
m_pBitmap = NULL;
}

Background::Background(Bitmap* pBitmap)
{
// Initialize the member variables
m_crColor = 0;
m_pBitmap = pBitmap;
m_iWidth = pBitmap->GetWidth();
m_iHeight = pBitmap->GetHeight();
}[/code]

Ahora Update() y Draw():

[code:1]void Background::Update()
{
// Do nothing since the basic background is not animated
}

void Background::Draw(HDC hDC)
{
// Draw the background
if (m_pBitmap != NULL)
m_pBitmap->Draw(hDC, 0, 0);
else
{
RECT rect = { 0, 0, m_iWidth, m_iHeight };
HBRUSH hBrush = CreateSolidBrush(m_crColor);
FillRect(hDC, &rect, hBrush);
DeleteObject(hBrush);
}
}[/code]

Creando una clase de fondo animado

Ahora creamos la clase StarryBackground (un cielo estrellado). Está derivada de la clase Background y requiere su propio constructor y su propia función Update() y Draw().

[code:1]class StarryBackground : Background
{
protected:
// Member Variables
int m_iNumStars;
int m_iTwinkleDelay;
POINT m_ptStars[100];
COLORREF m_crStarColors[100];

public:
// Constructor(s)/Destructor
StarryBackground(int iWidth, int iHeight, int iNumStars = 100,
int iTwinkleDelay = 50);
virtual ~StarryBackground();

// General Methods
virtual void Update();
virtual void Draw(HDC hDC);
};[/code]

Tenemos variables para el número de estrellas, el retraso del brillo y los colores. Sólo puede haber 100 estrellas y los colores son escalas de grises.

El constructor inicializa las variables y crea la tabla de estrellas y colores.

[code:1]StarryBackground::StarryBackground(int iWidth, int iHeight, int iNumStars,
int iTwinkleDelay) : Background(iWidth, iHeight, 0)
{
// Initialize the member variables
m_iNumStars = min(iNumStars, 100);
m_iTwinkleDelay = iTwinkleDelay;

// Create the stars
for (int i = 0; i < iNumStars; i++)
{
m_ptStars[i].x = rand() % iWidth;
m_ptStars[i].y = rand() % iHeight;
m_crStarColors[i] = RGB(128, 128, 128);
}
}[/code]

Ahora vemos los métodos Update() y Draw():

[code:1]void StarryBackground::Update()
{
// Randomly change the shade of the stars so that they twinkle
int iRGB;
for (int i = 0; i < m_iNumStars; i++)
if ((rand() % m_iTwinkleDelay) == 0)
{
iRGB = rand() % 256;
m_crStarColors[i] = RGB(iRGB, iRGB, iRGB);
}
}

void StarryBackground::Draw(HDC hDC)
{
// Draw the solid black background
RECT rect = { 0, 0, m_iWidth, m_iHeight };
HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0));
FillRect(hDC, &rect, hBrush);
DeleteObject(hBrush);

// Draw the stars
for (int i = 0; i < m_iNumStars; i++)
SetPixel(hDC, m_ptStars[i].x, m_ptStars[i].y, m_crStarColors[i]);
}[/code]

Programa de ejemplo : Roids
Roids.h , Roids.cpp.

En GameStart() creamos el fondo:

[code:1]// Create the starry background
_pBackground = new StarryBackground(500, 400);[/code]

500 x 400 son las dimensiones de la pantalla.

GamePaint() dibuja el fondo y los sprites:

[code:1]void GamePaint(HDC hDC)
{
// Draw the background
_pBackground->Draw(hDC);

// Draw the sprites
_pGame->DrawSprites(hDC);
}[/code]

En GameCycle() hay que actualizar el fondo con la línea _pBackground->Update();

Roids.h
[code:1]//-----------------------------------------------------------------
// Roids Application
// C++ Header - Roids.h
//-----------------------------------------------------------------

#pragma once

//-----------------------------------------------------------------
// Include Files
//-----------------------------------------------------------------
#include
#include "Resource.h"
#include "GameEngine.h"
#include "Bitmap.h"
#include "Sprite.h"
#include "Background.h"

//-----------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------
HINSTANCE _hInstance;
GameEngine* _pGame;
HDC _hOffscreenDC;
HBITMAP _hOffscreenBitmap;
Bitmap* _pAsteroidBitmap; //imagen del asteroide.
StarryBackground* _pBackground; //puntero al fondo de estrellas.[/code]

Roids.cpp
[code:1]//-----------------------------------------------------------------
// Roids Application
// C++ Source - Roids.cpp
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// Include Files
//-----------------------------------------------------------------
#include "Roids.h"

//-----------------------------------------------------------------
// Game Engine Functions
//-----------------------------------------------------------------
BOOL GameInitialize(HINSTANCE hInstance)
{
// Create the game engine
_pGame = new GameEngine(hInstance, TEXT("Roids"),
TEXT("Roids"), IDI_ROIDS, IDI_ROIDS_SM, 500, 400);
if (_pGame == NULL)
return FALSE;

// Set the frame rate
_pGame->SetFrameRate(30);

// Store the instance handle
_hInstance = hInstance;

return TRUE;
}

void GameStart(HWND hWindow)
{
// Seed the random number generator
srand(GetTickCount());

// Create the offscreen device context and bitmap
_hOffscreenDC = CreateCompatibleDC(GetDC(hWindow));
_hOffscreenBitmap = CreateCompatibleBitmap(GetDC(hWindow),
_pGame->GetWidth(), _pGame->GetHeight());
SelectObject(_hOffscreenDC, _hOffscreenBitmap);

// Create and load the asteroid bitmap
HDC hDC = GetDC(hWindow);
_pAsteroidBitmap = new Bitmap(hDC, IDB_ASTEROID, _hInstance);

// Create the starry background
_pBackground = new StarryBackground(500, 400);

// Create the asteroid sprites
RECT rcBounds = { 0, 0, 500, 400 };
Sprite* pSprite;
pSprite = new Sprite(_pAsteroidBitmap, rcBounds, BA_WRAP);
pSprite->SetNumFrames(14);
pSprite->SetFrameDelay(1);
pSprite->SetPosition(250, 200);
pSprite->SetVelocity(-3, 1);
_pGame->AddSprite(pSprite);
pSprite = new Sprite(_pAsteroidBitmap, rcBounds, BA_WRAP);
pSprite->SetNumFrames(14);
pSprite->SetFrameDelay(2);
pSprite->SetPosition(250, 200);
pSprite->SetVelocity(3, -2);
_pGame->AddSprite(pSprite);
pSprite = new Sprite(_pAsteroidBitmap, rcBounds, BA_WRAP);
pSprite->SetNumFrames(14);
pSprite->SetFrameDelay(3);
pSprite->SetPosition(250, 200);
pSprite->SetVelocity(-2, -4);
_pGame->AddSprite(pSprite);
}

void GameEnd()
{
// Cleanup the offscreen device context and bitmap
DeleteObject(_hOffscreenBitmap);
DeleteDC(_hOffscreenDC);

// Cleanup the asteroid bitmap
delete _pAsteroidBitmap;

// Cleanup the background
delete _pBackground;

// Cleanup the sprites
_pGame->CleanupSprites();

// Cleanup the game engine
delete _pGame;
}

void GameActivate(HWND hWindow)
{
}

void GameDeactivate(HWND hWindow)
{
}

void GamePaint(HDC hDC)
{
// Draw the background
_pBackground->Draw(hDC);

// Draw the sprites
_pGame->DrawSprites(hDC);
}

void GameCycle()
{
// Update the background
_pBackground->Update();

// Update the sprites
_pGame->UpdateSprites();

// Obtain a device context for repainting the game
HWND hWindow = _pGame->GetWindow();
HDC hDC = GetDC(hWindow);

// Paint the game to the offscreen device context
GamePaint(_hOffscreenDC);

// Blit the offscreen bitmap to the game screen
BitBlt(hDC, 0, 0, _pGame->GetWidth(), _pGame->GetHeight(),
_hOffscreenDC, 0, 0, SRCCOPY);

// Cleanup
ReleaseDC(hWindow, hDC);
}

void HandleKeys()
{
}

void MouseButtonDown(int x, int y, BOOL bLeft)
{
}

void MouseButtonUp(int x, int y, BOOL bLeft)
{
}

void MouseMove(int x, int y)
{
}

void HandleJoystick(JOYSTATE jsJoystickState)
{
}

BOOL SpriteCollision(Sprite* pSpriteHitter, Sprite* pSpriteHittee)
{
return FALSE;
}[/code]

Código fuente


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
publicidad
publicidad