C语言打砖块游戏.docx
《C语言打砖块游戏.docx》由会员分享,可在线阅读,更多相关《C语言打砖块游戏.docx(20页珍藏版)》请在冰豆网上搜索。
C语言打砖块游戏
C语言打砖块游戏
一、游戏截图
二、游戏源码
#include
#include
#include
#include
/*DEFINES********************************************************************************/
//definesforwindows
#defineWINDOW_CLASS_NAMETEXT("WIN32CLASS")
#defineWINDOW_WIDTH640
#defineWINDOW_HEIGHT480
//statesforgameloop
#defineGAME_STATE_INIT0
#defineGAME_STATE_START_LEVEL1
#defineGAME_STATE_RUN2
#defineGAME_STATE_SHUTDOWN3
#defineGAME_STATE_EXIT4
//blockdefines
#defineNUM_BLOCK_ROWS6
#defineNUM_BLOCK_COLUMNS8
#defineBLOCK_WIDTH64
#defineBLOCK_HEIGHT16
#defineBLOCK_ORIGIN_X8
#defineBLOCK_ORIGIN_Y8
#defineBLOCK_X_GAP80
#defineBLOCK_Y_GAP32
//paddledefines
#definePADDLE_START_X(WINDOW_WIDTH/2-16)
#definePADDLE_START_Y(WINDOW_HEIGHT-32);
#definePADDLE_WIDTH32
#definePADDLE_HEIGHT8
#definePADDLE_COLORRGB(0,0,255)
//balldefines
#defineBALL_START_Y(WINDOW_HEIGHT/2)
#defineBALL_SIZE4
//colordefines
#defineBACKGROUND_COLORRGB(0,0,0)
#defineBLOCK_COLORRGB(125,0,0)
#defineBALL_COLORRGB(222,0,222)
//thesereadthekeyboardasynchronously
#defineKEY_DOWN(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?
1:
0)
#defineKEY_UP(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?
0:
1)
/*basicunsignedtypes*******************************************************************/
typedefunsignedshortUSHORT;
typedefunsignedshortWORD;
typedefunsignedcharUCHAR;
typedefunsignedcharBYTE;
/*FUNCTIONDECLARATION*******************************************************************/
intGame_Init(void*parms=NULL);
intGame_Shutdown(void*parms=NULL);
intGame_Main(void*parms=NULL);
DWORDStart_Clock(void);
DWORDWait_Clock(DWORDcount);
/*GLOBALS*********************************************************************************/
HWNDmain_window_handle=NULL;//savethewindowhandle
HINSTANCEmain_instance=NULL;//savetheinstance
intgame_state=GAME_STATE_INIT;//startingstate
intpaddle_x=0,paddle_y=0;//trackspositionofpaddle
intball_x=0,ball_y=0;//trackspositionofball
intball_dx=0,ball_dy=0;//velocityofball
intscore=0;//thescore
intlevel=1;//thecurrentlevel
intblocks_hit=0;//tracksnumberofblockshit
DWORDstart_clock_count=0;//usedfortiming
//thiscontainsthegamegriddata
UCHARblocks[NUM_BLOCK_ROWS][NUM_BLOCK_COLUMNS];
/*WINDPROC********************************************************************************/
LRESULTCALLBACKWindowProc(HWNDhwnd,
UINTmsg,
WPARAMwparam,
LPARAMlparam)
{
//thisisthemainmessagehandlerofthesystem
PAINTSTRUCTps;
HDChdc;
switch(msg)
{
caseWM_CREATE:
return0;
caseWM_PAINT:
hdc=BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return0;
caseWM_DESTROY:
PostQuitMessage(0);
return0;
default:
break;
}
returnDefWindowProc(hwnd,msg,wparam,lparam);
}
/*WINMAIN********************************************************************************/
intWINAPIWinMain(HINSTANCEhinstance,
HINSTANCEhprevinstance,
LPSTRlpcmdline,
intncmdshow)
{
WNDCLASSwinclass;
HWNDhwnd;
MSGmsg;
HDChdc;
PAINTSTRUCTps;
/*CS_DBLCLKSSpecifiesthatthewindowshouldbenotifiedofdoubleclickswith
*WM_xBUTTONDBLCLKmessages
*CS_OWNDC标志,属于此窗口类的窗口实例都有自己的DC(称为私有DC),私有DC仅属于该窗口实例,
*所以程序只需要调用一次GetDC或BeginPaint获取DC,系统就为窗口初始化一个DC,并且保存程序
*对其进行的改变。
ReleaseDC和EndPaint函数不再需要了,因为其他程序无法访问和改变私有DC。
*/
winclass.style=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
winclass.lpfnWndProc=WindowProc;
winclass.cbClsExtra=0;
winclass.cbWndExtra=0;
winclass.hInstance=hinstance;
winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
winclass.hCursor=LoadCursor(NULL,IDC_ARROW);
winclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName=NULL;
winclass.lpszClassName=WINDOW_CLASS_NAME;
//registerthewindowclass
if(!
RegisterClass(&winclass))
return0;
//Createthewindow,notetheuseofWS_POPUP
hwnd=CreateWindow(
WINDOW_CLASS_NAME,//class
TEXT("WIN32GameConsole"),//title
WS_POPUP,//style
200,//initialx
100,//initialy
WINDOW_WIDTH,//initialwidth
WINDOW_HEIGHT,//initialheight
NULL,//handletoparent
NULL,//handletomenu
hinstance,//instance
NULL);//creationparms
if(!
hwnd)
return0;
ShowWindow(hwnd,ncmdshow);
UpdateWindow(hwnd);
//hidemouse
//ShowCursor(FALSE);
//savethewindowhandleandinstanceinaglobal
main_window_handle=hwnd;
main_instance=hinstance;
//performallgameconsolespecificinitialization
Game_Init();
//entermaineventloop
while
(1)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
//testifthisisaquitmsg
if(msg.message==WM_QUIT)
break;
//translateanyacceleratorkeys
TranslateMessage(&msg);
//sendthemessagetothewindowproc
DispatchMessage(&msg);
}
//maingameprocessinggoeshere
Game_Main();
Sleep(30);
}
//shutdowngameandreleaseallresources
Game_Shutdown();
//showmouse
//ShowCursor(TRUE);
//returntowindowslikethis
return(msg.wParam);
}
/*DRAWFUNCTION**************************************************************************/
intDraw_Rectangle(intx1,inty1,intx2,inty2,intcolor)
{
//thisfunctionusesWin32APItodrawafilledrectangle
HBRUSHhbrush;
HDChdc;
RECTrect;
SetRect(&rect,x1,y1,x2,y2);
hbrush=CreateSolidBrush(color);
hdc=GetDC(main_window_handle);
FillRect(hdc,&rect,hbrush);
ReleaseDC(main_window_handle,hdc);
DeleteObject(hbrush);
return1;
}
intDrawText_GUI(TCHAR*text,intx,inty,intcolor)
{
HDChdc;
hdc=GetDC(main_window_handle);
//setthecolorsforthetextup
SetTextColor(hdc,color);
//setbackgroundmodetotransparentsoblackisn'tcopied
SetBkMode(hdc,TRANSPARENT);
//drawthetext
TextOut(hdc,x,y,text,lstrlen(text));
//releasethedc
ReleaseDC(main_window_handle,hdc);
return1;
}
/*GAMEPROGRAMMINGCONSOLEFUNCTIONS*****************************************************/
voidInit_Blocks(void)
{
//initializetheblockfield
for(introw=0;rowfor(intcol=0;colblocks[row][col]=1;
}
voidDraw_Blocks(void)
{
//thisfunctiondrawsalltheblocksinrowmajorform
intx1=BLOCK_ORIGIN_X;
inty1=BLOCK_ORIGIN_Y;
//drawalltheblocks
for(introw=0;row{
//resetcolumnposition
x1=BLOCK_ORIGIN_X;
for(intcol=0;col{
if(blocks[row][col]!
=0)
{
Draw_Rectangle(x1,y1,x1+BLOCK_WIDTH,y1+BLOCK_HEIGHT,BLOCK_COLOR);
}
else
{
Draw_Rectangle(x1,y1,x1+BLOCK_WIDTH,y1+BLOCK_HEIGHT,BACKGROUND_COLOR);
}
x1+=BLOCK_X_GAP;//advancecolumnposition
}
y1+=BLOCK_Y_GAP;//advancetonextrowposition
}
}
intProcess_Ball(void)
{
//thisfunctiontestsiftheballhashitablockorthepaddleifso,theballisbounced
//andtheblockisremovedfromtheplayfieldnote:
verycheesycollisionalgorithm:
)
//firsttestforballblockcollisions
//thealgorithmbasicallyteststheballagainsteachblock'sboundingboxthisisinefficient,
//buteasytoimplement,laterwe'llseeabetterway
//currentrenderingposition
intx1=BLOCK_ORIGIN_X;
inty1=BLOCK_ORIGIN_Y;
//computercenterofball
intball_cx=ball_x+(BALL_SIZE/2);
intball_cy=ball_y+(BALL_SIZE/2);
//testtheballhashitthepaddle
if(ball_y>(WINDOW_HEIGHT/2)&&ball_dy>0)
{
//extractleadingedgeofball
intx=ball_x+(BALL_SIZE/2);
inty=ball_y+(BALL_SIZE/2);
//testforcollisionwithpaddle
if((x>=paddle_x&&x<=paddle_x+PADDLE_WIDTH)&&
(y>=paddle_y&&y<=paddle_y+PADDLE_HEIGHT))
{
ball_dy=-ball_dy;//reflectball
ball_y+=ball_dy;//pushballoutofpaddlesinceitmadecontact
//addalittleenglishtoballbasedonmotionofpaddle
if(KEY_DOWN(VK_RIGHT))
ball_dx-=rand()%3;
elseif(KEY_DOWN(VK_LEFT))
ball_dx+=rand()%3;
else
ball_dx+=(-1+rand()%3);
//makealittlenoise
MessageBeep(MB_OK);
return0;
}
}
//nowscanthrualltheblocksandseeofballhitblocks
for(introw=0;row{
x1=BLOCK_ORIGIN_X;
//scanthisrowofblocks
for(intcol=0;col{
if(blocks[row][col]!
=0)
{
//testballagainstboundingboxofblock
if((ball_cx>x1)&&(ball_cx(ball_cy>y1)&&(ball_cy{
blocks[row][col]=0;//removetheblock
//incrementglobalblockcounter,soweknowwhentostartanotherlevelup
blocks_hit++;
ball_dy=-ball_dy;//bouncetheball
ball_dx+=(-1+rand()%3);//addalittleenglish
MessageBeep(MB_OK);//makealittlenoise
//testiftherearenoblocks,ifsosendamessagetogamelooptostartanotherlevel
if(blocks_hit>=(NUM_BLOCK_ROWS*NUM_BLOCK_COLUMNS))
{
game_state=GAME_STATE_START_LEVEL;
level++;
}
//addsomepoints
score+=5*(level+(abs)(ball_dx));
return1;
}
}
x1+=BLOCK_X_GAP;//advancecolumnposition
}
y1+=BLOCK_Y_GAP;//advancerowposition
}
return0;
}
intGame_Init(void*parms)
{
//thisfunctioniswhereyoudoalltheinitializationfo