试验效果如图9:
图9 打乱效果图
1. 玩家交换图片
点击图片格,实现拼图。
private void pictureclick(object sender, System.EventArgs e)
{
PictureBox current = (PictureBox)sender; //出箱技术 将参考类型 转为实体类型
int number = int.Parse(current.Name);
//当前图片下方有可以交换的图片
int down = number + int.Parse(Math.Sqrt(modeselect).ToString());
if (down < modeselect & changeway[down] == -1)
{
picturebox[down].Image = current.Image;
picturebox[number].Image = null;
changeway[down] = changeway[number];
changeway[number] = -1;
copy(number); //备份玩家改变的图片轨迹
stop.Set();
return;
}
//当前图片上方有可以交换的图片
int up = number - int.Parse(Math.Sqrt(modeselect).ToString());
if (up > -1 & changeway[up] == -1)
{
picturebox[up].Image = current.Image;
picturebox[number].Image = null;
changeway[up] = changeway[number];
changeway[number] = -1;
copy(number); //备份玩家改变的图片轨迹
stop.Set();
return;
}
int left = number - 1;
if ((left >-1) & (number % int.Parse(Math.Sqrt(modeselect).ToString()) != 0) & changeway [left]==-1) //当前图片可以跟左边的图片交换
{
picturebox[left].Image = current.Image;
picturebox[number].Image = null;
changeway[left] =changeway [ number];
changeway[number] = -1;
copy(number); //备份玩家改变的图片路径
stop.Set();
return;
}
//当前图片可以跟右边的图片交换
int right = (number + 1);
if (((right %4) != 0) & changeway [right]==-1)
{
picturebox[right].Image = current.Image;
picturebox[number].Image = null;
changeway[right] = changeway[number];
changeway[number] = -1;
copy(number);
stop.Set();
return;
}
}
2. 判断拼图是否成功
检查两个数组是否相等,该过程在新线程中执行(因为是时时运算,运算量较大,不将其放在主界面中,确保主界面不出现假死现象)。
下面的局部代码说明了:在游戏图片打乱后,开启判断图片是否拼成功的线程。
…
if (!isrun) //确保运行一次程序,只启动一个线程
{
checkscucess = new Thread(new ThreadStart(this.jj)); //jj函数用于判断数组是否相等,确定是否拼图成功
checkscucess.Start();//开启线程,
isrun = true;
}
…
//检查两个数组是否相等
private void jj()
{
do
{
stop.WaitOne(); // 手动同步
int number = 0;
for (int i = 0; i < modeselect; i++) //检查是否两个数组相等
{
if (changeway[i] == check[i])
{
number = number + 1;
}
}
if (number == modeselect)
{
counttotaltime.Enabled = false;
MessageBox.Show("恭喜你:拼图成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
threadbool = true;
}
stop.Reset();
} while (true);
}
3. 录入数据并排名
当拼图成功后,就会跳出录入信息的窗口,其中时间和难度由游戏生成,玩家只要输入姓名,本软件不允许用户输入中文,这个限制看个人爱好了,读者也可以自己将这个限制去掉。
原理:先将玩家本次的游戏信息录入,再提取所有的信息,将其排名,并取前十名,将其输出,最后将排序好的前十名数据再次保存至文件中(覆盖原始数据)。
private void submit_Click(object sender, EventArgs e) //写入数据 ,读取所有数据(以便进行排序)
{
if (nametext.Text.Trim() != "")
{
string file = ":" + (nametext.Text).Trim() + ":" + degreetext.Text.Trim() + ":" + w.ToString();
write(file); //写入玩家本次的游戏信息
FileStream rd = new FileStream(Application .StartupPath + "\\grade.dat", FileMode.Open, FileAccess.Read); //读出所有的数据
byte[] bterd = new byte[rd.Length];
rd.Read(bterd, 0, int.Parse(rd.Length.ToString()));
p = Encoding.UTF8.GetString(bterd);
rd.Close();
submit.Enabled = false;
tiqunumber();//这里是提取数据流里面的数据,并将每个人的信息组合放在一起。
}
else
{
nametext.Focus();
MessageBox.Show("提交失败,请你输入你的姓名", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
//禁止输入中文
private void nametext_KeyPress(object sender, KeyPressEventArgs e)
{
if ((e.KeyChar >= '0' && e.KeyChar <= '9') | (e.KeyChar > 'A' && e.KeyChar < 'z') | (e.KeyChar == 0x8)|(e.KeyChar ==20))
{
e.Handled = false;
}
else
{
e.Handled = true;
}
}
//由于本部分不是本文的主要部分,是游戏附加的排名功能,详细代码,请读者下载阅读
public void tiqunumber() //提取字符 将每组记录放到一个数组里面去
{
。。。。。。。。。。。//省略
paixu();
}
public void paixu() //排序 ,显示结果
{
。。。。。。。。。//省略
writedatetofile(); //保存排序好的文件
}
public void writedatetofile()//保存排序好的文件
{
。。。。。。。。。。。。。。//省略
}
|