Whoever answers this gets a cookie (unwanted black background behind start menu)

Started by
3 comments, last by phil05 19 years, 4 months ago
Game rocks. Nothing wrong with it but a black background when the game first starts. Behind the start menu is a black screen that is ontop of the blue screen that is suppose to be there. When I click "start game" the black background is replaced with the blue background for good. I just learned double buffering so I wonder if it has something to do with the back buffer not setting to blue before it draws on the game_dc. Moving FillRect(back_dc, &rect, BLUE); around the loop didn't do any good. Any help is appreciated.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Program: Pong Frenzy
// Author:  Phillip Vaira
// Dates:	December 6, 2004
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// PREPROCESSOR DIRECTIVES
#include <windows.h>		// Win32 Header
#include <windowsx.h>		// Win32 Macros
#include <iostream>			// C++ Functions 
#include <string>			// Strings
#include "resource.h"		// Resource Header
#include <mmsystem.h>		// Multimedia System
#include "Header.h"			// Main Header File

// MACROS
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// GLOBALS
const char g_szClassName[]	= "ParentClassWindow";					// Class Name
const char g_szWinTitle[]	= "Pong Frenzy";						// Window Title
const long int WIDTH = 800, HEIGHT = 600;							// Width & Height Size
char PScoreBuffer[20] = "", CScoreBuffer[20] = "", Buffer[50] = ""; // Score & General Char Buffers 							 
bool Active = false, Multiplayer = false, keys[256];				// Paddles are able to move when Active is true.
int SPEED = 22, DIFFICULTY = 17, MaxWins = 10;						// when the player clicks Start Game in menu.
	
// Ball Coords
int ball_x	= 300;			// Starting x pos of ball
int ball_y	= 300;			// Starting y pos of ball
const int ball_cx = 50;		// Width of ball
const int ball_cy = 50;		// Height of Ball

// LPad Coords
int LPad_x	= 0;			// Default x value of LPad. Keeps the left pad on the left.
int LPad_y	= 180;			// Pad Position
const int LPad_cx = 17;		// Width of left pad
const int LPad_cy = 119;	// Height of left pad 

// RPad Coords
int RPad_x	= 776;			// Default x value of RPad. Keeps the right pad on the right.
int RPad_y	= 180;			// RPad Position
const int RPad_cx = 17;		// Width of RPad
const int RPad_cy = 119;	// Height of RPad
 
int PlayerScore = 0;		// Keeps Track of the Player's Score
int ComputerScore = 0;		// Keeps Track of the Computer's Score


// For Back Buffering
HDC back_dc = NULL;			// Handle for the back buffer
HDC game_dc = NULL;			// Handle for the game device context (main dc)
HDC obj_dc = NULL;			// Handle for the object buffer. Keeps track of the current bitmap. 
HBITMAP back_bmp = NULL;
HBITMAP old_bmp = NULL;
											
// HANDLES
HWND g_hWnd					= NULL;					// Global Handle for Parent Window
HINSTANCE g_hInstance		= NULL;					// Global Handle for Programsss's Instance
HBITMAP bmpLPad, bmpRPad, bmpBall = NULL;			// Handles to Bitmaps
RECT   rect;										// Stores the main window's rectangle (dimensions)sss
HWND hDlgOptions = NULL, hDlgStart = NULL;

// MCI Objects
CMP3_MCI CMP3;			// MCI Object For background music
CMP3_MCI MP3_Ball;		// MCI Object for HITBALL.wav
CMP3_MCI MP3_GameOver; // MCI Object for GAMEOVER.wav

// Used for FillRect() in the game loop. Keeps the background blue.
HBRUSH BLUE = CreateSolidBrush(RGB(0, 0, 100));

// WINMAIN
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;		// Window Class Structure Variable
	HWND hWnd = NULL;	// Handle to Parent Window
	MSG Msg;			// Message Structure Variable
	bool done = FALSE;	// Determines if Game Loop should End. Default: False

	// Setting Background Color of Parent Window
	LOGBRUSH Brush;
	Brush.lbColor	= RGB(0, 0, 100);						// RGB Color Value
	Brush.lbHatch	= 0;									// Hatch Value
	Brush.lbStyle	= BS_SOLID;								// Brush Style
	HBRUSH hBrush   = CreateBrushIndirect(&Brush);			// hBrush = Brush;

	// Registering Class Window
	wc.cbClsExtra			= 0;								// Extra Class Info Space
	wc.cbWndExtra			= 0;								// Extra Window Info Space
	wc.cbSize				= sizeof(WNDCLASSEX);				// Size of the Window Class Structure
	wc.hbrBackground		= hBrush;							// Using Color created from LOGBRUSH
	wc.hCursor				= LoadCursor(NULL, IDC_ARROW);		// Cursor Icon
	wc.hIcon				= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GAMEICON));	// Window Icon (32x32)
	wc.hIconSm				= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GAMEICON));	// Window Icon (16x16)
	wc.hInstance			= hInstance;						// Instance of the Application
	wc.lpfnWndProc			= WndProc;							// WndProc to Use
	wc.lpszClassName		= g_szClassName;					// Class Name
	wc.lpszMenuName			= NULL;								// Menu Name
	wc.style				= CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLKS;	// Style
	
	// If Registering Class Window Fails, Alert the User and Close the Application
	if (!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Registering Class Window Failed!", "Error...", MB_OK | MB_ICONEXCLAMATION);
		return 0;
	}

	// Creating Parent Window
	if (!(hWnd = CreateWindowEx(NULL, g_szClassName, g_szWinTitle, WS_CAPTION | WS_BORDER | 
		WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT, NULL, 
		LoadMenu(hInstance, MAKEINTRESOURCE(MAIN_MENU)), hInstance, NULL)))	
		{
			MessageBox(NULL, "Creating Parent Window Failed!", "Error...", MB_OK | MB_ICONEXCLAMATION);
			return 0;
		}

	g_hWnd = hWnd;				// Globally Assign Parent's Window Handle
	g_hInstance = hInstance;	// Globally Assign Application's Instance

	// Show & Update Window
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	// Get a Device Context for hWnd
	game_dc = GetDC(hWnd);
		 
	// Load Bitmaps before Game Loop Begins
	bmpLPad = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_LPAD));
	bmpRPad = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_RPAD));
	bmpBall = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BALL));
 	
   // For double buffering
   back_dc = CreateCompatibleDC(game_dc);
   obj_dc = CreateCompatibleDC(back_dc);
   back_bmp = CreateCompatibleBitmap(game_dc, WIDTH, HEIGHT);
   old_bmp = (HBITMAP)SelectObject(back_dc, back_bmp);

   // Loading Music & Sound Effects
   CMP3.Load("Audio\\song.mp3");				// load background song
   MP3_Ball.Load("Audio\\HITBALL.wav");			// load HITBALL.wav
   MP3_GameOver.Load("Audio\\GAMEOVER.wav");	// load GAMEOVER.wav

   CMP3.Play();	// Play background song before game loop begins.

 	// Seed Random Number Generator
	srand(GetTickCount());

	// Game Loop
	while (!done)
	{	   				
		DWORD start_time = GetTickCount();
			
		if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
		{
			// Did the Player Decide to Quit? If so, Exit the Game Loop.
			if (Msg.message == WM_QUIT)
			{
				done = TRUE;

			}
			else if ((PlayerScore == MaxWins) || (ComputerScore == MaxWins))
			{
				WinLostMessage();					  // Get a Random Winning/Loosing Message for the Player
				ResetGame();						  // Reset Game Data
				ShowWindow(hDlgStart, SW_SHOWNORMAL); // Show Start Menu
			}

			else
			{
				TranslateMessage(&Msg);		// Translate any Accelerator Keys
				DispatchMessage(&Msg);		// Send to WndProc
			}
		}
		else
		{ 

			if (Active == true)				// Only Get Player's Input/Physics/Collision/AI/Painting 
			{								// when Active Is set to true.			
				if (  KEYDOWN('W') || KEYDOWN('S') || KEYDOWN(VK_ESCAPE) || KEYDOWN(VK_UP) || KEYDOWN(VK_DOWN) )
				{
					// Input
					GetPlayerInput();
				}	
				
				// Physics & Collision
				GetPhysics();
				
				// GetAI
				GetAI();
			}
							
			// Paint Current LPad Position onto Back Buffer
			SelectObject(obj_dc, bmpLPad); 
			BitBlt(back_dc, LPad_x, LPad_y, LPad_cx, LPad_cy, obj_dc, 0, 0, SRCCOPY);	
			
			// Paint Current RPad Position onto Back Buffer
			SelectObject(obj_dc, bmpRPad);
			BitBlt(back_dc, 776, RPad_y, RPad_cy, RPad_cy, obj_dc, 0, 0, SRCCOPY);
				
			// Paint Current Ball Position onto Back Buffer
			SelectObject(obj_dc, bmpBall);
			BitBlt(back_dc, ball_x, ball_y, ball_cx, ball_cy, obj_dc, 0, 0, SRCCOPY);

			// Send back_dc to game_dc
			BitBlt(game_dc, 0, 0, WIDTH, HEIGHT, back_dc, 0, 0, SRCCOPY);

			// Erase Back Buffer
			BitBlt(back_dc, 0, 0, WIDTH, HEIGHT, back_dc, 0, 0, BLACKNESS);
				
			// Set Back Buffer Color to Blue
			FillRect(back_dc, &rect, BLUE);

			// Set Score on the Window Title
			SetScore();  
			 
 
		    // lock framerate to 33 milliseconds (30fps)
		    while((GetTickCount() - start_time) < 33);				
		}
	}
	

	ReleaseDC(hWnd, game_dc);		// Release the Device Context
	Active = false;					// Stop game activation
	
	CMP3.Stop();					// Stop the background music if it is still playing.
	MP3_Ball.Stop();				// Stop HITBALL.wav if it is still playing.
	MP3_GameOver.Stop();			// Stop GAMEOVER.wav if it is still playing.
	
	return Msg.wParam;
}


// Parent Window Procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HWND hDlgAbout = NULL;		// Handle to the About Dialog & Start Menu Dialog

	switch (Msg)
	{
 		case WM_CREATE:
			{
				// Centering Parent Window
				RECT rect;
				GetWindowRect(hWnd, &rect);
				int xSize = (rect.right - rect.left);
				int ySize = (rect.bottom - rect.top);
				int x = (GetSystemMetrics(SM_CXSCREEN) - xSize) / 2;
				int y = (GetSystemMetrics(SM_CYSCREEN) - ySize) / 2;
				SetWindowPos(hWnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);

				// Load the Start Menu after Execution
				hDlgStart = CreateDialog(NULL, MAKEINTRESOURCE(IDD_STARTMENU), hWnd, (DLGPROC)StartDlg);
				ShowWindow(hDlgStart, SW_SHOWNORMAL);

 			}
			break;

		case WM_PAINT:
			{
				// Validate the window
				game_dc = BeginPaint(hWnd, &ps);

				EndPaint(hWnd, &ps);
			}
			break;	
			
		case WM_CLOSE: 
			{
				// Destroy Parent Window upon Close-up
				DestroyWindow(hWnd);	
			}
			break;

		case WM_DESTROY:
			{	
				// Destroy Program
				PostQuitMessage(WM_QUIT);		
			}
			break;

  
		case WM_COMMAND:
			{
				// Menu Commands
				switch (LOWORD(wParam))
				{
					// EXIT
					case IDR_FILEEXIT: 
						{
							// Does the Player wish to Quit? 
							if (MessageBox(NULL, "Are you sure you want to quit?", "Exiting Pong Frenzy", 
								MB_YESNO | MB_ICONQUESTION) == IDYES) 
							{
								PostQuitMessage(WM_QUIT);							// Quit Game
							}
							else 
							{
								return DefWindowProc(hWnd, Msg, wParam, lParam);	// Else, Do Nothing
							}
						}
						break;

					// New Game
					case IDR_FILENEW:
						{
							ResetGame();	// Reset Game Data

							// Load the Start Menu
							hDlgStart = CreateDialog(NULL, MAKEINTRESOURCE(IDD_STARTMENU), hWnd, (DLGPROC)StartDlg);
							ShowWindow(hDlgStart, SW_SHOWNORMAL);
						}
						break;

					// ABOUT
					case IDR_FILEABOUT:
						{
							Active = false;			// Pause Game
							hDlgAbout = CreateDialog(NULL, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)AboutDlg);
							ShowWindow(hDlgAbout, SW_SHOWNORMAL);
						}
						break;
				}
			}
			break;

		default: return DefWindowProc(hWnd, Msg, wParam, lParam);
	}

	return 0;
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// About Dialog Procedure
//

BOOL CALLBACK AboutDlg(HWND hDlgAbout, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
		case WM_COMMAND:
			{
				switch (LOWORD(wParam))
				{
					case IDOK:
						{
							// Closing the About Dialog...
							Active = true;	// Activate the Game
							EndDialog(hDlgAbout, wParam);
							return TRUE;
						}
						break;
				}
			}
	}
	
	return FALSE;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Start Menu Dialog Procedure
//

BOOL CALLBACK StartDlg(HWND hDlgStart, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
		case WM_MOVE:
			{
				// If the Player Moves the Start Menu, Move it Back to the Center!! HAHA.
				RECT recto;
				GetWindowRect(hDlgStart, &recto);
				int xSize = (recto.right - recto.left);
				int ySize = (recto.bottom - recto.top);
				int x = (GetSystemMetrics(SM_CXSCREEN) - xSize) / 2;
				int y = (GetSystemMetrics(SM_CYSCREEN) - ySize) / 2;
				SetWindowPos(hDlgStart, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
			}
			break;


		case WM_COMMAND:
			{
				switch (LOWORD(wParam))
				{
					case IDC_STARTGAME:
						{
							// Close Dialog when Player clicks Start Game
							PlaySound(MAKEINTRESOURCE(IDW_BEEP3), 0, SND_RESOURCE | SND_ASYNC);
							Active = true;

							EndDialog(hDlgStart, wParam);
							return TRUE;
						}
						break;

					case IDC_OPTIONS:
						{
							PlaySound(MAKEINTRESOURCE(IDW_BEEP3), 0, SND_RESOURCE | SND_ASYNC);
							
							// Load Options Dialog
							hDlgOptions = CreateDialog(NULL, MAKEINTRESOURCE(IDD_OPTIONS), g_hWnd, (DLGPROC)OptionsDlg);
							SetDlgItemText(hDlgOptions, IDC_MAXWINS, "10");
							ShowWindow(hDlgOptions, SW_SHOW);
							
							// Setting Difficulty Combo Box in the Options Dialog  
							const char *LIST[] = { "Easy", "Normal", "Bring it on!" };

							for (int i = 0; i < 4; i++)
							{
								SendMessage(GetDlgItem(hDlgOptions, IDC_DIFFICULTYLEVEL), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(LIST));
							
							}

							// Setting Number of Players Combo Box in the Options Dialog
							const char *NUMPLAYERS[] = { "One Player", "Two Players" };

							for (int j = 0; j < 2; j++)
							{
								SendMessage(GetDlgItem(hDlgOptions, IDC_PLAYERS), CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(NUMPLAYERS[j]));
							}

							SendMessage(GetDlgItem(hDlgOptions, IDC_DIFFICULTYLEVEL), CB_SETCURSEL, 1, 0); // Default Selection: Normal
							SendMessage(GetDlgItem(hDlgOptions, IDC_PLAYERS), CB_SETCURSEL, 0, 0); // Default Selection: 1 Player
							
						 
							return TRUE;
						}
						break;

					case IDC_EXIT:
						{
							// Exit the Game
							// Does the Player wish to Quit? 
							if (MessageBox(NULL, "Are you sure you want to quit?", "Exiting Pong Frenzy", 
								MB_YESNO | MB_ICONQUESTION) == IDYES) 
							{
								PostQuitMessage(WM_QUIT);							// Quit Game
							}
							else 
							{
								return TRUE;	// Else, Do Nothing
							}
						}
						break;
				}
			}
	}

	return FALSE;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Options Menu Dialog Procedure
//

BOOL CALLBACK OptionsDlg(HWND hDlgOptions, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
 		case WM_COMMAND:
			{
				switch (LOWORD(wParam))
				{
						case IDOK:
						{

							char Difficulty_Buffer[20];
							char MaxWins_Buffer[20];
							char Player_Buffer[20];

							SendDlgItemMessage(hDlgOptions, IDC_DIFFICULTYLEVEL, WM_GETTEXT, 20, (LPARAM) Difficulty_Buffer);
							
							if (strcmp(Difficulty_Buffer, "Easy") == 0)
							{
								SPEED = 17;
								DIFFICULTY = 14;
							}
							else if (strcmp(Difficulty_Buffer, "Normal") == 0)
							{
								SPEED = 22;
								DIFFICULTY = 17;
							}
							else if (strcmp(Difficulty_Buffer, "Bring it on!") == 0)
							{
								SPEED = 33;
								DIFFICULTY = 20;
							}
							else
							{
								SPEED = 17;
								DIFFICULTY = 14;
							}


							 // Setting Max Wins in the Options Dialog
							SendDlgItemMessage(hDlgOptions, IDC_PLAYERS, WM_GETTEXT, 20, (LPARAM) Player_Buffer);
							if (strcmp(Player_Buffer, "One Player") == 0)
							{
								Multiplayer = false;
							}
							else if (strcmp(Player_Buffer, "Two Players") == 0)
							{
								Multiplayer = true;
							}
							else
							{
								Multiplayer = false;
								 
							}


							// Setting Max Wins in the Options Dialog
							GetDlgItemText(hDlgOptions, IDC_MAXWINS, MaxWins_Buffer, sizeof(MaxWins_Buffer));


							// If the MaxWins text field is empty or "0", set default back to 10.
							if ((strcmp(MaxWins_Buffer, "") == 0) || (strcmp(MaxWins_Buffer, "0") == 0))
							{
								MaxWins = 10; 															 
							}
							else
							{
								// MaxWins = MaxWins_Buffer
								MaxWins = atoi(MaxWins_Buffer);
								if ( (MaxWins < 500) )
								{
									// No code needed here.
								}
								else
								{
									// If number of wins is too high, alert player and reset to 10.
									MessageBox(NULL, "Your max number of wins may be too high.", "Pong Frenzy", MB_OK | MB_ICONEXCLAMATION);
									SetDlgItemText(hDlgOptions, IDC_MAXWINS, "10"); // Set default back.
									SetFocus(GetDlgItem(hDlgOptions, IDC_MAXWINS)); // Set focus back on text field
									return TRUE;									// Don't close options.
								}
								
							}
 
							// Closing the Options Dialog. Save data here.
							EndDialog(hDlgOptions, wParam);
							return TRUE;
						}
						break;

						case IDCANCEL:
						{
							// Canceling & Closing the Options Dialog. Don't save any data here.
							EndDialog(hDlgOptions, wParam);
							return TRUE;
						}
						break;
				}
			}
			
	}
	return FALSE;
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function: GetPlayerInput()
// Purpose:  Determine what the player is requesting via keyboard.
// Dates:	December 7, 2004
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

inline void GetPlayerInput()
{
	// Get Player's Movements
	if (KEYDOWN('W'))	// Did the player press up?
	{
		LPad_y = LPad_y - 15;
	}
	if (KEYDOWN('S'))	// Did the player press down?
	{
		LPad_y = LPad_y + 15;
	} 
	
	 
	if (Multiplayer == true)
	{
		// Get Second Player's Movements
		if (KEYDOWN(VK_UP))	// Did the second player press up?
		{	
			RPad_y = RPad_y - 15;
		}
		if (KEYDOWN(VK_DOWN))	// Did the second player press down?
		{
			RPad_y = RPad_y + 15;
		} 
	}
	 
	if (KEYDOWN(VK_ESCAPE))
	{
		// Does the Player wish to Quit? 
		if (MessageBox(NULL, "Are you sure you want to quit?", "Exiting Pong Frenzy", 
				MB_YESNO | MB_ICONQUESTION) == IDYES) 
		{
				PostQuitMessage(WM_QUIT); 	// Quit Game
		}
	}	

}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function: GetPhysics()
// Purpose:  Set the game physics and collision.
// Dates:	December 7, 2004
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

inline void GetPhysics()
{
	GetClientRect(g_hWnd, &rect);
	CMP3_MCI CMP3Ball;

	// Collision - Stop LPad if at the bottom of the screen.
	if ((LPad_y  + 172) > HEIGHT)
		LPad_y = HEIGHT - 172;

	// Collision - Stop LPad if at top of screen.
	if ((LPad_y) < 0)
		LPad_y = 0;

	// Collision - Stop RPad if at the bottom of the screen.
	if ((RPad_y  + 172) > HEIGHT)
		RPad_y = HEIGHT - 172;

	// Collision - Stop RPad if at top of screen.
	if ((RPad_y) < 0)
		RPad_y = 0;


	static bool ball_moveRight	= false;	// Should the ball be moving right?
	static bool ball_moveUp		= true;		// Should the ball be moving upward?

	// Collision Checking with X Axis
	if (ball_x > rect.right - ball_cx) { ball_x -= SPEED; ball_moveRight = false; PlayerScore++;}
	if (ball_x < rect.left) { ball_x += SPEED; ball_moveRight = true; ComputerScore++;	}

	// Collision Checking with Y Axis
	if (ball_y > rect.bottom - ball_cy) { ball_y -= SPEED; ball_moveUp = true; }
	if (ball_y < (rect.top - ball_y)) { ball_y += SPEED; ball_moveUp = false; }


	// Check Current Boolean States
	if (ball_moveRight == true)
		ball_x += SPEED;
	else
		ball_x -= SPEED;

	if (ball_moveUp == true)
		ball_y -= SPEED;

	if (ball_moveUp == false)
		ball_y += SPEED;


 	 // If the Ball hits LPad...	
	if (ball_x < LPad_cx && ball_y >= LPad_y  && ball_y <= LPad_y + LPad_cy 
		|| ball_x < LPad_cx && ball_y + ball_cy >= LPad_y && ball_y <= LPad_y +
		LPad_cy )
	{
			ball_x += SPEED; ball_moveRight = true; 
			MP3_Ball.Play();
	}
 
 	//If the Ball hits RPad...
	if (ball_x + ball_cx >= RPad_x && ball_y >= RPad_y && ball_y <= RPad_y + RPad_cy || 
	ball_x + ball_cx>= RPad_x && ball_y + ball_cy >= RPad_y && ball_y + ball_cy <= RPad_y + RPad_cy) 
	{
		ball_x -= SPEED; ball_moveRight = false;
		MP3_Ball.Play();
	}

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function: GetAI()
// Purpose:  Computer determines where to go to prevent the player from scoring a point. 
//			 If the game session is two players, ignore the AI.
// Dates:	December 9, 2004
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

inline void GetAI()
{
	if (Multiplayer == false)
	{
		// Computer AI 
		if (RPad_y < ball_y)
		{
			RPad_y = RPad_y + DIFFICULTY - 3;
		}
		else
		{
			RPad_y = RPad_y - DIFFICULTY;
		}
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function: WinLostMessage()
// Purpose:  After the player wins or looses, congradulate him with random messages.
// Dates:	December 9, 2004
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

inline void WinLostMessage()
{
	if (PlayerScore == MaxWins)
	{
		int RandNum = rand()%6;
		
		switch (RandNum)
		{
			case 0: MP3_GameOver.Play();
					MessageBox(NULL, "Good job! You won! Now get a life.", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			case 1: MP3_GameOver.Play();
					MessageBox(NULL, "Congratulations! You did it!", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			case 2: MP3_GameOver.Play();
					MessageBox(NULL, "And the crowd cheers! You win!", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			case 3: MP3_GameOver.Play();
					MessageBox(NULL, "You win the next generation console system! Just kidding. You win!", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			case 4: MP3_GameOver.Play();
					MessageBox(NULL, "You rule!", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			default:MP3_GameOver.Play(); 
					MessageBox(NULL, "You win!", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					 
		}
	}
	else if (ComputerScore == MaxWins)
	{
		int RandNum = rand()%6;
		
		switch (RandNum)
		{
			case 0: MP3_GameOver.Play();
					MessageBox(NULL, "What the heck was that?! You lost.", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			case 1: MP3_GameOver.Play();
					MessageBox(NULL, "You can do better!", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			case 2: MP3_GameOver.Play();
					MessageBox(NULL, "Maybe next time! Til then, you lost!", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			case 3: MP3_GameOver.Play();
					MessageBox(NULL, "How can you achieve in life if you can't defeat Pong Frenzy?", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			case 4: MP3_GameOver.Play();
					MessageBox(NULL, "No comment. You lost.", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
					break;
			default:MP3_GameOver.Play(); 
					MessageBox(NULL, "You lost!", "Pong Frenzy", MB_OK | MB_ICONINFORMATION);
		}
	}

 
 
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function: SetScore()
// Purpose:  Keeps the window titel bar updated with the latest scores. 
// Dates:	December 11, 2004
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

inline void SetScore()
{
				sprintf(PScoreBuffer, ("%d"), PlayerScore);		// Convert PlayerScore from int to char.
				sprintf(CScoreBuffer, ("%d"), ComputerScore);	// Convert ComputerScore from int to char
				
				// Display the New Window Title that has the Current Score  
				if (Multiplayer == false)
				{
					sprintf(Buffer, "Pong Frenzy    ::: Player: %d, Computer: %d :::", PlayerScore, ComputerScore);
				}
				else
				{
					sprintf(Buffer, "Pong Frenzy    ::: Player 1: %d, Player 2: %d :::", PlayerScore, ComputerScore);
				}
				
				SetWindowText(g_hWnd, Buffer); // Set Window Title to Show Current Scores
}

 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function: ResetGame()
// Purpose:  Reset game data when starting a new game or finishing a game session. 
// Dates:	December 15, 2004
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

inline void ResetGame()
{
	Active = false;			// Pause Game
	PlayerScore = 0;		// Reset Player Score to 0
	ComputerScore = 0;		// Reset Computer Score to 0
							
	ball_x	= 300;			// Reset Starting x pos of ball
	ball_y	= 300;			// Reset Starting y pos of ball
	LPad_x	= 0;			// Reset  Default x value of LPad. Keeps the left pad on the left.
	LPad_y	= 180;			// Reset Pad Position
	RPad_x	= 776;			// Reset Default x value of RPad. Keeps the right pad on the right.
	RPad_y	= 180;			// Reset RPad Position

	SPEED		= 22;		// Reset starting Speed of the Ball
	DIFFICULTY	= 17;		// Reset starting Difficulty to Normal
	MaxWins		= 10;		// Reset starting Max Wins
}

Advertisement
Ok, I think maybe I found your problem. When you call FillRect, you are passing the address of a global variable 'rect', as the rectangle to be filled. You set 'rect' to the dimensions of the window in your GetPhysics method, but that doesn't get called unless Active == true. So, you are passing an uninitialized rectangle to FillRect. The rectangle you are passing is probably invalid, so no blue color gets drawn at all. When you select the start option, Active gets set to true, and so GetPhysics will initialize you rect variable, and the blue starts getting drawn. So, somewhere in your code, you need to initialize your rect variable in a way that is not dependent on whether your game is active or not.

Also, I think there is a problem with the order in which you do your draw operations. Since you draw your blue background at the end a frame render, wont that mean that the first frame drawn wont have the blue background?

I don't have all the files to compile your program, so I can't be sure that what I've said is correct. But, if I understand your code correctly, this should fix you problem.
Yep, that was it :) In the physics function, I gave it a new rect name called "prect". I assigned the physics stuff to that. For the game loop, I passed it all to "rect" and did a GetClientRect() before the loop. I load the game, a flash of black happens quickly, but it sets itself to blue while the game menu is shown. To stop the black flash, I put FillRect() in the beginning like you mentioned. The first frame would pick it up immediately and it did.

Thanks for the help. I probably can't mail a cookie but I can give you a point :)
The problem is caused by the WM_PAINT handler doing nothing but telling Windows that whatever is currently drawn is perfectly fine.

Try puting a
RedrawWindow(hWnd, NULL, NULL, RDW_INTERNALPAINT);
before the while (!done) loop.

Also, this statement:
while((GetTickCount() - start_time) < 33);
should be changed to:
while((GetTickCount() - start_time) < 33) Sleep(1);
This is unlikely to slow your program down noticeably, but without the Sleep your CPU usage will always be 100% which is totally unnecessary and will make laptop users very unhappy when they get hot and the battery goes flat very quick or something.

btw, the only thing you have to do for double-buffering is to change EVERY statement that draws to your DC to draw to a different DC, then have ONE single place in your program where you draw that whole DC to the one you were previously drawing to. It's that simple.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Thanks for the tips. I'll definitely add what you mentioned. I didn't notice any speed differences, but could it for a slower computer? Just curious.

By the way, this is a bit off subject. You guys did enough, so it's up to you. When I minimize the game by clickign on the tab below in the toolbar, and max it back up, the scores went extremely high. This does not happen when I click to another window. But minimizing it from the toolbar is causing a score of 5 go to 65 in seconds. I tried inactive checking but that didn't do any good.

This topic is closed to new replies.

Advertisement