psycho_blood
asked on
Drawing a bitmap with custom function
In the code posted below, a window is created and an "asteroid" is randomly drawn inside the window on each frame. Is there a way to modify the DrawBitmap function in order to obtain a single asteroid slowly floating around the window? I modified my x and y variables from int to float type but it didn't work. Also, I read that I could mask the previous location of the asteroid and fill it with the same color as the background, but I don't know exactly how to do this.
#include <windows.h>
#include <winuser.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define APPTITLE "Game Loop"
//function prototypes
LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);
ATOM MyRegisterClass(HINSTANCE);
BOOL InitInstance(HINSTANCE,int);
void DrawBitmap(HDC,char*,float,float);
void Game_Init();
void Game_Run();
void Game_End();
//local variables
HWND global_hwnd;
HDC global_hdc;
//the window event callback function
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
global_hwnd = hWnd;
global_hdc = GetDC(hWnd);
switch (message)
{
case WM_DESTROY:
Game_End();
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
//helper function to set up the window properties
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//create the window class structure
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
//fill the struct with info
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE;
wc.hIconSm = NULL;
//set up the window with the class info
return RegisterClassEx(&wc);
}
//helper function to create the window and refresh it
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
//create a new window
hWnd = CreateWindow(
APPTITLE, //window class
APPTITLE, //title bar
WS_OVERLAPPEDWINDOW, //window style
CW_USEDEFAULT, //x position of window
CW_USEDEFAULT, //y position of window
500, //width of the window
400, //height of the window
NULL, //parent window
NULL, //menu
hInstance, //application instance
NULL); //window parameters
//was there an error creating the window?
if (!hWnd)
return FALSE;
//display the window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//entry point for a Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
int done = 0;
MSG msg;
// register the class
MyRegisterClass(hInstance);
// initialize application
if (!InitInstance (hInstance, nCmdShow))
return FALSE;
//initialize the game
Game_Init();
// main message loop
while (!done)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
//look for quit message
if (msg.message == WM_QUIT)
done = 1;
//decode and pass messages on to WndProc
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//process game loop
Game_Run();
}
return msg.wParam;
}
void DrawBitmap(HDC hdcDest, char *filename, float x, float y)
{
HBITMAP image;
BITMAP bm;
HDC hdcMem;
image = (HBITMAP)LoadImage(0,"asteroid.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//read the bitmap's properties
GetObject(image, sizeof(BITMAP), &bm);
//create a device context for the bitmap
hdcMem = CreateCompatibleDC(global_hdc);
SelectObject(hdcMem, image);
//draw the bitmap to the window (bit block transfer)
BitBlt(
global_hdc, //destination device context
x, y, //x,y location on destination
bm.bmWidth, bm.bmHeight, //width,height of source bitmap
hdcMem, //source bitmap device context
0, 0, //start x,y on source bitmap
SRCCOPY); //blit method
//delete the device context and bitmap
DeleteDC(hdcMem);
DeleteObject((HBITMAP)image);
}
void Game_Init()
{
//initialize the game...
//load bitmaps, meshes, textures, sounds, etc.
srand(time_t(NULL));
}
void Game_Run()
{
//this is called once every frame
//do not include your own loop here!
float x = 0, y = 0;
RECT rect;
GetClientRect(global_hwnd, &rect);
if (rect.right > 0)
{
x = rand() % (rect.right - rect.left);
y = rand() % (rect.bottom - rect.top);
DrawBitmap(global_hdc, "asteroid.bmp", x, y);
}
}
void Game_End()
{
}
asteroid.bmp
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I used your function but I had to change nX and nY to nCurX and nCurY. I think this is what you meant to write when calling DrawBitmap. Now the program compiles but the asteroid does not move at all. I will read your function later to see if I can understand why is that.
void Game_Run()
{
RECT rect;
GetClientRect(global_hwnd, &rect);
nCurX = nCurStepX; // move one step horizontal
nCurY = nCurStepY; // move one step vertical
if ( nCurX > rect.right ) { // at right edge? Switch to moving to the left
nCurStepX *= -1; // change 1 to -1 or -1 to 1
nCurX= rect.right;
}
if ( nCurX < rect.left ) { // at left edge? Switch to moving to the right
nCurStepX *= -1; // change 1 to -1 or -1 to 1
nCurX= rect.left;
}
if ( nCurY > rect.bottom ) { // at bottom? Switch to moving up
nCurStepY *= -1; // change 1 to -1 or -1 to 1
nCurY= rect.bottom;
}
if ( nCurY < rect.top ) { // at top? Switch to moving down
nCurStepY *= -1; // change 1 to -1 or -1 to 1
nCurY= rect.top;
}
DrawBitmap(global_hdc, "asteroid.bmp", nCurX, nCurY);
}
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Before your comment, I tried this:
nCurX = nCurStepX++;
nCurY = nCurStepY++;
Unfortunately, it didn't work. Then, I came back and noticed your comment, and that solved the problem.
Thanks!
nCurX = nCurStepX++;
nCurY = nCurStepY++;
Unfortunately, it didn't work. Then, I came back and noticed your comment, and that solved the problem.
Thanks!
ASKER
I splitted the points because all of you tried to help me. I hope my decision does not make anyone angry!
Once again, thank you all!
Once again, thank you all!
I tried to compile your code but instead of using the regular global variables I used static int values. For some odd reason when I code in the if statements for the top and the left hand sides, my asteroid picture shoots off in the upper left hand corner and disappears. My code matches yours with the exception of the static int values. Just curious if you know of some reason for this.
I want to retract my statement above (can't find an edit button) I mis read the > and < signs in the if statements. Noobish mistake on my part. You guys are amazing, you saved my whole week!
ASKER
Open in new window