⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.cpp

📁 游戏俄罗斯方块源程序
💻 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 + -