• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 97, 文章 - 22, 評論 - 81, 引用 - 0
            數據加載中……

            C語言 控制臺下 俄羅斯方塊(附源碼)

                 昨天看到百度之星的趣味賽的帖子,很多代碼挺有意思的,于是想在控制臺下寫個簡潔點的小游戲,想想還是寫個最經典的游戲------俄羅斯方塊 吧。睡覺的時候構思了下大致的情況,今天早起開始寫,遇到最大的困難是鍵盤按鍵的問題,本來想開一個線程,然后讓系統讀getch(),但是getch和ReadConsoleInput函數一樣,是同步的,沒有輸入的狀態下會阻塞,所以不能用于鍵盤響應,找來找去,最后找到了GetAsyncKeyState函數,這個函數是異步的,可以在程序進行的同時獲取鍵盤消息,而且簡單易用,GetAsyncKeyState(VK_UP)表示向上鍵被按下。按鍵的問題解決后基本就只有顯示的問題了,因為控制臺下的顯示效率很低,所以不能每次重繪整個游戲界面(system("cls")),這樣會閃屏,于是我采用的機制是:每次擦掉上一次運行的結果,然后重繪當前狀態,這樣最多擦掉某一個區域,不會導致整個控制臺的閃爍,并且利用SetConsoleCursorPosition來設置當前光標的位置,以及利用SetConsoleCursorInfo來將光標隱藏以求達到更加真實的游戲畫面。
            可執行文件下載地址:http://code.google.com/p/sguzty/downloads/detail?name=Tertrix.exe&can=2&q=#makechanges
            附兩張簡單截圖:



            /*
            Author : 周天涯
            email : menjitianya2007@163.com
            blog : 
            http://www.shnenglu.com/menjitianya/
            Description : 即興創作,《C控制臺 俄羅斯方塊》,歡迎交流與探討,直接將代碼粘貼到VC6.0的環境下即可運行。

            ← 左移
            → 右移
            ↓ 加速
            ↑ 旋轉

            連續消去1行得1分、2行得3分、3行得5分、4行得7分。
            積分達到一定程度,會有換命的活動,命最多6條。
            難度會隨積分的上升逐漸上升,最多到6的難度。
            */


            #include 
            <iostream>
            #include 
            <windows.h>
            #include 
            <vector>
            #include 
            <mmsystem.h>

            #pragma comment(lib, 
            "winmm.lib")
            using namespace std;

            #define GameW 10
            #define GameH 20
            const int CtrlLeft = GameW*2+4 + 3;

            struct Point {
                Point()
            {}
                Point(
            int x, int y) {_x = x, _y = y;}
                
            int _x, _y;
            }
            ;

            HANDLE g_hOutput 
            = GetStdHandle(STD_OUTPUT_HANDLE);
            HANDLE g_hInput  
            = GetStdHandle(STD_INPUT_HANDLE);

            Point g_ptCursor(
            0,0);
            BOOL isChecking 
            = FALSE;
            BOOL g_bGameOver 
            = FALSE;
            int g_nGameBack[GameH][GameW], Case;
            int nowKeyInfo = -1;
            int g_nDiff = 1;
            int g_nLife = 2;
            int g_nScore = 0;

            void SetCursor(COORD cd) {
                SetConsoleCursorPosition(g_hOutput, cd);
            }

            void SetCursor(int x, int y){
                COORD cd 
            = {x, y};
                SetCursor(cd);
            }

            void SetBlockCursor(int x, int y){
                COORD cd 
            = {2*+ 2, y + 1};
                SetCursor(cd);
            }


            void SetBack(int x, int y, BOOL bk) {
                SetBlockCursor(x, y);
                
            if (bk) 
                    printf(
            "%s""");
                
            else
                    printf(
            " ");
            }


            bool Out(int x, int y) {
                
            return x < 0 || y < 0 || x >= GameW || y >= GameH; 
            }


            struct xBlock {
            public:
                
            int len;
                
            int nowRotateID;
                BOOL mask[
            4][4][4];
                
            static vector <xBlock> List;

                xBlock() 
            { len = 0; }
                xBlock(
            int l, char *str) {
                    
            int i, j, k;
                    len 
            = l;
                    memset(mask, FALSE, 
            sizeof(mask));
                    
            for(i = 0; i < l; i++{
                        
            for(j = 0; j < l; j++{
                            mask[
            0][i][j] = str[i*+ j] - '0';
                        }

                    }

                    
            for(k = 1; k < 4; k++{
                        
            for(i = 0; i < len; i++{
                            
            for(j = 0; j < len; j++{
                                mask[k][i][j] 
            = mask[k-1][j][len-1-i];
                            }

                        }

                    }

                    nowRotateID 
            = rand() % 4;
                }


                
            void rotate() {
                    nowRotateID 
            ++;
                    
            if (nowRotateID >= 4)
                        nowRotateID 
            = 0;
                }


                BOOL getUnit(
            int x, int y, int roID) {
                    
            if (roID == -1{
                        roID 
            = nowRotateID;
                    }

                    
            return mask[roID][y][x];
                }

            }
            ;

            vector 
            <xBlock> xBlock::List;

            class Block {
            public:
                
            int x, y;
                
            int ID;
                xBlock bk;

                
            void reset(xBlock *pbk) {
                    bk 
            = *pbk;

                    x 
            = 4, y = 0;
                    ID 
            = ++ Case;

                    
            if(collide(0,0)) {
                        lifeDown();
                    }

                    draw();
                    
                    
            *pbk = xBlock::List[rand() % xBlock::List.size()];
                }

                
                
            void lifeDown() {
                    
            int i, j;
                    
            for(i = 0; i < GameH; i++{
                        
            for(j = 0; j < GameW; j++{
                            SetBack(j, i, TRUE);
                            Sleep(
            10);
                        }

                    }

                    
            if(g_nLife) {
                        g_nLife 
            --;
                        
            for(i = g_nLife; i < 6; i++{
                            SetCursor(CtrlLeft 
            + i, 15);
                            printf(
            "%c"' ');
                        }

                        
            for(i = GameH-1; i >= 0; i--{
                            
            for(j = GameW-1; j >= 0; j--{
                                SetBack(j, i, FALSE);
                                Sleep(
            10);
                                g_nGameBack[i][j] 
            = 0;
                            }

                        }

                    }
            else {
                        g_bGameOver 
            = TRUE;
                    }

                }


                
            void erase() {
                    
            int i, j;
                    
            for(i = 0; i < bk.len; i++{
                        
            for(j = 0; j < bk.len; j++{
                            
            if (bk.getUnit(j, i, -1)) {
                                
            if(!Out(j+x, i+y) && g_nGameBack[i+y][j+x]) {
                                    SetBack(j
            +x, i+y, FALSE);
                                    g_nGameBack[i
            +y][j+x] = 0;
                                }

                            }

                        }

                    }

                }

                
            void draw() {
                    
            int i, j;
                    
            for(i = 0; i < bk.len; i++{
                        
            for(j = 0; j < bk.len; j++{
                            
            if (bk.getUnit(j, i, -1)) {
                                
            if(!Out(j+x, i+y) && !g_nGameBack[i+y][j+x]) {
                                    SetBack(j
            +x, i+y, TRUE);
                                    g_nGameBack[i
            +y][j+x]  = ID;
                                }

                            }

                        }

                    }

                }

                
            void draw(int x, int y) {
                    
            int i, j;
                    
            for(i = 0; i < 4; i++{
                        
            for(j = 0; j < 4; j++{
                            SetCursor(x 
            + 2*j, y + i);
                            
            if (bk.getUnit(j, i, -1)) {    
                                printf(
            "%s""");
                            }
            else 
                                printf(
            " ");
                        }

                    }

                }

                
            bool collide(int dx, int dy, int roID = -1{
                    
            int i, j;
                    
            for(i = 0; i < bk.len; i++{
                        
            for(j = 0; j < bk.len; j++{
                            
            if (bk.getUnit(j, i, roID)) {
                                Point ptPos(j 
            + x + dx, i + y + dy);
                                
            if(Out(ptPos._x, ptPos._y)
                                
            || g_nGameBack[ptPos._y][ptPos._x] && ID != g_nGameBack[ptPos._y][ptPos._x]) {
                                    
            return TRUE;
                                }

                            }

                        }

                    }

                    
            return FALSE;
                }


                
            void rotate(int nTimes = 1{
                    
            int nextro = (bk.nowRotateID + nTimes) % 4;
                    
            if(collide(00, nextro)) {
                        
            return ;
                    }

                    Beep(
            1200050);
                    erase();
                    bk.nowRotateID 
            = nextro;
                    draw();
                }


                BOOL changepos(
            int dx, int dy) {
                    
            if(collide(dx, dy)) {
                        
            return FALSE;
                    }

                    erase();
                    x 
            += dx;
                    y 
            += dy;
                    draw();
                    
            return TRUE;
                }

            }
            ;

            void GameInit() {
                CONSOLE_CURSOR_INFO cursor_info;
                cursor_info.bVisible 
            = FALSE;
                cursor_info.dwSize   
            = 100;
                SetConsoleCursorInfo(g_hOutput, 
            &cursor_info);
                xBlock::List.push_back(xBlock(
            3"010111000"));
                xBlock::List.push_back(xBlock(
            3"110110000"));
                xBlock::List.push_back(xBlock(
            3"111001000"));
                xBlock::List.push_back(xBlock(
            3"111100000"));
                xBlock::List.push_back(xBlock(
            3"110011000"));
                xBlock::List.push_back(xBlock(
            3"011110000"));
                xBlock::List.push_back(xBlock(
            4"1000100010001000"));
            }


            void DrawFrame(int x, int y, int nWidth, int nHeight) {
                
            int i;
                
            for(i = 0; i < nWidth; i++{
                    SetCursor(x 
            + 2*+ 2, y);
                    printf(
            "%s""");
                    SetCursor(x 
            + 2*+ 2, y + nHeight+1);
                    printf(
            "%s""");
                }

                
            for(i = 0; i < nHeight; i++{
                    SetCursor(x, y 
            + i + 1);
                    printf(
            "%s""");
                    SetCursor(x 
            + nWidth*2+2, y + i + 1);
                    printf(
            "%s""");
                }
                    
                SetCursor(x, y);
                printf(
            "%s""");    
                SetCursor(x, y 
            + nHeight+1);
                printf(
            "%s""");
                SetCursor(x 
            + nWidth*2+2, y);
                printf(
            "%s""");    
                SetCursor(x 
            + nWidth*2+2, y + nHeight+1);
                printf(
            "%s""");
            }


            void MissionInit() {
                memset(g_nGameBack, FALSE, 
            sizeof(g_nGameBack));
                Case 
            = 1;
                
            int i;
                DrawFrame(
            00, GameW, GameH);
                DrawFrame(GameW
            *2+404, GameH);
                SetCursor(CtrlLeft, 
            2);
                printf(
            "Next");
                
                SetCursor(CtrlLeft, 
            8);
                printf(
            "Speed");
                
            for(i = 0; i < g_nDiff; i++{
                    SetCursor(CtrlLeft 
            + i, 9);
                    printf(
            "%c"1);
                }


                SetCursor(CtrlLeft, 
            11);
                printf(
            "Score");
                SetCursor(CtrlLeft, 
            12);
                printf(
            "%d", g_nScore);

                SetCursor(CtrlLeft, 
            14);
                printf(
            "Life");
                
            for(i = 0; i < g_nLife; i++{
                    SetCursor(CtrlLeft 
            + i, 15);
                    printf(
            "%c"3);
                }


                SetCursor(CtrlLeft
            -119);
                printf(
            "by Zty");
                SetCursor(CtrlLeft
            -120);
                printf(
            "Baidu A*");
            }


            void Check() {
                isChecking 
            = TRUE;
                
            int i, j, k;
                vector 
            <int> line;
                
            for(i = 0; i < GameH; i++{
                    
            for(j = 0; j < GameW; j++{
                        
            if(!g_nGameBack[i][j])
                            
            break;
                    }

                    
            if(j == GameW) {
                        line.push_back(i);
                    }

                }

                
            if(line.size()) {
                    
            int nCount = 7;
                    
            while(nCount --{
                        
            for(i = 0; i < line.size(); i++{
                            
            for(j = 0; j < GameW; j++{
                                SetBack(j, line[i], nCount
            &1);
                            }

                        }

                        Sleep(
            70);
                    }

                    
            for(i = 0; i < line.size(); i++{
                        
            for(j = 0; j < GameW; j++{
                            g_nGameBack[line[i]][j] 
            = 0;
                        }

                    }


                    
            for(i = 0; i < GameW; i++{
                        
            int next = GameH-1;
                        
            for(j = GameH-1; j >= 0; j--{
                            
            for(k = next; k >= 0; k--{
                                
            if(g_nGameBack[k][i]) 
                                    
            break;
                            }

                            next 
            = k - 1;
                            BOOL 
            is = (k >= 0);
                            SetBack(i, j, 
            is);
                            g_nGameBack[j][i] 
            = is;
                        }

                    }


                    g_nScore 
            += 2*line.size()-1;
                    SetCursor(CtrlLeft, 
            12);
                    printf(
            "%d", g_nScore);

                    
            if( g_nScore >= g_nDiff * g_nDiff * 10{
                        
            if(g_nDiff <= 6)
                            g_nDiff 
            ++;
                    }

                    
            if( g_nScore >= 50 * (g_nLife+1)) {
                        
            if(g_nLife <= 6)
                            g_nLife 
            ++;
                    }

                }


                isChecking 
            = FALSE;
            }

            int main() {
                Block
            * obj = new Block();
                Block
            * buf = new Block();
                

                BOOL bCreateNew 
            = FALSE;
                
            int nTimer = GetTickCount();
                
            int LastKeyDownTime = GetTickCount();


                GameInit();
                MissionInit();
                
                buf
            ->bk = xBlock::List[rand() % xBlock::List.size()];
                
            while(1{
                    
            if(!bCreateNew) {
                        bCreateNew 
            = TRUE;
                        obj
            ->reset(&buf->bk);
                        
            if(g_bGameOver)
                            
            break;
                        buf
            ->draw(CtrlLeft - 14);
                    }

                    
            if (GetTickCount() - nTimer >= 1000 / g_nDiff) {
                        nTimer 
            = GetTickCount();
                        
            if (!obj->collide(01))
                            obj
            ->changepos(01);
                        
            else {
                            Check();
                            bCreateNew 
            = FALSE;
                        }

                    }

                    
            if (GetTickCount() - LastKeyDownTime >= 100{
                        
            if(FALSE == isChecking) {
                            LastKeyDownTime 
            = GetTickCount();
                            
            if (GetAsyncKeyState(VK_UP)) {
                                obj
            ->rotate();
                            }

                            
            if (GetAsyncKeyState(VK_LEFT)) {
                                obj
            ->changepos(-10);
                            }

                            
            if (GetAsyncKeyState(VK_RIGHT)) {
                                obj
            ->changepos(10);
                            }

                            
            if (GetAsyncKeyState(VK_DOWN)) {
                                
            if( FALSE == obj->changepos(02) )
                                    obj
            ->changepos(01);
                            }

                        }

                    }

                }

                SetCursor(
            810);
                printf(
            "Game Over");

                SetCursor(
            0, GameH+3);
                printf(
            "按ESC鍵退出游戲");

                
            while(1{
                    
            if (GetAsyncKeyState(VK_ESCAPE))
                        
            break;
                }

                
            return 0;
            }






             




             

            posted on 2011-05-26 13:40 英雄哪里出來 閱讀(11096) 評論(8)  編輯 收藏 引用 所屬分類: 游戲開發

            評論

            # re: C語言 控制臺下 俄羅斯方塊(附源碼)  回復  更多評論   

            不錯,贊一個。
            2011-05-26 15:57 | 楊粼波

            # re: C語言 控制臺下 俄羅斯方塊(附源碼)  回復  更多評論   

            代碼挺不錯的

            正好御姐也寫過一個誒,你可以看下她的:
            http://hi.baidu.com/misaka20001/blog/item/a854150a49b6b9d87bcbe1b6.html

            2011-05-26 16:21 | 邱震鈺(zblc)

            # re: C語言 控制臺下 俄羅斯方塊(附源碼)  回復  更多評論   

            @邱震鈺(zblc)
            學習下~呵呵~~
            2011-05-26 17:20 | 英雄哪里出來

            # re: C語言 控制臺下 俄羅斯方塊(附源碼)  回復  更多評論   

            旋轉的時候不太正確,尤其是長條跟正方形,正方形旋轉居然會改變位置。需要修正下。
            2011-05-26 20:11 | foxtail

            # re: C語言 控制臺下 俄羅斯方塊(附源碼)  回復  更多評論   

            @foxtail
            恩,有道理,因為在控制臺下效率低一點就會出現閃屏了,一味追求效率把一些原始的東西改掉了~~
            2011-05-26 20:19 | 英雄哪里出來

            # re: C語言 控制臺下 俄羅斯方塊(附源碼)  回復  更多評論   

            bug太太太多了,再修改修改吧~
            2011-05-27 00:30 | myjfm

            # re: C語言 控制臺下 俄羅斯方塊(附源碼)  回復  更多評論   

            @myjfm
            歡迎提出建議~~Bug修改中~~
            2011-05-27 11:36 | 英雄哪里出來

            # re: C語言 控制臺下 俄羅斯方塊(附源碼)  回復  更多評論   

            每個IT男硬盤伸出都有一個當年寫的俄羅斯方塊~
            2011-05-30 09:46 | 欲三更
            91精品国产色综久久| 亚洲&#228;v永久无码精品天堂久久| 五月丁香综合激情六月久久| 亚洲精品无码久久一线| 狠狠色婷婷综合天天久久丁香 | 亚洲狠狠久久综合一区77777| 久久久久亚洲?V成人无码| 国产精品99久久久精品无码| 狠狠色丁香婷婷综合久久来 | 久久久无码精品亚洲日韩按摩| 久久福利青草精品资源站免费| 色偷偷88欧美精品久久久| 91精品国产乱码久久久久久| 久久亚洲中文字幕精品一区四 | 亚洲?V乱码久久精品蜜桃| 日本精品久久久中文字幕| 亚洲香蕉网久久综合影视 | 一本色道久久88综合日韩精品 | 亚洲精品无码久久久| 青青国产成人久久91网| 亚洲欧美日韩精品久久亚洲区| 久久精品国产一区| 亚洲AV日韩精品久久久久久| 欧美伊人久久大香线蕉综合69 | 久久大香萑太香蕉av| 国产成人99久久亚洲综合精品| 99久久久精品免费观看国产| 老男人久久青草av高清| 综合久久一区二区三区| 欧美麻豆久久久久久中文| 精品无码久久久久久国产| 国产精品成人精品久久久| 国产精品美女久久久久网| 久久夜色精品国产网站| 久久久久人妻一区二区三区vr| 久久婷婷五月综合成人D啪| 国内精品久久久久影院老司| 四虎影视久久久免费观看| 日本国产精品久久| 伊人色综合九久久天天蜜桃| 成人综合久久精品色婷婷|