Home Backend Development C#.Net Tutorial Sharing of graphic and text code for writing jigsaw puzzles in C# (Part 1)

Sharing of graphic and text code for writing jigsaw puzzles in C# (Part 1)

Apr 18, 2017 am 09:10 AM
c# puzzle game

这篇文章主要为大家详细介绍了C#拼图游戏的编写代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文设计了C#拼图游戏程序,供大家参考,具体内容如下

功能描述:

  1.用户自定义上传图片

  2.游戏难度选择:简单(3*3)、一般(5*5)、困难(9*9)三个级别

  3.纪录完成步数

模块:

  1.拼图类

  2.配置类

  3.游戏菜单窗口

  4.游戏运行窗口

 代码文件VS2013版本:

下载链接: 拼图游戏

--------------------------------------------------我叫分割线---------------------------------------------------------------

1.拼图类

方法:

  1.构造函数:传图片并分割成一个一个小图片

  2.交换方法

  3.大图中截取小单元方法

  4.移动单元的方法

  5.打乱单元顺序方法

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

namespace 拼图
{
 public class Puzzle
 {
 public enum Diff //游戏难度
 {
 simple,//简单
 ordinary,//普通
 difficulty//困难
 }
 private struct Node //拼图单元格结构体
 {
 public Image Img;
 public int Num;
 }
 private Image _img; //拼图图片
 public int Width; //拼图边长
 private Diff _gameDif; //游戏难度
 private Node[,] node; //单元格数组
 public int N; //单元格数组行列数

 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="Img">拼图大图</param>
 /// <param name="GameDif">游戏难度,该类下结构体Diff</param>
 public Puzzle(Image Img,int Width, Diff GameDif)
 {
 this._gameDif = GameDif;
 this._img = Img;
 this.Width = Width;
 switch(this._gameDif)
 {
 case Diff.simple:    //简单则单元格数组保存为3*3的二维数组
  this.N = 3;
  node=new Node[3,3];
  break;
 case Diff.ordinary:   //一般则为5*5
  this.N = 5;
  node = new Node[5, 5];
  break;
 case Diff.difficulty:  //困难则为9*9
  this.N = 9;
  node = new Node[9, 9];
  break;
 }
 
 //分割图片形成各单元保存在数组中
 int Count = 0;
 for (int x = 0; x < this.N; x++)
 {
 for (int y = 0; y < this.N; y++)
 {

  node[x, y].Img = CaptureImage(this._img, this.Width / this.N, this.Width / this.N, x * (this.Width / this.N), y * (this.Width / this.N));
  node[x, y].Num = Count;
  Count++;
 }
 }
 
 for (int x = 0; x < this.N; x++)
 {
 for (int y = 0; y < this.N; y++)
 {

  Graphics newGra = Graphics.FromImage(node[x, y].Img);
  newGra.DrawLine(new Pen(Color.White), new Point(0, 0), new Point(0, this.Width / this.N));
  newGra.DrawLine(new Pen(Color.White), new Point(0, 0), new Point(this.Width / this.N, 0));
  newGra.DrawLine(new Pen(Color.White), new Point(this.Width / this.N, this.Width / this.N), new Point(this.Width / this.N, 0));
  newGra.DrawLine(new Pen(Color.White), new Point(this.Width / this.N, this.Width / this.N), new Point(0,this.Width / this.N));
 }
 }
 //(最后一项为空单独处理)
 node[N - 1, N - 1].Img = Image.FromFile("Image\\end.PNG");
 Graphics newGra2 = Graphics.FromImage(node[N - 1, N - 1].Img);
 newGra2.DrawLine(new Pen(Color.Red), new Point(1, 1), new Point(1, this.Width / this.N - 1));
 newGra2.DrawLine(new Pen(Color.Red), new Point(1, 1), new Point(this.Width / this.N - 1, 1));
 newGra2.DrawLine(new Pen(Color.Red), new Point(this.Width / this.N - 1, this.Width / this.N - 1), new Point(this.Width / this.N - 1, 1));
 newGra2.DrawLine(new Pen(Color.Red), new Point(this.Width / this.N - 1, this.Width / this.N - 1), new Point( 1,this.Width / this.N - 1));
 //打乱拼图
 this.Upset();

 }


 /// <summary>
 /// 由图片fromImage中截图并返回
 /// </summary>
 /// <param name="fromImage">原图片</param>
 /// <param name="width">宽</param>
 /// <param name="height">高</param>
 /// <param name="spaceX">起始X坐标</param>
 /// <param name="spaceY">起始Y坐标</param>
 /// <returns></returns>
 public Image CaptureImage(Image fromImage, int width, int height, int spaceX, int spaceY)
 {
 int x = 0;
 int y = 0;
 int sX = fromImage.Width - width;
 int sY = fromImage.Height - height;
 if (sX > 0)
 {
 x = sX > spaceX ? spaceX : sX;
 }
 else
 {
 width = fromImage.Width;
 }
 if (sY > 0)
 {
 y = sY > spaceY ? spaceY : sY;
 }
 else
 {
 height = fromImage.Height;
 }

 //创建新图位图 
 Bitmap bitmap = new Bitmap(width, height);
 //创建作图区域 
 Graphics graphic = Graphics.FromImage(bitmap);
 //截取原图相应区域写入作图区 
 graphic.DrawImage(fromImage, 0, 0, new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
 //从作图区生成新图 
 Image saveImage = Image.FromHbitmap(bitmap.GetHbitmap());
 return saveImage;
 }
 /// <summary>
 /// 移动坐标(x,y)拼图单元
 /// </summary>
 /// <param name="x">拼图单元x坐标</param>
 /// <param name="y">拼图单元y坐标</param>
 public bool Move(int x,int y)
 {
 //MessageBox.Show(" " + node[2, 2].Num);
 if (x + 1 != N && node[x + 1, y].Num == N * N - 1)
 {
 Swap(new Point(x + 1, y), new Point(x, y));
 return true;
 }
 if (y + 1 != N && node[x, y + 1].Num == N * N - 1)
 {
 Swap(new Point(x, y + 1), new Point(x, y));
 return true;
 } 
 if (x - 1 != -1 && node[x - 1, y].Num == N * N - 1)
 {
 Swap(new Point(x - 1, y), new Point(x, y));
 return true;
 } 
 if (y - 1 != -1 && node[x, y - 1].Num == N * N - 1)
 {
 Swap(new Point(x, y - 1), new Point(x, y));
 return true;
 }
 return false;
 
 }
 //交换两个单元格
 private void Swap(Point a, Point b)
 {
 Node temp = new Node();
 temp = this.node[a.X, a.Y];
 this.node[a.X, a.Y] = this.node[b.X, b.Y];
 this.node[b.X, b.Y] = temp;
 }
 public bool Judge()
 {
 int count=0;
 for (int x = 0; x < this.N; x++)
 {
 for (int y = 0; y < this.N; y++)
 {
  if (this.node[x, y].Num != count)
  return false;
  count++;
 }
 }
 return true;
 }
 public Image Display()
 {
 Bitmap bitmap = new Bitmap(this.Width, this.Width);
 //创建作图区域 
 Graphics newGra = Graphics.FromImage(bitmap);
 for (int x = 0; x < this.N; x++)
 for (int y = 0; y < this.N; y++)
  newGra.DrawImage(node[x, y].Img, new Point(x * this.Width / this.N, y * this.Width / this.N));
 return bitmap;
 }
 /// <summary>
 /// 打乱拼图
 /// </summary>
 public void Upset()
 {
 int sum = 100000;
 if (this._gameDif == Diff.simple) sum = 10000;
 //if (this._gameDif == Diff.ordinary) sum = 100000;
 Random ran = new Random();
 for (int i = 0, x = N - 1, y = N - 1; i < sum; i++)
 {
 long tick = DateTime.Now.Ticks;
 ran = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32)|ran.Next());
 switch (ran.Next(0, 4))
 {
  case 0:
  if (x + 1 != N)
  {
  Move(x + 1, y);
  x = x + 1;
  }
  
  break;
  case 1:
  if (y + 1 != N)
  {
  Move(x, y + 1);
  y = y + 1;
  } 
  break;
  case 2:
  if (x - 1 != -1)
  {
  Move(x - 1, y);
  x = x - 1;
  } 
  break;
  case 3:
  if (y - 1 != -1)
  {
  Move(x, y - 1);
  y = y - 1;
  }
  break;
 }

 }
 }

 

 }
}
Copy after login

2、配置类:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 拼图
{
 public static class GamePage
 {
 public static Puzzle.Diff Dif; //游戏难度
 public static Image img; //拼图图案
 }
}
Copy after login

游戏菜单:

通过菜单,上传图片至配置类img,并选择难度上传至配置类Dif,然后拼图对象构造时读取配置


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 Menu : Form
 {
 public Menu()
 {
 InitializeComponent();
 GamePage.img =Image.FromFile(@"Image\\拼图.jpg");
 Control.CheckForIllegalCrossThreadCalls = false;
 }

 private void button1_Click(object sender, EventArgs e)
 {
 GamePage.Dif = Puzzle.Diff.simple;
 this.Hide();
 Form1 ff = new Form1();
 ff.closefather+=new 拼图.Form1.childclose(this.closethis); 
 ff.Show();
 
 }

 private void button2_Click(object sender, EventArgs e)
 {
 GamePage.Dif = Puzzle.Diff.ordinary;
 this.Hide();
 Form1 ff = new Form1();
 ff.closefather += new 拼图.Form1.childclose(this.closethis); 
 ff.Show();
 
 }

 private void button3_Click(object sender, EventArgs e)
 {
 GamePage.Dif = Puzzle.Diff.difficulty;
 this.Hide();
 Form1 ff = new Form1();
 ff.closefather += new 拼图.Form1.childclose(this.closethis); 
 ff.Show();
 
 }

 public void closethis()
 {
 this.Show();
 }


 private void button4_Click(object sender, EventArgs e)
 {
 OpenFileDialog ofd = new OpenFileDialog();
 ofd.ShowDialog();
 GamePage.img = Image.FromFile(ofd.FileName).GetThumbnailImage(600,600,new Image.GetThumbnailImageAbort(delegate { return false; }), IntPtr.Zero); 

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

 }
}
Copy after login

游戏运行窗口:

1.注册鼠标点击事件来获得输入消息

2.显示功能

3.pictureBox1用来展示游戏拼图情况

4.pictureBox2展示完整拼图的缩略图(当鼠标移至pictureBox2时,发送消息,使pictureBox1显示完整拼图)

5.Numlabel来显示移动步数(通过变量Num的累加来计算)


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

namespace 拼图
{
 public partial class Form1 : Form
 {
 public Form1()
 {
 InitializeComponent();
 }
 private Puzzle puzzle;
 private int Num=0;
 private Image img;
 private void Form1_Load(object sender, EventArgs e)
 {
 img = GamePage.img;
 pictureBox2.Image = img.GetThumbnailImage(120,120, new Image.GetThumbnailImageAbort(delegate { return false; }), IntPtr.Zero);
 puzzle = new Puzzle(img, 600, GamePage.Dif);
 pictureBox1.Image =puzzle.Display();
 }

 private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
 {
 if (puzzle.Move(e.X / (puzzle.Width / puzzle.N), e.Y / (puzzle.Width / puzzle.N)))
 {
 Num++;
 pictureBox1.Image = puzzle.Display();
 if (puzzle.Judge())
 { 
  if (MessageBox.Show("恭喜过关", "是否重新玩一把", MessageBoxButtons.OKCancel) == DialogResult.OK)
  {
  Num = 0;
  puzzle.Upset();
  pictureBox1.Image = puzzle.Display();
  
  }
  else
  {
  Num = 0;
  closefather();
  this.Close();
  }

 }

 }
 NumLabel.Text = Num.ToString();
 }

 private void pictureBox2_MouseEnter(object sender, EventArgs e)
 {
 pictureBox1.Image = img;
 }

 private void pictureBox2_MouseLeave(object sender, EventArgs e)
 {
 pictureBox1.Image = puzzle.Display();
 }


 private void Form1_FormClosed(object sender, FormClosedEventArgs e)
 {
 closefather();
 }
 public delegate void childclose();
 public event childclose closefather;

 }
}
Copy after login

The above is the detailed content of Sharing of graphic and text code for writing jigsaw puzzles in C# (Part 1). For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Active Directory with C# Active Directory with C# Sep 03, 2024 pm 03:33 PM

Guide to Active Directory with C#. Here we discuss the introduction and how Active Directory works in C# along with the syntax and example.

C# Serialization C# Serialization Sep 03, 2024 pm 03:30 PM

Guide to C# Serialization. Here we discuss the introduction, steps of C# serialization object, working, and example respectively.

Random Number Generator in C# Random Number Generator in C# Sep 03, 2024 pm 03:34 PM

Guide to Random Number Generator in C#. Here we discuss how Random Number Generator work, concept of pseudo-random and secure numbers.

C# Data Grid View C# Data Grid View Sep 03, 2024 pm 03:32 PM

Guide to C# Data Grid View. Here we discuss the examples of how a data grid view can be loaded and exported from the SQL database or an excel file.

Factorial in C# Factorial in C# Sep 03, 2024 pm 03:34 PM

Guide to Factorial in C#. Here we discuss the introduction to factorial in c# along with different examples and code implementation.

Patterns in C# Patterns in C# Sep 03, 2024 pm 03:33 PM

Guide to Patterns in C#. Here we discuss the introduction and top 3 types of Patterns in C# along with its examples and code implementation.

Prime Numbers in C# Prime Numbers in C# Sep 03, 2024 pm 03:35 PM

Guide to Prime Numbers in C#. Here we discuss the introduction and examples of prime numbers in c# along with code implementation.

The difference between multithreading and asynchronous c# The difference between multithreading and asynchronous c# Apr 03, 2025 pm 02:57 PM

The difference between multithreading and asynchronous is that multithreading executes multiple threads at the same time, while asynchronously performs operations without blocking the current thread. Multithreading is used for compute-intensive tasks, while asynchronously is used for user interaction. The advantage of multi-threading is to improve computing performance, while the advantage of asynchronous is to not block UI threads. Choosing multithreading or asynchronous depends on the nature of the task: Computation-intensive tasks use multithreading, tasks that interact with external resources and need to keep UI responsiveness use asynchronous.

See all articles