CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Nov 2009
    Posts
    32

    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.

  2. #2
    Join Date
    Sep 2001
    Location
    Québec, Canada
    Posts
    1,923

    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
    CodeGuru VB FAQ Visual Basic Frequently Asked Questions
    VB Code color Tool to color your VB code on CodeGuru
    Before you post Importants informations to know before posting

  3. #3
    Join Date
    Nov 2009
    Posts
    32

    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.

  4. #4
    Join Date
    Nov 2009
    Posts
    32

    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.

  5. #5
    Join Date
    Apr 2009
    Posts
    598

    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.

  6. #6
    Join Date
    Sep 2001
    Location
    Québec, Canada
    Posts
    1,923

    Re: Breakout Clone Collision Detection

    Quote Originally Posted by Newkid34 View Post
    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
    CodeGuru VB FAQ Visual Basic Frequently Asked Questions
    VB Code color Tool to color your VB code on CodeGuru
    Before you post Importants informations to know before posting

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured