本文实例为大家分享了C#实现扫雷游戏的具体代码,供大家参考,具体内容如下
1、掌握c#窗体和控件的常用属性和功能
2、完成扫雷游戏的基本功能
1、游戏基本功能必须实现。鼠标左键点非雷点,否则游戏结束;鼠标右键一次标记雷点,右键二次取消标记。
2、可以对游戏设置
3、符合游戏逻辑。每个点周围的雷的个数必须正确
4、点开雷点,显示游戏结束,并且显示各个点的情况,还会显示排名
5、点开所有非雷点或者标记完所有雷点时,能够显示游戏胜利
6、不接受键盘操作,只接受鼠标操作
主窗体代码
private void Form1_Load(object sender, EventArgs e)
{
//初始化数据
numbers = new int[length, length];
isBomb = new bool[length, length];
isClicked = new bool[length, length];
isFlaged = new bool[length, length];
startTime = 0;
endTime = 0;
clickNumber = 0;
this.Text = "扫雷(大小:" + length + ",雷数:" + bombNumber + ")";
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
numbers[i, j] = 0;
isBomb[i, j] = false;
isClicked[i, j] = false;
isFlaged[i, j] = false;
}
}
//初始化按钮
btns = new Button[length * length];
//旗子数量
flagNumber = 0;
//显示按钮
int x0 = 5, y0 = 5, w = 30, d = w + 5;
for (int i = 0; i < btns.Length; i++)
{
Button btn = new Button();
int r = i / length; //行
int c = i % length; //列
btn.Left = x0 + c * d;
btn.Top = y0 + r * d;
btn.Width = w;
btn.Height = w;
btn.Font = new Font("楷体", 14);
btn.Visible = true;
btns[i] = btn;
this.pnlBoard.Controls.Add(btn);
btn.MouseDown += new System.Windows.Forms.MouseEventHandler(this.UpdateClick);
btn.Name = i.ToString();
}
}
protected void UpdateClick(object sender, MouseEventArgs e)
{
//获取按钮
Button button = (Button)sender;
//获取该位置数据
int placeMouse = int.Parse(button.Name);
//获取坐标
int x = placeMouse / length;
int y = placeMouse % length;
if (e.Button == MouseButtons.Left)
{
//MessageBox.Show(button.Name+" ("+x+","+y+")");
//等价于对button操作
//判断是否为初次点击
if (firstClick)
{
initialX = x;
initialY = y;
//将该位置更改为有地雷再进行生成
isBomb[x, y] = true;
/
/随机生成地图
GenerateMap();
//这个位置不可能是地雷啊喂!
isBomb[x, y] = false;
//不再是初次点击
firstClick = false;
}
//处理当前点击的按钮的信息
//按钮已被点击过
if (isClicked[x, y])
return;//直接返回
//点击了一次
clickNumber++;
//如果该位置是地雷
if (isBomb[x, y])
{
GameOver();//游戏结束
return;
}
//其他情况,特别对待
//被点击过了
isClicked[x, y] = true;
//更改色调,以区分点击与未点击
button.BackColor = Color.DarkGray;
//显示地图
if (numbers[x, y] != 0)
button.Text = numbers[x, y].ToString();
spreadMap(x, y);
//点击获胜
if(clickNumber==length*length-bombNumber)
{
GameWin();
}
}
else if (e.Button == MouseButtons.Right)
{
//点击过了,就直接跳过
if (isClicked[x, y] == true)
return;
if(isFlaged[x,y]==false)
{
// 显示炸弹图
button.BackgroundImage = Image.FromFile(flagPath);
//标记
isFlaged[x, y] = true;
//插旗数量++
flagNumber++;
}
else
{
//撤回标记
button.BackgroundImage = null;
isFlaged[x, y] = false;
flagNumber--;
}
//判断是否能通过插旗获得游戏胜利
if (flagNumber==bombNumber)
{
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
if (isFlaged[i, j] == false)
continue;
if (isBomb[i, j] == false)
return;//插旗错误,无法获得游戏胜利
}
}
//执行到这个语句表明找对了
GameWin();
}
}
}
public void GameOver()
{
//显示地图全貌
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
//如果之前被插了旗子
if (isFlaged[i, j] == true)
{
isFlaged[i, j] = false;
btns[i * length + j].BackgroundImage = null;
}
if (isClicked[i, j] == true)
continue;
//更改色调,以区分点击与未点击
btns[i*length+j].BackColor = Color.DarkGray;
//全部设置为完成点击
isClicked[i, j] = true;
//如果是炸弹
if (isBomb[i, j])
{
btns[i * length + j].BackgroundImage = Image.FromFile(bombPath,true);
continue;
}
//显示地图
if (numbers[i, j] != 0)
btns[i * length + j].Text = numbers[i, j].ToString();
}
}
MessageBox.Show("你输了!");
RestartGame(bombNumber, length);
}
public void GameWin()
{
//显示地图全貌
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
//如果之前被插了旗子
if (isFlaged[i, j] == true)
{
isFlaged[i, j] = false;
btns[i * length + j].BackgroundImage = null;
}
if (isClicked[i, j] == true)
continue;
//更改色调,以区分点击与未点击
btns[i * length + j].BackColor = Color.DarkGray;
//全部设置为完成点击
isClicked[i, j] = true;
//如果是炸弹
if (isBomb[i, j])
{
btns[i * length + j].BackgroundImage = Image.FromFile(bombPath, true);
continue;
}
//显示地图
if (numbers[i, j] != 0)
btns[i * length + j].Text = numbers[i, j].ToString();
}
}
游戏胜利__ fp = new 游戏胜利__(length, bombNumber, endTime - startTime);
fp.Owner = this;
this.Hide();
fp.ShowDialog();
}
//以x,y为起点扩展地图
public void spreadMap(int x,int y)
{
//判断该位置的八个方向
//左上
if (x != 0 && y != 0 && isBomb[x - 1, y - 1] == false && isClicked[x - 1, y - 1] == false)
{
//点击过了
isClicked[x - 1, y - 1] = true;
//更改色调,以区分点击与未点击
btns[(x - 1) * length + y - 1].BackColor = Color.DarkGray;
//点击次数
clickNumber++;
if (isFlaged[x-1, y-1] == true)
{
isFlaged[x-1, y-1] = false;
btns[(x - 1) * length + y - 1].BackgroundImage = null;
}
if (numbers[x - 1, y - 1] != 0)
btns[(x - 1) * length + y - 1].Text = numbers[x - 1, y - 1].ToString();
else
{
//非零需要继续拓展
spreadMap(x - 1, y - 1);
}
}
//正上
if (x != 0 && isBomb[x - 1, y] == false && isClicked[x - 1, y ] == false)
{
//点击过了
isClicked[x - 1, y] = true;
//更改色调,以区分点击与未点击
btns[(x - 1) * length + y].BackColor = Color.DarkGray;
//点击次数
clickNumber++;
if (isFlaged[x - 1, y ] == true)
{
isFlaged[x - 1, y - 1] = false;
btns[(x - 1) * length + y ].BackgroundImage = null;
}
if (numbers[x - 1, y] != 0)
btns[(x - 1) * length + y].Text = numbers[x - 1, y].ToString();
else
{
//非零需要继续拓展
spreadMap(x - 1, y);
}
}
//右上
if (x != 0 && y!=length-1&&isBomb[x - 1, y+1] == false && isClicked[x - 1, y + 1] == false)
{
//点击过了
isClicked[x - 1, y + 1] = true;
//更改色调,以区分点击与未点击
btns[(x - 1) * length + y + 1].BackColor = Color.DarkGray;
//点击次数
clickNumber++;
if (isFlaged[x - 1, y + 1] == true)
{
isFlaged[x - 1, y + 1] = false;
btns[(x - 1) * length + y + 1].BackgroundImage = null;
}
if (numbers[x - 1, y + 1] != 0)
btns[(x - 1) * length + y + 1].Text = numbers[x - 1, y + 1].ToString();
else
{
//非零需要继续拓展
spreadMap(x - 1, y + 1);
}
}
//正左方
if (y != 0 && isBomb[x, y - 1] == false && isClicked[x , y - 1] == false)
{
//点击过了
isClicked[x, y - 1] = true;
//更改色调,以区分点击与未点击
btns[x * length + y - 1].BackColor = Color.DarkGray;
//点击次数
clickNumber++;
if (isFlaged[x , y - 1] == true)
{
isFlaged[x , y - 1] = false;
btns[x * length + y - 1].BackgroundImage = null;
}
if (numbers[x, y - 1] != 0)
btns[x * length + y - 1].Text = numbers[x, y - 1].ToString();
else
{
//非零需要继续拓展
spreadMap(x, y - 1);
}
}
//正右方
if (y != length - 1 && isBomb[x, y + 1] == false && isClicked[x, y + 1] == false)
{
//点击过了
isClicked[x, y + 1] = true;
//更改色调,以区分点击与未点击
btns[x * length + y + 1].BackColor = Color.DarkGray;
//点击次数
clickNumber++;
if (isFlaged[x, y + 1] == true)
{
isFlaged[x, y + 1] = false;
btns[x * length + y + 1].BackgroundImage = null;
}
if (numbers[x, y + 1] != 0)
btns[x * length + y + 1].Text = numbers[x, y + 1].ToString();
else
{
//非零需要继续拓展
spreadMap(x, y + 1);
}
}
//左下方
if (x != length - 1 && y != 0 && isBomb[x + 1, y - 1] == false && isClicked[x + 1, y - 1] == false)
{
//点击过了
isClicked[x + 1, y - 1] = true;
//更改色调,以区分点击与未点击
btns[(x + 1) * length + y - 1].BackColor = Color.DarkGray;
//点击次数
clickNumber++;
if (isFlaged[x + 1, y - 1] == true)
{
isFlaged[x + 1, y - 1] = false;
btns[(x + 1) * length + y - 1].BackgroundImage = null;
}
if (numbers[x + 1, y - 1] != 0)
btns[(x + 1) * length + y - 1].Text = numbers[x + 1, y - 1].ToString();
else
{
//非零需要继续拓展
spreadMap(x + 1, y - 1);
}
}
//正下方
if (x != length - 1 && isBomb[x + 1, y] == false && isClicked[x + 1, y] == false)
{
//点击过了
isClicked[x + 1, y] = true;
//更改色调,以区分点击与未点击
btns[(x + 1) * length + y].BackColor = Color.DarkGray;
//点击次数
clickNumber++;
if (isFlaged[x + 1, y ] == true)
{
isFlaged[x + 1, y ] = false;
btns[(x + 1) * length + y ].BackgroundImage = null;
}
if (numbers[x + 1, y] != 0)
btns[(x + 1) * length + y].Text = numbers[x + 1, y].ToString();
else
{
//非零需要继续拓展
spreadMap(x + 1, y);
}
}
//右下方
if (x != length - 1 && y != length - 1 && isBomb[x + 1, y + 1] == false && isClicked[x + 1, y + 1] == false)
{
//点击过了
isClicked[x + 1, y + 1] = true;
//更改色调,以区分点击与未点击
btns[(x + 1) * length + y + 1].BackColor = Color.DarkGray;
//点击次数
clickNumber++;
if (isFlaged[x + 1, y + 1] == true)
{
isFlaged[x + 1, y + 1] = false;
btns[(x + 1) * length + y + 1].BackgroundImage = null;
}
if (numbers[x + 1, y + 1] != 0)
btns[(x + 1) * length + y + 1].Text = numbers[x + 1, y + 1].ToString();
else
{
//非零需要继续拓展
spreadMap(x + 1, y + 1);
}
}
//返回
return;
}
private void 新游戏ToolStripMenuItem_Click(object sender, EventArgs e)
{
//MessageBox.Show()
RestartGame(bombNumber, length);
}
扫雷界面
插红旗样式展示
输赢展示
游戏设置展示
排行榜展示