码迷,mamicode.com
首页 > 其他好文 > 详细

俄罗斯方块

时间:2015-04-24 18:42:23      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:

                         我们选择改进Tetris(俄罗斯方块)作为我们的Pair Project

    经过调研,我们发现大家对传统的俄罗斯方块游戏已经非常厌倦了,因为它游戏模式单一,缺乏挑战性和竞技性,只能一个人玩,同时方块种类没有任何改变,都是大家很厌倦的那几种,因此我们希望在这些方面上做提高。

    考虑到传统的俄罗斯方块的不足,我们对此进行了如下的改进:

  1. 把传统的俄罗斯方块做成双人对战模式。这个想法来自其他多人版单机游戏(如实况、拳皇),能和朋友在一台电脑上玩竞技游戏是很有好处的(玩过实况PES和拳皇KOF的都很清楚吧)。为了增加双人竞技的难度和趣味性,每隔一段时间电脑会为双方自动加一行,如果自己消多行也能给对手增加行数。
  2. 玩家可以自定义方块的类型,这是为了使玩家不厌烦于习惯性的7种方块,增加方块种类提高他们的兴趣;
  3. 加入了很多很不错的音乐,单人玩的时候和双人对战别是一般风味; 

以下是传统的俄罗斯方块游戏界面:

 技术分享

在我们经过不断地讨论和修改之后,最终我们实现了一下功能:

  1. 单人对战中实现了菜单、快速下落、暂停、设置键位等功能;

 技术分享

 

2. 成功修改为双人对战模式,包含单人游戏和双人游戏,双人对战时也可以修改键位(这个想法也是来自PES和KOF),同时支持暂停、快速下降等功能;

3. 添加了本地记录setting的功能,这样同一个玩家在下次游戏的时候可以自动读取以前的setting;

4. 添加用户id的设置和排行榜和双人对战结果显示,以及进行本地存储和帮助信息;

5. 增加了音乐效果,在单人、双人、消行、结束的时候都会有音乐效果;

6. 增加了每隔一段时间加一行的功能,增加了游戏的难度。同时,在双人对战模式中,自己消行会导致对手增加行数,增加了趣味性;

7. 添加了用户自定义方块的功能,在block下可以自定义,同时增加了方块浏览器,在浏览器中用户可以查看自己设置的方块类型和原有的方块,同时在这个浏览器中可以对方块进行删减(限于自定义方块)。

 技术分享

下面是方块浏览器:(可以对方块进行查看和删减)

 技术分享

       使用附加功能以后还可以通过block/原始模式 恢复到原始模式,但是保存自定义方块种类。

Pair programming的优点:

  1. 有利于思想上的交流,可以一起思考,一起想到一些好的idea并且共同去实现;
  2. 有利于框架的搭建,如果有什么没有想到的地方,partner会及时提醒。同时,对于双方的代码可以互相改进,发现其中的bug,提出bug所在并进行修改;
  3. Pair progamming可以充分发挥双方的优势,让双方的优点相结合,是很不错的一个编程模式;
  4. 可以用户体验,同时可以避免出现一个人写程序无聊的情况等。

不足:

  1. 在idea的确定上可能会浪费一定的时间,但是这个在某些程度上是有好处的;
  2. 在时间的确定和搭配上可能会出现一定的问题,这个需要在进行结对编程的时候着重考虑;
  3. 在结对编程的时候需要进行充分明确的分工,这样在进行编程的时候就不会出现重复代码等情况。同时,双方需要进行及时的沟通和版本控制。                                                                                代码:

    #include "Tetris.h"

     

    //Windows 入口函数

    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)

    {

            static TCHAR    szClsName[] = TEXT("Tetris");

            HWND            hwnd;

            MSG             msg;

            WNDCLASSEX      wndclass;

          

            InitCommonControls(); //初始化通用控件类库

     

            //程序启动时初始化数据

            hInst = hInstance;

            RandomBlock(&ii,&jj,&cc);

            //x = 4; y = -1;

            iLevel = 1; iSorce = 0;

            iLayer = 0; iSorceMax = TetrisIni(0);

            hDcAlert = CreateCompatibleDC(NULL);

     

            //注册窗口类

            wndclass.hInstance      = hInstance;

            wndclass.lpszClassName  = szClsName;

            wndclass.lpfnWndProc    = WndProc;

            wndclass.cbClsExtra     = 0;

            wndclass.cbWndExtra     = 0;

            wndclass.cbSize         = sizeof(WNDCLASSEX);

            wndclass.style          = CS_HREDRAW|CS_VREDRAW;

            wndclass.hIcon          = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));

            wndclass.hIconSm        = NULL;

            wndclass.hCursor        = LoadCursor(NULL,IDC_ARROW);

            wndclass.hbrBackground  = (HBRUSH)(COLOR_BTNFACE+1);

            wndclass.lpszMenuName   = MAKEINTRESOURCE(IDR_MENU1);

            if ( !RegisterClassEx(&wndclass) )

            {

                    MessageBox(

                            NULL,

                            TEXT("This program requires Windows NT!"),

                            TEXT("RegisterClass ERROR"),

                            MB_ICONERROR);

                    return 0;

     

            }

     

            //创建主窗口

            hwnd = CreateWindowEx(

                    WS_EX_CLIENTEDGE,

                    szClsName,

                    TEXT("俄罗斯方块Win32版"),

                    WS_MINIMIZEBOX|WS_SYSMENU,

                    GetSystemMetrics(SM_CXFULLSCREEN)/2-370/2,

                    GetSystemMetrics(SM_CYFULLSCREEN)/2-520/2,

                    370,

                    520,

                    NULL,

                    NULL,

                    hInstance,

                    NULL);

          

            //显示窗口并刷新客户区

            ShowWindow(hwnd,iCmdShow);

            UpdateWindow(hwnd);

     

            //构建消息循环

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

            {

                    TranslateMessage(&msg);

                    DispatchMessage(&msg);

            }

     

            return msg.wParam;

    }

     

    //主窗口过程

    LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)

    {

            HDC             hdc;

            PAINTSTRUCT     ps;

     

            switch ( message )

            {

            case WM_CREATE:

                    GameUI(hwnd); //创建界面控件

                    GameStart(hwnd); //数据初始化

                    //背景音乐初始化

                    bMusicOn = TRUE;

                    iMusicBG = IDR_WAVE1;

                    hMenu = GetMenu(hwnd);

                    MusicItem(IDM_MUSIC1);

                    return 0;

            case WM_PAINT:

                    hdc = BeginPaint(hwnd,&ps);

                    DrawMatrix(hdc); //绘制游戏区

                    DrawTetris(hdc,0,0,0); //绘制方块

                    DrawNext(hdc); //绘制预览区

                    BitBlt(hdc,40,200,160,50,hDcAlert,0,0,SRCCOPY);//绘制提示语

                    EndPaint(hwnd,&ps);

                    return 0;

            case WM_TIMER:

                    DropTetris(hwnd);

                    return 0;

            case WM_DRAWITEM:

                    DrawButton(lParam); //绘制方向按钮

                    return TRUE;

            case WM_KEYDOWN:

                    switch ( (int)wParam )

                    {

                    case VK_LEFT:

                            if ( !bStart ) break;

                            if ( CheckBlock(x-1,y) )

                            {

                                    x --;

                                    hdc = GetDC(hwnd);

                                    DrawTetris(hdc,-1,0,0);

                                    ReleaseDC(hwnd,hdc);

                            }

                          

                            break;

                    case VK_RIGHT:

                            if ( !bStart ) break;

                            if ( CheckBlock(x+1,y) )

                            {

                                    x ++;

                                    hdc = GetDC(hwnd);

                                    DrawTetris(hdc,1,0,0);

                                    ReleaseDC(hwnd,hdc);

                            }

                          

                            break;

                    case VK_UP:

                            if ( !bStart || y<0 ) break;

                            RankTetris(hwnd);

                            break;

                    case VK_DOWN:

                            if ( !bStart ) break;

                            DropTetris(hwnd);

                            break;

                    case VK_SPACE:

                            GamePause(hwnd);

                            break;

                    }

                    return 0;

            case WM_COMMAND:

                    switch ( LOWORD(wParam) )

                    {

                    case IDM_STOP:

                            if ( y == -1 ) break;

                            GameOver(hwnd);

                            break;

                    case IDM_NEW:

                            GameStart(hwnd);

                            GamePause(hwnd);

                            break;

                    case IDM_PAUSE:

                            GamePause(hwnd);

                            break;

                    case IDM_EXIT:

                            SendMessage(hwnd,WM_DESTROY,NULL,NULL);

                            break;

                    case IDM_ABOUT:

                            DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1),hwnd,AboutDlgProc);

                            break;

                    case IDM_HELP:

                            DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG2),hwnd,HelpDlgProc);

                            break;

                    case IDM_MUSIC:

                            DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG3),hwnd,MusicDlgProc);

                            break;

                    case IDM_MUSIC1:

                            MusicItem(IDM_MUSIC1);

                            break;

                    case IDM_MUSIC2:

                            MusicItem(IDM_MUSIC2);

                            break;

                    case IDM_MUSICOFF:

                            MusicItem(IDM_MUSICOFF);

                            break;

                    case IDM_LEFT:

                            SendMessage(hwnd,WM_KEYDOWN,VK_LEFT,0);

                            SetFocus(hwnd);

                            break;

                    case IDM_RIGHT:

                            SendMessage(hwnd,WM_KEYDOWN,VK_RIGHT,0);

                            SetFocus(hwnd);

                            break;

                    case IDM_UP:

                            SendMessage(hwnd,WM_KEYDOWN,VK_UP,0);

                            SetFocus(hwnd);

                            break;

                    case IDM_DOWN:

                            SendMessage(hwnd,WM_KEYDOWN,VK_DOWN,0);

                            SetFocus(hwnd);

                            break;

                    }

                    return 0;

            case WM_CLOSE:

                    if ( iSorce > iSorceMax ) iSorceMax = iSorce;

                    TetrisIni(iSorceMax);

            case WM_DESTROY:

                    PostQuitMessage(0);

                    return 0;

            }

     

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

    }

     

    //关于对话框窗口过程

    BOOL CALLBACK AboutDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)

    {

            switch ( message )

            {

            case WM_INITDIALOG:

                    return TRUE;

            case WM_COMMAND:

                    switch ( LOWORD(wParam) )

                    {

                    case IDOK:

                            EndDialog(hDlg,0);

                            break;

                    }

                    break;

            }

            return FALSE;

    }

     

    //帮助对话框窗口过程

    BOOL CALLBACK HelpDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)

    {

            switch ( message )

            {

            case WM_INITDIALOG:

                    return TRUE;

            case WM_COMMAND:

                    switch ( LOWORD(wParam) )

                    {

                    case IDOK:

                            EndDialog(hDlg,0);

                            break;

                    }

                    break;

            }

            return FALSE;

    }

     

    //背景音乐对话框窗口过程

    BOOL CALLBACK MusicDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)

    {

            switch ( message )

            {

            case WM_INITDIALOG:

                    if( iMusicBG == IDR_WAVE1 ) CheckRadioButton(hDlg,IDC_RADIO1,IDC_RADIO3,IDC_RADIO1);

                    if( iMusicBG == IDR_WAVE2 ) CheckRadioButton(hDlg,IDC_RADIO1,IDC_RADIO3,IDC_RADIO2);

                    if( !bMusicOn ) CheckRadioButton(hDlg,IDC_RADIO1,IDC_RADIO3,IDC_RADIO3);

                    return TRUE;

            case WM_COMMAND :

                    switch ( LOWORD(wParam) )

                    {

                    case IDC_RADIO1:

                            CheckRadioButton(hDlg,IDC_RADIO1,IDC_RADIO3,IDC_RADIO1);

                            break;

                    case IDC_RADIO2:

                            CheckRadioButton(hDlg,IDC_RADIO1,IDC_RADIO3,IDC_RADIO2);

                            break;

                    case IDC_RADIO3:

                            CheckRadioButton(hDlg,IDC_RADIO1,IDC_RADIO3,IDC_RADIO3);

                            break;

                    case IDOK:

                            if ( IsDlgButtonChecked(hDlg,IDC_RADIO1) == BST_CHECKED )

                            {

                                    bMusicOn = TRUE;

                                    iMusicBG = IDR_WAVE1;

                                    MusicItem(IDM_MUSIC1);

                                    if ( bStart ) TetrisMusic(TRUE);

                            }

                            if ( IsDlgButtonChecked(hDlg,IDC_RADIO2) == BST_CHECKED )

                            {

                                    bMusicOn = TRUE;

                                    iMusicBG = IDR_WAVE2;

                                    MusicItem(IDM_MUSIC2);

                                    if ( bStart ) TetrisMusic(TRUE);

                            }

                            if ( IsDlgButtonChecked(hDlg,IDC_RADIO3) == BST_CHECKED )

                            {

                                    bMusicOn = FALSE;

                                    MusicItem(IDM_MUSICOFF);

                                    TetrisMusic(FALSE);

                            }

                            EndDialog(hDlg,0);

                            break;

                    case IDCANCEL:

                            EndDialog(hDlg,0);

                            break;

                    }

                    break;

            }

            return FALSE;

    }

     

    //音乐菜单处理

    void MusicItem(int iCheckID)

    {

            CheckMenuRadioItem(hMenu,IDM_MUSIC1,IDM_MUSICOFF,iCheckID,MF_BYCOMMAND);

     

            if ( iCheckID == IDM_MUSIC1 )

            {

                    bMusicOn = TRUE;

                    iMusicBG = IDR_WAVE1;

                    if ( bStart ) TetrisMusic(TRUE);

            }else if ( iCheckID == IDM_MUSIC2 )

            {

                    bMusicOn = TRUE;

                    iMusicBG = IDR_WAVE2;

                    if ( bStart ) TetrisMusic(TRUE);

            }

            else

            {

                    bMusicOn = FALSE;

                    TetrisMusic(FALSE);

            }

     

            return;

    }

     

    //背景音乐

    void TetrisMusic(BOOL start)

    {

            if ( start && bMusicOn && !bGOver )

                    PlaySound(MAKEINTRESOURCE(iMusicBG),NULL,SND_RESOURCE|SND_LOOP|SND_ASYNC);

            else

                    PlaySound(NULL,NULL,NULL);

            return;

    }

     

    //初始化游戏数据

    void GameStart(HWND hwnd)

    {

            int     m, n;

            HDC     hdc;

            hDcBitmap = CreateCompatibleDC(NULL);

     

            //初始化Matrix矩阵

            for ( m=0; m<=18; m++ )

            {

                    for ( n=0; n<=9; n++ )

                    {

                            Matrix[m][n] = -1; //Matrix[m][n]处初始颜色值为-1

                    }

            }

     

            //初始化方块位置

            x = 4; y = -1;

          

            //初始化标志变量

            bStart = FALSE;

            bGOver = FALSE;

          

            //初始化游戏区

            hdc = GetDC(hwnd);

            DrawMatrix(hdc);

            ReleaseDC(hwnd,hdc);

     

            //初始化计分器

            iLevel = 1;

            wsprintf(szBuffer,TEXT("%i"),iLevel);

            SetWindowText(hLevel,szBuffer); //级别

     

            iLayer = 0;

            wsprintf(szBuffer,TEXT("%i"),iLayer);

            SetWindowText(hLayer,szBuffer); //满行

     

            if ( iSorce > iSorceMax ) iSorceMax = iSorce;

            wsprintf(szBuffer,TEXT("%i"),iSorceMax);

            SetWindowText(hSorceMax,szBuffer); //最高分

     

            iSorce = 0;

            wsprintf(szBuffer,TEXT("%i"),iSorce);

            SetWindowText(hSorce,szBuffer); //得分

     

            //状态栏提示

            SendMessage(hStatus,SB_SETTEXT,0,(LPARAM)TEXT("空格键开始/暂停"));

            SendMessage(hStatus,SB_SETTEXT,1,(LPARAM)TEXT("方向键上键控制变形,左、右、下键控制移动"));

     

            //清除提示DC在的位图

            hDcAlert = CreateCompatibleDC(NULL);

     

            return;

    }

     

    //暂停/继续游戏

    void GamePause(HWND hwnd)

    {

            if( bGOver ) return;

            if ( bStart )

            {

                    KillTimer(hwnd, 1);

                    SendMessage(hStatus,SB_SETTEXT,0,(LPARAM)TEXT("游戏暂停"));

                    TetrisMusic(FALSE);

            }

            else

            {

                    SetTimer(hwnd, 1, (550-55*iLevel), NULL);

                    SendMessage(hStatus,SB_SETTEXT,0,(LPARAM)TEXT("游戏中 ^-^"));

                    TetrisMusic(TRUE);

            }

            bStart = !bStart;

            return;

    }

     

    //游戏结束

    void GameOver(HWND hwnd)

    {

            HDC     hdc;

     

            KillTimer(hwnd, 1);

            SelectObject(hDcAlert,LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP9)));

            hdc = GetDC(hwnd);

            BitBlt(hdc,40,200,160,50,hDcAlert,0,0,SRCCOPY);//绘制提示语

            ReleaseDC(hwnd,hdc);

            SendMessage(hStatus,SB_SETTEXT,0,(LPARAM)TEXT("游戏结束"));

     

            bGOver = TRUE;

            x = 4; y = -1;

     

            TetrisMusic(FALSE);

            return;

    }

     

    //从INI文件中读/写最高分

    int TetrisIni(int value)

    {

            int iSorceMax = 0;

            TCHAR szBuffer[10];

            TCHAR szIniFile[100];

     

            SHGetSpecialFolderPath(0,szIniFile,CSIDL_APPDATA,0);

            lstrcat(szIniFile,TEXT("\\Win32Tetris"));

            CreateDirectory(szIniFile,NULL);

            lstrcat(szIniFile,TEXT("\\Config.ini"));

     

            if ( value == 0 )

            {//读

                    iSorceMax = GetPrivateProfileInt(TEXT("Win32Tetris"),TEXT("SorceMax"),0,szIniFile);

            }

            else

            {//写

                    wsprintf(szBuffer,TEXT("%i"),value);

                    WritePrivateProfileString(TEXT("Win32Tetris"),TEXT("Contact"),TEXT("www.EasyIDE.cn"),szIniFile);

                    WritePrivateProfileString(TEXT("Win32Tetris"),TEXT("SorceMax"),szBuffer,szIniFile);

            }

          

            return iSorceMax;

    }

     

    //用Matrix中的数据绘制游戏区

    void DrawMatrix(HDC hdc)

    {

            int     m, n;

            //绘制Matrix矩阵

            for ( m=0; m<=18; m++ )

            {

                    for ( n=0; n<=9; n++ )

                    {

                            if ( Matrix[m][n] == -1 )

                            {

                                    PatBlt(hdc,20+n*20,40+m*20,20,20,BLACKNESS);

                            }

                            else

                            {

                                    SelectObject(hDcBitmap,LoadBitmap(hInst,MAKEINTRESOURCE(120+Matrix[m][n])));

                                    BitBlt(hdc,20+n*20,40+m*20,20,20,hDcBitmap,0,0,SRCCOPY);

                            }

                    }

            }

            return;

    }

     

    //绘制方块

    void DrawTetris(HDC hdc, int iOffsetX, int iOffsetY, int iRank)

    {

            int iX, iY, iJ;

     

            if ( y == -1 ) return;

     

            //如果方块平移过则擦除原来的方块位置

            if ( iOffsetX != 0 || iOffsetY != 0 )

            {

                    iX = x + Tetris[i][j].a.x - iOffsetX;

                    iY = y + Tetris[i][j].a.y - iOffsetY;

                    PatBlt(hdc,20+iX*20,40+iY*20,20,20,BLACKNESS);

     

                    iX = x + Tetris[i][j].b.x - iOffsetX;

                    iY = y + Tetris[i][j].b.y - iOffsetY;

                    PatBlt(hdc,20+iX*20,40+iY*20,20,20,BLACKNESS);

     

                    iX = x + Tetris[i][j].c.x - iOffsetX;

                    iY = y + Tetris[i][j].c.y - iOffsetY;

                    PatBlt(hdc,20+iX*20,40+iY*20,20,20,BLACKNESS);

     

                    iX = x + Tetris[i][j].d.x - iOffsetX;

                    iY = y + Tetris[i][j].d.y - iOffsetY;

                    PatBlt(hdc,20+iX*20,40+iY*20,20,20,BLACKNESS);

            }

     

            //如果方块旋转过则擦除原来的方块位置

            if ( iRank != 0 )

            {

                    iJ = j==0 ? 3 : j-1;

     

                    iX = x + Tetris[i][iJ].a.x;

                    iY = y + Tetris[i][iJ].a.y;

                    PatBlt(hdc,20+iX*20,40+iY*20,20,20,BLACKNESS);

     

                    iX = x + Tetris[i][iJ].b.x;

                    iY = y + Tetris[i][iJ].b.y;

                    PatBlt(hdc,20+iX*20,40+iY*20,20,20,BLACKNESS);

     

                    iX = x + Tetris[i][iJ].c.x;

                    iY = y + Tetris[i][iJ].c.y;

                    PatBlt(hdc,20+iX*20,40+iY*20,20,20,BLACKNESS);

     

                    iX = x + Tetris[i][iJ].d.x;

                    iY = y + Tetris[i][iJ].d.y;

                    PatBlt(hdc,20+iX*20,40+iY*20,20,20,BLACKNESS);

            }

     

            //绘制新位置方块

            SelectObject(hDcBitmap,LoadBitmap(hInst,MAKEINTRESOURCE(120+c)));

     

            iX = x + Tetris[i][j].a.x;

            iY = y + Tetris[i][j].a.y;

            BitBlt(hdc,20+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);

     

            iX = x + Tetris[i][j].b.x;

            iY = y + Tetris[i][j].b.y;

            BitBlt(hdc,20+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);

     

            iX = x + Tetris[i][j].c.x;

            iY = y + Tetris[i][j].c.y;

            BitBlt(hdc,20+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);

     

            iX = x + Tetris[i][j].d.x;

            iY = y + Tetris[i][j].d.y;

            BitBlt(hdc,20+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);

          

            return;

    }

     

    //绘制预览区

    void DrawNext(HDC hdc)

    {

            RECT    rc;

            int     iX, iY;

     

            //预览区填充黑色

            rc.left = 240; rc.top = 40;

            rc.right = 340; rc.bottom = 140;

            FillRect(hdc,&rc,CreateSolidBrush(RGB(0,0,0)));

     

            //绘制预览方块

            SelectObject(hDcBitmap,LoadBitmap(hInst,MAKEINTRESOURCE(120+cc)));

     

            iX = 1 + Tetris[ii][jj].a.x; iY = 1 + Tetris[ii][jj].a.y;

            BitBlt(hdc,240+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);

     

            iX = 1 + Tetris[ii][jj].b.x; iY = 1 + Tetris[ii][jj].b.y;

            BitBlt(hdc,240+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);

     

            iX = 1 + Tetris[ii][jj].c.x; iY = 1 + Tetris[ii][jj].c.y;

            BitBlt(hdc,240+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);

     

            iX = 1 + Tetris[ii][jj].d.x; iY = 1 + Tetris[ii][jj].d.y;

            BitBlt(hdc,240+iX*20,40+iY*20,20,20,hDcBitmap,0,0,SRCCOPY);

     

            return;

    }

     

    //随机产生新的方块数据

    void RandomBlock(int * l, int * m, int * n)

    {

            srand((unsigned)time(NULL));

     

            * l = rand() % 7;

            * m = rand() % 4;

            * n = rand() % 7;

     

            return;

    }

     

    //方块越界检测

    BOOL CheckBlock(int x, int y)

    {

            int     m, n;

     

            //初始位置不允许左右移动

            if( y == -1 ) return false;

     

            //游戏区越界检测

            if ( Tetris[i][j].a.x+x<0 || Tetris[i][j].a.x+x>9 || Tetris[i][j].a.y+y>18 ) return FALSE;

            if ( Tetris[i][j].b.x+x<0 || Tetris[i][j].b.x+x>9 || Tetris[i][j].b.y+y>18 ) return FALSE;

            if ( Tetris[i][j].c.x+x<0 || Tetris[i][j].c.x+x>9 || Tetris[i][j].c.y+y>18 ) return FALSE;

            if ( Tetris[i][j].d.x+x<0 || Tetris[i][j].d.x+x>9 || Tetris[i][j].d.y+y>18 ) return FALSE;

          

            //方块相遇检测

            for ( m=0; m<=18; m++ )

            {

                    for ( n=0; n<=9; n++ )

                    {

                            if ( m==Tetris[i][j].a.y+y && n==Tetris[i][j].a.x+x && Matrix[m][n]!=-1 ) return FALSE;

                            if ( m==Tetris[i][j].b.y+y && n==Tetris[i][j].b.x+x && Matrix[m][n]!=-1 ) return FALSE;

                            if ( m==Tetris[i][j].c.y+y && n==Tetris[i][j].c.x+x && Matrix[m][n]!=-1 ) return FALSE;

                            if ( m==Tetris[i][j].d.y+y && n==Tetris[i][j].d.x+x && Matrix[m][n]!=-1 ) return FALSE;

                    }

            }

     

            return TRUE;

    }

     

    //方块下落

    void DropTetris(HWND hwnd)

    {

            BOOL            bReDraw;

            int             l, m, n;

            HDC             hdc;

     

            //检测下一个方块位

            if ( CheckBlock(x,y+1) )

            { //可以下落

     

                    hdc = GetDC(hwnd);

                    if ( y == -1 )

                    {

                            //传递方块并重绘预览区

                            i = ii; j = jj; c = cc;

                            RandomBlock(&ii,&jj,&cc);

                            DrawNext(hdc);

     

                            //绘制新方块

                            y ++;

                            DrawTetris(hdc,0,0,0);

                    }

                    else

                    {

                            //绘制新方块

                            y ++;

                            DrawTetris(hdc,0,1,0);

     

                    }

                    ReleaseDC(hwnd,hdc);

            }

            else

            { //不能下落

                  

                    //在初始位置越界则结束游戏

                    if ( y == -1 )

                    {

                            GameOver(hwnd);

                            return;

                    }

                  

                    //保存当前方块

                    Matrix[ Tetris[i][j].a.y+y ][ Tetris[i][j].a.x+x ] = c;

                    Matrix[ Tetris[i][j].b.y+y ][ Tetris[i][j].b.x+x ] = c;

                    Matrix[ Tetris[i][j].c.y+y ][ Tetris[i][j].c.x+x ] = c;

                    Matrix[ Tetris[i][j].d.y+y ][ Tetris[i][j].d.x+x ] = c;

                  

                    //逐行扫描 检测满行

                    for ( l=18; l>=0; l-- )

                    {

                            bReDraw = TRUE;

                            for ( m=0; m<=9; m++ )

                            {

                                    if ( Matrix[l][m] == -1 )

                                    {

                                            bReDraw = FALSE;

                                            //break;

                                    }

                            }

                            if ( bReDraw )//检测到第l行为满行

                            {

                                    //更新计分器

                                    iLayer += 1;

                                    wsprintf(szBuffer,TEXT("%i"),iLayer);

                                    SetWindowText(hLayer,szBuffer); //满行

                                    iSorce += 10;

                                    wsprintf(szBuffer,TEXT("%i"),iSorce);

                                    SetWindowText(hSorce,szBuffer); //得分

                                    if ( iSorce >= (iLevel*50+50)*iLevel/2 ) //升级

                                    {

                                            iLevel ++;

                                            wsprintf(szBuffer,TEXT("%i"),iLevel);

                                            SetWindowText(hLevel,szBuffer);

                                            SendMessage(hStatus,SB_SETTEXT,1,(LPARAM)TEXT("恭喜升级!"));

                                    }

                                    else

                                    {

                                            wsprintf(szBuffer,TEXT("恭喜加分!距离下次升级还需 %i 分!"),(iLevel*50+50)*iLevel/2-iSorce);

                                            SendMessage(hStatus,SB_SETTEXT,1,(LPARAM)szBuffer);

                                    }

                                    //删除满行数据

                                    for ( m=0; m<=9; m++ ) Matrix[l][m] = -1;

                                    //数据整体下移

                                    for ( n=l; n>0; n-- )

                                    {

                                            for ( m=0; m<=9; m++ )

                                            {

                                                    Matrix[n][m] = Matrix[n-1][m];

                                                    Matrix[n-1][m] = -1;

                                            }

                                    }

                                    //重绘游戏区

                                    hdc = GetDC(hwnd);

                                    DrawMatrix(hdc);

                                    ReleaseDC(hwnd,hdc);

                                    l ++; //重新检查当前行

                            }

                    }

     

                    //重置方块位置

                    x = 4; y = -1;

            }

    }

     

    //方块旋转

    void RankTetris(HWND hwnd)

    {

            HDC     hdc;

            if ( j == 3 )

            {

                    j = 0;

                    if ( CheckBlock(x,y) )

                    {

                            hdc = GetDC(hwnd);

                            DrawTetris(hdc,0,0,1);

                            ReleaseDC(hwnd,hdc);

                    }

                    else

                    {

                            j = 3;

                    }

            }

            else

            {

                    j++;

                    if ( CheckBlock(x,y) )

                    {

                            hdc = GetDC(hwnd);

                            DrawTetris(hdc,0,0,1);

                            ReleaseDC(hwnd,hdc);

                    }

                    else

                    {

                            j --;

                    }

            }

    }

     

    //在控件中显示默认设备字体

    void SetNormalText(HWND hwnd,BOOL redraw)

    {

            static HFONT    hFont;

            LOGFONT         lfBuffer;

          

            GetObject(GetStockObject(DEFAULT_GUI_FONT),sizeof(lfBuffer),&lfBuffer);

            hFont = CreateFontIndirect(&lfBuffer); 

            SendMessage(hwnd,WM_SETFONT,(WPARAM)hFont,(LPARAM)redraw);

     

            return;

    }

     

    //处理自绘消息

    void DrawButton(LPARAM lParam)

    {

            HDC                     hdc;

            LPDRAWITEMSTRUCT        pdis;

            HPEN                    hpen;

     

            pdis = (LPDRAWITEMSTRUCT)lParam; //包含自绘信息的结构体

            hdc = pdis->hDC;

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

            SelectObject(hdc,hpen);

            switch ( pdis->CtlID )

            {

            case IDM_UP:

                    //FillRect(pdis->hDC,&pdis->rcItem,(HBRUSH)(COLOR_BTNFACE+1));

                    SendMessage(pdis->hwndItem,WM_ERASEBKGND,(WPARAM)pdis->hDC,NULL);

                    if ( pdis->itemState & ODS_SELECTED )

                    {

                            MoveToEx(hdc,13,1,NULL);

                            LineTo(hdc,1,25);

                            LineTo(hdc,25,25);

                            LineTo(hdc,13,1);

                            MoveToEx(hdc,12,3,NULL);

                            LineTo(hdc,2,24);

                    }

                    else

                    {

                            MoveToEx(hdc,12,1,NULL);

                            LineTo(hdc,1,24);

                            LineTo(hdc,24,24);

                            LineTo(hdc,12,1);

                            MoveToEx(hdc,13,2,NULL);

                            LineTo(hdc,25,25);

                            LineTo(hdc,2,25);

                    }

                    break;

            case IDM_DOWN:

                    //FillRect(pdis->hDC,&pdis->rcItem,(HBRUSH)(COLOR_BTNFACE+1));

                    SendMessage(pdis->hwndItem,WM_ERASEBKGND,(WPARAM)pdis->hDC,NULL);

                    if ( pdis->itemState & ODS_SELECTED )

                    {

                            MoveToEx(hdc,1,1,NULL);

                            LineTo(hdc,13,25);

                            LineTo(hdc,25,1);

                            LineTo(hdc,1,1);

                            MoveToEx(hdc,1,2,NULL);

                            LineTo(hdc,24,2);

                    }

                    else

                    {

                            MoveToEx(hdc,1,1,NULL);

                            LineTo(hdc,13,24);

                            LineTo(hdc,24,1);

                            LineTo(hdc,1,1);

                            MoveToEx(hdc,25,2,NULL);

                            LineTo(hdc,13,25);

                            LineTo(hdc,1,2);

                    }

                    break;

            case IDM_LEFT:

                    //FillRect(pdis->hDC,&pdis->rcItem,(HBRUSH)(COLOR_BTNFACE+1));

                    SendMessage(pdis->hwndItem,WM_ERASEBKGND,(WPARAM)pdis->hDC,NULL);

                    if ( pdis->itemState & ODS_SELECTED )

                    {

                            MoveToEx(hdc,1,13,NULL);

                            LineTo(hdc,25,25);

                            LineTo(hdc,25,1);

                            LineTo(hdc,1,13);

                            MoveToEx(hdc,2,13,NULL);

                            LineTo(hdc,24,2);

                    }

                    else

                    {

                            MoveToEx(hdc,1,12,NULL);

                            LineTo(hdc,24,23);

                            LineTo(hdc,24,1);

                            LineTo(hdc,1,12);

                            MoveToEx(hdc,1,13,NULL);

                            LineTo(hdc,25,25);

                            LineTo(hdc,25,1);

                    }

                    break;

            case IDM_RIGHT:

                    //FillRect(pdis->hDC,&pdis->rcItem,(HBRUSH)(COLOR_BTNFACE+1));

                    SendMessage(pdis->hwndItem,WM_ERASEBKGND,(WPARAM)pdis->hDC,NULL);

                    if ( pdis->itemState & ODS_SELECTED )

                    {

                            MoveToEx(hdc,1,1,NULL);

                            LineTo(hdc,1,25);

                            LineTo(hdc,25,12);

                            LineTo(hdc,1,1);

                            MoveToEx(hdc,2,24,NULL);

                            LineTo(hdc,2,2);

                            LineTo(hdc,24,13);

                    }

                    else

                    {

                            MoveToEx(hdc,1,1,NULL);

                            LineTo(hdc,1,24);

                            LineTo(hdc,24,12);

                            LineTo(hdc,1,1);

                            MoveToEx(hdc,1,25,NULL);

                            LineTo(hdc,25,13);    

                    }

                    break;

            }

            DeleteObject(hpen);

     

            return;

    }

     

    //游戏界面控件

    void GameUI(HWND hwnd)

    {

            int     stWidth[] = {100,-1};

            HWND    hTemp;

     

            //工具栏

            CreateToolbarEx(

                    hwnd,  //hwnd 父窗口句柄

                    WS_VISIBLE|WS_CHILD|TBSTYLE_FLAT|TBSTYLE_TOOLTIPS|CCS_NODIVIDER,  //ws 工具栏风格

                    IDR_TOOLBAR1,  //wID 工具栏的子窗口ID

                    6,  //nBitmaps 位图中包含多少个按钮小图标

                    hInst,  //hBMInst 包含位图资源的模块句柄

                    IDB_BITMAP1,  //wBMID 位图资源ID

                    tbButtons,  //lpButtons

                    8,  //iNumButtons 按钮总数

                    16,  //dxButton 单个按钮宽度

                    16,  //dyButton 单个按钮高度

                    16,  //dxBitmap 单个按钮小图标的宽度

                    16,  //dyBitmap 单个按钮小图标的高度

                    sizeof(TBBUTTON));  //uStructSize

     

            //状态栏

            hStatus = CreateStatusWindow(

                    WS_CHILD|WS_VISIBLE,

                    NULL,

                    hwnd,

                    IDS_STATUSBAR);

            SendMessage(hStatus,SB_SETPARTS,2,(LPARAM)(stWidth));

     

            //工具栏下的黑线

            CreateWindow(

                    TEXT("static"),  //lpClassName 类名

                    NULL,  //lpWindowName 标题

                    WS_CHILD|WS_VISIBLE|SS_BLACKFRAME,

                    1,24,

                    358,1,

                    hwnd,  //hWndParent

                    NULL,  //hMenu

                    hInst,

                    NULL);  //lpParam  额外的参数

     

            //游戏区的外框

            CreateWindow(

                    TEXT("static"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|SS_GRAYFRAME,

                    17,37,

                    206,386,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

     

            //预览区的外框

            CreateWindow(

                    TEXT("static"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|SS_GRAYFRAME,

                    237,37,

                    106,106,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

     

            //级别

            hTemp = CreateWindow(

                    TEXT("static"),

                    TEXT("级别 :"),

                    WS_CHILD|WS_VISIBLE|SS_LEFT,

                    240,190,

                    48,12,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

            SetNormalText(hTemp,FALSE);

            hLevel = CreateWindowEx(

                    WS_EX_STATICEDGE,

                    TEXT("static"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|WS_GROUP|SS_RIGHT|SS_CENTERIMAGE,

                    280,186,

                    60,18,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

            SetNormalText(hLevel,FALSE);

     

            //满行

            hTemp = CreateWindow(

                    TEXT("static"),

                    TEXT("满行 :"),

                    WS_CHILD|WS_VISIBLE|SS_LEFT,

                    240,220,

                    36,12,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

            SetNormalText(hTemp,FALSE);

            hLayer = CreateWindowEx(

                    WS_EX_STATICEDGE,

                    TEXT("static"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|WS_GROUP|SS_RIGHT|SS_CENTERIMAGE,

                    280,216,

                    60,18,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

            SetNormalText(hLayer,FALSE);

     

            //得分

            hTemp = CreateWindow(

                    TEXT("static"),

                    TEXT("得分 :"),

                    WS_CHILD|WS_VISIBLE|SS_LEFT,

                    240,250,

                    36,12,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

            SetNormalText(hTemp,FALSE);

            hSorce = CreateWindowEx(

                    WS_EX_STATICEDGE,

                    TEXT("static"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|WS_GROUP|SS_RIGHT|SS_CENTERIMAGE,

                    280,246,

                    60,18,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

            SetNormalText(hSorce,FALSE);

     

            //最高分

            hTemp = CreateWindow(

                    TEXT("static"),

                    TEXT("最高分"),

                    WS_CHILD|WS_VISIBLE|SS_LEFT,

                    240,280,

                    36,12,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

            SetNormalText(hTemp,FALSE);

            hSorceMax = CreateWindowEx(

                    WS_EX_STATICEDGE,

                    TEXT("static"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|WS_GROUP|SS_RIGHT|SS_CENTERIMAGE,

                    280,276,

                    60,18,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

            SetNormalText(hSorceMax,FALSE);

     

            //方向键 上

            CreateWindow(

                    TEXT("button"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,

                    280,340,

                    26,26,

                    hwnd,

                    (HMENU)IDM_UP,

                    hInst,

                    NULL);

     

            //方向键 下

            CreateWindow(

                    TEXT("button"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,

                    280,370,

                    26,26,

                    hwnd,

                    (HMENU)IDM_DOWN,

                    hInst,

                    NULL);

     

            //方向键 左

            CreateWindow(

                    TEXT("button"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,

                    253,355,

                    26,26,

                    hwnd,

                    (HMENU)IDM_LEFT,

                    hInst,

                    NULL);

     

            //方向键 右

            CreateWindow(

                    TEXT("button"),

                    NULL,

                    WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,

                    307,355,

                    26,26,

                    hwnd,

                    (HMENU)IDM_RIGHT,

                    hInst,

                    NULL);

          

            hTemp = CreateWindow(

                    TEXT("static"),

                    TEXT("下载本程序源代码请访问作者主页:http://www.EasyIDE.cn"),

                    WS_CHILD|WS_VISIBLE|SS_LEFT|WS_DISABLED,

                    18,433,

                    500,12,

                    hwnd,

                    NULL,

                    hInst,

                    NULL);

            SetNormalText(hTemp,FALSE);

     

     

            return;

    }

    地址:
    https://github.com/XUXUDONGNIC/E-luo-si-fangkuai/blob/master/eluosifangkuai.md

俄罗斯方块

标签:

原文地址:http://www.cnblogs.com/xuxudong/p/4453934.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!