一個俄羅斯方塊遊戲源程式 (轉)
一
///////////////////[stdafx.cpp]/////////////////////////
// stdafx.cpp : file that includes just the standard includes
// ToyBricks.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this fil
檔案二
//////////////////////////////////////[stdafx.h]//////////////////////////////////////////
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__A983DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define _LEAN_AND_MEAN // Exclude rarely-used stuff from headers
#include
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
檔案三
/////////////////////////////////[game.cpp]////////////////////////////////////////////////////
// ToyBricks.cpp : Defines the entry point for the application.
//
#include "StdAfx.h"
/*******************************************************/
#include
#include
#include
#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 WIN WinMain ( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
static char AppName[]="ToyBrick"; //視窗類名
HWND hwnd;
MSG msg; //訊息結構
WNDCLASSEX wndclass; //視窗類
int iScreenW; //定義一個整型變數來取得視窗的寬度
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)GetStock (WHITE_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," 開始遊戲nn_軟體學院模擬專案","開始",MB_OK);
SendMessage(hwnd,MS_NEWBLOCK,0,0);
SetTimer (hwnd, 1, 500,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)
Lo (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)); // 紅色畫刷
Object(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
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
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 (WHITE_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
cells[0][i]=1;
cells[W-7][i]=1;
}
// 將最底下一行【方格】置1,控制【方塊】不超出遊戲區域
for(i=0; i
// 其他【方格】置0,遊戲方塊只能在這裡移動
for(i=1; i<=W-8; i++)
for(j=0; j
return 0;
case MS_NEWBLOCK:
flag=0; // flag表示【方塊】旋轉了幾次
for(i=top; i
lines =0;
// 迴圈語句檢查是否有某一行全部被【方格】都填滿
for(j=1; j<=W-7; j++)
if(! cells[j][i])
{
lines=1;
break;
}
// 若該行被填滿,則將上一行的填充狀態複製到該行,依此類推
// 即從該行開始,所有的【方格】都下移一行
if(!lines)
{ for(j=1;j
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,"re",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
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);
}
/*************************-----結------束------*******************************/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-981631/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一個dos下tc編的俄羅斯方塊源程式(附註釋) (轉)
- JavaScript 寫遊戲 : 俄羅斯方塊 (轉)JavaScript遊戲
- 一個俄羅斯方塊的原始碼 (轉)原始碼
- Tetris 俄羅斯方塊遊戲遊戲
- 一個javascript指令碼寫的俄羅斯方塊 (轉)JavaScript指令碼
- 【Java遊戲】java俄羅斯方塊!Java遊戲
- 使用JavaScript實現一個俄羅斯方塊JavaScript
- 鵬躍俄羅斯方塊遊戲 1.0遊戲
- 我的俄羅斯方塊程式
- JS編寫的俄羅斯方塊 (轉)JS
- 基於Flutter的俄羅斯方塊小遊戲Flutter遊戲
- 基於MonoGame重製《俄羅斯方塊》遊戲MonoGAM遊戲
- 請大家談談‘俄羅斯方塊程式
- Python:遊戲:300行程式碼實現俄羅斯方塊Python遊戲行程
- python開發俄羅斯方塊小遊戲程式碼例項Python遊戲
- 俄羅斯方塊聯機小遊戲的實現遊戲
- Python 實戰開發俄羅斯方塊遊戲Python遊戲
- 俺用c語言寫的一個天下演算法最爛的俄羅斯方塊程式 (轉)C語言演算法
- 使用C#和MonoGame開發俄羅斯方塊遊戲C#MonoGAM遊戲
- canvas實現俄羅斯方塊Canvas
- Win32俄羅斯方塊Win32
- 俄羅斯方塊(JS+CSS)JSCSS
- 《俄羅斯方塊》系列 35 週年 一窺遊戲歷年玩法演變遊戲
- Flutter Web 實戰 - 俄羅斯方塊FlutterWeb
- java控制檯版本 俄羅斯方塊Java
- [分享]純python3手寫Tetris(俄羅斯方塊)遊戲Python遊戲
- pyqt5製作俄羅斯方塊小遊戲-----原始碼解析QT遊戲原始碼
- 用 SQL 寫的俄羅斯方塊遊戲「GitHub 熱點速覽」SQL遊戲Github
- 趣味python程式設計之經典俄羅斯方塊Python程式設計
- HTML5 canvas遊戲開發實戰 6 : 俄羅斯方塊HTMLCanvas遊戲開發
- android遊戲開發之我的小小遊戲3——俄羅斯方塊遊戲3Android遊戲開發
- 俄羅斯方塊+塔防 國產獨立遊戲《方境戰記》5月25日發售遊戲
- 函數語言程式設計嘗試之俄羅斯方塊函數程式設計
- 我編寫的俄羅斯方塊原始碼,支援單機對戰,可定製方塊數,鍵盤等!!! (轉)原始碼
- 如何讓 Emacs 俄羅斯方塊變得更難Mac
- 最新《 java實戰開發俄羅斯方塊教程》Java
- c#實現簡單的俄羅斯方塊C#
- 用kotlin來實現一個打方塊的小遊戲Kotlin遊戲