當前位置:編程學習大全網 - 源碼下載 - 急求俄羅斯方塊C++語言源代碼,用Microsoft Visual C++ 6.0能編譯出來 。 郵箱地址:332542559@qq.com!謝

急求俄羅斯方塊C++語言源代碼,用Microsoft Visual C++ 6.0能編譯出來 。 郵箱地址:332542559@qq.com!謝

#include <windows.h> //windows.h文件中包含應用程序中所需的數據類型和數據結構的定義

#include <time.h> //包含SetTimer()、KillTimer()等關於定時器的函數

#include <stdlib.h>

#define CELL 15 // 方格的邊長(pix)

#define W 20 // 遊戲區寬(12個方格邊長,8個格子用來繪制"下壹個"方塊)

#define H 26 // 遊戲區高(26個方格邊長)

#define MS_NEWBLOCK WM_USER+1 // 消息ID,產生新的方塊

#define MS_DRAW WM_USER+2 // 消息ID,用來畫方塊

#define MS_NEXTBLOCK WM_USER+3 //消息ID,用來顯示下壹個俄羅斯方塊形狀

//------------------------窗口函數的說明------------------------

LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM);

//---------------------------------------------------------------

int WINAPI WinMain ( HINSTANCE hInstance,

HINSTANCE hPrevInstance,

PSTR szCmdLine,

int iCmdShow)

{

static char AppName[]="ToyBrick"; //窗口類名

HWND hwnd;

MSG msg; //消息結構

WNDCLASSEX wndclass; //窗口類

int iScreenWide; //定義壹個整型變量來取得窗口的寬度

wndclass.cbSize = sizeof(wndclass);

wndclass.style = CS_HREDRAW|CS_VREDRAW;//窗口類型

//CS_HREDRAW :Redraws the entire window if a movement or size

// adjustment changes the width of the client area.

//CS_VREDRAW :Redraws the entire window if a movement or size

// adjustment changes the height of the client area.

wndclass.lpfnWndProc = WndProc; //窗口處理函數為 WndProc

wndclass.cbClsExtra = 0; //窗口類無擴展

wndclass.cbWndExtra = 0; //窗口實例無擴展

wndclass.hInstance = hInstance; //當前實例句柄

wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); //默認圖標

wndclass.hCursor = LoadCursor (NULL,IDC_ARROW); //箭頭光標

wndclass.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH); //背景為黑色

wndclass.lpszMenuName = NULL; //窗口中無菜單

wndclass.lpszClassName = AppName; //類名為"ToyBrick"

wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);

//----------------------------------窗口類的註冊-----------------------------------------

if(!RegisterClassEx (&wndclass)) //如果註冊失敗則發出警報聲音,返回FALSE

{

MessageBeep(0);

return FALSE;

}

// 獲取顯示器分辨率的X值iScreenWide,將程序窗口置於屏幕中央

iScreenWide=GetSystemMetrics (SM_CXFULLSCREEN);

hwnd =CreateWindow (

AppName, //窗口類名

"四面楚歌制作", //窗口實例的標題名

WS_MINIMIZEBOX|WS_SYSMENU , //窗口的風格

iScreenWide/2-W*CELL/2, //窗口左上角橫坐標(X)

CELL, //窗口左上角縱坐標(Y)

W*CELL, //窗口的寬

H*CELL, //窗口的高

NULL, //窗口無父窗口

NULL, //窗口無主菜單

hInstance, //創建此窗口的應用程序的當前句柄

NULL //不使用該值

);

if(!hwnd) return FALSE;

//顯示窗口

ShowWindow (hwnd,iCmdShow);

//繪制用戶區

UpdateWindow (hwnd);

MessageBox(hwnd," 開始遊戲\n\n OH YEAH","開始",MB_OK);

SendMessage(hwnd,MS_NEWBLOCK,0,0);

SetTimer (hwnd, 1, 100,NULL);

//消息循環

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg);

DispatchMessage (&msg);

}

//消息循環結束即程序終止時將消息返回系統

return msg.wParam;

}

// 函數DrawRact: 畫正方形----- (□)

// 參數: 設備環境句柄和正方形的四角坐標

void DrawRect (HDC hdc, int l, int t, int r, int b)

{

MoveToEx (hdc, l, t, NULL); //將光標移動到(l,t)

LineTo (hdc, r, t);

LineTo (hdc, r, b);

LineTo (hdc, l, b);

LineTo (hdc, l,t);

}

// 函數DrawCell: 畫方格-----(紅色■)

// 參數: 設備環境句柄和方格的四角坐標

void DrawCell (HDC hdc, int l, int t, int r, int b)

{

HBRUSH hbrush;

hbrush=CreateSolidBrush(RGB(255,0,0)); // 紅色畫刷

SelectObject(hdc,hbrush);

Rectangle(hdc,l, t, r, b);

DeleteObject (hbrush);

}

//繪出遊戲區域的方格,其中包括"遊戲空間"和"顯示下壹個方塊空間"

//此函數包含在Cover函數中。參數:設備環境句柄

void DrawGamePlace(HDC hdc)

{

int i,j;

HPEN hpen1,hpen2;

hpen1=CreatePen(PS_SOLID,1,RGB(0,255,0));

hpen2=CreatePen(PS_DASHDOTDOT,3,RGB(0,0,255));

//繪制分割線

SelectObject(hdc,hpen2);

MoveToEx(hdc,(W-8)*CELL,0,NULL);

LineTo(hdc,(W-8)*CELL,H*CELL);

//繪制遊戲區域方格線(綠色)

SelectObject(hdc,hpen1);

for (i=1; i<H-1; i++)

for(j=1; j<=W-8; j++)

DrawRect (hdc, (j-1)*CELL, (i-1)*CELL, j*CELL, i*CELL);

//繪制"顯示下壹個"區域的方格線

for(i=5;i<9;i++) // 5≤i≤8

for(j=W-5;j<W-1;j++) // 15≤j≤18

DrawRect (hdc, (j-1)*CELL, (i-1)*CELL, j*CELL, i*CELL);

DeleteObject(hpen2);

DeleteObject(hpen1);

}

// 函數DrawBlock: 畫遊戲中出現的俄羅斯方塊

// 參數: 設備環境句柄和俄羅斯方塊中四個方格在遊戲區域中的位置

// 每個俄羅斯方塊由四個方格組成7種不同的形狀

void DrawBlock (HDC hdc, int block[4][2])

{

int i;

for(i=0; i<4; i++)

DrawCell (hdc, (block[i][0]-1)*CELL, (block[i][1]-1)*CELL, //....

block[i][0]*CELL, block[i][1]*CELL);

}

// 函數Cover: 清除原來位置的俄羅斯方塊

// 參數: 設備環境句柄和待清除的俄羅斯方塊

//作用(1) 清除俄羅斯方塊即在該俄羅斯方塊的每個方格處畫壹個正方形的白塊

// (2) 重新繪制遊戲區域的方格

void Cover (HDC hdc, int org[4][2])

{

int i;

HBRUSH hbrush;

//重新繪制遊戲區域

DrawGamePlace(hdc);

hbrush=(HBRUSH)GetStockObject (BLACK_BRUSH);

SelectObject (hdc,hbrush );

for(i=0; i<4; i++)

Rectangle ( hdc, (org[i][0]-1)*CELL, (org[i][1]-1)*CELL, //.....

org[i][0]*CELL, org[i][1]*CELL);

DeleteObject(hbrush);

}

//-------------------窗口過程函數WndProc-----------------------------

LRESULT CALLBACK WndProc ( HWND hwnd,

UINT iMsg,

WPARAM wParam,

LPARAM lParam )

{

int i,j,k,lines,r;

static int top, sel, flag;

static int cells[W-6][H]; // 控制遊戲區域的方格矩陣

static int org[4][2], block[4][2],org2[4][2]; // 方塊

HDC hdc;

HPEN hpen;

PAINTSTRUCT ps;

switch (iMsg)

{

case WM_CREATE:

//當壹個應用程序使用函數CreateWindow或CreateWindowEx來創建壹個窗口時,

//系統將發送該消息給此新建窗口過程。該消息將在創建窗口之後,顯示窗口

//之前發送該消息,該消息將在CreateWindow或CreateWindowEx函數返回之前發送。

top=H-1;

// 將第壹列和最後壹列方格置1,控制方塊不超出遊戲區域

for(i=0; i<H; i++)

{

cells[0][i]=1;

cells[W-7][i]=1;

}

// 將最底下壹行方格置1,控制方塊不超出遊戲區域

for(i=0; i<W-6; i++)

cells[i][H-1]=1;

// 其他方格置0,遊戲方塊只能在這裏移動

for(i=1; i<=W-8; i++)

for(j=0; j<H-1; j++)

cells[i][j]=0;

return 0;

case MS_NEWBLOCK:

flag=0; // flag表示方塊旋轉了幾次

for(i=top; i<H-1; i++)

{

lines =0;

// 循環語句檢查是否有某壹行全部被方格都填滿

for(j=1; j<=W-7; j++)

if(! cells[j][i])

{

lines=1;

break;

}

// 若該行被填滿,則將上壹行的填充狀態復制到該行,依此類推

// 即從該行開始,所有的方格都下移壹行

if(!lines)

{ for(j=1;j<W-7; j++)

for(k=i; k>=top; k--)

cells[j][k]=cells[j][k-1];

top++;

//該函數把指定窗口用戶區域內的矩形加入到該窗口的更新區域之外

//使該矩形無效。這個無效的矩形,連同更新區域中的其他區域,在收到下

//壹條WM_PAINT消息時將被重畫。無效區壹直積累在更新區域之中,直到

//下壹條WM_PAINT消息發生時對該區域進行處理。

InvalidateRect(hwnd, NULL, TRUE);

}

}

// 產生隨機數0~7,分別代表方塊的7種形狀

srand( (unsigned)time( NULL ) );

sel =rand()%7;

//方塊形狀初始化

//方塊的形狀由其每個方格的位置決定

// 遊戲區寬W=20,block[?][0]=4/5/6/7,block[?][1]=0/1/2

// 這樣方塊初始位置在遊戲區域的最頂部的中央

switch(sel)

{

case 0:

// ▓▓

// ▓▓

org[0][0]=block[0][0] =5; org[0][1]=block[0][1] =0;

org[1][0]=block[1][0] =6; org[1][1]=block[1][1] =0;

org[2][0]=block[2][0] =5; org[2][1]=block[2][1] =1;

org[3][0]=block[3][0] =6; org[3][1]=block[3][1] =1;

for(i=0;i<4;i++)

{

org2[i][0]=org[i][0]+11;

org2[i][1]=org[i][1]+5;

}

break;

case 1:

//▓▓▓▓

org[0][0]=block[0][0] =4; org[0][1]=block[0][1] =0;

org[1][0]=block[1][0] =5; org[1][1]=block[1][1] =0;

org[2][0]=block[2][0] =6; org[2][1]=block[2][1] =0;

org[3][0]=block[3][0] =7; org[3][1]=block[3][1] =0;

for(i=0;i<4;i++)

{

org2[i][0]=org[i][0]+11;

org2[i][1]=org[i][1]+5;

}

break;

case 2:

//▓

//▓▓

// ▓

org[0][0]=block[0][0] =5; org[0][1]=block[0][1] =0;

org[1][0]=block[1][0] =5; org[1][1]=block[1][1] =1;

org[2][0]=block[2][0] =6; org[2][1]=block[2][1] =1;

org[3][0]=block[3][0] =6; org[3][1]=block[3][1] =2;

for(i=0;i<4;i++)

{

org2[i][0]=org[i][0]+11;

org2[i][1]=org[i][1]+5;

}

break;

case 3:

// ▓

//▓▓

//▓

org[0][0]=block[0][0] =6; org[0][1]=block[0][1] =0;

org[1][0]=block[1][0] =6; org[1][1]=block[1][1] =1;

org[2][0]=block[2][0] =5; org[2][1]=block[2][1] =1;

org[3][0]=block[3][0] =5; org[3][1]=block[3][1] =2;

for(i=0;i<4;i++)

{

org2[i][0]=org[i][0]+11;

org2[i][1]=org[i][1]+5;

}

break;

case 4:

//▓

//▓

//▓▓

org[0][0]=block[0][0] =5; org[0][1]=block[0][1] =0;

org[1][0]=block[1][0] =5; org[1][1]=block[1][1] =1;

org[2][0]=block[2][0] =5; org[2][1]=block[2][1] =2;

org[3][0]=block[3][0] =6; org[3][1]=block[3][1] =2;

for(i=0;i<4;i++)

{

org2[i][0]=org[i][0]+11;

org2[i][1]=org[i][1]+5;

}

break;

case 5:

// ▓

// ▓

//▓▓

org[0][0]=block[0][0] =5; org[0][1]=block[0][1] =0;

org[1][0]=block[1][0] =5; org[1][1]=block[1][1] =1;

org[2][0]=block[2][0] =5; org[2][1]=block[2][1] =2;

org[3][0]=block[3][0] =4; org[3][1]=block[3][1] =2;

for(i=0;i<4;i++)

{

org2[i][0]=org[i][0]+11;

org2[i][1]=org[i][1]+5;

}

break;

case 6:

// ▓

//▓▓▓

org[0][0]=block[0][0] =5; org[0][1]=block[0][1] =0;

org[1][0]=block[1][0] =4; org[1][1]=block[1][1] =1;

org[2][0]=block[2][0] =5; org[2][1]=block[2][1] =1;

org[3][0]=block[3][0] =6; org[3][1]=block[3][1] =1;

for(i=0;i<4;i++)

{

org2[i][0]=org[i][0]+11;

org2[i][1]=org[i][1]+5;

}

SendMessage (hwnd, MS_NEXTBLOCK, 0, 0);

break;

default:

SendMessage (hwnd, MS_NEWBLOCK, 0, 0);

SendMessage (hwnd, MS_NEXTBLOCK, 0, 0);

break;

}

return 0;

case WM_TIMER:

// 每個時間節拍方塊自動下移壹行

for(i=0; i<4; i++)

block[i][1]++;

// 檢查方塊下移是否被檔住,即判斷下移後新位置是否有方格

for(i=0; i<4; i++)

if(cells[ block[i][0] ][ block[i][1] ])

{

SendMessage (hwnd, MS_NEXTBLOCK, 0, 0);

for(i=0; i<4; i++)

cells[ org[i][0] ][ org[i][1] ]=1;

if(top>org[0][1]-2)

top=org[0][1]-2;

if (top<1)

{

KillTimer (hwnd, 1);

MessageBox (hwnd, "遊戲結束,即將退出 !\n 四面楚歌", "退出", MB_OK);

PostQuitMessage (0);

}

SendMessage (hwnd, MS_NEWBLOCK, 0, 0);

return 0;

}

SendMessage (hwnd, MS_DRAW, 0, 0);

return 0;

// 響應鍵盤控制

case WM_KEYDOWN:

r=0;

switch((int)wParam)

{

case VK_LEFT:

for(i=0; i<4; i++)

block[i][0]--;

break;

case VK_RIGHT:

for(i=0; i<4; i++)

block[i][0]++;

break;

case VK_DOWN:

for(i=0; i<4; i++)

block[i][1]++;

break;

// 按[向上鍵],方塊順時針旋轉

//方塊的旋轉不是真正的旋轉,而是根據不同的方塊形狀和該方塊旋轉過的

// 次數來移動其中的壹個或幾個方格,從而達到旋轉的效果 。這樣做很復雜,算法

// 不夠理想,但是能夠保持方塊旋轉時的重心比較穩定。

case VK_UP:

r=1;

flag++; //方塊旋轉加1

switch(sel) // sel代表當前方塊的形狀

{

case 0: break;

case 1:

flag =flag%2;

for(i=0; i<4; i++)

{

block[i][(flag+1)%2] =org[2][(flag+1)%2];

block[i][flag] =org[2][flag]-2+i;

}

break;

case 2:

flag =flag%2;

if(flag)

{ block[0][1] +=2; block[3][0] -=2; }

else

{ block[0][1] -=2; block[3][0] +=2; }

break;

case 3:

flag =flag%2;

if(flag)

{ block[0][1] +=2; block[3][0] +=2; }

else

{ block[0][1] -=2; block[3][0] -=2; }

break;

case 4:

flag=flag%4;

switch(flag)

{

case 0:

block[2][0] +=2; block[3][0] +=2;

block[2][1] +=1; block[3][1] +=1;

break;

case 1:

block[2][0] +=1; block[3][0] +=1;

block[2][1] -=2; block[3][1] -=2;

break;

case 2:

block[2][0] -=2; block[3][0] -=2;

block[2][1] -=1; block[3][1] -=1;

break;

case 3:

block[2][0] -=1; block[3][0] -=1;

block[2][1] +=2; block[3][1] +=2;

break;

}

break;

case 5:

flag=flag%4;

switch(flag)

{

case 0:

block[2][0] +=1; block[3][0] +=1;

block[2][1] +=2; block[3][1] +=2;

break;

case 1:

block[2][0] +=2; block[3][0] +=2;

block[2][1] -=1; block[3][1] -=1;

break;

case 2:

block[2][0] -=1; block[3][0] -=1;

block[2][1] -=2; block[3][1] -=2;

break;

case 3:

block[2][0] -=2; block[3][0] -=2;

block[2][1] +=1; block[3][1] +=1;

break;

}

break;

case 6:

flag =flag%4;

switch(flag)

{

case 0:

block[0][0]++; block[0][1]--;

block[1][0]--; block[1][1]--;

block[3][0]++; block[3][1]++;

break;

case 1:

block[1][0]++; block[1][1]++; break;

case 2:

block[0][0]--; block[0][1]++; break;

case 3:

block[3][0]--; block[3][1]--; break;

}

break;

}

break;

}

// 判斷方塊旋轉後新位置是否有方格,若有,則旋轉取消

for(i=0; i<4; i++)

if(cells[ block[i][0] ][ block[i][1] ])

{

if(r) flag +=3;

for(i=0; i<4; i++)

for(j=0; j<2; j++)

block[i][j]=org[i][j];

return 0;

}

SendMessage(hwnd, MS_DRAW, 0, 0);;

return 0;

// 清楚當前方塊,並在顯示“下壹個方塊”處繪制下壹個方塊

case MS_NEXTBLOCK:

hdc=GetDC(hwnd);

Cover(hdc,org2);

// DrawBlock(hdc,org2);

return 0;

// 清除當前方塊,並在新的位置重新繪制方塊

case MS_DRAW:

hdc =GetDC (hwnd);

Cover (hdc, org);

DrawBlock(hdc,org2);

for(i=0; i<4; i++)

for(j=0; j<2; j++)

org[i][j]=block[i][j];

DrawBlock (hdc,block);

ReleaseDC (hwnd, hdc);

return 0;

// 按照方格矩陣重繪遊戲區域的方格

case WM_PAINT:

hdc =BeginPaint (hwnd, &ps);

DrawGamePlace(hdc);

TextOut(hdc,15*CELL,12*CELL,"Score",lstrlen("Score"));

TextOut(hdc,15*CELL,13*CELL,"i",lstrlen("i"));

TextOut(hdc,15*CELL,15*CELL,"Level",lstrlen("Level"));

TextOut(hdc,15*CELL-5,19*CELL,"四面楚歌",lstrlen("四面楚歌"));

hpen =CreatePen (PS_SOLID,1,RGB(0,255,0));

SelectObject (hdc,hpen);

for (i=top; i<H-1; i++)

for(j=1; j<=W-8; j++)

if( cells[j][i] )

DrawCell (hdc, (j-1)*CELL, (i-1)*CELL, j*CELL, i*CELL);

DeleteObject (hpen);

EndPaint (hwnd, &ps);

return 0;

case WM_DESTROY:

KillTimer (hwnd, 1);

PostQuitMessage (0);

return 0;

}

return DefWindowProc (hwnd, iMsg, wParam, lParam);

}

  • 上一篇:淘寶網可以保稅倉發貨嗎?跨境電商問題
  • 下一篇:中間網頁源代碼
  • copyright 2024編程學習大全網