伊莉討論區

標題: 兒時遊戲_打磚塊!!! [打印本頁]

作者: 小o賴    時間: 2011-6-5 05:32 PM     標題: 兒時遊戲_打磚塊!!!

本帖最後由 小o賴 於 2011-6-5 05:38 PM 編輯

最近因為某些原因,而開始寫這個遊戲,大約花了我約五天的時間在這程式上,
其中最麻煩的莫過於球與磚塊的撞擊那方面,需判斷的方式有許多種,
在這上面也花了比較多的時間在Debug,因此希望各位喜歡囉!!!

打磚塊遊戲程式碼說明:
                                1.此遊戲每關之磚塊為5*10個。
                                2.每關撞擊獲得分數並不同。
                                3.移動條反彈之區域為球之正下方的格子需有移動條。
                                4.每關開始前,可利用左右方向鍵調整球的起始位子。
                                5.遊戲進行時,下方會顯示目前之積分及所玩之關卡。
                                6.每進行到下一關,速度會增快一些,最後一關速度為最快。
By 小o賴


載點:訊六(內含CPP.EXE檔)

執行畫面:
[attach]58333579[/attach]

[attach]58333685[/attach]

程式碼:(程式碼排版不好,請多見諒,可於載點之RAR檔中取得)
  1. #include<iostream>
  2. #include<conio.h>
  3. #include<windows.h>
  4. using namespace std;
  5. int i,j,s,key=6,h=0,speed,space=0,run,win,score=0;
  6. //i:表示行;j:表示列、key;表示移動條起始位子;h:判斷是否撞擊過; s:速度迴圈用;
  7. //speed:關卡之速度;space:計算是否已完成;run:判斷是否開始跑; win:判斷是否過關;
  8. //score:紀錄所獲得之總分;
  9. int block[16][16];//存放方塊與球的值
  10. char yn;//紀錄輸入的為Y或N之字元
  11. void func(short x, short y)//宣告FUNC函式用
  12. {
  13. static HANDLE hConsole=0; // 宣告一個可控制硬體的變數
  14. static int InstanceCount=0;
  15. COORD coord; // 宣告座標,給後來呼叫的函數用
  16. if(!InstanceCount){
  17. // 取得螢幕的控制
  18. hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
  19. InstanceCount=1;
  20. }
  21. coord.X=x, coord.Y=y;
  22. // 將游標移至所指定的座標位置
  23. SetConsoleCursorPosition(hConsole, coord);
  24. }
  25. class Circle//碰撞球之結構
  26. {
  27. public:
  28.         Circle(int a,int b):x(a),y(b){};
  29.         int x,y;
  30. };
  31. Circle c(13,7);//設定碰撞球的起始位子
  32. void keyboard()//移動條移動函式及開始遊戲之按鈕判斷
  33. {
  34. int k;
  35. if(kbhit())
  36. {
  37.   k=getch();
  38.   if(k==13){ run=1; }
  39.   if(k==75){
  40.              if(run==0){ key--; if(key<0){key=0;} block[14][key]=1; block[14][key+4]=0;
  41.                          if(c.y>1){ block[13][c.y]=0; c.y--; block[13][c.y]=2; }
  42.                        }
  43.              else{ key--; if(key<0){key=0;} block[14][key]=1; block[14][key+4]=0; }
  44.            }
  45.   if(k==77){
  46.              if(run==0){ key++; if(key>12){key=12;} block[14][key-1]=0; block[14][key+3]=1;
  47.                          if(c.y<13){ block[13][c.y]=0; c.y++; block[13][c.y]=2; }
  48.                        }
  49.              else{ key++; if(key>12){key=12;} block[14][key-1]=0; block[14][key+3]=1; }
  50.            }
  51. }
  52. }
  53. int main()
  54. {
  55. //******************************************************************************************* cout << "打磚塊遊戲規則說明:" << endl << endl << "1.進入遊戲後,可利用左右之方向鍵調整發球位子。" << endl
  56.       << "2.發球位子確定後,按下【Enter】鍵,開始遊戲。" << endl
  57.       << "3.每結束一關,會問是否繼續遊戲,若是,則繼續;若否,則會顯示所獲得的總積分。" << endl
  58.       << "4.若在遊戲中,闖關失敗的話,則會問是否重新闖關,若是,則分數及關卡重新;\n  若否,則顯示所獲得的總積分。" << endl
  59.       << "5.此遊戲,球與移動條之碰撞位子,只有一格,也就是當球的正下方有移動條,\n  才可反彈,否則失敗。" << endl
  60.       << "6.此遊戲共有10關,第一關每塊磚塊為1分,依序加一,最後一關每塊為10分,\n  滿分為2750分。" << endl
  61.       << endl << "請按下任一鍵開始遊戲!!!" << "                                             By小o賴";
  62. getch();
  63. //*******************************************************************************************score=0; speed=1;
  64. while(1)// 1  
  65. {
  66.   int ru=1,lu=0,ld=0,rd=0,win=0,;//ru:球方向為右上; lu:球方向為左上; ld:球方向為左下; rd:球方向為右下;
  67.   c.x=13; c.y=7; run=0; key=6;
  68.   for(j=0;j<16;j++){//起始位子設定
  69.                     if(j>=0 && j<=1){ for(i=0;i<16;i++){block[j][i]=0;} }
  70.                     if(j>=2 && j<=6){ for(i=0;i<16;i++){if(i>=3 && i<=12){block[j][i]=1;}else{block[j][i]=0;}} }
  71.                     if(j>=7 && j<=12){ for(i=0;i<16;i++){block[j][i]=0;} }
  72.                     if(j==13){ for(i=0;i<16;i++){if(i==7){block[j][i]=2;}else{block[j][i]=0;}} }
  73.                     if(j==14){ for(i=0;i<16;i++){if(i>=6 && i<=9){block[j][i]=1;}else{block[j][i]=0;}} }
  74.                     if(j==15){ for(i=0;i<16;i++){block[j][i]=0;} }
  75.                    }
  76. system("cls");
  77. while(1)// 2  
  78. {
  79.   space=0;
  80.   for(j=2;j<7;j++){ for(i=3;i<13;i++){ if(block[j][i]==0){space++;} } }
  81.   if(space==50){ win=1; score=score+50*speed; break; }//判斷是否已成功過關
  82.   for(s=0;s<11-speed;s++){//顯示區
  83.                           func(0,0); h=0;
  84.                           for(j=0;j<16;j++){
  85.                                              for(i=0;i<16;i++){
  86.                                                                 if(block[j][i]==0){cout << "  ";}
  87.                                                                 else{ if(block[j][i]==1){cout << "■";}
  88.                                                                       else{cout << "●";}
  89.                                                                     }
  90.                                                                }
  91.                                              cout << endl;  keyboard();
  92.                                              }
  93.                           cout << "第 " << speed << " 關" << endl << "分數: " << (space*speed)+score << " 分        "
  94.                                << "By小o賴";
  95.                           keyboard();
  96.                          }
  97. //******************************************************************************************  if(run==1){// 3  
  98. //遇到牆壁反彈  
  99.   if(c.y==15){ if(ru==1){ ru=0; lu=1; } if(rd==1){ rd=0; ld=1; } }
  100.   if(c.y==0){ if(lu==1){ lu=0; ru=1; } if(ld==1){ld=0; rd=1;} }
  101.   if(c.x==0){ if(lu==1){ lu=0; ld=1; } if(ru==1){ru=0; rd=1;} }
  102.   if(c.x==13){
  103.                if(rd==1){ rd=0; ru=1; } if(ld==1){ld=0; lu=1;}
  104.                if(block[c.x+1][c.y]==1){if(rd==1){ rd=0; ru=1; } if(ld==1){ld=0; lu=1;}}
  105.                else{
  106.                      score=score+space*speed; break;
  107.                    }
  108.              }
  109. //撞到磚塊消掉磚塊後反彈
  110. if(ru==1){ if(block[c.x][c.y+1]==1 && c.x>1)
  111.    { block[c.x][c.y]=0; block[c.x][c.y+1]=0; lu=1; ru=0; c.x--; c.y--;
  112.               if(block[c.x][c.y+1]==1){ block[c.x][c.y+1]=0; c.x=c.x+2; ld=1; lu=0; }
  113.               block[c.x][c.y]=2; h=1;
  114.             }
  115.    else{
  116.      if(block[c.x-1][c.y]==1 && c.y>2)
  117.      { block[c.x][c.y]=0; block[c.x-1][c.y]=0; rd=1; ru=0; c.x++; c.y++; block[c.x][c.y]=2; h=1;}
  118.      else{
  119.                       if(block[c.x-1][c.y+1]==0){c.x--; c.y++; block[c.x][c.y]=2; block[c.x+1][c.y-1]=0; }
  120.           else{ block[c.x][c.y]=0; block[c.x-1][c.y+1]=0; lu=1; ru=0; c.x--; c.y--;
  121.                             if(block[c.x][c.y]==1){ rd=1; lu=0; c.x=c.x+2; c.y=c.y+2; }
  122.                             block[c.x][c.y]=2; h=1;
  123.                           }
  124.                      }
  125.                 }
  126.           }
  127.   
  128. if(lu==1 && h==0){ if(block[c.x][c.y-1]==1 && c.x>1)
  129.                       { block[c.x][c.y]=0; block[c.x][c.y-1]=0; ru=1; lu=0; c.x--; c.y++;
  130.                         if(block[c.x][c.y]==1){ block[c.x][c.y-1]=0; rd=1; ru=0; c.x=c.x+2;}
  131.                         block[c.x][c.y]=2; h=1;
  132.                       }
  133.              else{
  134.                if(block[c.x-1][c.y]==1 && c.y>2)
  135.                            { block[c.x][c.y]=0; block[c.x-1][c.y]=0; ld=1; lu=0; c.x++; c.y--; block[c.x][c.y]=2; h=1;}
  136.                else{
  137.                                 if(block[c.x-1][c.y-1]==0){c.x--; c.y--; block[c.x][c.y]=2; block[c.x+1][c.y+1]=0; }
  138.                     else{ block[c.x][c.y]=0; block[c.x-1][c.y-1]=0; ld=1; lu=0; c.x++; c.y--; block[c.x][c.y]=2; h=1; }
  139.                                }
  140.                            }
  141.                     }
  142.   
  143. if(rd==1 && h==0){ if(block[c.x][c.y+1]==1 && c.x>1 && block[c.x+1][c.y]!=1)
  144.              {
  145.                        block[c.x][c.y]=0; block[c.x][c.y+1]=0; ld=1; rd=0; c.x++; c.y--;
  146.                        if(block[c.x][c.y]==1){ lu=1; ld=0; c.x=c.x-2; }
  147.                        block[c.x][c.y]=2; h=1;
  148.                       }
  149.              else{
  150.                if(block[c.x+1][c.y]==1 && c.y>2 && block[c.x][c.y+1]!=1)
  151.                {
  152.                             block[c.x][c.y]=0; block[c.x+1][c.y]=0; block[c.x][c.y+1]=0; ru=1; rd=0; c.x--; c.y++;
  153.                             if(block[c.x][c.y]==1){ lu=1; ru=0; c.y=c.y-2;  }
  154.                             block[c.x][c.y]=2; h=1;
  155.                            }
  156.                else{
  157.                                 if(block[c.x+1][c.y+1]==0){c.x++; c.y++; block[c.x][c.y]=2; block[c.x-1][c.y-1]=0; }
  158.                                 else{ block[c.x][c.y]=0;
  159.                                       if(block[c.x+1][c.y]==1 && block[c.x][c.y+1]==1)
  160.                                       { block[c.x+1][c.y]=0; block[c.x][c.y+1]=0; lu=1; rd=0; c.x--; c.y--;}
  161.                                       else{ block[c.x+1][c.y+1]=0; ru=1; rd=0; c.x--; c.y++; }
  162.                                       if(block[c.x][c.y]==1){ lu=1; ru=0; c.y=c.y-2; }
  163.                                       block[c.x][c.y]=2; h=1;
  164.                                     }
  165.                                }
  166.                           }   
  167.                     }

  168. if(ld==1 && h==0){ if(block[c.x][c.y-1]==1 && c.x>1 && block[c.x+1][c.y+1]!=1)
  169.              { block[c.x][c.y]=0; block[c.x][c.y-1]=0; rd=1; ld=0; c.x++; c.y++;
  170.                         if(block[c.x][c.y]==1){ ru=1; rd=0; c.x=c.x-2; c.y=c.y-2; }
  171.                         block[c.x][c.y]=2; h=1;
  172.                       }
  173.              else{
  174.                if(block[c.x+1][c.y]==1 && c.y>2)
  175.                {
  176.                             block[c.x][c.y]=0; block[c.x+1][c.y]=0;
  177.                             if(block[c.x][c.y-1]==1){ block[c.x][c.y-1]=0; ru=1; ld=0; c.x--; c.y++; }
  178.                             else{lu=1; ld=0; c.x--; c.y--;}
  179.                             block[c.x][c.y]=2; h=1;
  180.                            }
  181.                else{
  182.                                 if(block[c.x+1][c.y-1]==0){
  183.                                                            c.x++; c.y--; block[c.x-1][c.y+1]=0;
  184.                                                            if(block[c.x-1][c.y]==1){ ru=1; ld=0; c.x=c.x-2; c.y=c.y-2;}
  185.                                                            block[c.x][c.y]=2;
  186.                                                           }
  187.                     else{
  188.                                       block[c.x][c.y]=0;
  189.                                       if(block[c.x][c.y-1]==1){ block[c.x][c.y-1]=0; c.x++; c.y++;
  190.                                                                 if(block[c.x][c.y]==1){ block[c.x][c.y]=0; lu=1; ld=0; c.x=c.x-2; c.y=c.y-2;
  191.                                                                                         if(block[c.x][c.y]==1){ ru=1; lu=0; c.y=c.y+2; }
  192.                                                                                       }
  193.                                                                 block[c.x][c.y]=2; h=1;
  194.                                                               }
  195.                                       else{
  196.                                            block[c.x+1][c.y-1]=0; lu=1; ld=0; c.x--; c.y--;
  197.                                            if(block[c.x][c.y]==1 && c.y>13){ ru=1; lu=0; c.y=c.y+2; }
  198.                                            else{
  199.                                                  if(block[c.x+2][c.y+2]==1){ lu=1; rd=0; }
  200.                                                  else{rd=1; lu=0; c.x=c.x+2; c.y=c.y+2;}
  201.                                                }
  202.                                            block[c.x][c.y]=2; h=1;
  203.                                           }
  204.                                     }
  205.                                }
  206.                       }
  207.                     }
  208.   keyboard();
  209. }// 3  
  210. //*******************************************************************************************
  211. }// 2  
  212. system("cls");
  213. func(0,0);
  214. if(win==1){
  215.             while(1)
  216.             {
  217.              cout << "是否繼續闖關(Y/N):";
  218.              cin >> yn;
  219.              if(yn=='Y' || yn=='y' || yn=='N' || yn=='n'){break;}
  220.              else{continue;}
  221.             }
  222.             if(yn=='Y' || yn=='y'){ speed++; if(speed>10){ cout << "恭喜你全數過關!!!" << endl; break;}else{ continue; } }
  223.             else{
  224.                   cout << "恭喜過關^^!!!" << endl;
  225.                   break;
  226.                 }
  227.            }
  228. else{ cout << "不好意思,您闖關失敗ˊˋ!!!" << endl; getch();
  229.        while(1)
  230.        {
  231.         cout << "是否重新闖關(Y/N):";
  232.         cin >> yn;
  233.         if(yn=='Y' || yn=='y' || yn=='N' || yn=='n'){break;}
  234.         else{continue;}
  235.        }
  236.        if(yn=='Y' || yn=='y'){ score=0; speed=1; continue; }else{ break; }
  237.      }

  238. }// 1  
  239. //******************************************************************************************* cout << "獲得總分為:" << score << endl;
  240. getch();
  241. return 0;
  242. }
複製代碼

作者: 撲殺兔    時間: 2011-6-7 07:58 PM

本帖最後由 撲殺兔 於 2011-6-7 08:02 PM 編輯

推自製遊戲,  怎麼沒人推? 我來當第一個, 樓主繼續加油!

p.s. 話說第一關速度也太快了吧
作者: 小o賴    時間: 2011-7-12 03:24 PM

我想要問一下,雖然遊戲是寫出來了,可是畫面似乎有點閃爍(個人感覺太閃),
是否有方法可以讓它改善呢???
作者: NelsonLF    時間: 2011-7-12 03:41 PM

我個人之前是用"只刷新改變部分的符號"
例如說移動
===
一開始
  ===
↑      ↑改變部分
    ===
  ↑      ↑改變部分

看你上面磚塊是固定的.沒打到的話可以不用重新印
作者: 小o賴    時間: 2011-7-12 10:33 PM

嗯,了解,感謝妳,我會再去試試看的。
作者: dn0710sh    時間: 2011-7-20 12:16 PM

真是高手
來花一點時間就一下大大寫的程式
看起來真的是不錯玩
感謝大大的分享
作者: r2337331asdf    時間: 2011-7-26 01:43 PM

感覺不錯下載來玩看看3QQQQ
作者: qwert4209    時間: 2011-7-26 03:02 PM

自製遊戲耶
我現在才剛學
希望之後也可以做出來
謝謝大大
作者: asd5530025    時間: 2011-7-28 05:27 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: iseeyou    時間: 2011-7-28 10:05 AM

回復 4# 小o賴

通常閃爍. 的改善, 都會用所謂的double buffer 技巧
double buffer 指的是
一個前景頁. 一般就是硬體的顯示
令一個背景頁. 你得作畫都在這個背景業作 .

等你把所有的要顯示的東西. 都在背景做頁作好. 再一次全部更新到前景.
不過這通常都要硬體支援
如果硬體不支援下. 我們只好自己模擬一個背景頁
在memory 中模擬. 你把所有的東西都先在memory 中的頁面畫好. 再一次通通搬到前景頁去

windows 的console 是有support memory buffer . 你自己管理的memory buffer. 但是. 這東西沒辦法用printf 來動作. 所以你要自己寫一套東西來管理你的memory buffer

你畫好的東西也可以一次通通丟到console 去. Windows API 有提供這樣的指令

你可以參考這篇
http://www07.eyny.com/thread-6173893-1-1.html
作者: NelsonLF    時間: 2011-7-28 10:10 AM

回復
iseeyou 發表於 2011-7-28 10:05 AM



可是這程式不是api
沒辦法先印在畫布上再貼出來
作者: 小o賴    時間: 2011-7-28 11:41 AM

回復 11# iseeyou

說真的,你的那種跟我寫程式的方式不同,如果用一開始在前面這位大大NelsonLF說的方式下去修改,是一種可行方式,雖然還沒試過,但大概知道方式,也了解他的可行性,而我寫的程式也如同那位大大再第二頁回復你的,該程式並非使用API下去寫,所以可行性仍有待考慮。
作者: xiaojiba9898    時間: 2012-11-11 08:17 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: m0neypig    時間: 2012-11-11 11:38 PM

厲害!程式也挺小的。
如果喜歡寫些視窗小遊戲的話,可以考慮C# + WPF  (C++ 也可)
寫得更快還有強大的UI support
要孰悉 XAML就是
作者: davion911    時間: 2014-8-17 02:50 PM

請問 為什麼我用Dev C++無法編譯呢? 如果要改成可以編譯的版本要怎麼改?
作者: sh7162c    時間: 2014-8-17 11:26 PM

很厲害!沒有 windows,純推不下 XD





歡迎光臨 伊莉討論區 (http://64896.eyny.com/) Powered by Discuz!