📄 game.cpp
字号:
#include "windows.h"
#include "resource.h"
#include "ddutil.h"
#include "stdio.h"
#include "game.h"
//#include "gamemusic.h"
#define ERRMSG(i) MessageBox(NULL,i,"errmsg",MB_OK|MB_ICONERROR)
#define FREE_OBJECT(p) {if(p){delete p;p=NULL;}}
CDisplay* g_pDisplay=NULL;
CSurface* g_pBackSurface=NULL;
CSurface* g_pBack2Surface[4]={NULL};
CSurface* g_pGameOverSurface=NULL;
CSurface* g_pSurface[9]={NULL};
CSurface* g_pNONESurface=NULL;
CSurface* g_pTextSurface=NULL;
BOOL g_bActive=FALSE;
HRESULT InitDirectDraw(HWND hwnd);
void FreeDirectDraw(void);
HRESULT Render();
HRESULT DelRender();
void WaitTime(DWORD times);
void GameOver();
HWND InitWindow(HINSTANCE hInst,int nCmdShow);
void GameLoop(void);
LRESULT WINAPI WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int nCmdShow)
{
HWND hwnd;
if((hwnd=InitWindow(hInst ,nCmdShow))==NULL){
ERRMSG("创建窗口错误!");
return 0;
}
if(FAILED(InitDirectDraw(hwnd))){
if (g_pDisplay)
g_pDisplay->GetDirectDraw()->SetCooperativeLevel(NULL, DDSCL_NORMAL);
ERRMSG("DirectDraw init failed. The sample will now exit.");
return 0;
}
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
GameLoop();
FreeDirectDraw();
return 1;
}
HWND InitWindow(HINSTANCE hInst,int nCmdShow)
{
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L,
GetModuleHandle(NULL),LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1)),
NULL, NULL, NULL,"DX Project 1", NULL};
RegisterClassEx(&wc);
HWND hWnd = CreateWindow("DX Project 1", " 游戏—俄罗斯方块",
WS_OVERLAPPED |
WS_SYSMENU |
WS_MINIMIZEBOX
,50, 50, 500, 500,
GetDesktopWindow(), NULL, wc.hInstance, NULL);
return hWnd;
}
HRESULT InitDirectDraw(HWND hwnd)
{
HRESULT hr;
char str[10];
g_pDisplay=new CDisplay();
if(FAILED(hr=g_pDisplay->CreateWindowedDisplay(hwnd,400,450))){
ERRMSG("荧屏初始化错误!");
return hr;
}
if(FAILED(hr=g_pDisplay->CreateSurfaceFromBitmap(&g_pBackSurface,"bk.bmp",400,400))){
ERRMSG("背景位图载入错误!");
return hr;
}
if(FAILED(hr=g_pDisplay->CreateSurfaceFromBitmap(&g_pBack2Surface[0],"start.bmp",400,50))){
ERRMSG("背景位图start.bmp载入错误!");
return hr;
}
if(FAILED(hr=g_pDisplay->CreateSurfaceFromBitmap(&g_pBack2Surface[1],"开始.bmp",400,50))){
ERRMSG("背景位图 开始.bmp载入错误!");
return hr;
}
if(FAILED(hr=g_pDisplay->CreateSurfaceFromBitmap(&g_pBack2Surface[2],"暂停.bmp",400,50))){
ERRMSG("背景位图 暂停.bmp载入错误!");
return hr;
}
if(FAILED(hr=g_pDisplay->CreateSurfaceFromBitmap(&g_pBack2Surface[3],"结束.bmp",400,50))){
ERRMSG("背景位图 结束.bmp载入错误!");
return hr;
}
for(int i=0;i<9;i++){
sprintf(str,"%d.bmp",i+1);
if(FAILED(hr=g_pDisplay->CreateSurfaceFromBitmap(&g_pSurface[i],str,0,0))){
ERRMSG("位图载入错误!");
return hr;
}
}
if(FAILED(hr=g_pDisplay->CreateSurfaceFromBitmap(&g_pNONESurface,"0.bmp",0,0))){
ERRMSG("位图载入错误!");
return hr;
}
if(FAILED(hr=g_pDisplay->CreateSurfaceFromBitmap(&g_pGameOverSurface,"gameover.bmp",0,0))){
ERRMSG("位图gameover.bmp载入错误!");
return hr;
}
g_pGameOverSurface->SetColorKey(RGB(0,0,0));
if(FAILED(hr=g_pDisplay->CreateSurfaceFromText(&g_pTextSurface,NULL,"NUM: 000000",RGB(0,0,0),RGB(21,222,30)))){
ERRMSG("字符缓冲区错误");
return hr;
}
g_pTextSurface->SetColorKey(RGB(0,0,0));
g_bActive=TRUE;
return S_OK;
}
void FreeDirectDraw()
{
FREE_OBJECT(g_pDisplay);
FREE_OBJECT(g_pTextSurface);
for(int i=0;i<9;i++)
FREE_OBJECT(g_pSurface[i]);
FREE_OBJECT(g_pBackSurface);
for(i=0;i<4;i++)
FREE_OBJECT(g_pBack2Surface[i]);
FREE_OBJECT(g_pNONESurface);
}
HRESULT Render()
{
HRESULT hr;
int i,j,FK_X,FK_Y,nIndex,pos,t_num=0;
BOOL IsFull=FALSE;
g_pDisplay->Clear(0);
if(FAILED(hr=g_pDisplay->Blt(0,0,g_pBackSurface,NULL))){
ERRMSG("图块拷贝错误!");
return hr;
}
if(GameStatus==PLAY)
g_pDisplay->Blt(0,400,g_pBack2Surface[1],NULL);
else if(GameStatus==PAUSE)
g_pDisplay->Blt(0,400,g_pBack2Surface[2],NULL);
else if(GameStatus==STOP||GameStatus==AUTOSTOP)
g_pDisplay->Blt(0,400,g_pBack2Surface[3],NULL);
else if(GameStatus==START)
g_pDisplay->Blt(0,400,g_pBack2Surface[0],NULL);
///////////////////////
if(GameStatus==PLAY||GameStatus==PAUSE||GameStatus==AUTOSTOP)
for(i=0;i<20;i++){
pos=0;
for(j=0;j<20;j++)
if((nIndex=DS_FanKai[j][i])==NONE)
continue;
else{
FK_X=j*20;
FK_Y=i*20;
g_pDisplay->Blt(FK_X,FK_Y,g_pSurface[nIndex],NULL);
if(IsStop==TRUE) pos++;
}
if(pos==20){
FullFK[i]=TRUE;
t_num++;
IsFull=TRUE;
}
}
///////////////////////
if(FAILED(hr=g_pDisplay->Blt(300,10,g_pTextSurface,NULL))){
ERRMSG("分数字符显示错误!");
return hr;
}
if(FAILED(hr=g_pDisplay->Present())){
ERRMSG("画图操作错误!");
return hr;
}
if(IsFull&&IsStop){
if(FAILED(hr=DelRender())){
ERRMSG("消行操作出错!");
return hr;
}
num+=t_num*t_num*10;
char s[10],str[20]="NUM: ";
sprintf(s,"%d",num);
if(strlen(s)<6)
for(i=0;i<(6-(int)strlen(s));i++)
strcat(str,"0");
strcat(str,s);
FREE_OBJECT(g_pTextSurface);
g_pDisplay->CreateSurfaceFromText(&g_pTextSurface,NULL,
str,RGB(0,0,0),RGB(21,222,30));
g_pTextSurface->SetColorKey(RGB(0,0,0));
}
if(GameStatus==AUTOSTOP)
GameOver();
return S_OK;
}
HRESULT DelRender()
{
HRESULT hr;
int i,j,t;
///////////////////
for(i=19;i>=1;i--)
if(FullFK[i]==TRUE)
for(j=19;j>=0;j--)
if(FAILED(hr=g_pDisplay->Blt(j*20,i*20,
g_pSurface[3],NULL)))
return hr;
if(FAILED(hr=g_pDisplay->Present()))
return hr;
WaitTime(300);
/////////////////////
for(i=19;i>=1;i--)
if(FullFK[i]==TRUE)
for(j=19;j>=0;j--)
if(FAILED(hr=g_pDisplay->Blt(j*20,i*20,
g_pSurface[0],NULL)))
return hr;
if(FAILED(hr=g_pDisplay->Present()))
return hr;
WaitTime(300);
///////////////////////
for(i=1;i<20;i++)
if(FullFK[i]==TRUE)
for(j=19;j>=0;j--){
if(FAILED(hr=g_pDisplay->Blt(j*20,i*20,
g_pSurface[3],NULL)))
return hr;
for(t=i;t>=1;t--)
DS_FanKai[j][t]=DS_FanKai[j][t-1];
}
if(FAILED(hr=g_pDisplay->Present()))
return hr;
WaitTime(300);
//////////////////////////
for(i=0;i<20;i++){
for(j=19;j>=1;j--)
if(FullFK[j]==TRUE){
if(FAILED(hr=g_pDisplay->Blt(i*20,j*20,
g_pNONESurface,NULL)))
return hr;
if(i==19)
FullFK[j]=FALSE;
}
g_pDisplay->Present();
WaitTime(50);
}
////////////////
return S_OK;
}
void WaitTime(DWORD times)
{
DWORD dwCount=GetTickCount();
while(GetTickCount()-dwCount<times);
}
void GameOver()
{
int i,j;
g_pDisplay->Blt(100,300,g_pGameOverSurface,NULL);
g_pDisplay->Present();
WaitTime(5000);
num=0;
IsStop=TRUE;
GameStatus=STOP;
for(i=0;i<20;i++)
for(j=0;j<20;j++)
DS_FanKai[i][j]=NONE;
if(g_pTextSurface)
FREE_OBJECT(g_pTextSurface);
g_pDisplay->CreateSurfaceFromText(&g_pTextSurface,NULL,"NUM: 000000",
RGB(0,0,0),RGB(21,222,30));
g_pTextSurface->SetColorKey(RGB(0,0,0));
}
void GameLoop()
{
MSG msg;
BOOL fMessage;
PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
while(msg.message != WM_QUIT)
{
fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
if(fMessage)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if(g_bActive)
if(FAILED(Render()))
return;
}
}
}
LRESULT WINAPI WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
int i,j;
switch (msg)
{ case WM_KEYDOWN:
if(GameStatus==PLAY)
if(IsStop==FALSE)
switch((char)wParam){
case VK_UP:MoveFK(0);break;
case VK_LEFT:MoveFK(1);break;
case VK_DOWN:MoveFK(2);break;
case VK_RIGHT:MoveFK(3);break;
}
else InitFK();
return 0L;
case WM_CHAR:
switch((char)wParam){
case '\r': GameStatus=PLAY ;break;
case 'p':
case 'P':
GameStatus=PAUSE;break;
case 'q':
case 'Q':
if(GameStatus!=PLAY) break;
GameStatus=PAUSE;
if(IDYES==MessageBox(hWnd,"是否结束游戏?","结束游戏",MB_YESNO|MB_ICONQUESTION))
{
num=0;
IsStop=TRUE;
GameStatus=STOP;
for(i=0;i<20;i++)
for(j=0;j<20;j++)
DS_FanKai[i][j]=NONE;
if(g_pTextSurface)
FREE_OBJECT(g_pTextSurface);
g_pDisplay->CreateSurfaceFromText(&g_pTextSurface,NULL,"NUM: 000000",
RGB(0,0,0),RGB(21,222,30));
g_pTextSurface->SetColorKey(RGB(0,0,0));
}
else GameStatus=PLAY;
break;
}
return 0L;
case WM_PAINT:
if (g_pDisplay)
{ // Display the new position of the sprite
if (FAILED(Render()))
{ PostMessage(hWnd,WM_CLOSE,0,0);
}
}
break;
case WM_MOVE:
if (g_pDisplay) g_pDisplay->UpdateBounds();
return 0L;
case WM_SIZE:
// Check to see if we are losing our window...
if (SIZE_MAXHIDE==wParam||SIZE_MINIMIZED==wParam) g_bActive= FALSE;
else g_bActive= TRUE;
if (g_pDisplay) g_pDisplay->UpdateBounds();
break;
case WM_DESTROY:
// Cleanup and close the app
KillTimer(hWnd,1);
FreeDirectDraw();
PostQuitMessage(0);
return 0L;
case WM_CREATE:
SetTimer(hWnd,1,500,NULL);
return 0;
case WM_TIMER:
if(GameStatus==PLAY)
if(IsStop==FALSE)
MoveFK(2);
else InitFK();
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -