猜猜看C#小游戏
一、最终成果(演示截图)
1.开始界面
2.数据库表
3.题目表设计
4.题目表部分内容
5.图片表设计
6.图片表部分内容
7.随机产生题目
8.答题正确后直接到下一题
9.答题错误后停留在本题知道答对
二、开发过程
1. 建立名为guess的winform项目。
2. 功能分析:
1) 开始后点击按钮随机产生一个题目,并且显示出来。
2) 图片显示
a. 随机产生三张图片并且显示出来。
b. 从中随机选一张出来作为正确答案。并显示对应的题目。
3) 答案验证。并显示出来。
4) 统计答题正误次数并显示出来。
3. 数据库设计。
4. 通过工具栏添加控件:三个pictureBox、一个“产生题目”button、8个label。
5. 设置控件属性。如pictureBox原始图片,每个pictureBox附上一个label用来标记图片ID的一个数组元素,一个label用来显示题目,一个label显示答题的正确性,两个label用来计数答对或答错题目的次数显示等。
所有控件:
6.代码实现功能。
三、设计完的界面如下:
四、开发后的感受与体会
这个学期的C#课程是从一个听闻开始的-丁老师。第一节课我对舒适区到学习区的认识极为深刻。下面我先对我这次课程设计做一下简短的总结,其实题目是一开始就拿到的,那时候还是一点计划都没有的,随着课程的进行我开始有所思考。同时也开始了初步的设计,先是在网上找到一些资料,资料的内容主要是有关的项目以及他们的思想,比如说我参考了《疯狂猜图》这种游戏,他们是填字游戏,而我的需求分析里面要求的是题目加上选项,是选择题。需求分析的撰写,我主要从功能入手,如何随机产生题目,产生题目后如何随机产生一个正确答案,答案如何判断。题目和图片也要怎么存取,于是我用了数据库来存取这些数据。用到数据库我就得想一个简单一点的办法不要每次存取都要写数据库打开关闭的代码,于是我就把数据库操作封装到一个工具类里面,到时候只需要调用就可以方便使用。而且为了方便使用我还把图片和题目封装到对象类里,以后每一次存取只需要调用对象就可以取到任何图片或题目的信息。最后当然就是要美化和让用户操作简单化,实现更好的交互。我查看了一下相关的控件操作的文档,然后就做出了自己的初步界面。
以上是我此次课程设计的简单总结,下面是我对C#变程的一点小体会。对于编程我觉得大多数人都是从过程化到对象过渡的。然而对于我来说对象似乎更加符合我的口味,但是这次我还没有很大程度上对象化我的项目,比如我还没有把交互部分封装,还有些相应的方法也还没有封装。我只是觉得有些部分并不需要保密(私有化),所以就可以把他们放在公有部分,人人都可以取用。万物皆对象,我觉得这是很有道理的,代码里面的每一个部分我们都是可以写成一个对象的。就像这个小游戏,用户我们可以把他作为一个对象具有打开游戏,关闭游戏、随机产生题目、选答案这些功能。而数据库也是一个对象,我们可以封装增删查改这些操作到里面。图片题目也是对象把它们的属性封装好。这样我们这个游戏里面只有一个个的对象,我们剩下要做的就是要拼装整合,开发所需要的功能,和有趣的交互。不仅仅如此,对象还可以继承,如果日后想到新的功能还可以继承原来功能和扩展更多新的内容。总的来说我希望我的游戏因为对象变得简单,变得好玩。
困难,开发过程最难以避免的就是瓶颈,就像开始所说的学习区是让人很不舒适的,遇到棘手的问题我往往是先从网上搜索解决的方法,然后再问大神们。其实搜索引擎虽然很给力,我发现其中的诀窍还是要知其所以,懂得写大概然后才能够提出合适的问题。在访问搜索引擎的过程中我学习到了一些扩展的东西,比如我把MVC模式里面的数据库操作封装带到我的开发里面来,而且我只需要改动一下之前的代码而已。我尝试了用uml建立相关模型,让我的思路可以直观的显示出来。指点,在一些跟同学的交流里我受到很多指点,我原本的开发是一种散乱的过程处理,一步一步来,等我把代码越写愈多的时候自己也开始混乱了,特别是隔了很多天回去看的时候。有一个人他告诉我他把一个对象封装起来,很容易就调用起来了。我才恍然大悟,于是我脑袋里一堆之前积累的东西涌现了出来。比如数据库操作封装、方法封装等。
最后,就是谨记逃离舒适区,扩展舒适区。
五、核心代码实现
(一)随机数产生工具类:
产生指定数量的在一定范围内的随机数,比如我在主函数里面调用GetRandom(3,1,33)来产生33个大于1小于6的随机数。
另外我还用了一个Api里面的方法Next()来产生一个随机数,用来在产生的三张图片中随机选一个作为正确答案。
class RandomUtils
{
public int[]GetRandom( int count,intminValue, int maxValue)
{
Random rnd = new Random();
int length = maxValue - minValue + 1;
byte[] keys = new byte[length];
rnd.NextBytes(keys);
int[] items = new int[length];
for (int i = 0; i< length; i++)
{
items[i] = i + minValue;
}
Array.Sort(keys, items);
int[]result = new int[count];
Array.Copy(items, result, count);
return result;
}
}
<span style="white-space:pre"> </span>Random ran = new Random(); //在三张图片中随机产生一个正确答案
int qid = ran.Next(1, 4);
(二)数据库实现工具类:
1)得到图片信息
主要用到"select* from picinfo查询图片信息,将查询结果放到一个图片对象里面。
三个方法:
1)public Picture getPic()无参数方法
2)public PicturegetPic(int id)通过ID号查询并返回一个图片对象
3)public Picture[]getPic(int[] id)通过ID号数组查询并返回一个对应的图片对象数组
public Picture getPic()
{
Picture p = new Picture();
conn = getConnection();
string sql = "select* from picinfo";
MySqlCommand cmd = newMySqlCommand(sql,conn);
MySqlDataReader mdr = cmd.ExecuteReader();
while (mdr.Read())
{
p.PicAddr = mdr["PicAddr"].ToString();
p.PicName = mdr["PicName"].ToString();
p.PicId = mdr["PicId"].ToString();
}
return p;
}
public PicturegetPic(int id)
{
Picture p = new Picture();
conn = getConnection();
string sql = "select* from picinfo where picId="+id;
MySqlCommand cmd = newMySqlCommand(sql, conn);
MySqlDataReader mdr = cmd.ExecuteReader();
while (mdr.Read())
{
p.PicAddr = mdr["PicAddr"].ToString();
p.PicName = mdr["PicName"].ToString();
p.PicId = mdr["PicId"].ToString();
}
return p;
}
public Picture[]getPic(int[] id)
{
Picture[] p = {
getPic(id[0]),getPic(id[1]),getPic(id[2])
};
return p;
}
2)得到题目信息
主要用到"select* from question
查询图片信息,将查询结果放到一个图片对象里面。
两个方法:
1)public Question getQuestion()无参数方法
2)public QuestiongetQuestion(int id)通过ID号查询并返回一个题目对象
public Question getQuestion()
{
Question q = new Question();
conn = getConnection();
string sql = "select* from question";
MySqlCommand cmd = newMySqlCommand(sql,conn);
MySqlDataReader mdr = cmd.ExecuteReader();
while (mdr.Read())
{
q.Qid = mdr["Qid"].ToString();
q.Quest = mdr["question"].ToString();
q.Ctanswer = mdr["ctaPic"].ToString();
}
return q;
}
public QuestiongetQuestion(int id)
{
Question q = new Question();
conn = getConnection();
string sql = "select* from question where Qid="+id;
MySqlCommand cmd = newMySqlCommand(sql, conn);
MySqlDataReader mdr = cmd.ExecuteReader();
while(mdr.Read())
{
q.Qid = mdr["Qid"].ToString();
q.Quest = mdr["question"].ToString();
q.Ctanswer = mdr["ctaPic"].ToString();
}
return q;
}
(三)信息封装的类:
1)封装图片信息的类publicclass Picture
private string picAddr;
private stringpicName;
private string picId;
2)封装题目信息的类publicclass Question
<span style="white-space:pre"> </span>private string qid;
private string quest;
private stringctanswer;
(四)一个正确性判断方法:publicbool isCorrect(LabelyourLabel)
六、源代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data;
using MySql.Data.MySqlClient;
namespace guess
{
public partial class Form1 : Form
{
static int count = 0;
static int wrong = 0;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
RandomUtils rd = new RandomUtils();
int[] r = rd.GetRandom(3,1,33); //产生三个大于1小于6的随机数
DButils db = new DButils();
//string picName = db.getPic(r[1]).PicAddr;
Picture[] p = db.getPic(r); //得到三个图片对象
show(p); //显示随机产生id号对应的图片
Random ran = new Random(); //在三张图片中随机产生一个正确答案
int qid = ran.Next(1, 4);
//MessageBox.Show(qid.ToString());
Question q = db.getQuestion(r[qid-1]);
label1.Text = q.Quest;
label5.Text = q.Qid;
//string picName = "original_oVLC_54f000015136125c.jpg";
//show(picName);
}
public void show(string picName)
{
string Path = @"D:\用户目录\我的文档\Visual Studio 2010\Projects\guess\guess\image\" + picName;
//在pictureBox控件中显示你的图片
pictureBox2.Image = Image.FromFile(Path);
}
public void show(string[] picNames)
{
string[] Path = null;
for (int i = 0; i <= picNames.Length; i++)
{
Path[i] = @"D:\用户目录\我的文档\Visual Studio 2010\Projects\guess\guess\image\" + picNames[i];
}
//在pictureBox控件中显示你的图片
pictureBox1.Image = Image.FromFile(Path[0]);
pictureBox2.Image = Image.FromFile(Path[1]);
pictureBox3.Image = Image.FromFile(Path[2]);
}
public void show(Picture[] p)
{
string s1 = @"D:\用户目录\我的文档\Visual Studio 2010\Projects\guess\guess\image\" + p[0].PicAddr;
label2.Text = p[0].PicId;
string s2 = @"D:\用户目录\我的文档\Visual Studio 2010\Projects\guess\guess\image\" + p[1].PicAddr;
label3.Text = p[1].PicId;
string s3 = @"D:\用户目录\我的文档\Visual Studio 2010\Projects\guess\guess\image\" + p[2].PicAddr;
label4.Text = p[2].PicId;
string[] Path = {s1,s2,s3};
//在pictureBox控件中显示你的图片
pictureBox1.Image = Image.FromFile(Path[0]);
pictureBox2.Image = Image.FromFile(Path[1]);
pictureBox3.Image = Image.FromFile(Path[2]);
}
//用来产生随机数的类
class RandomUtils
{
//产生count个大于minValue小于maxValue的随机数
public int[] GetRandom( int count,int minValue, int maxValue)
{
Random rnd = new Random();
int length = maxValue - minValue + 1;
byte[] keys = new byte[length];
rnd.NextBytes(keys);
int[] items = new int[length];
for (int i = 0; i < length; i++)
{
items[i] = i + minValue;
}
Array.Sort(keys, items);
int[] result = new int[count];
Array.Copy(items, result, count);
return result;
}
}
//数据库操作工具类
class DButils
{
MySqlConnection conn;
//打开数据库连接
public MySqlConnection getConnection()
{
string strConn = "server=localhost;uid=root;password=123456;database=guess"; //根据自己的设置
conn = new MySqlConnection(strConn);
conn.Open();
// MessageBox.Show("数据库打开!");
return conn;
}
//关闭数据库连接
public void dbClose()
{
if (conn.State==ConnectionState.Open)
{
conn.Close();
MessageBox.Show("数据库已关闭!");
}
}
//得到图片对象信息
public Picture getPic()
{
Picture p = new Picture();
conn = getConnection();
string sql = "select * from picinfo";
MySqlCommand cmd = new MySqlCommand(sql,conn);
MySqlDataReader mdr = cmd.ExecuteReader();
while (mdr.Read())
{
p.PicAddr = mdr["PicAddr"].ToString();
p.PicName = mdr["PicName"].ToString();
p.PicId = mdr["PicId"].ToString();
}
return p;
}
public Picture getPic(int id)
{
Picture p = new Picture();
conn = getConnection();
string sql = "select * from picinfo where picId="+id;
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlDataReader mdr = cmd.ExecuteReader();
while (mdr.Read())
{
p.PicAddr = mdr["PicAddr"].ToString();
p.PicName = mdr["PicName"].ToString();
p.PicId = mdr["PicId"].ToString();
}
return p;
}
public Picture[] getPic(int[] id)
{
Picture[] p = {
getPic(id[0]),getPic(id[1]),getPic(id[2])
};
return p;
}
//得到题目对象信息
public Question getQuestion()
{
Question q = new Question();
conn = getConnection();
string sql = "select * from question";
MySqlCommand cmd = new MySqlCommand(sql,conn);
MySqlDataReader mdr = cmd.ExecuteReader();
while (mdr.Read())
{
q.Qid = mdr["Qid"].ToString();
q.Quest = mdr["question"].ToString();
q.Ctanswer = mdr["ctaPic"].ToString();
}
return q;
}
public Question getQuestion(int id)
{
Question q = new Question();
conn = getConnection();
string sql = "select * from question where Qid="+id;
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlDataReader mdr = cmd.ExecuteReader();
while (mdr.Read())
{
q.Qid = mdr["Qid"].ToString();
q.Quest = mdr["question"].ToString();
q.Ctanswer = mdr["ctaPic"].ToString();
}
return q;
}
}
//封装题目数据
public class Question
{
private string qid;
private string quest;
private string ctanswer;
public string Qid
{
get { return qid; }
set { qid = value; }
}
public string Quest
{
get { return quest; }
set { quest = value; }
}
public string Ctanswer
{
get { return ctanswer; }
set { ctanswer = value; }
}
}
//封装图片数据
public class Picture
{
private string picAddr;
private string picName;
private string picId;
public string PicId
{
get { return picId; }
set { picId = value; }
}
public string PicAddr
{
get { return picAddr; }
set { picAddr = value; }
}
public string PicName
{
get { return picName; }
set { picName = value; }
}
}
//判断答题正确性的方法
public bool isCorrect(Label yourLabel)
{
bool ct = true;
if (yourLabel.Text.Equals(label5.Text))
{
label8.ForeColor = System.Drawing.Color.Green;
label8.Text = "您的答案正确!";
count++;
label6.Text = "答对次数为:" + count;
}
else
{
label8.ForeColor = System.Drawing.Color.Red;
label8.Text = "答错了哦!";
wrong++;
label7.Text = "答错次数为:" + wrong;
ct = false;
}
return ct;
}
private void Form1_Load(object sender, EventArgs e)
{
label6.Text = "答对次数为:"+count;
label7.Text = "错误题数为:" + wrong;
}
private void pictureBox1_Click(object sender, EventArgs e)
{
//isCorrect(label2);
if (isCorrect(label2))
{
button1_Click(sender, e);
}
}
private void pictureBox2_Click(object sender, EventArgs e)
{
if (isCorrect(label3))
{
button1_Click(sender, e);
}
}
private void pictureBox3_Click(object sender, EventArgs e)
{
if (isCorrect(label4))
{
button1_Click(sender, e);
}
}
}
}