综合实验(四)拼图游戏

2020-01-21  本文已影响0人  九除以三还是三哦

实验题目

本章的主要内容是设计开发一个趣味拼图游戏,其功能是对加载的图片进行分割(如分割3×3矩阵或其他类型矩阵)并随机加载到图片框矩阵中,用户使用鼠标拖动图片框中的图片进行拼图,系统能够自动判别拼图是否成功并进行提示。设计过程包括项目分析、界面设计、代码编写和运行调试。

实验方案

算法流程图

界面设计

主窗体
查看原图窗体

功能展示

1.查看原图



2.单边切割任意边数


3×3
6×6
3.普通模式拼图(正计时+步数统计)
拼图成功

扩展功能

(1)挑战模式难度选择
设计思路:设计了三个难度,分别对应的是不同的倒计时限制和单边切割数。简单模式(2×2切割,10s倒计时);一般模式(4×4切割,30s倒计时);简单模式(6×6切割,60s倒计时);需要在代码中单独设置一个变量来记录模式。


难度选择
挑战成功
挑战失败

(2)步数统计
设计思路:单独设置一个变量count,每次移动计数,显示在文本框里,成功后清零即可。
(3)时间控制
设计思路:主要是用到了timer控件,因为挑战模式和普通模式分别对应了正计时和倒计时两种表示,但基本原理是一样的。为了保证timer控件的开启,还新增了“开始游戏”按钮。


开始游戏提示
正计时
倒计时

实验总结

本次实验代码体量较小,但是代码难度较高,理解起来相当复杂。基础部分主要参考书上代码以及网上的内容。拓展部分主要参考网上的内容自行理解加以修正。整体碰见以下问题,现加以分析:
1.在参考书上的代码敲上去以后,发现缺失一部分代码,所以上网上查找相关的代码,后来参考网上的代码完成实验的基本操作。
2.在拓展部分出现计时功能,查找相关计时的控件以及使用方式得以解决,在同学的建议下将挑战模式的计时变成倒计时更符合实验的功能。
3.在制作时,还有很重要的是对txt_step,txt_time1,txt_time2的清空操作,不恰当的话用户体验很不好。
4.看到同学们增加了音频(每次移动图片都会有声音,成功也有声音提醒)。初步了解下原理发现和加图片差不多,但没有做出来,希望以后有机会可以试一下。

源码展示

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Media;

namespace myPuzzle
{
    public partial class Form_Main : Form
    {
        public Form_Main()
        {
            InitializeComponent();
            InitGame();
        }
        PictureBox[] pictureList = null;
        SortedDictionary<string, Bitmap> PictureLocationDictDict = new SortedDictionary<string,Bitmap>();
        Point[] pointList = null;
        SortedDictionary<string, PictureBox> PictureBoxLocationDict = new SortedDictionary<string, PictureBox>();
        int second=0;
        int count = 0;
        int dif = 0;
        PictureBox currentPictureBox = null;
        PictureBox haveToPictureBox = null;
        Point oldLocation = Point.Empty;
        Point newLocation = Point.Empty;
        Point mouseDownPoint = Point.Empty;
        Rectangle rect = Rectangle.Empty;
        bool isDrag = false;

        public string originalpicpath;
        private int ImgNumbers
        {
            get
            {
                return (int)this.numericUpDown1.Value;
            }
        }
        private int SideLength
        {
            get
            {
                return 600 / this.ImgNumbers;
            }
        }
        private void InitRandomPictureBox()
        {
            pnl_Picture.Controls.Clear();
            pictureList = new PictureBox[ImgNumbers * ImgNumbers];
            pointList = new Point[ImgNumbers * ImgNumbers];
            for (int i=0;i<this.ImgNumbers;i++)
            {
                for(int j=0;j<this.ImgNumbers;j++)
                {
                    PictureBox pic = new PictureBox();
                    pic.Name = "pictureBox" + (j + i * ImgNumbers + 1).ToString();
                    pic.Location = new Point(j * SideLength, i * SideLength);
                    pic.Size = new Size(SideLength, SideLength);
                    pic.Visible = true;
                    pic.BorderStyle = BorderStyle.FixedSingle;
                    pic.MouseDown += new MouseEventHandler(pictureBox_MouseDown);
                    pic.MouseMove += new MouseEventHandler(pictureBox_MouseMove);
                    pic.MouseUp += new MouseEventHandler(pictureBox_MouseUp);
                    pnl_Picture.Controls.Add(pic);
                    pictureList[j + i * ImgNumbers] = pic;
                    pointList[j + i * ImgNumbers] = new Point(j * SideLength, i * SideLength);
                    
                }
            }
        }

        public void Flow(string path,bool disorder)
        {
            InitRandomPictureBox();
            Image bm = CutPicture.Resize(path, 600, 600);
            CutPicture.BitMapList = new List<Bitmap>();
            for(int y=0;y<600;y+=SideLength)
            {
                for(int x=0;x<600;x+=SideLength)
                {
                    Bitmap temp = CutPicture.Cut(bm, x, y, SideLength, SideLength);
                    CutPicture.BitMapList.Add(temp);
                }
            }
            ImportBitMap(disorder);
       }

        /// 打乱数据
        public Point[] DisOrderLocation()
        {
            Point[] tempArray = (Point[])pointList.Clone();
            for (int i = tempArray.Length - 1; i > 0; i--)
            {
                Random rand = new Random();
                int p = rand.Next(i);
                Point temp = tempArray[p];
                tempArray[p] = tempArray[i];
                tempArray[i] = temp;
            }
            return tempArray;
            
        }
        public void ResetPictureLocation()
        {
            Point[] temp = DisOrderLocation();
            int i = 0;
            foreach (PictureBox item in pictureList)
            {
                item.Location = temp[i];
                i++;
            }
        }
        public void ImportBitMap(bool disorder)
        {
            try
            {
                int i = 0;
                foreach(PictureBox item in pictureList)
                {
                    Bitmap temp = CutPicture.BitMapList[i];
                    item.Image = temp;
                    i++;
                }
                if (disorder)
                    ResetPictureLocation();
            }
            catch(Exception exp)
            {
                Console.WriteLine(exp.Message);
            }
        }
        public void InitGame()
        {
            //if(!Directory.Exists(Application.StartupPath.ToString() + "\\picture"))
            {
                Directory.CreateDirectory(Application.StartupPath.ToString() + "\\Picture");
                //Properties.Resources.默认.Save(Application.StartupPath.ToString() + "\\Picture\\1.jpg");
                Properties.Resources._1.Save(Application.StartupPath.ToString() + "\\Picture\\1.jpg");
                Properties.Resources._2.Save(Application.StartupPath.ToString() + "\\Picture\\2.jpg");
                Properties.Resources._3.Save(Application.StartupPath.ToString() + "\\Picture\\3.jpg");
                Properties.Resources._4.Save(Application.StartupPath.ToString() + "\\Picture\\4.jpg");
                Properties.Resources._5.Save(Application.StartupPath.ToString() + "\\Picture\\5.jpg");
                Properties.Resources._0.Save(Application.StartupPath.ToString() + "\\Picture\\0.jpg");
                
            }
            Random r = new Random();
            int i = r.Next(6);
            originalpicpath = Application.StartupPath.ToString() + "\\Picture\\" + i.ToString() + ".jpg";
            Flow(originalpicpath, true);
            
        }
        
        public PictureBox GetPictureBoxByLocation(int x,int y)
        {
            PictureBox pic = null;
            foreach(PictureBox item in pictureList)
            {
                if(x>item.Location.X&&y>item.Location.Y&&item.Location.X+SideLength>x&&item.Location.Y+SideLength>y)
                {
                    pic = item;
                }
            }
            return pic;
        }

        private void Pnl_Picture_MouseDown(object sender, MouseEventArgs e)
        {

        }
        //通过hashcode获取picture,用mouseeventargs之后获取相对于picture的坐标不是相对窗体
        public PictureBox GetPictureBoxByHashCode(string hascode)
        {
            PictureBox pic = null;
            foreach (PictureBox item in pictureList)
            {
                if (hascode == item.GetHashCode().ToString())
                {
                    pic = item;
                }
            }
            return pic;
        }

        private void pictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            if(timer1.Enabled==false)
            {
                MessageBox.Show("请点击开始游戏!");
            }
            else
            {
               oldLocation = new Point(e.X, e.Y);
               currentPictureBox = GetPictureBoxByHashCode(sender.GetHashCode().ToString());
               MoseDown(currentPictureBox, sender, e);
            }
            
        }
        private void MoseDown(PictureBox pic,object sender, MouseEventArgs e)
        {
            if(e.Button==MouseButtons.Left)
            {
                oldLocation = e.Location;
                rect = pic.Bounds;
            }
        }
        private Point getPointToForm(Point p)
        {
            return this.PointToClient(pictureList[0].PointToScreen(p));
        }
        private void pictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if(e.Button==MouseButtons.Left)
            {
                isDrag = true;
                rect.Location = getPointToForm(new Point(e.Location.X - oldLocation.X,e.Location.Y - oldLocation.Y));
                this.Refresh();
            }
        }
        private void reset()
        {
            mouseDownPoint = Point.Empty;
            rect = Rectangle.Empty;
            isDrag = false;
        }

        private void pictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            oldLocation = new Point(currentPictureBox.Location.X, currentPictureBox.Location.Y);
            if(oldLocation.X+e.X>600||oldLocation.Y+e.Y>600||oldLocation.X+e.X<0||oldLocation.Y+e.Y<0)
            {
                return;
            }
            haveToPictureBox = GetPictureBoxByLocation(oldLocation.X + e.X, oldLocation.Y + e.Y );
            newLocation = new Point(haveToPictureBox.Location.X, haveToPictureBox.Location.Y);
            haveToPictureBox.Location = oldLocation;
            PictureMouseUp(currentPictureBox,sender ,e);
            if(Judge())
            {
                if (rad_true.Checked)
                {
                    timer1.Stop();
                    MessageBox.Show("挑战成功!");
                    second = 0;
                    txt_time.Text = "";
                    InitGame();
                    
                }
                else
                {
                    timer1.Stop();
                    MessageBox.Show("成功!");
                    second = 0;
                    txt_time2.Text = "";
                    txt_step.Text = "";
                    InitGame();
                    
                }
                
            }
        }

        private void PictureMouseUp(PictureBox pic, object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if(isDrag)
                {
                    isDrag = false;
                    pic.Location = newLocation;
                    count++;
                    if (rad_false.Checked)  txt_step.Text = count.ToString();
                    this.Refresh();
                }
                reset();
            }
        }
        public bool Judge()
        {
            bool result = true;
            int i = 0;
            foreach(PictureBox item in pictureList)
            {
                if(item.Location!=pointList[i])
                {
                    result = false;
                }
                i++;
            }
            return result;
        }

        private void Btn_import_Click(object sender, EventArgs e)
        {
            OpenFileDialog new_picture = new OpenFileDialog();
            if (new_picture.ShowDialog()==DialogResult.OK)
            {
                //lab_result.Text = "";
            }
            originalpicpath = new_picture.FileName;
            CutPicture.PicturePath = new_picture.FileName;
            Flow(CutPicture.PicturePath, true);
        }

        private void Btn_Changepic_Click(object sender, EventArgs e)
        {
            Random r = new Random();
            int i = r.Next(6);
            originalpicpath = Application.StartupPath.ToString() + "\\Picture\\" + i.ToString() + ".jpg";
            Flow(originalpicpath, true);
        }

        private void Btn_Reset_Click(object sender, EventArgs e)
        {
            Flow(originalpicpath, true);
            second = 0;
            txt_time.Text = "";
        }

        private void Btn_Originalpic_Click(object sender, EventArgs e)
        {
            Form_Original original = new Form_Original();
            original.picpath = originalpicpath;
            original.ShowDialog();
           
        }

        private void Label1_Click(object sender, EventArgs e)
        {

        }

        private void Button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        private void Timer1_Tick(object sender, EventArgs e)
        {
            if (rad_true.Checked)
            {
                //second = 0;
                second--;
                txt_time.Text = (dif+second).ToString();
                if (dif+second == 0)
                {
                    timer1.Stop();
                    MessageBox.Show("挑战失败!");
                    second = 0;
                    txt_time.Text = "";
                    //txt_time2.Text = "";
                    InitGame();
                }
            }
            else if (rad_false.Checked)
            {
                //second = 0;
                second++;
                txt_time2.Text = second.ToString();
            }
        }

        private void Rad_false_CheckedChanged(object sender, EventArgs e)
        {
            //timer1.Enabled = true;
        }

        private void Rad_true_CheckedChanged(object sender, EventArgs e)
        {
            option.Text = "简单";
            //timer1.Enabled = true;
        }

        private void Btn_start_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        private void NumericUpDown1_ValueChanged(object sender, EventArgs e)
        {
           
        }

        private void Option_SelectedIndexChanged(object sender, EventArgs e)
        {
            
            if (option.Text == "简单")
            {
                dif = 10;
                numericUpDown1.Value = 2;
                Flow(originalpicpath, true);
            }
            if (option.Text == "一般")
            {
                dif = 30;
                numericUpDown1.Value = 4;
                Flow(originalpicpath, true);
            }
            if (option.Text == "困难")
            {
                dif = 60;
                numericUpDown1.Value = 6;
                Flow(originalpicpath, true);
            }
        }
    }
}

Form_Original.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace myPuzzle
{
    public partial class Form_Original : Form
    {
        public string picpath;
        public Form_Original()
        {
            InitializeComponent();
        }
        private void Form_original_Load(object sender, EventArgs e)
        {
            //pb_Original.Image = CutPicture.Resize(picpath, 600, 600);
        }

        private void Form_Original_Load_1(object sender, EventArgs e)
        {
            pb_Original.Image = CutPicture.Resize(picpath, 600, 600);
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读