轉載請标明是引用于 http://blog.csdn.net/chenyujing1234
例子代碼:
http://www.rayfile.com/zh-cn/files/9d09926e-736b-11e1-b9a4-0015c55db73d/
設計思路:
由10*10組成,圖案更不相同,為存儲遊戲畫面中的圖案方塊,采用Block類二維數組blocks[10,10];
在定時器控制下,不停地統計使用者的得分,并控制生命進度條,如果生命進度條為0,則遊戲結束。
當使用者滑鼠連續選中兩相鄰塊firstblock2和secondblock2,交換以後調用check()檢測是否有符合消去
的方塊,如果有被消去的方塊則修改要繪制的圖案代号rectan2[10,10]數組對應的元素值,不需要繪制為0.
通過按列統計rectan2數組0值,得出每列被消去的方塊的個數,并調用fill()從遊戲螢幕該列上方重新随機産生新的方塊,
依次下移填充被削去方塊,重畫需要繪制的所有方塊,進而看到動态效果。
下面介紹設計過程:
1、建立一C# windows窗體工程。
将Form1.cs改名為Start.cs
在解決方案中添加兩個檔案平:images sound并把相關圖檔與聲音資源包含進來.
給Start窗體的ICON選擇圖檔小狗.ico
2、窗體Start.cs添加新控件
progressBar記得value值選100
在加載聲音pictureBox時為Image屬性選擇圖檔
在加入了statusStrip contextMenuStrip timer1後,接下來為statusStrip添加toolStripDropDownButton
方法是右擊statusSctrip1右選擇編輯項,然後從清單中選擇toolStripDropDownButton1然後點添加
3、界面算是畫好了,接下來開始進行代碼設計.
建立Block.cs檔案來定義方塊的坐标位置、小方塊圖案、圖案種類代号字段成員及通路相應的屬性.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using SuperPeng.Properties;
namespace SuperPeng
{
/*本類描述的對象是對對碰的每個小方塊*/
class Block
{
private Point location; //小方塊坐标
private Bitmap blockImage; //小方塊圖案
private int imageType; //圖檔種類
public int ImageType//ImageType屬性
{
get
{
return imageType;
}
}
public Point Location//Location屬性
{
get
{
return location;
}
set
{
location= value;
}
}
public Block(int imageIndex,int x,int y)
{
location = new Point(x, y);
imageType = imageIndex;
//初始化小方塊圖案
switch (imageIndex)
{
case 1:
blockImage = Resources._1;
break;
case 2:
blockImage = Resources._2;
break;
case 3:
blockImage = Resources._3;
break;
case 4:
blockImage = Resources._4;
break;
case 5:
blockImage = Resources._5;
break;
case 6:
blockImage = Resources._6;
break;
case 7:
blockImage = Resources._7;
break;
case 8:
blockImage = Resources._8;
break;
default:
blockImage = Resources._4;
imageType = 4;
break;
}
}
/*畫對象*/
public void Draw(Image img)
{
Graphics g = Graphics.FromImage(img);
Rectangle r = new Rectangle(location, new Size(50, 50));
g.DrawImage(blockImage, r);
}
public void DrawSelectedBlock(Graphics g)
{
//畫選中方塊的示意邊框線
Pen myPen = new Pen(Color.Black, 3);
Rectangle r = new Rectangle(location, new Size(50, 50));
g.DrawRectangle(myPen, r);
}
public void ClearSelectedBlock(int x, int y, Graphics g)
{
//清除選中方塊
}
}
}
Block()構造函數,參數提供了方塊圖案種類的代号imageIndex 及坐标位置(x,y),該構造函數中Switch(/case根據方塊種類代号設定相應的方塊圖案。
Draw(方法将方塊畫在Image對象上,而不是遊戲面闆上,這樣便于采用雙緩沖技術。
DrawSelectedBlock将方塊周圍選中的示意邊框線,這是直接畫在傳遞過來的遊戲面闆上,而不是IMage對象上
4、接下來設計GameField.cs。
它是遊戲執行個體,首先定義在遊戲面闆中存儲所有方塊的容器 ---- 二維數組 blocks[10,10],記錄要繪制方塊的圖案代号rectan2[10,10]數組
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Media;
using SuperPeng.Properties;
namespace SuperPeng
{
/*
* 場景大小:500×500
* 方塊大小:50×50
*/
class GameField
{
public IntPtr winHandle;
public Image bufferImage; //雙緩存
public Block[,] blocks=new Block[10,10]; //場景中所有的小圖檔
//存儲繪制的方塊圖案帶代号的數組,不需繪制的值為0
private int[,] rectan2 = new int[10, 10];
private int[] empty = new int[10];//每列有多少個可以消去方塊
private int RowSames = 1; //檢測到同行相同數
private int ColumSames = 1; //檢測到同列相同數
private SoundPlayer sound = new SoundPlayer();
public bool soundSwitch = true;//聲音開關 true為開
遊戲場景類GameField中生成場景中所有的Block方塊對象,調用createAll畫在遊戲面闆中
/*生成場景中所有的對象*/
public void createAll()
{
Random rand = new Random();
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
{
Block b = new Block(rand.Next(8) + 1, j * 50, i * 50);
blocks[i, j] = b;
//rectan[i,j] = b.ImageType;//******************7-06
rectan2[i, j] = b.ImageType;
}
reDraw();
}
reDraw();采用雙緩沖技術。先将所有的方塊繪制在Image對象bufferImage上,然後将繪制好的bufferImage顯示在遊戲面闆上.
exchange(int x1, int y1, int x2, int y2)交換選中兩個相鄰的方塊
/*交換兩個方塊,參數x,y為矩陣坐标*/
public void exchange(int x1, int y1, int x2, int y2)
{
//交換blocks
Block temp = blocks[x1, y1];
blocks[x1, y1] = blocks[x2, y2];
blocks[x2, y2] = temp;
交換rectan //******************7-06
//rectan[x1, y1] = blocks[x1, y1].ImageType;
//rectan[x2, y2] = blocks[x2, y2].ImageType;
//交換rectan2
rectan2[x1, y1] = blocks[x1, y1].ImageType;
rectan2[x2, y2] = blocks[x2, y2].ImageType;
//交換坐标
Point tmploc = blocks[x1, y1].Location;
blocks[x1, y1].Location = blocks[x2, y2].Location;
blocks[x2, y2].Location = tmploc;
PlaySound("Exchange");
//重畫一下
reDraw();
}
check()完成檢測是否有3上以上方塊對象有相同的圖像并傳回可以消除的方塊個數。
若有超過3個(含3個)則儲存要繪制方塊的圖案代号的rectan2[10,10]數組對應元素的值為0,通過統計rectan2數組0值,
得出每列被消去方塊的個數及所有列被消去方塊的總線.
/*對對碰檢測,傳回可以消除方塊對象的個數*/
public int check()
{
//檢測是否同行或列有超過3個一樣
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
//for内開始
//行檢測
if (j == 0)
RowSames = 1;
else
{
if (blocks[i, j - 1].ImageType == blocks[i, j].ImageType)//圖案相同
RowSames++;
else
{
if (RowSames >= 3)
{
//該位置之前rowsames個格子的物體都要消除
for (int n = 1; n <= RowSames; n++)
rectan2[i, j - n] = 0;
}
RowSames = 1;
}
if (j==9&&RowSames >= 3)
{
//該位置之前rowsames個格子的物體都要消除
for (int n = 1; n <= RowSames; n++)
rectan2[i, 10 - n] = 0;
}
}
//列檢測
if (j == 0)
ColumSames = 1;
else
{
if (blocks[j - 1, i].ImageType == blocks[j, i].ImageType)//圖案相同
ColumSames++;
else
{
if (ColumSames >= 3)
{
//該位置之上的columsames個格子的物體要消除
for (int n = 1; n <= ColumSames; n++)
rectan2[j - n, i] = 0;
}
ColumSames = 1;
}
if (j==9&&ColumSames >= 3)
{
//該位置之前rowsames個格子的物體都要消除
for (int n = 1; n <= ColumSames; n++)
rectan2[10 - n, i] = 0;
}
}
//for内結束
}
}
RowSames = 1;
ColumSames = 1;
//檢測每列有多少個空格
int temp=0;
int result = 0;//總和
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (rectan2[j, i] == 0)
temp++;
}
empty[i] = temp;
result += temp;
temp = 0;
}
//reDraw();
return result;
}
fill()從遊戲螢幕該列上方重新随機産生新的方塊,依次下移填充被削去的方塊,重畫需要繪制的所有方塊
/*生成填補*/
public void fill()
{
Random rand = new Random();
for (int j = 0; j < 10;j++ ) //每列
{
if(empty[j] > 0)
{
for (int i = 0; i < 10; i++) //每行
{
while(rectan2[i, j] == 0)
{
if (i >0)
{//空格之後的所有圖檔向下移一位
for (int n = i-1; n>=0; n--)
down(n,j);
}
//填充最頂上一格方塊
Block tb = new Block(rand.Next(8) + 1, j * 50,0 );
blocks[0, j] = tb;
//rectan[0, j] = tb.ImageType;
rectan2[0, j] = tb.ImageType;
}
}
//本來想在這裡重畫,不料令遊戲速度太慢
}
}
PlaySound("AddScore");
//重畫一下
reDraw();
}