Sign in to follow this  
M4rtin

Win/Lose image not displayed

Recommended Posts

Hi, I recently tried to create a Win 32 API game (first one). All the parts of the game are working. Except the image that you see when you loose. The code below is Main.cpp . Only the parts that handle the graphics are shown in the code.
 
#include <windows.h>
#include <iostream>
#include "Graphics.h"
#include "Level.h"
#include "Player.h"
#include "Enemy.h"
#include "Block.h"
#include "Attack.h"

/******************************************************************************
	Constant variables
******************************************************************************/

/**
 * Keys for controling the player
 */
const int PengoUp    = VK_UP;

LRESULT CALLBACK WindowProc(HWND windowHandle, UINT message, WPARAM wParam,
							LPARAM lParam)
{
	// Which message is received
	switch (message)
	{

  case WM_PAINT:
    	{
		// draw level
		DrawLevel(GlobalLevel, windowHandle);

		// WM_PAINT is done
		ValidateRect(windowHandle, NULL);
		return 0;
	 }

case WM_KEYDOWN:
	{
		// which key is pressed
		switch (wParam)
		{
		case PengoUp:
			{
				// set direction
				GlobalLevel.Player.Direction = Up;
	
				// move player
				GlobalLevel.Player.IsMoving = true;
			} break;
                  //other movements
		}
	
		return 0;
	}
	}

	return DefWindowProc(windowHandle, message, wParam, lParam);
}


int WINAPI WinMain(HINSTANCE instance, HINSTANCE previousInstance, LPSTR
				   commandLine, int show)
{
   // make window class
WNDCLASS myWindowClass;
myWindowClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
myWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
myWindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
myWindowClass.hInstance = instance;
myWindowClass.lpfnWndProc = WindowProc;
myWindowClass.lpszMenuName = 0;
myWindowClass.lpszClassName = "StandardWindowClass";
myWindowClass.style = CS_VREDRAW | CS_HREDRAW;
myWindowClass.cbClsExtra = 0;
myWindowClass.cbWndExtra = 0;
// register window class
RegisterClass(&myWindowClass);

// size of level
RECT myRectangle;

myRectangle.left   = 0;
myRectangle.right  = GlobalLevel.Width * 20;
myRectangle.top    = 0;
myRectangle.bottom = GlobalLevel.Height * 20 + 25;

// calculate size of level
AdjustWindowRect(&myRectangle, WS_CAPTION, false);

int myWindowWidth = myRectangle.right - myRectangle.left;
int myWindowHeight = myRectangle.bottom - myRectangle.top;


// make window
HWND myWindowHandle = CreateWindow(
	"StandardWindowClass",       	// name of the window class
	"Pengo",                      	// title of the venster
	WS_OVERLAPPED | WS_VISIBLE | WS_SYSMENU,	// window style
	CW_USEDEFAULT, CW_USEDEFAULT, 	// position of the venster
	myWindowWidth, myWindowHeight,	// size of the venster
	0, 0,                        	// not used
	instance,                    	// the instance
	0);

// load bitmap
int myWidth  = 1 * BitmapWidth;
int myHeight = 4 * BitmapHeight;
Bitmaps = LoadImage(0, "Sprites.bmp", IMAGE_BITMAP, myWidth, myHeight, LR_LOADFROMFILE);

// event loop
MSG msg;

do
{
	// is a message sent to the window?
	if (PeekMessage(&msg, myWindowHandle, 0, 0, PM_REMOVE))
	{
		// translate message
		TranslateMessage(&msg);

		// Dispatch message
		DispatchMessage(&msg);
	}

/*
The rest of the game loop here
*/

// Tell Windows to redraw the window
InvalidateRect(myWindowHandle, 0, false);


} while ( (msg.message != WM_QUIT) && (!GlobalLevel.Player.IsDead) && (GlobalLevel.Enemies.size() > 0) );


	if (PeekMessage(&msg, myWindowHandle, 0, 0, PM_REMOVE))
	{
	TranslateMessage(&msg);
		DispatchMessage(&msg);
	}


// Delete bitmap object
DeleteObject(Bitmaps);

Sleep(2000);
PostQuitMessage(WM_DESTROY);
	 //system("pause");
	return 0;
}
And here is Graphics.cpp
#include <windows.h>
#include "Graphics.h"


/******************************************************************************
	Global variables
******************************************************************************/

// all bitmaps
HANDLE Bitmaps;
HANDLE theBitmaps;
void DrawLevel(const Level& level, HWND windowHandle)
{
	// ask device context
	HDC myWindowDC = GetDC(windowHandle);

	// make device context for bitmap
	HDC myBitmapDC = CreateCompatibleDC(myWindowDC);
	if (GlobalLevel.Player.IsDead) {
		DeleteObject(Bitmaps);
     theBitmaps = LoadImage(0, "GameOver.bmp", IMAGE_BITMAP, 288, 216, LR_LOADFROMFILE);
	}
	if (GlobalLevel.Enemies.size() == 0) {
		DeleteObject(Bitmaps);
     theBitmaps = LoadImage(0, "YouWin.bmp", IMAGE_BITMAP, 288, 216, LR_LOADFROMFILE);
	}
	if (GlobalLevel.Player.IsDead || GlobalLevel.Enemies.size() == 0) {
     SelectObject(myBitmapDC, theBitmaps);
	}
	else {
	// place bitmap in device context
	SelectObject(myBitmapDC, Bitmaps);
	}

	// distance of back buffer
	int myWidth  = GlobalLevel.Width * BitmapWidth;
	int myHeight = GlobalLevel.Height * BitmapHeight + 25;

	// make bitmap for back buffer
	HANDLE myBackBuffer = CreateCompatibleBitmap(myWindowDC, myWidth,
		myHeight);

	// make device context for back buffer
	HDC myBackBufferDC = CreateCompatibleDC(myWindowDC);

	// place back buffer bitmap in back buffer device context
	SelectObject(myBackBufferDC, myBackBuffer);
	
	// clear back buffer
	RECT myRectangle;
	myRectangle.left = 0;
	myRectangle.right = myWidth;
	myRectangle.top = 0;
	myRectangle.bottom = myHeight;

	FillRect(myBackBufferDC, &myRectangle,
		(HBRUSH) GetStockObject(BLACK_BRUSH));

	if (GlobalLevel.Player.IsDead || GlobalLevel.Enemies.size() == 0) {
     DrawEnd(myBackBufferDC, myBitmapDC);
	}
	else {
	// draw all blocks
	for (int i = 0; i < level.Blocks.size(); i++)
	{
		// draw blok
		DrawBlock(level.Blocks.at(i), myBackBufferDC, myBitmapDC);
	}
	// draw player
	DrawPlayer(level.Player, myBackBufferDC, myBitmapDC);
	if (GlobalLevel.myAttack.isalive) {
	// draw attack
	DrawAttack(myBackBufferDC, myBitmapDC);
	}

   //draw power
   DrawPower(myBackBufferDC, myBitmapDC);


	// draw all enemies
	for (int j = 0; j < level.Enemies.size(); j++)
	{
		// Draw enemy
		DrawEnemy(level.Enemies.at(j), myBackBufferDC, myBitmapDC);
	}

	}//als het spel nog aan de gang is

// copy back buffer to window
BitBlt(myWindowDC, 0, 0, myWidth, myHeight, myBackBufferDC, 0, 0, SRCCOPY);

	// delete device context of back buffer
	DeleteDC(myBackBufferDC);

	// delete bitmap of back buffer
	DeleteObject(myBackBuffer);

	// delete device context of bitmap
	DeleteDC(myBitmapDC);

	// delete device context of window
	ReleaseDC(windowHandle, myWindowDC);
}

void DrawEnd(HDC windowDC, HDC bitmapDC)
{
	//x place of bitmap
	int myX = 5;
		//y place of bitmap
	int myY = 5;
   // draw bitmap
	BitBlt(windowDC, myX, myY, 288, 216, bitmapDC,
		0, 0, SRCCOPY);
}

void DrawAttack(HDC windowDC, HDC bitmapDC) //example of a draw that works
{
	//x place of bitmap
	int myX = GlobalLevel.myAttack.X * BitmapWidth;
		//y place of bitmap
	int myY = GlobalLevel.myAttack.Y * BitmapHeight;
	// draw bitmap
	BitBlt(windowDC, myX, myY, BitmapWidth, BitmapHeight, bitmapDC,
		0, 3 * BitmapHeight, SRCCOPY);
}

 
All the objects are drawn. But when the game is over. the screen just turns black (nothing is copied to the back-buffer). Thanks in advance [Edited by - M4rtin on July 2, 2008 3:52:01 PM]

Share this post


Link to post
Share on other sites
Check if LoadBitmap fails (eg. returns NULL). If it fails, check the return value of GetLastError.

Not related to your problem, using ValidateRect in WM_PAINT is not nice. You should be using BeginPaint/EndPaint.

Share this post


Link to post
Share on other sites
Call GetLastError instantly after LoadImage fails. Otherwise another Win API function might reset it to zero. I'll wager a guess that the returned value is 2 (meaning file not found).

Make sure the bitmap files are in the working directory. With Visual Studio if you didn't modify the default the working directory when starting inside the IDE is the folder the solution is stored in.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
The opposite of "win" is "lose". The opposite of "loose" is "tight".


Corrected.


I think it was also possible to include bitmaps in the project. That might solve it.

How do you call the function LoadImage() when you bitmap is in a project (something with the first zero), and is there anything special you need to do to include the bitmap (in visual C++ 2008 express)?

Thanks in advance.

Share this post


Link to post
Share on other sites
Sorry for double post. But I found the problem. The image was supposed to be converted from .jpg to .bmp . But something in there failed. So creating a new .bmp and copying the content from the .jpg in the .bmp (select area, copy, paste in bmp) created a bmp which can be loaded.

It is working perfect now. But thanks anyway. This topic can be closed.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this