本游戏素材和大部分代码都来自于《C#Windows游戏设计》一书中,在这里我只说明和记录一些关键方法。这些对大家来说比较熟悉的游戏,做起来也并不是很麻烦。
拼图游戏就是将一幅图片平均分成一些方块,然后随机将这些方块打乱。游戏运行效果如下图:
本游戏的难点在于随机打乱图片,这也是该游戏的核心算法,下面阐述一下如何实现:
首先举个例子,我们定义并初始化一个数组:
int[] a = new int[10];
//初始化数组a[10]
for (int i = 0; i < 10; i++)
a[i] = i + 1;
现在要随机打乱这个数组,方法是产生一个0~9的随机数,假设这个随机数为6,则交换a[6]与a[9],现在a[0]到a[9]分别为1、2、3、4、5、6、10、8、9、7
然后产生一个0~8的随机数x,交换a[x]与a[8];
产生一个0~7的随机数y,交换a[y]与a[7];
......
直到产生随机数的范围为1时停止,就将这个数组的次序彻底打乱了,而且每一项保证不会重复,就像抽奖程序,从50人里随机抽出10个人,如果你只是简单的使用代码:
PersonNum = GetRandom(50);
就很容易出现一个人被抽取两次甚至多次的结果,而拼图游戏绝对不允许在打乱之后有两个一模一样的小方块
上述思想的实现代码如下:
//随机打乱一个数组
int lenth = 10;
Random rd = new Random();
while (lenth >= 1)
{
//产生0~length-1之间的一个随机数index
int index = rd.Next(lenth);
//交换a[index]与a[lenth - 1]
int t = a[index];
a[index] = a[lenth - 1];
a[lenth - 1] = t;
lenth--;
}
这样就实现了打乱数组
该游戏将图片文件夹(GamePictures)与声音文件夹(GameSounds)均放在bin/Debug文件夹中,在解决方案中新建文件夹,加入了GetRandom与LoadBitmap类
游戏实现的步骤:
5.1界面尺寸的设计
5.2全局变量及相关类
5.3显示图片及方格
5.4为菜单项添加响应函数
5.5随机打乱图片
5.6响应用户输入(鼠标事件)
5.7处理游戏状态与添加声音
源代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//5.2添加
using PuzzleGame.BaseClass;
//5.7添加
using System.Runtime.InteropServices;
namespace PuzzleGame
{
public partial class FrmPuzzle : Form
{
public FrmPuzzle()
{
InitializeComponent();
}
//5.2 全局变量
readonly Color COLOR_SELECTED = Color.OrangeRed; //图片方块被选中的边框颜色
readonly Color COLOR_MOUSEMOVEIN = Color.MediumBlue; //鼠标移入方块的边框颜色
//以下几个全局变量在大部分游戏中都需要考虑到
readonly int[,] Difficulty = new int[,] { { 2, 3 }, { 3, 3}, { 3, 4 }, { 4, 4 }, { 4, 6 } }; //不同难度对应的行数和列数
int iGameLevel = 0; //游戏难度级别,开始时为0,即Difficulty的第一个数组2X3
bool bPlaySound = true; //是否开启声音,默认开启
string[] GameState=new string[]{"等待","运行","胜利","失败"}; //游戏状态所对应的字符串,在状态栏中显示
int iGameState = 0; //游戏状态,和GameState的索引对应,初始为"等待"
//int iGameLeaveTime = 0; //游戏剩余时间,在状态栏中显示
bool bUseMyPicture = false; //是否自选图片,默认为false
Bitmap[] bmpGrids = new Bitmap[24]; //位图数组,这里将其最大索引设置为最高级别的行数乘以列数4X6=24,当级别较低时,例如2X3时,后18个为空
readonly int bmpWidth = 840, bmpHeight = 600; //位图的宽度和高度
//5.3 全局变量
readonly int iWidth = 840, iHeight = 600; //图片的尺寸
readonly Point ptLeftTop = new Point(2, 26); //图片左上角的坐标
int iRowsCount=2,iColumnsCount=3; //图片在初始状态下被分成2X3个方块,当所选择的难度变化时,这两个变量也随之变化
string strMyPicturePath = &