-
November 21st, 2010, 11:42 PM
#1
Problem painting the BITMAP
Code:
#include <windows.h>
#include "resource.h"
const char g_szClassName[] = "myWindowClass";
HBITMAP g_hbmBall = NULL;
HBITMAP g_hbmBrick = NULL;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
g_hbmBall = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BALL));
if(g_hbmBall == NULL)
MessageBox(hwnd, "Could not load IDB_BALL!", "Error", MB_OK | MB_ICONEXCLAMATION);
g_hbmBrick = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BRICK));
if(g_hbmBrick == NULL)
MessageBox(hwnd, "Could not load IDB_BRICK!", "Error", MB_OK | MB_ICONEXCLAMATION);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_PAINT:
{
// Just a note, never use a MessageBox from inside WM_PAINT
// The box will cause more WM_PAINT messages and you'll probably end up
// stuck in a loop
BITMAP bm;
BITMAP bm2;
PAINTSTRUCT ps;
PAINTSTRUCT ps2;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdc2 = BeginPaint(hwnd, &ps2);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_hbmBall);
HDC hdcMem2 = CreateCompatibleDC(hdc);
HBITMAP hbmOld2 = (HBITMAP)SelectObject(hdcMem2, g_hbmBrick);
GetObject(g_hbmBall, sizeof(bm), &bm);
GetObject(g_hbmBrick, sizeof(bm2), &bm2);
BitBlt(hdc, 10, 10, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
BitBlt(hdc, 50, 50, bm2.bmWidth, bm.bmHeight, hdcMem2, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
DeleteObject(g_hbmBall);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"A Bitmap Program",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
so basically when i run this program i get the error that says it cannot load IDB_BRICK. i dont understand how i can get it to load that bitmap image.
heres my resource file too
Code:
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by bmp_one.rc
//
#define IDB_BALL 101
#define IDB_BRICK 102
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
incidentally i'm trying to create a breakout clone and am wondering if i am going about this the right way.
-
November 22nd, 2010, 02:15 AM
#2
Re: Problem painting the BITMAP
Well, the error message seems correct. Your "resource" file (at least, what you have shown as a resource file) does not contain any resource at all. Neither bitmaps now anything else.
Victor Nijegorodov
-
November 22nd, 2010, 08:27 AM
#3
Re: Problem painting the BITMAP
Have you included the resource file in your project ? (It is not enough to have #include "resource.h")
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdc2 = BeginPaint(hwnd, &ps2);
[...]EndPaint(hwnd, &ps);
Two BeginPaint() ! I have never seen so many before at once ! Not sure this will work.
Only one EndPaint() !
-
November 22nd, 2010, 04:09 PM
#4
Re: Problem painting the BITMAP
well what i don't understand is that the file paints the image of the ball that is displayed but not the image of the brick. i was wondering the same thing, where do i declare what the bmp file is, or where it is located in the project. this is directly from the forgers win32 api tutorial and i have no idea how he gets the ball to display, without declaring the bmp as a resource anywhere in the program. i have looked over the code several times and just cant understand how to do it.
also, if i dont declare begin paint multiple times how can i paint multiple objects to the screen? just using 1 begin paint?
-
November 23rd, 2010, 05:52 AM
#5
Re: Problem painting the BITMAP
BeginPaint() is used to retrieve a handle to a display context (hdc).
If you need another handle, usually, you call CreateComptaibleDC(), instead of calling again BeginPaint(). I don't know if calling several times BeginPaint() is working or not. It is just that I have never thought of doing that, and never seen a program doing that (although I am programming Windows applications for ten years).
Otherwise, your code looks correct. I have done almost the same thing. If IDB_BRICK cannot be loaded, it might be a problem with the creation of the bitmap in the resource file. Maybe you could try to load it before loading the ball. Maybe you can try to store a third bitmap in the resource file, one that would be like the ball, and try to load it after having loaded the ball.
Also, release hdcMem2 with SelectObject(hdcMem2, hbmOld2); DeleteDC(hdcMem2);;
Last edited by olivthill2; November 23rd, 2010 at 05:55 AM.
-
November 23rd, 2010, 02:42 PM
#6
Re: Problem painting the BITMAP
i cant figure out how to make a brick break program, i have put days of work into this and i dont understand how this is to be easy....Does anyone have, or know of, a tutorial where i can get a better understanding of how to make a game like this?
-
November 24th, 2010, 04:42 AM
#7
Re: Problem painting the BITMAP
Unfortunately this is not easy, you are right.
I once suggested drawing a rectangle, because, myself, I have spent several days debugging the display of images from resources. In the end, I got the correct result, but maybe you don't have much time.
If you want to keep on working with images, then, show us your code (I guess you have updated it since last time), show us your resource file. Like I said before, I think the problem is with the resource file. But you don't seem to listen to my advice :-(. Have you tried to remove the second BeginPaint()? Have you tried to load the brick before the ball? Have you tried to load the ball twice? What have you tried to do? Are there other problems than this loading of the brick? Can you draw a rectangle instead of loading the bitmap, so that you can go ahead and later you will try again loading the image? Good luck to you!
-
November 26th, 2010, 09:36 PM
#8
Re: Problem painting the BITMAP
ok so COMPLETE code remodification.....
here is the new code
Code:
#include <windows.h>
#include <string>
using namespace std;
const char g_szClassName[] = "myWindowClass";
const int ID_TIMER = 1;
const int BALL_MOVE_DELTA = 4; //ball speed
typedef struct _BALLINFO
{
int width;
int height;
int x;
int y;
int dx;
int dy;
}BALLINFO;
BALLINFO g_ballInfo;
typedef struct _PADDLEINFO
{
int width;
int height;
int x;
int y;
int dx;
int dy;
}PADDLEINFO;
PADDLEINFO g_leftPaddleInfo;
string message = "A sample message.";
void DrawBall(HDC hdc, RECT* prc)
{
HBRUSH blueBrush=CreateSolidBrush(RGB(0,0,255));
HGDIOBJ old=SelectObject(hdc,blueBrush);
Ellipse(hdc, g_ballInfo.x, g_ballInfo.y, g_ballInfo.x+g_ballInfo.width, g_ballInfo.y+g_ballInfo.height);
DeleteObject(blueBrush);
SelectObject(hdc,old);
}
void DrawLeftPaddle(HDC hdc, RECT* prc)
{
HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
HGDIOBJ old=SelectObject(hdc,redBrush);
Rectangle(hdc, g_leftPaddleInfo.x, g_leftPaddleInfo.y, g_leftPaddleInfo.x + g_leftPaddleInfo.width, g_leftPaddleInfo.y+g_leftPaddleInfo.height);
DeleteObject(redBrush);
SelectObject(hdc,old);
}
void UpdateBall(RECT* prc)
{
// collision detection
g_ballInfo.x += g_ballInfo.dx;
g_ballInfo.y += g_ballInfo.dy;
if(g_ballInfo.x < 0)
{
g_ballInfo.x = 0;
g_ballInfo.dx = BALL_MOVE_DELTA;
}
else if(g_ballInfo.x + g_ballInfo.width > prc->right)
{
g_ballInfo.x = prc->right - g_ballInfo.width;
g_ballInfo.dx = -BALL_MOVE_DELTA;
}
if(g_ballInfo.y < 0)
{
g_ballInfo.y = 0;
g_ballInfo.dy = BALL_MOVE_DELTA;
}
else if(g_ballInfo.y + g_ballInfo.height > prc->bottom)
{
g_ballInfo.y = prc->bottom - g_ballInfo.height;
g_ballInfo.dy = -BALL_MOVE_DELTA;
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
UINT ret; //unsigned int to hold result of timer creation
g_leftPaddleInfo.width = 60;
g_leftPaddleInfo.height = 10;
g_leftPaddleInfo.x = 20; // this is where the paddle starts
g_leftPaddleInfo.y = 340; // also here
g_ballInfo.width = 10;
g_ballInfo.height = 10;
g_ballInfo.dx = BALL_MOVE_DELTA;
g_ballInfo.dy = BALL_MOVE_DELTA;
ret = SetTimer(hwnd, ID_TIMER, 20, NULL); // 20 milliseconds
if(ret == 0)
MessageBox(hwnd, "Could not SetTimer()!", "Error", MB_OK | MB_ICONEXCLAMATION);
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_PAINT:
{
RECT rcClient; //struct to hold rectangle coordinates
PAINTSTRUCT ps; //struct representing client area of window
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rcClient); //get coordinates of client area of window
DrawBall(hdc, &rcClient);
EndPaint(hwnd, &ps);
}
break;
case WM_TIMER:
{
/*if (GetAsyncKeyState(VK_UP) < 0)
{
g_leftPaddleInfo.y-=6;
}
if(GetAsyncKeyState(VK_DOWN) < 0)
{
g_leftPaddleInfo.y+=6;
}
*/
if (GetAsyncKeyState(VK_RIGHT) < 0)
{
g_leftPaddleInfo.x+=6;
}
if(GetAsyncKeyState(VK_LEFT) < 0)
{
g_leftPaddleInfo.x-=6;
}
if(g_leftPaddleInfo.x < 0)
{
g_leftPaddleInfo.x = 0;
//g_ballInfo.dx = BALL_MOVE_DELTA;
}
else if(g_leftPaddleInfo.x + g_leftPaddleInfo.width > 385)
{
g_leftPaddleInfo.x =320; // prc->right - g_leftPaddleInfo.width;
//g_ballInfo.dx = -BALL_MOVE_DELTA;
}
RECT rcClient; //struct to hold rectangle coordinates
HDC hdc = GetDC(hwnd); //grab a handle to the window (Device Context)
GetClientRect(hwnd, &rcClient); //get coordinates of client area of window
// and store them in rcClient
UpdateBall(&rcClient); //calculate next ball position
FillRect(hdc, &rcClient, (HBRUSH)GetStockObject(WHITE_BRUSH));
TextOut(hdc, 20, 20, message.c_str(), message.length());
DrawBall(hdc, &rcClient); //clear screan and draw ball in new position
DrawLeftPaddle(hdc, &rcClient);
ReleaseDC(hwnd, hdc); //release the handle to the window (Device Context)
}
break;
case WM_KEYDOWN:
/* if(wParam == VK_DOWN) // try this way instead - See the problem?
y+=6;
if(wParam == VK_UP)
y-=6;
*/
break;
case WM_KEYUP:
break;
case WM_DESTROY:
KillTimer(hwnd, ID_TIMER);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"An Animation Program",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
and up until this point i have been very happy with myself. my problem now is getting collision detection working for the paddle on the bottom. i just dont know how to get that done. any tips?
ive fiddled around with different x and y positions like if(x of ball = x of paddle and y of ball = y of paddle)(ball move delta) but that doesnt work and if i set x of ball to x of paddle, the ball stays on a straight line horizontally and vice versa if i set y of ball to y of paddle.
the message is a place holder for a possible score keeping system later on.
Last edited by Newkid34; November 26th, 2010 at 10:39 PM.
-
November 27th, 2010, 01:48 PM
#9
Re: Problem painting the BITMAP
Code:
#include <windows.h>
#include <string>
using namespace std;
const char g_szClassName[] = "myWindowClass";
const int ID_TIMER = 1;
const int BALL_MOVE_DELTA = 4; //ball speed
typedef struct _BALLINFO
{
int width;
int height;
int x;
int y;
int dx;
int dy;
}BALLINFO;
BALLINFO g_ballInfo;
typedef struct _PADDLEINFO
{
int width;
int height;
int x;
int y;
int dx;
int dy;
}PADDLEINFO;
PADDLEINFO g_leftPaddleInfo;
string message = "A sample message.";
void DrawBall(HDC hdc, RECT* prc)
{
HBRUSH blueBrush=CreateSolidBrush(RGB(0,0,255));
HGDIOBJ old=SelectObject(hdc,blueBrush);
Ellipse(hdc, g_ballInfo.x, g_ballInfo.y, g_ballInfo.x+g_ballInfo.width, g_ballInfo.y+g_ballInfo.height);
DeleteObject(blueBrush);
SelectObject(hdc,old);
}
void DrawLeftPaddle(HDC hdc, RECT* prc)
{
HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
HGDIOBJ old=SelectObject(hdc,redBrush);
Rectangle(hdc, g_leftPaddleInfo.x, g_leftPaddleInfo.y, g_leftPaddleInfo.x + g_leftPaddleInfo.width, g_leftPaddleInfo.y+g_leftPaddleInfo.height);
DeleteObject(redBrush);
SelectObject(hdc,old);
}
void DrawBlock(HDC hdc, RECT* prc)
{
HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
HGDIOBJ old=SelectObject(hdc,redBrush);
Rectangle(hdc, 50,50,110,60);
Rectangle(hdc, 110,50,170,60);
Rectangle(hdc, 170,50,230,60);
Rectangle(hdc, 230,50,290,60);
Rectangle(hdc, 50,60,110,70);
Rectangle(hdc, 110,60,170,70);
Rectangle(hdc, 170,60,230,70);
Rectangle(hdc, 230,60,290,70);
Rectangle(hdc, 50,70,110,80);
Rectangle(hdc, 110,70,170,80);
Rectangle(hdc, 170,70,230,80);
Rectangle(hdc, 230,70,290,80);
DeleteObject(redBrush);
SelectObject(hdc,old);
}
/* void DrawRectLoop(HDC hdc, RECT*prc)
{
HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
HGDIOBJ old=SelectObject(hdc,redBrush);
Rectangle(hdc, 50,50,110,60);
DeleteObject(redBrush);
SelectObject(hdc,old);
}
*/
void UpdateBall(RECT* prc)
{
// collision detection
g_ballInfo.x += g_ballInfo.dx;
g_ballInfo.y += g_ballInfo.dy;
if(g_ballInfo.x < 0)
{
g_ballInfo.x = 0;
g_ballInfo.dx = BALL_MOVE_DELTA;
}
else if(g_ballInfo.x + g_ballInfo.width > prc->right)
{
g_ballInfo.x = prc->right - g_ballInfo.width;
g_ballInfo.dx = -BALL_MOVE_DELTA;
}
if(g_ballInfo.y < 0)
{
g_ballInfo.y = 0;
g_ballInfo.dy = BALL_MOVE_DELTA;
}
else if(g_ballInfo.y + g_ballInfo.height > prc->bottom)
{
g_ballInfo.y = prc->bottom - g_ballInfo.height;
g_ballInfo.dy = -BALL_MOVE_DELTA;
}
//if((g_ballInfo.x = g_leftPaddleInfo.x) & (g_ballInfo.y = g_leftPaddleInfo.y))
{
//g_ballInfo.y = 0;
//g_ballInfo.dx = -BALL_MOVE_DELTA;
//g_ballInfo.dy = -BALL_MOVE_DELTA;
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
UINT ret; //unsigned int to hold result of timer creation
g_leftPaddleInfo.width = 60;
g_leftPaddleInfo.height = 10;
g_leftPaddleInfo.x = 20; // this is where the paddle starts
g_leftPaddleInfo.y = 340; // also here
g_ballInfo.width = 10;
g_ballInfo.height = 10;
g_ballInfo.dx = BALL_MOVE_DELTA;
g_ballInfo.dy = BALL_MOVE_DELTA;
ret = SetTimer(hwnd, ID_TIMER, 20, NULL); // 20 milliseconds
if(ret == 0)
MessageBox(hwnd, "Could not SetTimer()!", "Error", MB_OK | MB_ICONEXCLAMATION);
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_PAINT:
{
RECT rcClient; //struct to hold rectangle coordinates
PAINTSTRUCT ps; //struct representing client area of window
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rcClient); //get coordinates of client area of window
DrawBall(hdc, &rcClient);
EndPaint(hwnd, &ps);
}
break;
case WM_TIMER:
{
/*if (GetAsyncKeyState(VK_UP) < 0)
{
g_leftPaddleInfo.y-=6;
}
if(GetAsyncKeyState(VK_DOWN) < 0)
{
g_leftPaddleInfo.y+=6;
}
*/
if (GetAsyncKeyState(VK_RIGHT) < 0)
{
g_leftPaddleInfo.x+=6;
}
if(GetAsyncKeyState(VK_LEFT) < 0)
{
g_leftPaddleInfo.x-=6;
}
if(g_leftPaddleInfo.x < 0)
{
g_leftPaddleInfo.x = 0;
//g_ballInfo.dx = BALL_MOVE_DELTA;
}
else if(g_leftPaddleInfo.x + g_leftPaddleInfo.width > 385)
{
g_leftPaddleInfo.x =320; // prc->right - g_leftPaddleInfo.width;
//g_ballInfo.dx = -BALL_MOVE_DELTA;
}
RECT rcClient; //struct to hold rectangle coordinates
HDC hdc = GetDC(hwnd); //grab a handle to the window (Device Context)
GetClientRect(hwnd, &rcClient); //get coordinates of client area of window
// and store them in rcClient
UpdateBall(&rcClient); //calculate next ball position
FillRect(hdc, &rcClient, (HBRUSH)GetStockObject(WHITE_BRUSH));
TextOut(hdc, 20, 20, message.c_str(), message.length());
DrawBall(hdc, &rcClient); //clear screan and draw ball in new position
DrawLeftPaddle(hdc, &rcClient);
DrawBlock(hdc,&rcClient);
ReleaseDC(hwnd, hdc); //release the handle to the window (Device Context)
}
break;
case WM_KEYDOWN:
/* if(wParam == VK_DOWN) // try this way instead - See the problem?
y+=6;
if(wParam == VK_UP)
y-=6;
*/
break;
case WM_KEYUP:
break;
case WM_DESTROY:
KillTimer(hwnd, ID_TIMER);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"An Animation Program",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
This is the newest code i have. collision detection is still a problem but i have fixed the paddle and drawn the blocks to the window. i cant get the collision detection to work for the paddle or the blocks =/.
-
November 29th, 2010, 04:38 AM
#10
Re: Problem painting the BITMAP
Code:
//if((g_ballInfo.x = g_leftPaddleInfo.x) & (g_ballInfo.y = g_leftPaddleInfo.y))
Beware of the difference between = and ==, and between & and && (and also | and ||). Here, I think you meant == and &&.
-
November 29th, 2010, 09:09 PM
#11
Re: Problem painting the BITMAP
ohhh your right about that, Thanks. will try and repost
-
November 29th, 2010, 10:42 PM
#12
Re: Problem painting the BITMAP
Code:
#include <windows.h>
#include <string>
using namespace std;
const char g_szClassName[] = "myWindowClass";
const int ID_TIMER = 1;
const int BALL_MOVE_DELTA = 4; //ball speed
typedef struct _BALLINFO
{
int width;
int height;
int x;
int y;
int dx;
int dy;
}BALLINFO;
BALLINFO g_ballInfo;
typedef struct _PADDLEINFO
{
int width;
int height;
int x;
int y;
int dx;
int dy;
}PADDLEINFO;
PADDLEINFO g_leftPaddleInfo;
string message = "A sample message.";
void DrawBall(HDC hdc, RECT* prc)
{
HBRUSH blueBrush=CreateSolidBrush(RGB(0,0,255));
HGDIOBJ old=SelectObject(hdc,blueBrush);
Ellipse(hdc, g_ballInfo.x, g_ballInfo.y, g_ballInfo.x+g_ballInfo.width, g_ballInfo.y+g_ballInfo.height);
DeleteObject(blueBrush);
SelectObject(hdc,old);
}
void DrawLeftPaddle(HDC hdc, RECT* prc)
{
HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
HGDIOBJ old=SelectObject(hdc,redBrush);
Rectangle(hdc, g_leftPaddleInfo.x, g_leftPaddleInfo.y, g_leftPaddleInfo.x + g_leftPaddleInfo.width, g_leftPaddleInfo.y+g_leftPaddleInfo.height);
DeleteObject(redBrush);
SelectObject(hdc,old);
}
void DrawBlock(HDC hdc, RECT* prc)
{
HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
HGDIOBJ old=SelectObject(hdc,redBrush);
Rectangle(hdc, 50,50,110,60);
Rectangle(hdc, 110,50,170,60);
Rectangle(hdc, 170,50,230,60);
Rectangle(hdc, 230,50,290,60);
Rectangle(hdc, 50,60,110,70);
Rectangle(hdc, 110,60,170,70);
Rectangle(hdc, 170,60,230,70);
Rectangle(hdc, 230,60,290,70);
Rectangle(hdc, 50,70,110,80);
Rectangle(hdc, 110,70,170,80);
Rectangle(hdc, 170,70,230,80);
Rectangle(hdc, 230,70,290,80);
DeleteObject(redBrush);
SelectObject(hdc,old);
}
/* void DrawRectLoop(HDC hdc, RECT*prc)
{
HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
HGDIOBJ old=SelectObject(hdc,redBrush);
Rectangle(hdc, 50,50,110,60);
DeleteObject(redBrush);
SelectObject(hdc,old);
}
*/
void UpdateBall(RECT* prc)
{
// collision detection
g_ballInfo.x += g_ballInfo.dx;
g_ballInfo.y += g_ballInfo.dy;
if(g_ballInfo.x < 0)
{
g_ballInfo.x = 0;
g_ballInfo.dx = BALL_MOVE_DELTA;
}
else if(g_ballInfo.x + g_ballInfo.width > prc->right)
{
g_ballInfo.x = prc->right - g_ballInfo.width;
g_ballInfo.dx = -BALL_MOVE_DELTA;
}
if(g_ballInfo.y < 0)
{
g_ballInfo.y = 0;
g_ballInfo.dy = BALL_MOVE_DELTA;
}
else if(g_ballInfo.y + g_ballInfo.height > prc->bottom)
{
g_ballInfo.y = prc->bottom - g_ballInfo.height;
g_ballInfo.dy = -BALL_MOVE_DELTA;
}
if(g_ballInfo.x > g_leftPaddleInfo.x && g_ballInfo.x < g_leftPaddleInfo.x + g_leftPaddleInfo.width && g_ballInfo.y == g_leftPaddleInfo.y)
{
//g_ballInfo.x = 0;
g_ballInfo.dx = BALL_MOVE_DELTA;
g_ballInfo.dy = -BALL_MOVE_DELTA;
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
UINT ret; //unsigned int to hold result of timer creation
g_leftPaddleInfo.width = 60;
g_leftPaddleInfo.height = 10;
g_leftPaddleInfo.x = 20; // this is where the paddle starts
g_leftPaddleInfo.y = 340; // also here
g_ballInfo.width = 10;
g_ballInfo.height = 10;
g_ballInfo.dx = BALL_MOVE_DELTA;
g_ballInfo.dy = BALL_MOVE_DELTA;
ret = SetTimer(hwnd, ID_TIMER, 20, NULL); // 20 milliseconds
if(ret == 0)
MessageBox(hwnd, "Could not SetTimer()!", "Error", MB_OK | MB_ICONEXCLAMATION);
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_PAINT:
{
RECT rcClient; //struct to hold rectangle coordinates
PAINTSTRUCT ps; //struct representing client area of window
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rcClient); //get coordinates of client area of window
DrawBall(hdc, &rcClient);
EndPaint(hwnd, &ps);
}
break;
case WM_TIMER:
{
/*if (GetAsyncKeyState(VK_UP) < 0)
{
g_leftPaddleInfo.y-=6;
}
if(GetAsyncKeyState(VK_DOWN) < 0)
{
g_leftPaddleInfo.y+=6;
}
*/
if (GetAsyncKeyState(VK_RIGHT) < 0)
{
g_leftPaddleInfo.x+=6;
}
if(GetAsyncKeyState(VK_LEFT) < 0)
{
g_leftPaddleInfo.x-=6;
}
if(g_leftPaddleInfo.x < 0)
{
g_leftPaddleInfo.x = 0;
//g_ballInfo.dx = BALL_MOVE_DELTA;
}
else if(g_leftPaddleInfo.x + g_leftPaddleInfo.width > 385)
{
g_leftPaddleInfo.x =320; // prc->right - g_leftPaddleInfo.width;
//g_ballInfo.dx = -BALL_MOVE_DELTA;
}
RECT rcClient; //struct to hold rectangle coordinates
HDC hdc = GetDC(hwnd); //grab a handle to the window (Device Context)
GetClientRect(hwnd, &rcClient); //get coordinates of client area of window
// and store them in rcClient
UpdateBall(&rcClient); //calculate next ball position
FillRect(hdc, &rcClient, (HBRUSH)GetStockObject(WHITE_BRUSH));
TextOut(hdc, 20, 20, message.c_str(), message.length());
DrawBall(hdc, &rcClient); //clear screan and draw ball in new position
DrawLeftPaddle(hdc, &rcClient);
DrawBlock(hdc,&rcClient);
ReleaseDC(hwnd, hdc); //release the handle to the window (Device Context)
}
break;
case WM_KEYDOWN:
/* if(wParam == VK_DOWN) // try this way instead - See the problem?
y+=6;
if(wParam == VK_UP)
y-=6;
*/
break;
case WM_KEYUP:
break;
case WM_DESTROY:
KillTimer(hwnd, ID_TIMER);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"An Animation Program",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
HAHA! ive got the collision detection working for the paddle, Thanks Oliv, but now for the bricks. I drew each brick individually so I don't know if there is any easy way to get the collision detection off of a brick. anyone have any tips.
-
December 2nd, 2010, 11:55 AM
#13
Re: Problem painting the BITMAP
can someone give me some insight as to how to create an array of bricks instead of drawing each individually? I realize individually it makes it significantly harder to do a brick collision detection.
Thanks.
-
December 2nd, 2010, 12:53 PM
#14
Re: Problem painting the BITMAP
as the original problem is solved im going to open a new thread for the current problem. it seems no one is answering this and i think the misleading title may be the cause
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|