C#实现拼图游戏

 更新时间:2021年07月23日 14:32:20   作者:Cooooooooco  
这篇文章主要为大家详细介绍了C#实现拼图游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C#实现拼图游戏的具体代码,供大家参考,具体内容如下

(一)需求:(这个需求书写较为简单)

  • 图片:有图
  • 切割:拼图不是一个图,我们需要把一个整图它切割成N*N的小图
  • 打乱:把这N*N的小图打乱顺序,才能叫拼图qwq
  • 判断:判断拼图是否成功
  • 交互:选择鼠标点击拖动的方式
  • 展示原图:拼不出来可以看看
  • 更换图片:腻了可以从本地选择一张你喜欢的来拼图
  • 选择难度:除了2×2还可以选择切割成3×3或者4×4,看你喜欢qwq

(二)设计:

使用VS的c#来实现

界面设计:picturebox控件来显示图片,button控件来实现按钮点击的各类事件:图片重排、换图、查看原图等,使用numericUpDown控件来控制切割的边数。如下图:

把要拼的图片放进resource文件里
设计函数,使用cutpicture类来切割图片

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

namespace 拼图游戏
{
    class CutPicture
    {
        public static string picturePath = "";
        public static List<Bitmap> BitMapList = null;
        public static Image Resize(string path, int iwidth, int iheignt)
        {
            Image thumbnail = null;
            try
            {
                var img = Image.FromFile(path);
                thumbnail = img.GetThumbnailImage(iwidth, iheignt, null, IntPtr.Zero);
                thumbnail.Save(Application.StartupPath.ToString() + "//Picture//img.jpeg");
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp.Message);
            }
            return thumbnail;
        }
        public static Bitmap Cut(Image b, int startX, int startY, int iwidth, int iheight)
        {
            if (b == null)
            { return null; }
            int w = b.Width;
            int h = b.Height;
            if (startX >= w || startY >= h)
            { return null; }
            if (startX + iwidth > w)
            { iwidth = w - startX; }
            if (startY + iheight > h)
            { iheight = h - startY; }
            try
            {
                Bitmap bmpout = new Bitmap(iwidth, iheight, PixelFormat.Format24bppRgb);
                Graphics g = Graphics.FromImage(bmpout);
                g.DrawImage(b, new Rectangle(0, 0, iwidth, iheight), new Rectangle(startX, startY, iwidth, iheight),
                    GraphicsUnit.Pixel);
                g.Dispose();
                return bmpout;
            }
            catch
            {
                return null;
            }
        }
    }
}

Form_Main函数为主函数

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;

namespace 拼图游戏
{
    public partial class Form_Main : Form
    {
        PictureBox[] picturelist = null;
        SortedDictionary<string, Bitmap> pictureLocationDict = new SortedDictionary<string, Bitmap>();
        Point []pointlist=null;
        SortedDictionary<string, PictureBox > pictureBoxLocationDict = new SortedDictionary<string, PictureBox>();
        
        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 Imgnubers
        {
            get
            {
                return (int)this.numericUpDown1.Value;
            }
        }
        private int sidelength
        {
            get { return 600 / this.Imgnubers; }
        }
        public void InitRandomPictureBox()
        {
            pnl_Picture.Controls.Clear();
            picturelist = new PictureBox[Imgnubers * Imgnubers];
            pointlist = new Point [Imgnubers * Imgnubers];
           
            for (int i = 0; i < this.Imgnubers; i++)
            {
                for (int j = 0; j < this.Imgnubers; j++)
                {
                    PictureBox pic = new PictureBox();
                    pic.Name = "picturebox" + (j + i * Imgnubers + 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(picture_MouseDown);
                    pic.MouseMove += new MouseEventHandler(picture_MouseMove);
                    pic.MouseUp += new MouseEventHandler(picture_MouseUp);
                    pnl_Picture.Controls.Add(pic);
                    picturelist[j + i * Imgnubers] = pic;
                    pointlist[j + i * Imgnubers] = 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);
                }
            }
                ImporBitMap(disorder );
        }
        public void ImporBitMap(bool disorder)
        {
            try
            {
                int i=0;
                foreach (PictureBox item in picturelist )
                {
                    Bitmap temp = CutPicture.BitMapList[i];
                    item.Image = temp;
                    i++;
                }
                if(disorder )ResetPictureLoaction();
            }
            catch (Exception exp)
            {
                Console .WriteLine (exp.Message );
            }
        }
        public void ResetPictureLoaction()
        {
            Point[] temp = DisOrderLocation();
            int i = 0;
            foreach (PictureBox item in picturelist)
            {
                item.Location = temp[i];
                i++;
            }
        }
        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;
        }  
        private void Form_Main_Load(object sender, EventArgs e)
        {
        
        }
        public void initgame()
        { 
           /* picturelist = new PictureBox[9] { pictureBox1, pictureBox2, pictureBox3, pictureBox4, pictureBox5, pictureBox6, pictureBox7, pictureBox8, pictureBox9 };  
            pointlist = new Point[9] { new Point(0, 0), new Point(100, 0), new Point(200, 0), new Point(0, 100), new Point(100, 100), new Point(200, 100), new Point(0, 200), new Point(100, 200), new Point(200, 200) };
            */if (!Directory.Exists(Application.StartupPath.ToString() + "//Resources"))
            {
                Directory.CreateDirectory(Application.StartupPath.ToString() + "//Resources");
                Properties.Resources._0.Save(Application.StartupPath.ToString() + "//Resources//0.jpg");
                Properties.Resources._1.Save(Application.StartupPath.ToString() + "//Resources//1.jpg");
                Properties.Resources._2.Save(Application.StartupPath.ToString() + "//Resources//2.jpg");
                Properties.Resources._3.Save(Application.StartupPath.ToString() + "//Resources//3.jpg");
                Properties.Resources._4.Save(Application.StartupPath.ToString() + "//Resources//4.jpg");
            }
            Random r=new Random ();
            int i=r.Next (5);
            originalpicpath = Application.StartupPath.ToString() + "//Resources//" + 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;
        }
        public PictureBox GetPictureBoxByHashCode(string hascode)
        {
            PictureBox pic = null;
            foreach (PictureBox item in picturelist)
            {
                if (hascode == item.GetHashCode().ToString())
                {
                    pic = item;
                }
            }
            return pic;
        }
        private void picture_MouseDown(object sender, MouseEventArgs e)
        {
            oldlocation = new Point(e.X, e.Y);
            currentpicturebox = GetPictureBoxByHashCode(sender.GetHashCode().ToString());
            MoseDown(currentpicturebox, sender, e);
        }
        public void MoseDown(PictureBox pic, object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                oldlocation = e.Location;
                rect = pic.Bounds;
            }
        }
        
        private void picture_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 Point getPointToForm(Point p)
        {
            return this.PointToClient(pictureBox1 .PointToScreen (p));
        }
        private void reset()
        {
            mouseDownPoint = Point.Empty;
            rect = Rectangle.Empty;
            isDrag = false;
        }

        private void picture_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())
            {
                MessageBox.Show("恭喜拼图成功");  
            }
        }
        public void PictureMouseUp(PictureBox pic, object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (isDrag)
                {
                    isDrag = false;
                    pic.Location = newlocation;
                    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;
        }
        public void ExchangePictureBox(MouseEventArgs e)
        { }
        public PictureBox[] DisOrderArray(PictureBox[] pictureArray)
        {
            PictureBox[] tempArray = pictureArray;
            for (int i = tempArray.Length - 1; i > 0; i--)
            {
                Random rand = new Random();
                int p = rand.Next(i);
                PictureBox temp = tempArray[p];
                tempArray[p] = tempArray[i];
                tempArray[i] = temp;
            }
            return tempArray;
        }  
        public Form_Main()
        {
            InitializeComponent();
            initgame();
        }

        private void pnl_Picture_Paint(object sender, PaintEventArgs e)
        {

        }

        private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void btn_import_Click(object sender, EventArgs e)
        {
            if (new_picture.ShowDialog() == DialogResult.OK)
            {
                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(5);
            originalpicpath = Application.StartupPath.ToString() + "//Resources//" + i.ToString() + ".jpg";
            Flow(originalpicpath, true);
        }

        private void btn_Reset_Click(object sender, EventArgs e)
        {
            Flow(originalpicpath, true);
        }

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

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Start();
            timer1.Enabled = true;
            timer1.Interval = 10000;
           
           


        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (Judge())
            { MessageBox.Show("挑战成功"); timer1.Stop(); }
            else { MessageBox.Show("挑战失败"); timer1.Stop(); }
        }
    }
}

ps:挑战模式貌似有点小问题,没法显示倒数的时间在页面上,体验感觉不好。

接下来是设计显示原图的页面,只需要一个picturebox即可,代码如下:

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 拼图游戏
{
    public partial class Form_Original : Form
    {
        public string picpath;
        public Form_Original()
        {
            InitializeComponent();
        }

        private void pic_Original_Click(object sender, EventArgs e)
        {

        }

        private void Form_Original_Load(object sender, EventArgs e)
        {
            pic_Original.Image = CutPicture.Resize(picpath, 600, 600);
        }
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#如何给枚举类型增加一个描述特性详解

    C#如何给枚举类型增加一个描述特性详解

    这篇文章主要给大家介绍了关于C#如何给枚举类型增加一个描述特性的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-02-02
  • Chrome Visual Studio 2005下的编译过程

    Chrome Visual Studio 2005下的编译过程

    研究Chrome ,首先得把它编译出来,这对于后续的代码分析和阅读有很大的帮助,想想自己编译出一个 Chrome 浏览器来使用,那是一件很炫的事情。
    2009-07-07
  • C#生成唯一不重复订单号

    C#生成唯一不重复订单号

    本文给大家介绍的是使用C#生成唯一不重复订单号的方法,主要用到了lock锁,有需要的小伙伴可以参考下。
    2015-07-07
  • Unity3D动态生成平面网格

    Unity3D动态生成平面网格

    这篇文章主要为大家详细介绍了Unity3D动态生成平面网格,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • C#实现读写CSV文件的方法详解

    C#实现读写CSV文件的方法详解

    项目中经常遇到CSV文件的读写需求,其中的难点主要是CSV文件的解析。本文会介绍CsvHelper、TextFieldParser、正则表达式三种解析CSV文件的方法,需要的可以参考一下
    2022-06-06
  • C# 定时器定时更新的简单实例

    C# 定时器定时更新的简单实例

    这篇文章主要介绍了C#中定时器定时更新的简单实例。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • C#使用WebSocket与网页实时通信的实现示例

    C#使用WebSocket与网页实时通信的实现示例

    本文主要介绍了C#使用WebSocket与网页实时通信的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • C#实现变量交换、斐波那契数列、质数、回文方法合集

    C#实现变量交换、斐波那契数列、质数、回文方法合集

    这篇文章介绍了C#实现变量交换、斐波那契数列、质数、回文的方法合集,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • C#基于XNA生成随机颜色的方法

    C#基于XNA生成随机颜色的方法

    这篇文章主要介绍了C#基于XNA生成随机颜色的方法,涉及XNA Color类的使用技巧,需要的朋友可以参考下
    2015-06-06
  • C#异步编程的三种模式

    C#异步编程的三种模式

    本文详细讲解了C#异步编程的三种模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04

最新评论