程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 俄羅斯方塊——圖形編程

俄羅斯方塊——圖形編程

編輯:關於.NET

第三個題目是俄羅斯方塊游戲。該游戲算法比較簡單,主要功夫都在界面體驗上了,比如方塊圖形、用戶控制、消去與累計等。

圖形我們采用GDI+畫圖方式顯示,共8種圖形,當然可以根據自己的喜好隨意定制。如何表示圖形?我們可以借鑒馬賽克效果。把所有圖形都用3*3矩陣表示,0表示背景色顯示,1表示著色顯示。比如

{0,0,0},

{0,1,0}, 表示T型,看出來了嗎?每個數字位置其實就是一個正方形小塊。

{1,1,1}

用戶控制?簡單KeyPress事件實現就好。當然還有一個無需用戶控制的就是自動下落,可以使用Timer實現。

消去算法?^_^,當然很簡單,如果一行上有為0的單元格,那麼表示沒有充滿,就不用消去;否則就要消去。累計就是數組追加,消去就是元素刪除。

當然了,消去與累計都需要將數據的變化體現到界面上,那就是畫圖。Graphics對象我們都會使用,在該windows窗體游戲中,我們可以實現OnPaint事件。每當需要重繪的時候,比如用戶控制,消去等,就調用窗體refresh,那麼自然會觸發Paint事件。以下是代碼示例:

public int[][,] figures = new int[8][,]//8種圖形
  {
    new int[3,3] {
  {0,0,0},
  {0,1,0},
  {1,1,1}
  },
    new int[3,3]
  {
  {0,0,0},
  {0,2,2},
  {2,2,0}
  },
    new int[3,3]
  {
  {0,0,0},
  {3,3,0},
  {0,3,3}
  },
    new int[2,2]
  {
  {4,4},
  {4,4}
  },
    new int[3,3]
  {
  {5,0,0},
  {5,0,0},
  {5,5,0}
  },
    new int[3,3]
  {
  {0,6,0},
  {0,6,0},
  {6,6,0}
  },
    new int[4,4]
  {
  {7,0,0,0},
  {7,0,0,0},
  {7,0,0,0},
  {7,0,0,0}
  },
    new int[3,3]
  {
  {0,8,0},
  {8,8,8},
  {0,0,0}
  }
  };

你能從上面的定義看出有哪些圖形嗎?^_^,為什麼不為0的地方不全是1?因為我想讓不同的圖形顯示不同的顏色,如果無此要求則不必這樣。

在具體畫圖時,我們需要將將數組大小轉換為區域邊長方格數

int conversize(int sz)
    {
      int s = 0;
      if (sz == 4) s = 2;
      if (sz == 9) s = 3;
      if (sz == 16) s = 4;
      return s;
    }

當然出現的圖形是隨機的,直接用Random就可以做到。

記住無論什麼動作引起的圖形變化,包括移動、旋轉等都要用Refresh,以便刷新游戲界面。例如向左

public void moveLeft()
    {

      if (check(figure, px - 1, py)) px = px - 1;
      Refresh();//this.Refresh();
    }

protected override void OnPaint(PaintEventArgs e)這個熟悉吧?嗯,界面就是它畫出來的。你要在界面顯示什麼,就在裡面畫什麼。記住,是全部界面,因為我們的這個游戲沒有任何其他資源,沒有任何控件,只有圖形。

當然了,圖形位置移動必須要要檢查越界和是否遇到障礙物。也就是上述的check方法。基本思路就是圖形經過的位置中無越界並且無不為0的單元格存在。

bool check(int[,] fg, int x, int y)
    {
      int sz = conversize(fg.Length);

      for (int i = 0; i < sz; i++)
        for (int j = 0; j < sz; j++)
        {
          int rx = i + x;
          int ry = j + y;
          if ((rx < 0 || rx > 9 || ry < 0 || ry > 19) && fg[i, j] != 0) return false;
          if (!(rx < 0 || rx > 9 || ry < 0 || ry > 19))
            if (board[rx, ry] != 0 && fg[i, j] != 0) return false;
        }

      return true;
    }

旋轉怎麼實現?一個純數組倒序排列的簡單題目,不是嗎?

最後是游戲難度的問題,等級越高,降落速度越快,其實就是把等級數字跟計時器的Interval掛鉤就是了。

其他的就不多說了。有興趣的可以把它做成控件,方便大家使用。祝你玩的開心。

明天搞那個木馬記錄器……

本文出自 “王傑瑞的技術博客” 博客,請務必保留此出處http://wangjierui.blog.51cto.com/186879/56005

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved