-
December 2nd, 2010, 12:55 PM
#1
Breakout Clone Collision Detection
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);
int a=30;
int b =10;
int height = 50;
int width = 60;
for (int j=1;j<6;j++){
for(int i=1;i<6;i++){
Rectangle(hdc,a,height,width+a,height+b);
a=a+width;
//b=b*i;
//height=height*i;
//width=width+();
}
a=30;
b=10;
//width=60;
height = 50;
height=height+(10*j);
}
/*
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 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.y = g_leftPaddleInfo.y;
g_ballInfo.dx = BALL_MOVE_DELTA;
g_ballInfo.dy = -BALL_MOVE_DELTA;
}
/*
if(g_ballInfo.x > 50 && g_ballInfo.x < 110 && g_ballInfo.y > 70 && g_ballInfo.y < 80)
{
//g_ballInfo.x = 0;
//g_ballInfo.y = 75;
g_ballInfo.dx = BALL_MOVE_DELTA;
g_ballInfo.dy = BALL_MOVE_DELTA;
}
if(g_ballInfo.x > 170 && g_ballInfo.x < 230 && g_ballInfo.y > 70 && g_ballInfo.y < 80)
{
//g_ballInfo.x = 0;
//g_ballInfo.y = 75;
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;
}
so here is the code for my breakout clone. ive done a lot to it and to keep my previous work i have "commented out" a lot of it.
What i need help with doing is creating a loop for collision detection on the bricks, that are built via an array. Also creating something to make the bricks disappear when they get hit.
any tips?
Thanks.
-
December 2nd, 2010, 04:02 PM
#2
Re: Breakout Clone Collision Detection
I see you have a structure for the ball and one for the paddle. I suggest you create a similar structure for a brick. In this structure, you keep the position of the brick and a boolean to know if the brick is "alive" or "dead". Dead brick are not drawn and are not checked for collision detection.
Now for the collision detection, with an array of "brick", it should be easy to check if the ball collide with one of them.
Hope that helps
JeffB
-
December 4th, 2010, 10:33 AM
#3
Re: Breakout Clone Collision Detection
thanks,
can i ask why this was moved? i am using visual studio and also using WINAPI.
can i get this moved back to the appropriate sub-forum?
Last edited by Newkid34; December 4th, 2010 at 06:11 PM.
-
December 5th, 2010, 11:12 AM
#4
Re: Breakout Clone Collision Detection
i dont understand how booleans in a struct work. can anyone give me some help?
to be honest i dont know how boolean variables work at all and i tried to read up on it but i am still unclear.
Thanks.
-
December 6th, 2010, 10:14 AM
#5
Re: Breakout Clone Collision Detection
Booleans, in C, are just integers.
In windef.h, you can see
Code:
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
More explanations are given by Wikipedia ( http://en.wikipedia.org/wiki/Boolean_data_type )
The initial standards for the C language (1972) provided no Boolean type; and, to this day, Boolean values are commonly represented by integers (ints) in C programs. The comparison operators ('>', '==', etc.) are defined to return a signed integer (int) result, either zero (for false) or 1 (for true). The same convention is assumed by the logical operators ('&&', '||', '!', etc.) and condition-testing statements ('if', 'while'). Thus logical values can be stored in integer variables, and used anywhere integers would be valid, including in indexing, arithmetic, parsing, and formatting. This approach ("Boolean values are just integers") was retained in all later versions of C. Some of its dialects, like C99 and Objective-C, provide standard definitions of a Boolean type as a synonym of int and macros for "false" and "true" as 0 and 1, respectively. Visual Basic uses a similar approach. C++ has a separate Boolean data type ('bool'), but with automatic conversions from scalar and pointer values that are very similar to those of C. This approach was adopted also by many later languages, especially by some scripting ones such as AWK and Perl. One problem with this approach is that the tests if(t==TRUE){...} and if(t) are not equivalent.
-
December 7th, 2010, 10:37 AM
#6
Re: Breakout Clone Collision Detection
Originally Posted by Newkid34
thanks,
can i ask why this was moved? i am using visual studio and also using WINAPI.
can i get this moved back to the appropriate sub-forum?
Hi Newkid,
The "C++ and WinAPI" forum is for question related to usage of API. Sometimes, it is not very clear in which forum a post should be, but usually, if your question is about the usage of an API, for example, if your question would be about using the API CreateSolidBrush(), the WinAPI forum would be the good choice. Your question here does not mention any API, even if your code uses API, your question is not related to one of them, so it belong more in this forum.
JeffB
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
|