綜合實(shí)驗(yàn)(四)拼圖游戲

實(shí)驗(yàn)題目

本章的主要內(nèi)容是設(shè)計(jì)開發(fā)一個(gè)趣味拼圖游戲,其功能是對(duì)加載的圖片進(jìn)行分割(如分割3×3矩陣或其他類型矩陣)并隨機(jī)加載到圖片框矩陣中,用戶使用鼠標(biāo)拖動(dòng)圖片框中的圖片進(jìn)行拼圖,系統(tǒng)能夠自動(dòng)判別拼圖是否成功并進(jìn)行提示。設(shè)計(jì)過程包括項(xiàng)目分析、界面設(shè)計(jì)、代碼編寫和運(yùn)行調(diào)試。

實(shí)驗(yàn)方案

算法流程圖

界面設(shè)計(jì)

主窗體

查看原圖窗體

功能展示

1.查看原圖



2.單邊切割任意邊數(shù)


3×3

6×6

3.普通模式拼圖(正計(jì)時(shí)+步數(shù)統(tǒng)計(jì))
拼圖成功

擴(kuò)展功能

(1)挑戰(zhàn)模式難度選擇
設(shè)計(jì)思路:設(shè)計(jì)了三個(gè)難度,分別對(duì)應(yīng)的是不同的倒計(jì)時(shí)限制和單邊切割數(shù)。簡(jiǎn)單模式(2×2切割,10s倒計(jì)時(shí));一般模式(4×4切割,30s倒計(jì)時(shí));簡(jiǎn)單模式(6×6切割,60s倒計(jì)時(shí));需要在代碼中單獨(dú)設(shè)置一個(gè)變量來記錄模式。


難度選擇

挑戰(zhàn)成功

挑戰(zhàn)失敗

(2)步數(shù)統(tǒng)計(jì)
設(shè)計(jì)思路:?jiǎn)为?dú)設(shè)置一個(gè)變量count,每次移動(dòng)計(jì)數(shù),顯示在文本框里,成功后清零即可。
(3)時(shí)間控制
設(shè)計(jì)思路:主要是用到了timer控件,因?yàn)樘魬?zhàn)模式和普通模式分別對(duì)應(yīng)了正計(jì)時(shí)和倒計(jì)時(shí)兩種表示,但基本原理是一樣的。為了保證timer控件的開啟,還新增了“開始游戲”按鈕。


開始游戲提示

正計(jì)時(shí)

倒計(jì)時(shí)

實(shí)驗(yàn)總結(jié)

本次實(shí)驗(yàn)代碼體量較小,但是代碼難度較高,理解起來相當(dāng)復(fù)雜?;A(chǔ)部分主要參考書上代碼以及網(wǎng)上的內(nèi)容。拓展部分主要參考網(wǎng)上的內(nèi)容自行理解加以修正。整體碰見以下問題,現(xiàn)加以分析:
1.在參考書上的代碼敲上去以后,發(fā)現(xiàn)缺失一部分代碼,所以上網(wǎng)上查找相關(guān)的代碼,后來參考網(wǎng)上的代碼完成實(shí)驗(yàn)的基本操作。
2.在拓展部分出現(xiàn)計(jì)時(shí)功能,查找相關(guān)計(jì)時(shí)的控件以及使用方式得以解決,在同學(xué)的建議下將挑戰(zhàn)模式的計(jì)時(shí)變成倒計(jì)時(shí)更符合實(shí)驗(yàn)的功能。
3.在制作時(shí),還有很重要的是對(duì)txt_step,txt_time1,txt_time2的清空操作,不恰當(dāng)?shù)脑捰脩趔w驗(yàn)很不好。
4.看到同學(xué)們?cè)黾恿艘纛l(每次移動(dòng)圖片都會(huì)有聲音,成功也有聲音提醒)。初步了解下原理發(fā)現(xiàn)和加圖片差不多,但沒有做出來,希望以后有機(jī)會(huì)可以試一下。

源碼展示

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);
       }

        /// 打亂數(shù)據(jù)
        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.默認(rèn).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之后獲取相對(duì)于picture的坐標(biāo)不是相對(duì)窗體
        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("請(qǐng)點(diǎn)擊開始游戲!");
            }
            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("挑戰(zhàn)成功!");
                    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("挑戰(zhàn)失??!");
                    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 = "簡(jiǎn)單";
            //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 == "簡(jiǎn)單")
            {
                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);
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、窗體 1、常用屬性 (1)Name屬性:用來獲取或設(shè)置窗體的名稱,在應(yīng)用程序中可通過Name屬性來引用窗體。 ...
    Moment__格調(diào)閱讀 4,749評(píng)論 0 11
  • 今天看到一篇網(wǎng)文,叫《初二現(xiàn)象》。想著我家女兒馬上也初二了,就點(diǎn)進(jìn)去看了下。 原來這個(gè)令家長(zhǎng)聞風(fēng)喪膽的“初二現(xiàn)象”...
    閑敲鍵盤閱讀 327評(píng)論 0 3
  • 一大早,離開南京,我們又開始了新一天的旅程。走過無錫和蘇州,找到些古色古香的意蘊(yùn),竹樓青林,荷香微溢,斜陽(yáng)正好,水...
    滿目山河都是你閱讀 669評(píng)論 0 3
  • 懶得翻動(dòng)桌上的日歷,估摸著是冬天到了吧。伴隨著鬧鈴醒來,感覺越來越難和溫暖的被褥分別,早餐買的熱豆?jié){也變成了早自習(xí)...
    無所謂hero閱讀 521評(píng)論 0 0
  • 如何管理好自己 成為一個(gè)成功的管理者是所有管理者的共同心愿,但是如何才能成為一個(gè)成功的管理者?我認(rèn)為要成為一個(gè)成功...
    設(shè)計(jì)王奕雲(yún)閱讀 126評(píng)論 0 0

友情鏈接更多精彩內(nèi)容