当前位置:文档之家› 扫雷源码

扫雷源码

前言:扫雷游戏是Windows系统的一款经典游戏。搜索一下google,有94万条网页。包括本人也写过2个版本的扫雷游戏。其实我们注重的不是游戏本身,而是技术或者说是知识点。



先看看我要介绍的这款扫雷涉及哪些知识点。
1) 自定义控件
2) GDI+
3) 枚举
4) 集合
5) 属性
6) 递归
大致看来涉及这些。我在介绍的过程中尽量结合C#的知识点运用。
需求说明:
1) 有不同级别,不同级别有不同的砖块,地雷数也不同
2) 点击砖块,如果没有地雷显示周围地雷数
3) 右击砖块可以设置多种状态:标志、疑问、取消标志
4) 如果砖块周围无雷,则打开周围的无雷区
5) 鼠标移动到砖块上,砖块颜色变化


1.制作砖块
需求分析:
1) 为了实现“鼠标移动到砖块上,砖块颜色变化”,决定采用自定义控件,这样将每个砖块都作为一个控件,可以定义MouseEnter和MouseLeave事件
(1)创建自定义控件Brick
public partial class Brick : UserControl{
……
}
(2)定义砖块状态的枚举
public partial class Brick : UserControl{
///


///砖块状态
///

public enum BrickState {
UnSwept = 0, //未扫
Mark = 1, //标记
Unknow = 2, //未知
Swept = 3 //已扫
}
}
(3)定义一些成员变量。如:状态、周围地雷数、位置以及是否有地雷
(4)根据不同的状态,显示不同的图片。这里我采用了属性设置。通过setter访问器实现状态与背景图片的关联。
[DefaultValue("UnSwept"), Description("砖块状态"), Category("Appearance")]
public BrickState State {
get { return state; }
set {
state = value;
if(state == BrickState.UnSwept) {
BackgroundImage = images[0];
} else if(state == BrickState.Mark) {
BackgroundImage = images[1];
} else if(state == BrickState.Unknow) {
BackgroundImage = images[2];
} else if(state == BrickState.Swept && !IsMine) {
BackgroundImage = images[3];
} else if(state == BrickState.Swept && IsMine) {
BackgroundImage = images[11];
}
}
}
注意到[DefaultValue("UnSwept"), Description("砖块状态"), Category("Appearance")],这是为了让VS2005能看属性窗口中看到自定义的属性。
DefaultValue是默认值,Description是说明
(5)鼠标事件:鼠标移动砖块上(MouseEnter)、鼠标移出砖块(MouseLeave)、鼠标点击(左击、右击、左右同击)
这里说明一下,鼠标左右同击比较难以判断。现采用这种方式:当左键点击后记录下来,右键点击后也记录下来,再判断两个记录值,如果都为true表示左右同击。当鼠标键抬起时也要将记录改过来。
private void Brick_MouseEnter(object sender, EventArgs

e) {
if(state == BrickState.UnSwept) {
BackgroundImage = images[4];
}
}
private void Brick_MouseLeave(object sender, EventArgs e) {
if(state == BrickState.UnSwept) {
BackgroundImage = images[0];
}
}
bool leftButton = false, rightButton = false;
private void Brick_MouseDown(object sender, MouseEventArgs e) {
if(e.Button == MouseButtons.Left) {
leftButton = true;
} else if(e.Button == MouseButtons.Right) {
rightButton = true;
}
if(state == BrickState.Swept && leftButton && rightButton) {
//左右键同时双击数字
TogetherClick();
} else if(state != BrickState.Swept && leftButton) {
//左键未扫砖块
LeftClick();
} else if(state != BrickState.Swept && rightButton) {
//右键未扫砖块
RightClick();
}
}

private void Brick_MouseUp(object sender, MouseEventArgs e) {
if(e.Button == MouseButtons.Left) {
leftButton = false;
} else if(e.Button == MouseButtons.Right) {
rightButton = false;
}
}
(6)后面就是不同点击的逻辑问题
Code:
using System;
using System.Collections.Generic;
using https://www.doczj.com/doc/8f5226478.html,ponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace MineSweeper {
///


/// 砖块
///

public partial class Brick : UserControl {

///
/// 砖块状态
///

public enum BrickState {
UnSwept = 0,
Mark = 1,
Unknow = 2,
Swept = 3
}

private BrickState state;
private Bitmap[] images = new Bitmap[12];
private int arroundMines;
private int x;
private int y;
private bool isMine;

[DefaultValue("UnSwept"), Description("砖块状态"), Category("Appearance")]
public BrickState State {
get { return state; }
set {
state = value;
if (state == BrickState.UnSwept) {
BackgroundImage = images[0];
} else if (state == BrickState.Mark) {
BackgroundImage = images[1];
} else if (state == BrickState.Unknow) {
BackgroundImage = images[2];
} else if (state == BrickState.Swept && !IsMine) {
BackgroundImage = images[3];
} else if (state == BrickState.Swept && IsMine) {
BackgroundImage = images[11];
}
}
}
[DefaultValue("0"), Description("四周地雷数"), Category("Appearance")]
public int ArroundMines {

get { return arroundMines; }
set { arroundMines = value; }
}
[DefaultValue("0"), Description("距离左边的个数"), Category("Appearance")]
public int X {
get { return x; }
set { x = value; }
}
[DefaultValue("0"), Description("距离上方的个数"), Category("Appearance")]
public int Y {
get { return y; }
set { y = value; }
}
[DefaultValue("false"), Description("标记该砖块是否是地雷"), Category("Appearance")]
public bool IsMine {
get { return isMine; }
set { isMine = value; }
}

public Brick() {
InitializeComponent();

images[0] = global::MineSweeper.Properties.Resources.blank;
images[1] = global::MineSweeper.Properties.Resources.blank;
images[2] = global::MineSweeper.Properties.Resources.blank;
images[3] = global::MineSweeper.Properties.Resources.blankBack;
images[4] = global::MineSweeper.Properties.Resources.move;

images[5] = global::MineSweeper.Properties.Resources._1;
images[6] = global::MineSweeper.Properties.Resources._2;
images[7] = global::MineSweeper.Properties.Resources._3;
images[8] = global::MineSweeper.Properties.Resources._4;
images[9] = global::MineSweeper.Properties.Resources._5;
images[10] = global::MineSweeper.Properties.Resources._6;

images[11] = global::MineSweeper.Properties.Resources.mine;

BackgroundImageLayout = ImageLayout.Stretch;
BackgroundImage = images[0];
}



#region 鼠标相关事件
private void Brick_MouseEnter(object sender, EventArgs e) {
if (state == BrickState.UnSwept) {
BackgroundImage = images[4];
}
}
private void Brick_MouseLeave(object sender, EventArgs e) {
if (state == BrickState.UnSwept) {
BackgroundImage = images[0];
}
}
bool leftButton = false, rightButton = false;
private void Brick_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
leftButton = true;
} else if (e.Button == MouseButtons.Right) {
rightButton = true;
}
if (state == BrickState.Swept && leftButton && rightButton) {
//左右键同时双击数字
TogetherClick();
} else if (state != BrickState.Swept && leftButton) {
//左键未扫砖块

LeftClick();
} else if (state != BrickState.Swept && rightButton) {
//右键未扫砖块
RightClick();
}
}

private void Brick_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
leftButton = false;
} else if (e.Button == MouseButtons.Right) {
rightButton = false;
}
}

private void TogetherClick() {

}
private void LeftClick() {
if (IsMine) {
BackgroundImage = images[11];
} else {
if (ArroundMines == 0) {
BackgroundImage = images[3];
} else {
BackgroundImage = images[ArroundMines + 4];
}
SweepBricks(Y, X);
}
state = BrickState.Swept;
}
private void SweepBricks(int x, int y) {
int rows = Game.Bricks.GetLength(0);
int cols = Game.Bricks.GetLength(1);
if (x < 0 || x > rows - 1 || y < 0 || y > cols - 1)
return;
Brick brick = Game.Bricks[x, y];
if (brick.state == BrickState.UnSwept) {
if (brick.ArroundMines == 0) {
brick.BackgroundImage = images[3];
brick.state = BrickState.Swept;

SweepBricks(Y, X - 1);
SweepBricks(Y, X + 1);
SweepBricks(Y - 1, X);
SweepBricks(Y + 1, X);
} else {
brick.BackgroundImage = images[brick.ArroundMines + 4];
brick.state = BrickState.Swept;
}
}
}
private void RightClick() {
State = (BrickState)((((int)state) + 1) % 3);
}
#endregion




}
}



相关主题
文本预览
相关文档 最新文档