├── lib
├── SharpDX.dll
├── SharpDX.DXGI.dll
├── SharpDX.Direct2D1.dll
├── SharpDX.Direct3D11.dll
└── License.txt
├── Cyjb.Projects.JigsawGame
├── JigsawGame.ico
├── GlobalSuppressions.cs
├── Resources
│ ├── Loading.gif
│ ├── JigsawHelp.png
│ ├── Settings.png
│ ├── ShowThumb.png
│ ├── ShowBackground.png
│ └── ShowBorderOnly.png
├── Jigsaw
│ ├── JigsawPieceType.cs
│ ├── JigsawPieceState.cs
│ └── JigsawPieceSelectedCollection.cs
├── Renderer
│ ├── JigsawRendererType.cs
│ ├── JigsawScaleChangedEventArgs.cs
│ ├── JigsawRenderer.cs
│ ├── JigsawSimpleRenderer.cs
│ └── JigsawRenderPanel.cs
├── Shape
│ ├── PathType.cs
│ ├── JigsawShapeType.cs
│ ├── LineSegment.cs
│ ├── EndFigureSegment.cs
│ ├── PathSegment.cs
│ ├── BezierSegment.cs
│ ├── JigsawStandardCircleShape.cs
│ ├── JigsawStandardShape.cs
│ ├── ArcSegment.cs
│ ├── JigsawStandardSmoothShape.cs
│ ├── Path.cs
│ └── JigsawShape.cs
├── Cyjb.Projects.JigsawGame.csproj.user
├── WinFormUtility.cs
├── LoadingForm.cs
├── JigsawSerializeContext.cs
├── Program.cs
├── HelpForm.cs
├── ToolForm.Designer.cs
├── AssemblyInfo.cs
├── JigsawInfo.cs
├── BugReportForm.cs
├── ThumbForm.Designer.cs
├── LoadingForm.Designer.cs
├── SettingForm.cs
├── ToolForm.cs
├── JigsawSetting.settings
├── App.config
├── SharpDXUtility.cs
├── BugReportForm.Designer.cs
├── ThumbForm.cs
├── Resources.Designer.cs
├── HelpForm.Designer.cs
├── HelpForm.resx
├── LoadingForm.resx
├── ThumbForm.resx
├── BugReportForm.resx
├── NewGameForm.resx
├── SettingForm.resx
├── Resources.resx
├── SettingForm.Designer.cs
├── JigsawSetting.Designer.cs
├── NewGameForm.cs
├── Cyjb.Projects.JigsawGame.csproj
├── DeviceManager.cs
└── MainForm.Designer.cs
├── .gitignore
├── README.md
└── Cyjb.Projects.JigsawGame.sln
/lib/SharpDX.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/lib/SharpDX.dll
--------------------------------------------------------------------------------
/lib/SharpDX.DXGI.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/lib/SharpDX.DXGI.dll
--------------------------------------------------------------------------------
/lib/SharpDX.Direct2D1.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/lib/SharpDX.Direct2D1.dll
--------------------------------------------------------------------------------
/lib/SharpDX.Direct3D11.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/lib/SharpDX.Direct3D11.dll
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/JigsawGame.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/Cyjb.Projects.JigsawGame/JigsawGame.ico
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/GlobalSuppressions.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/Cyjb.Projects.JigsawGame/GlobalSuppressions.cs
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Resources/Loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/Cyjb.Projects.JigsawGame/Resources/Loading.gif
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Resources/JigsawHelp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/Cyjb.Projects.JigsawGame/Resources/JigsawHelp.png
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Resources/Settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/Cyjb.Projects.JigsawGame/Resources/Settings.png
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Resources/ShowThumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/Cyjb.Projects.JigsawGame/Resources/ShowThumb.png
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Resources/ShowBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/Cyjb.Projects.JigsawGame/Resources/ShowBackground.png
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Resources/ShowBorderOnly.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CYJB/Cyjb.Projects.JigsawGame/HEAD/Cyjb.Projects.JigsawGame/Resources/ShowBorderOnly.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
2 | bin
3 | obj
4 | Properties
5 | *.pdb
6 |
7 | # mstest test results
8 | TestResults
9 |
10 | # my test project
11 | ConsoleTest
12 |
13 | # files
14 | *.suo
15 | *.snk
16 | *.vspx
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Jigsaw/JigsawPieceType.cs:
--------------------------------------------------------------------------------
1 | namespace Cyjb.Projects.JigsawGame.Jigsaw
2 | {
3 | ///
4 | /// 表示拼图碎片的类型。
5 | ///
6 | public enum JigsawPieceType
7 | {
8 | ///
9 | /// 普通碎片。
10 | ///
11 | Normal,
12 | ///
13 | /// 边界碎片。
14 | ///
15 | Border
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Renderer/JigsawRendererType.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace Cyjb.Projects.JigsawGame.Renderer
4 | {
5 | ///
6 | /// 拼图渲染器的类型。
7 | ///
8 | public enum JigsawRendererType
9 | {
10 | ///
11 | /// 简单渲染器。
12 | ///
13 | [Description("简单渲染器")]
14 | Simple,
15 | ///
16 | /// 特效渲染器。
17 | ///
18 | [Description("特效渲染器")]
19 | Effect
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/PathType.cs:
--------------------------------------------------------------------------------
1 | namespace Cyjb.Projects.JigsawGame.Shape
2 | {
3 | ///
4 | /// 路径的类型。
5 | ///
6 | public enum PathType
7 | {
8 | ///
9 | /// 直线段。
10 | ///
11 | Line,
12 | ///
13 | /// 弧线。
14 | ///
15 | Arc,
16 | ///
17 | /// 三次贝塞尔曲线。
18 | ///
19 | Bezier,
20 | ///
21 | /// 结束形状。
22 | ///
23 | EndFigure
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Cyjb.Projects.JigsawGame.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 发布\
5 |
6 |
7 |
8 |
9 |
10 | zh-CN
11 | false
12 |
13 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/JigsawShapeType.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace Cyjb.Projects.JigsawGame.Shape
4 | {
5 | ///
6 | /// 拼图的形状类型
7 | ///
8 | public enum JigsawShapeType
9 | {
10 | ///
11 | /// 四边形。
12 | ///
13 | [Description("四边形")]
14 | Square,
15 | ///
16 | /// 标准圆形。
17 | ///
18 | [Description("标准圆形")]
19 | StandardCirle,
20 | ///
21 | /// 标准形状。
22 | ///
23 | [Description("标准形状")]
24 | Standard,
25 | ///
26 | /// 标准平滑形。
27 | ///
28 | [Description("标准平滑形")]
29 | StandardSmooth,
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Jigsaw/JigsawPieceState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Cyjb.Projects.JigsawGame.Jigsaw
4 | {
5 | ///
6 | /// 拼图碎片所处的状态。
7 | ///
8 | [Flags]
9 | [Serializable]
10 | public enum JigsawPieceState
11 | {
12 | ///
13 | /// 普通状态。
14 | ///
15 | None = 0x0,
16 | ///
17 | /// 高亮状态。
18 | ///
19 | Highlight = 0x1,
20 | ///
21 | /// 被选中的状态。
22 | ///
23 | Selected = 0x2,
24 | ///
25 | /// 正在拖动状态。
26 | ///
27 | Draging = 0x4,
28 | ///
29 | /// 被选中且拖动状态。
30 | ///
31 | SelectedDraging = 0x6
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/WinFormUtility.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Windows.Forms;
3 |
4 | namespace Cyjb.Projects.JigsawGame
5 | {
6 | ///
7 | /// 包含 WinForm 的实用方法。
8 | ///
9 | public static class WinFormUtility
10 | {
11 | ///
12 | /// 初始化文件对话框的文件名。
13 | ///
14 | /// 对话框。
15 | /// 文件名。
16 | public static void InitFileName(this FileDialog dialog, string fileName)
17 | {
18 | if (!string.IsNullOrWhiteSpace(fileName))
19 | {
20 | dialog.FileName = Path.GetFileName(fileName);
21 | dialog.InitialDirectory = Path.GetDirectoryName(fileName);
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/LoadingForm.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace Cyjb.Projects.JigsawGame
4 | {
5 | ///
6 | /// 等待窗体。
7 | ///
8 | public partial class LoadingForm : ToolForm
9 | {
10 | ///
11 | /// 构造函数。
12 | ///
13 | public LoadingForm()
14 | {
15 | this.BackColor = JigsawSetting.Default.BackgroundColor;
16 | InitializeComponent();
17 | }
18 | ///
19 | /// 将窗体置于父窗体的中心。
20 | ///
21 | public void CenterParent()
22 | {
23 | this.Location = new Point(this.Owner.Location.X + (this.Owner.Size.Width - this.Width) / 2,
24 | this.Owner.Location.Y + (this.Owner.Size.Height - this.Height) / 2);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/LineSegment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct2D1;
4 |
5 | namespace Cyjb.Projects.JigsawGame.Shape
6 | {
7 | ///
8 | /// 表示一条直线路径段。
9 | ///
10 | [Serializable]
11 | public sealed class LineSegment : PathSegment
12 | {
13 | ///
14 | /// 使用指定的终结点初始化 类的新实例。
15 | ///
16 | /// 直线路径段的终结点。
17 | public LineSegment(Vector2 end)
18 | : base(PathType.Line, end)
19 | { }
20 | ///
21 | /// 使用当前的路径填充指定的路径几何。
22 | ///
23 | /// 要填充的路径几何。
24 | public override void FillGeometry(GeometrySink sink)
25 | {
26 | sink.AddLine(this.EndPoint);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Renderer/JigsawScaleChangedEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Cyjb.Projects.JigsawGame.Renderer
4 | {
5 | ///
6 | /// 拼图缩放比例被改变的事件参数。
7 | ///
8 | public sealed class JigsawScaleChangedEventArgs : EventArgs
9 | {
10 | ///
11 | /// 初始化 类的新实例。
12 | ///
13 | public JigsawScaleChangedEventArgs()
14 | { }
15 | ///
16 | /// 使用指定的缩放比例初始化 类的新实例。
17 | ///
18 | /// 拼图的缩放比例。
19 | public JigsawScaleChangedEventArgs(float scale)
20 | {
21 | this.Scale = scale;
22 | }
23 | ///
24 | /// 获取或设置拼图的缩放比例。
25 | ///
26 | public float Scale { get; set; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/JigsawSerializeContext.cs:
--------------------------------------------------------------------------------
1 | using SharpDX.Direct2D1;
2 |
3 | namespace Cyjb.Projects.JigsawGame
4 | {
5 | ///
6 | /// 拼图反序列化的上下文。
7 | ///
8 | public sealed class JigsawSerializeContext
9 | {
10 | ///
11 | /// 设备管理器。
12 | ///
13 | private DeviceManager manager;
14 | ///
15 | /// 使用指定的设备管理器初始化 类的新实例。
16 | ///
17 | /// 设备管理器。
18 | public JigsawSerializeContext(DeviceManager manager)
19 | {
20 | this.manager = manager;
21 | }
22 | ///
23 | /// 获取 Direct2D 的工厂。
24 | ///
25 | public Factory Factory { get { return manager.D2DFactory; } }
26 | ///
27 | /// 获取 Direct2D 的设备上下文。
28 | ///
29 | public DeviceContext DeviceContext { get { return manager.D2DContext; } }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | JigsawGame
2 | ====
3 |
4 | 该项目是我使用 [SharpDX 类库](http://sharpdx.org/)实现拼图游戏的源代码,仅供个人学习使用。
5 |
6 | 使用 Visual Studio 2013 编写,游戏的最低系统要求是 **Windows 7**,需要 **.Net Framework 4.5** 的支持。一些游戏特效需要 **DirectX 11.1** 的支持,但不影响游戏过程。
7 |
8 | 游戏操作很简单,用户选定的图片会被分割为很多拼图碎片,游戏过程就是拖动拼图碎片,并拼成完整的图案。关于游戏的更多说明,请参见我的[博客](http://www.cnblogs.com/cyjb/p/JigsawGame.html)。
9 |
10 | 
JigsawGame 由 CYJB 创作,采用 知识共享 Attribution-NonCommercial-NoDerivatives 4.0 国际 许可协议进行许可。
11 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace Cyjb.Projects.JigsawGame
5 | {
6 | static class Program
7 | {
8 | ///
9 | /// 应用程序的主入口点。
10 | ///
11 | [STAThread]
12 | static void Main(string[] fileNames)
13 | {
14 | Application.EnableVisualStyles();
15 | Application.SetCompatibleTextRenderingDefault(false);
16 | Application.ThreadException += (sender, e) =>
17 | {
18 | new BugReportForm(e.Exception).ShowDialog();
19 | Application.Exit();
20 | };
21 | AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
22 | {
23 | new BugReportForm(e.ExceptionObject as Exception).ShowDialog();
24 | };
25 | DeviceManager device = new DeviceManager();
26 | if (!device.SupportD2D)
27 | {
28 | MessageBox.Show("您的操作系统不支持 Direct2D 特性,不能运行此游戏");
29 | return;
30 | }
31 | Application.Run(new MainForm(device, fileNames));
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cyjb.Projects.JigsawGame", "Cyjb.Projects.JigsawGame\Cyjb.Projects.JigsawGame.csproj", "{1D1EF63A-E2E6-4869-81BB-AB049718781F}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {1D1EF63A-E2E6-4869-81BB-AB049718781F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {1D1EF63A-E2E6-4869-81BB-AB049718781F}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {1D1EF63A-E2E6-4869-81BB-AB049718781F}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {1D1EF63A-E2E6-4869-81BB-AB049718781F}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/HelpForm.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Windows.Forms;
3 |
4 | namespace Cyjb.Projects.JigsawGame
5 | {
6 | ///
7 | /// 帮助窗口。
8 | ///
9 | public partial class HelpForm : Form
10 | {
11 | ///
12 | /// 构造函数。
13 | ///
14 | public HelpForm()
15 | {
16 | InitializeComponent();
17 | }
18 | ///
19 | /// 打开链接的事件。
20 | ///
21 | private void pbxLink_Click(object sender, System.EventArgs e)
22 | {
23 | Process.Start("http://www.cnblogs.com/cyjb/");
24 | }
25 | ///
26 | /// 打开协议的事件。
27 | ///
28 | private void pbxLicense_Click(object sender, System.EventArgs e)
29 | {
30 | Process.Start("http://creativecommons.org/licenses/by-nc-nd/3.0/cn/");
31 | }
32 | ///
33 | /// 打开帮助链接的事件。
34 | ///
35 | private void pbxHelpLink_Click(object sender, System.EventArgs e)
36 | {
37 | Process.Start("http://www.cnblogs.com/cyjb/p/JigsawGame.html");
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/EndFigureSegment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct2D1;
4 |
5 | namespace Cyjb.Projects.JigsawGame.Shape
6 | {
7 | ///
8 | /// 结束当前形状的路径段。
9 | ///
10 | [Serializable]
11 | public sealed class EndFigureSegment : PathSegment
12 | {
13 | ///
14 | /// 使用指定的终结点初始化 类的新实例。
15 | ///
16 | /// 形状结束段的终结点。
17 | /// 下一段路径是否为黑色。
18 | public EndFigureSegment(Vector2 endPoint, bool isBlack)
19 | : base(PathType.EndFigure, endPoint)
20 | {
21 | this.IsBlack = isBlack;
22 | }
23 | ///
24 | /// 获取下一段路径是否为黑色。
25 | ///
26 | public bool IsBlack { get; private set; }
27 | ///
28 | /// 使用当前的路径填充指定的路径几何。
29 | ///
30 | /// 要填充的路径几何。
31 | public override void FillGeometry(GeometrySink sink)
32 | {
33 | sink.EndFigure(FigureEnd.Closed);
34 | sink.BeginFigure(EndPoint, FigureBegin.Filled);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/ToolForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cyjb.Projects.JigsawGame
2 | {
3 | partial class ToolForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.components = new System.ComponentModel.Container();
32 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
33 | this.Text = "ToolForm";
34 | }
35 |
36 | #endregion
37 | }
38 | }
--------------------------------------------------------------------------------
/lib/License.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2012 SharpDX - Alexandre Mutel
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Resources;
4 | using System.Runtime.InteropServices;
5 |
6 | // 有关程序集的常规信息通过以下
7 | // 特性集控制。更改这些特性值可修改
8 | // 与程序集关联的信息。
9 | [assembly: AssemblyTitle("JigsawGame")]
10 | [assembly: AssemblyDescription("拼图游戏")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("CYJB")]
13 | [assembly: AssemblyProduct("JigsawGame")]
14 | [assembly: AssemblyCopyright("Copyright © CYJB 2013")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // 将 ComVisible 设置为 false 使此程序集中的类型
19 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
20 | // 则将该类型上的 ComVisible 特性设置为 true。
21 | [assembly: ComVisible(false)]
22 |
23 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
24 | [assembly: Guid("ca084006-b01a-4a28-a713-792b46358bf1")]
25 |
26 | // 程序集的版本信息由下面四个值组成:
27 | //
28 | // 主版本
29 | // 次版本
30 | // 生成号
31 | // 修订号
32 | //
33 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
34 | // 方法是按如下所示使用“*”:
35 | // [assembly: AssemblyVersion("1.0.*")]
36 | [assembly: AssemblyVersion("1.1.0.0")]
37 | [assembly: AssemblyFileVersion("1.1.0.0")]
38 | [assembly: NeutralResourcesLanguageAttribute("en")]
39 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/PathSegment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct2D1;
4 |
5 | namespace Cyjb.Projects.JigsawGame.Shape
6 | {
7 | ///
8 | /// 表示一条路径段。
9 | ///
10 | [Serializable]
11 | public abstract class PathSegment
12 | {
13 | ///
14 | /// 使用指定的路径段类型和终结点初始化 类的新实例。
15 | ///
16 | /// 路径段的类型。
17 | /// 路径的终结点。
18 | protected PathSegment(PathType type, Vector2 end)
19 | {
20 | this.PathType = type;
21 | this.EndPoint = end;
22 | }
23 | ///
24 | /// 获取路径段的类型。
25 | ///
26 | public PathType PathType { get; private set; }
27 | ///
28 | /// 获取路径的终结点。
29 | ///
30 | public Vector2 EndPoint { get; private set; }
31 | ///
32 | /// 使用当前的路径填充指定的路径几何。
33 | ///
34 | /// 要填充的路径几何。
35 | public abstract void FillGeometry(GeometrySink sink);
36 | ///
37 | /// 返回当前对象的字符串表示形式。
38 | ///
39 | /// 当前对象的字符串表示形式。
40 | public override string ToString()
41 | {
42 | return string.Concat(PathType, " (", EndPoint.X, ", ", EndPoint.Y, ")");
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/JigsawInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics.CodeAnalysis;
3 | using System.Drawing;
4 |
5 | namespace Cyjb.Projects.JigsawGame
6 | {
7 | ///
8 | /// 表示拼图游戏的相关信息。
9 | ///
10 | [Serializable]
11 | public sealed class JigsawInfo
12 | {
13 | ///
14 | /// 获取或设置是否允许旋转拼图。
15 | ///
16 | public bool Rotatable { get; set; }
17 | ///
18 | /// 获取或设置是否允吸附到背景。
19 | ///
20 | public bool AnchorToBackground { get; set; }
21 | ///
22 | /// 获取或设置吸附的半径。
23 | ///
24 | public float AnchorRadius { get; set; }
25 | ///
26 | /// 获取或设置拼图碎片的总个数。
27 | ///
28 | public int PieceSum { get; set; }
29 | ///
30 | /// 获取或设置当前游戏的缩放比例。
31 | ///
32 | public float Scale { get; set; }
33 | ///
34 | /// 获取或设置当前游戏窗口的滚动位置。
35 | ///
36 | public Point ScrollPosition { get; set; }
37 | ///
38 | /// 获取或设置拼图的图像数据。
39 | ///
40 | [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
41 | public byte[] ImageData { get; set; }
42 | ///
43 | /// 获取或设置已被使用的时间。
44 | ///
45 | public TimeSpan UsedTime { get; set; }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/BezierSegment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct2D1;
4 | using D2D1 = SharpDX.Direct2D1;
5 |
6 | namespace Cyjb.Projects.JigsawGame.Shape
7 | {
8 | ///
9 | /// 表示一条三次贝塞尔曲线路径段。
10 | ///
11 | [Serializable]
12 | public sealed class BezierSegment : PathSegment
13 | {
14 | ///
15 | /// 使用指定的设置初始化 类的新实例。
16 | ///
17 | /// 三次贝塞尔曲线路径段的终结点。
18 | /// 三次贝塞尔曲线路径的第一个控制点。
19 | /// 三次贝塞尔曲线路径的第二个控制点。
20 | public BezierSegment(Vector2 end, Vector2 point1, Vector2 point2)
21 | : base(PathType.Arc, end)
22 | {
23 | this.Point1 = point1;
24 | this.Point2 = point2;
25 | }
26 | ///
27 | /// 获取第一个控制点。
28 | ///
29 | public Vector2 Point1 { get; private set; }
30 | ///
31 | /// 获取第二个控制点。
32 | ///
33 | public Vector2 Point2 { get; private set; }
34 | ///
35 | /// 使用当前的路径填充指定的路径几何。
36 | ///
37 | /// 要填充的路径几何。
38 | public override void FillGeometry(GeometrySink sink)
39 | {
40 | D2D1.BezierSegment bezier = new D2D1.BezierSegment()
41 | {
42 | Point1 = this.Point1,
43 | Point2 = this.Point2,
44 | Point3 = this.EndPoint
45 | };
46 | sink.AddBezier(bezier);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/JigsawStandardCircleShape.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct2D1;
4 |
5 | namespace Cyjb.Projects.JigsawGame.Shape
6 | {
7 | ///
8 | /// 拼图的标准圆形。
9 | ///
10 | public sealed class JigsawStandardCircleShape : JigsawShape
11 | {
12 | ///
13 | /// 初始化 的新实例。
14 | ///
15 | public JigsawStandardCircleShape() : base(0) { }
16 | ///
17 | /// 向拼图碎片的路径中添加一条边,路径的当前节点总是在起始点。
18 | ///
19 | /// 路径。
20 | /// 边的起始点。
21 | /// 边的结束点。
22 | /// 该边的凹凸性。
23 | /// 与该条边相关的一组随机数,范围都是 [0, 1)。
24 | protected override void AddBorder(Path path, Vector2 startPoint, Vector2 endPoint,
25 | bool border, float[] randoms)
26 | {
27 | Vector2 sp = Vector2.Lerp(startPoint, endPoint, 1f / 3);
28 | Vector2 ep = Vector2.Lerp(startPoint, endPoint, 2f / 3);
29 | path.AddLine(sp);
30 | double angle = Math.Atan2(endPoint.Y - startPoint.Y, endPoint.X - startPoint.X) * 180 / Math.PI + 180;
31 | float len = Vector2.Distance(startPoint, endPoint) / 6;
32 | path.AddArc(ep, new Size2F(len, len), (float)angle,
33 | border ? SweepDirection.CounterClockwise : SweepDirection.Clockwise, ArcSize.Small);
34 | path.AddLine(endPoint);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/BugReportForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Text;
4 | using System.Windows.Forms;
5 |
6 | namespace Cyjb.Projects.JigsawGame
7 | {
8 | ///
9 | /// 报告异常的窗体。
10 | ///
11 | public partial class BugReportForm : Form
12 | {
13 | ///
14 | /// 初始化 类的新实例。
15 | ///
16 | /// 异常对象。
17 | public BugReportForm(Exception ex)
18 | {
19 | InitializeComponent();
20 | if (ex == null)
21 | {
22 | tbxException.Text = "无异常信息。";
23 | }
24 | else
25 | {
26 | StringBuilder text = new StringBuilder();
27 | FormatException(ex, text);
28 | tbxException.Text = text.ToString();
29 | }
30 | }
31 | ///
32 | /// 格式化异常。
33 | ///
34 | /// 要格式化的异常对象。
35 | /// 格式化后的文本。
36 | private void FormatException(Exception ex, StringBuilder text)
37 | {
38 | text.Append(ex.GetType());
39 | text.Append(": ");
40 | text.AppendLine(ex.Message);
41 | text.AppendLine(ex.StackTrace);
42 | if (ex.InnerException != null)
43 | {
44 | text.AppendLine();
45 | text.AppendLine("InnerException:");
46 | FormatException(ex.InnerException, text);
47 | }
48 | }
49 | ///
50 | /// 报告异常的链接。
51 | ///
52 | private void linkReport_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
53 | {
54 | Process.Start("http://www.cnblogs.com/cyjb/p/JigsawGame.html");
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/JigsawStandardShape.cs:
--------------------------------------------------------------------------------
1 | using SharpDX;
2 |
3 | namespace Cyjb.Projects.JigsawGame.Shape
4 | {
5 | ///
6 | /// 拼图的标准形状。
7 | ///
8 | public sealed class JigsawStandardShape : JigsawShape
9 | {
10 | ///
11 | /// 初始化 的新实例。
12 | ///
13 | public JigsawStandardShape() : base(3) { }
14 | ///
15 | /// 向拼图碎片的路径中添加一条边,路径的当前节点总是在起始点。
16 | ///
17 | /// 路径。
18 | /// 边的起始点。
19 | /// 边的结束点。
20 | /// 该边的凹凸性。
21 | /// 与该条边相关的一组随机数,范围都是 [0, 1)。
22 | protected override void AddBorder(Path path, Vector2 startPoint, Vector2 endPoint,
23 | bool border, float[] randoms)
24 | {
25 | // 贝塞尔曲线的起始和结束点。
26 | float rate1 = 1f / 3 + randoms[0] / 12;
27 | Vector2 sp = Vector2.Lerp(startPoint, endPoint, rate1);
28 | Vector2 ep = Vector2.Lerp(startPoint, endPoint, 1 - rate1);
29 | // 贝塞尔曲线的控制点。
30 | float rate2 = rate1 - randoms[1] / 4;
31 | Vector2 c1 = Vector2.Lerp(startPoint, endPoint, rate2);
32 | Vector2 c2 = Vector2.Lerp(startPoint, endPoint, 1 - rate2);
33 | // 与边框垂直的向量。
34 | Vector2 cross = new Vector2(endPoint.Y - startPoint.Y, startPoint.X - endPoint.X);
35 | if (!border)
36 | {
37 | cross.X *= -1;
38 | cross.Y *= -1;
39 | }
40 | cross *= 1f / 4 + randoms[2] / 8;
41 | path.AddLine(sp);
42 | path.AddBezier(ep, c1 + cross, c2 + cross);
43 | path.AddLine(endPoint);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/ArcSegment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using SharpDX;
3 | using SharpDX.Direct2D1;
4 | using D2D1 = SharpDX.Direct2D1;
5 |
6 | namespace Cyjb.Projects.JigsawGame.Shape
7 | {
8 | ///
9 | /// 表示一条弧线路径段。
10 | ///
11 | [Serializable]
12 | public sealed class ArcSegment : PathSegment
13 | {
14 | ///
15 | /// 使用指定的设置初始化 类的新实例。
16 | ///
17 | /// 弧线路径段的终结点。
18 | /// 弧线路径段的尺寸。
19 | /// 弧线路径段的旋转角度。
20 | /// 弧线路径段的绘制方向。
21 | /// 弧线路径段是否大于 180 度。
22 | public ArcSegment(Vector2 end, Size2F size, float rotationAngel,
23 | SweepDirection sweepDirection, ArcSize arcSize)
24 | : base(PathType.Arc, end)
25 | {
26 | this.Size = size;
27 | this.RotationAngle = rotationAngel;
28 | this.SweepDirection = sweepDirection;
29 | this.ArcSize = arcSize;
30 | }
31 | ///
32 | /// 获取弧线路径段的尺寸。
33 | ///
34 | public Size2F Size { get; private set; }
35 | ///
36 | /// 获取弧线路径段的旋转角度。
37 | ///
38 | public float RotationAngle { get; private set; }
39 | ///
40 | /// 获取弧线路径段的绘制方向。
41 | ///
42 | public SweepDirection SweepDirection { get; private set; }
43 | ///
44 | /// 获取弧线路径段是否大于 180 度。
45 | ///
46 | public ArcSize ArcSize { get; private set; }
47 | ///
48 | /// 使用当前的路径填充指定的路径几何。
49 | ///
50 | /// 要填充的路径几何。
51 | public override void FillGeometry(GeometrySink sink)
52 | {
53 | D2D1.ArcSegment arc = new D2D1.ArcSegment()
54 | {
55 | Point = EndPoint,
56 | Size = Size,
57 | RotationAngle = RotationAngle,
58 | SweepDirection = SweepDirection,
59 | ArcSize = ArcSize
60 | };
61 | sink.AddArc(arc);
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/JigsawStandardSmoothShape.cs:
--------------------------------------------------------------------------------
1 | using SharpDX;
2 |
3 | namespace Cyjb.Projects.JigsawGame.Shape
4 | {
5 | ///
6 | /// 拼图的标准平滑形状。
7 | ///
8 | public sealed class JigsawStandardSmoothShape : JigsawShape
9 | {
10 | ///
11 | /// 初始化 的新实例。
12 | ///
13 | public JigsawStandardSmoothShape() : base(5) { }
14 | ///
15 | /// 向拼图碎片的路径中添加一条边,路径的当前节点总是在起始点。
16 | ///
17 | /// 路径。
18 | /// 边的起始点。
19 | /// 边的结束点。
20 | /// 该边的凹凸性。
21 | /// 与该条边相关的一组随机数,范围都是 [0, 1)。
22 | protected override void AddBorder(Path path, Vector2 startPoint, Vector2 endPoint, bool border, float[] randoms)
23 | {
24 | // 贝塞尔曲线的起始和结束点。
25 | float rate1 = 1f / 3 + randoms[0] / 12;
26 | Vector2 sp = Vector2.Lerp(startPoint, endPoint, rate1);
27 | Vector2 ep = Vector2.Lerp(startPoint, endPoint, 1 - rate1);
28 | // 贝塞尔曲线的控制点。
29 | float rate2 = rate1 - randoms[1] / 4;
30 | Vector2 c1 = Vector2.Lerp(startPoint, endPoint, rate2);
31 | Vector2 c2 = Vector2.Lerp(startPoint, endPoint, 1 - rate2);
32 | // 与边框垂直的向量。
33 | Vector2 cross = new Vector2(endPoint.Y - startPoint.Y, startPoint.X - endPoint.X);
34 | if (!border)
35 | {
36 | cross.X *= -1;
37 | cross.Y *= -1;
38 | }
39 | cross *= 1f / 4 + randoms[2] / 8;
40 | c1 += cross;
41 | c2 += cross;
42 | // 连接边框的贝塞尔曲线。
43 | float rate3 = 1f / 6 + randoms[3] / 6;
44 | Vector2 sc2 = sp + (sp - c1) * rate3;
45 | Vector2 sc1 = Vector2.Lerp(startPoint, sc2, randoms[4]);
46 | Vector2 ec1 = ep + (ep - c2) * rate3;
47 | Vector2 ec2 = Vector2.Lerp(endPoint, ec1, randoms[4]);
48 | path.AddBezier(sp, sc1, sc2);
49 | path.AddBezier(ep, c1, c2);
50 | path.AddBezier(endPoint, ec1, ec2);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/ThumbForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cyjb.Projects.JigsawGame
2 | {
3 | partial class ThumbForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.SuspendLayout();
32 | //
33 | // ThumbForm
34 | //
35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
37 | this.ClientSize = new System.Drawing.Size(284, 261);
38 | this.DoubleBuffered = true;
39 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
40 | this.MaximizeBox = false;
41 | this.MinimizeBox = false;
42 | this.MinimumSize = new System.Drawing.Size(100, 100);
43 | this.Name = "ThumbForm";
44 | this.ShowIcon = false;
45 | this.ShowInTaskbar = false;
46 | this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
47 | this.Text = "缩略图";
48 | this.SizeChanged += new System.EventHandler(this.ThumbForm_SizeChanged);
49 | this.Paint += new System.Windows.Forms.PaintEventHandler(this.ThumbForm_Paint);
50 | this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ThumbForm_MouseDown);
51 | this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ThumbForm_MouseMove);
52 | this.ResumeLayout(false);
53 |
54 | }
55 |
56 | #endregion
57 |
58 | }
59 | }
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/LoadingForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cyjb.Projects.JigsawGame
2 | {
3 | partial class LoadingForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.pictureBox1 = new System.Windows.Forms.PictureBox();
32 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
33 | this.SuspendLayout();
34 | //
35 | // pictureBox1
36 | //
37 | this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
38 | this.pictureBox1.Image = global::Cyjb.Projects.JigsawGame.Resources.Loading;
39 | this.pictureBox1.Location = new System.Drawing.Point(0, 0);
40 | this.pictureBox1.Name = "pictureBox1";
41 | this.pictureBox1.Size = new System.Drawing.Size(100, 100);
42 | this.pictureBox1.TabIndex = 0;
43 | this.pictureBox1.TabStop = false;
44 | //
45 | // LoadingForm
46 | //
47 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
48 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
49 | this.ClientSize = new System.Drawing.Size(100, 100);
50 | this.Controls.Add(this.pictureBox1);
51 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
52 | this.MaximumSize = new System.Drawing.Size(100, 100);
53 | this.MinimumSize = new System.Drawing.Size(100, 100);
54 | this.Name = "LoadingForm";
55 | this.ShowIcon = false;
56 | this.ShowInTaskbar = false;
57 | this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
58 | this.Text = "等待...";
59 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
60 | this.ResumeLayout(false);
61 |
62 | }
63 |
64 | #endregion
65 |
66 | private System.Windows.Forms.PictureBox pictureBox1;
67 | }
68 | }
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/SettingForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows.Forms;
4 | using Cyjb.Projects.JigsawGame.Renderer;
5 |
6 | namespace Cyjb.Projects.JigsawGame
7 | {
8 | ///
9 | /// 设置窗体。
10 | ///
11 | public partial class SettingForm : Form
12 | {
13 | ///
14 | /// 构造函数。
15 | ///
16 | /// 是否可以使用 Effect 拼图渲染器。
17 | public SettingForm(bool enabledEffect)
18 | {
19 | InitializeComponent();
20 | this.tbarBackgroundAlpha.Value = (int)(JigsawSetting.Default.BackgroundAlpha * 100);
21 | this.pbxBackgroundColor.BackColor = JigsawSetting.Default.BackgroundColor;
22 | if (enabledEffect)
23 | {
24 | this.RendererType = EnumExt.Parse(JigsawSetting.Default.Renderer);
25 | if (this.RendererType == JigsawRendererType.Effect)
26 | {
27 | rbtnEffect.Checked = true;
28 | }
29 | this.lblEffectWarn.Visible = false;
30 | }
31 | else
32 | {
33 | this.rbtnSample.Checked = true;
34 | this.rbtnEffect.Enabled = false;
35 | this.lblEffectWarn.Visible = true;
36 | }
37 | }
38 | ///
39 | /// 获取设置的拼图渲染器。
40 | ///
41 | public JigsawRendererType RendererType { get; private set; }
42 | ///
43 | /// 背景不透明度被改变的事件。
44 | ///
45 | private void tbarBackgroundAlpha_Scroll(object sender, EventArgs e)
46 | {
47 | lblBackgroundAlphaInfo.Text = tbarBackgroundAlpha.Value.ToString(CultureInfo.CurrentCulture) + "%";
48 | JigsawSetting.Default.BackgroundAlpha = (float)tbarBackgroundAlpha.Value / 100;
49 | }
50 | ///
51 | /// 打开颜色设置对话框。
52 | ///
53 | private void pbxBackgroundColor_Click(object sender, EventArgs e)
54 | {
55 | this.backgroundColorDialog.Color = JigsawSetting.Default.BackgroundColor;
56 | if (this.backgroundColorDialog.ShowDialog() == DialogResult.OK)
57 | {
58 | JigsawSetting.Default.BackgroundColor = this.backgroundColorDialog.Color;
59 | this.pbxBackgroundColor.BackColor = JigsawSetting.Default.BackgroundColor;
60 | }
61 | }
62 | ///
63 | /// 拼图渲染器被改变的事件。
64 | ///
65 | private void rbtnSample_CheckedChanged(object sender, EventArgs e)
66 | {
67 | if (rbtnSample.Checked)
68 | {
69 | this.RendererType = JigsawRendererType.Simple;
70 | }
71 | else
72 | {
73 | this.RendererType = JigsawRendererType.Effect;
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/ToolForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Security.Permissions;
4 | using System.Windows.Forms;
5 |
6 | namespace Cyjb.Projects.JigsawGame
7 | {
8 | ///
9 | /// 工具窗体的基类。
10 | ///
11 | public partial class ToolForm : Form
12 | {
13 | ///
14 | /// 初始化 类的新实例。
15 | ///
16 | public ToolForm()
17 | {
18 | InitializeComponent();
19 | }
20 | ///
21 | /// 获取或设置是否可以在工作区拖动窗体。
22 | ///
23 | protected bool ClientDraggable { get; set; }
24 |
25 | #region 消息循环
26 |
27 | ///
28 | /// 设置活动窗口。
29 | ///
30 | /// 活动窗口的句柄。
31 | /// 返回值。
32 | [DllImport("user32.dll")]
33 | private extern static IntPtr SetActiveWindow(IntPtr handle);
34 | ///
35 | /// WM_ACTIVATE 消息。
36 | ///
37 | private const int WM_ACTIVATE = 0x006;
38 | ///
39 | /// WM_ACTIVATEAPP 消息。
40 | ///
41 | private const int WM_ACTIVATEAPP = 0x01C;
42 | ///
43 | /// WM_NCACTIVATE 消息。
44 | ///
45 | private const int WM_NCACTIVATE = 0x086;
46 | ///
47 | /// WA_INACTIVE 消息。
48 | ///
49 | private const int WA_INACTIVE = 0;
50 | ///
51 | /// WM_MOUSEACTIVATE 消息。
52 | ///
53 | private const int WM_MOUSEACTIVATE = 0x21;
54 | ///
55 | /// MA_NOACTIVATE 消息。
56 | ///
57 | private const int MA_NOACTIVATE = 3;
58 | ///
59 | /// 窗口消息循环重载,用于使缩略图窗口不接受焦点。
60 | ///
61 | [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
62 | protected override void WndProc(ref Message m)
63 | {
64 | // 鼠标左键按下
65 | if (m.Msg == 0x0201)
66 | {
67 | // 当可以在工作区拖动窗体时。
68 | if (this.ClientDraggable)
69 | {
70 | // 改消息为非客户区按下鼠标
71 | m.Msg = 0x00a1;
72 | // 默认值
73 | m.LParam = IntPtr.Zero;
74 | // 鼠标放在标题栏内
75 | m.WParam = new IntPtr(2);
76 | }
77 | }
78 | else if (m.Msg == WM_MOUSEACTIVATE)
79 | {
80 | m.Result = new IntPtr(MA_NOACTIVATE);
81 | return;
82 | }
83 | else if (m.Msg == WM_NCACTIVATE)
84 | {
85 | if (((int)m.WParam & 0xFFFF) != WA_INACTIVE)
86 | {
87 | if (m.LParam != IntPtr.Zero)
88 | {
89 | SetActiveWindow(m.LParam);
90 | }
91 | else
92 | {
93 | SetActiveWindow(IntPtr.Zero);
94 | }
95 | }
96 | }
97 | base.WndProc(ref m);
98 | }
99 |
100 | #endregion // 消息循环
101 |
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/JigsawSetting.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 0.3
7 |
8 |
9 | 400, 300
10 |
11 |
12 | 0, 0
13 |
14 |
15 | True
16 |
17 |
18 | White
19 |
20 |
21 | 0, 0
22 |
23 |
24 | 0, 0
25 |
26 |
27 | Normal
28 |
29 |
30 | 0
31 |
32 |
33 | 0
34 |
35 |
36 |
37 |
38 |
39 | Effect
40 |
41 |
42 | False
43 |
44 |
45 | False
46 |
47 |
48 | False
49 |
50 |
51 | False
52 |
53 |
54 | 0.3
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Jigsaw/JigsawPieceSelectedCollection.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 |
4 | namespace Cyjb.Projects.JigsawGame.Jigsaw
5 | {
6 | ///
7 | /// 表示被选择的拼图碎片集合。
8 | ///
9 | public sealed class JigsawPieceSelectedCollection : IEnumerable
10 | {
11 | ///
12 | /// 拼图碎片集合。
13 | ///
14 | private HashSet items = new HashSet();
15 | ///
16 | /// 是否选择了单个拼图碎片。
17 | ///
18 | private bool singleSelected = false;
19 | ///
20 | /// 获取是否选择了单个拼图碎片。
21 | ///
22 | public bool SingleSelected { get { return singleSelected; } }
23 | ///
24 | /// 将指定的拼图碎片添加到被选择的集合中。
25 | ///
26 | /// 要添加的拼图碎片。
27 | public void Add(JigsawPiece piece)
28 | {
29 | piece.State |= JigsawPieceState.Selected;
30 | items.Add(piece);
31 | singleSelected = true;
32 | }
33 | ///
34 | /// 将指定的拼图碎片集合添加到被选择的集合中。
35 | ///
36 | /// 要添加的拼图碎片集合。
37 | public void AddRange(IEnumerable pieces)
38 | {
39 | foreach (JigsawPiece piece in pieces)
40 | {
41 | if (!piece.Frozen)
42 | {
43 | piece.State |= JigsawPieceState.Selected;
44 | items.Add(piece);
45 | }
46 | }
47 | singleSelected = false;
48 | }
49 | ///
50 | /// 清除所有被选择的拼图碎片。
51 | ///
52 | public void Clear()
53 | {
54 | foreach (JigsawPiece piece in this.items)
55 | {
56 | piece.State &= ~JigsawPieceState.Selected;
57 | }
58 | this.items.Clear();
59 | singleSelected = false;
60 | }
61 | ///
62 | /// 返回当前集合中是否包含给定的拼图碎片。
63 | ///
64 | /// 要测试的拼图碎片。
65 | /// 如果指定的拼图碎片包含在集合中,则为 true;
66 | /// 否则为 false。
67 | public bool Contains(JigsawPiece piece)
68 | {
69 | return this.items.Contains(piece);
70 | }
71 | ///
72 | /// 修改当前的集合,以仅包含该对象和指定集合中存在的元素。
73 | ///
74 | /// 要与当前的集合进行比较的集合。
75 | public void IntersectWith(IEnumerable other)
76 | {
77 | this.items.IntersectWith(other);
78 | }
79 |
80 | #region IEnumerable 成员
81 |
82 | ///
83 | /// 返回一个循环访问集合的枚举器。
84 | ///
85 | /// 可用于循环访问集合的 。
86 | public IEnumerator GetEnumerator()
87 | {
88 | return this.items.GetEnumerator();
89 | }
90 |
91 | #endregion // IEnumerable 成员
92 |
93 | #region IEnumerable 成员
94 |
95 | ///
96 | /// 返回一个循环访问集合的枚举器。
97 | ///
98 | /// 可用于循环访问集合的 。
99 | IEnumerator IEnumerable.GetEnumerator()
100 | {
101 | return this.GetEnumerator();
102 | }
103 |
104 | #endregion // IEnumerable 成员
105 |
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | 0.3
15 |
16 |
17 | 400, 300
18 |
19 |
20 | 0, 0
21 |
22 |
23 | True
24 |
25 |
26 | White
27 |
28 |
29 | 0, 0
30 |
31 |
32 | 0, 0
33 |
34 |
35 | Normal
36 |
37 |
38 | 0
39 |
40 |
41 | 0
42 |
43 |
44 |
45 |
46 |
47 | Effect
48 |
49 |
50 | False
51 |
52 |
53 | False
54 |
55 |
56 | False
57 |
58 |
59 | False
60 |
61 |
62 | 0.3
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/SharpDXUtility.cs:
--------------------------------------------------------------------------------
1 | using SharpDX;
2 | using SharpDX.Direct2D1;
3 |
4 | namespace Cyjb.Projects.JigsawGame
5 | {
6 | ///
7 | /// 包含 SharpDX 的实用方法。
8 | ///
9 | public static class SharpDXUtility
10 | {
11 |
12 | #region 几何操作
13 |
14 | ///
15 | /// 获取给定点集合中心(坐标平均值)。
16 | ///
17 | /// 要计算的点集合。
18 | /// 点集合的中心。
19 | public static Vector2 GetCenter(params Vector2[] args)
20 | {
21 | float x = 0, y = 0;
22 | for (int i = 0; i < args.Length; i++)
23 | {
24 | x += args[i].X;
25 | y += args[i].Y;
26 | }
27 | return new Vector2(x / args.Length, y / args.Length);
28 | }
29 | ///
30 | /// 计算三角形的面积(的二倍)。
31 | ///
32 | /// 三角形的第一个顶点坐标。
33 | /// 三角形的第二个顶点坐标。
34 | /// 三角形的第三个顶点坐标。
35 | ///
36 | public static float Area(Vector2 p1, Vector2 p2, Vector2 p3)
37 | {
38 | float area = (p1.X - p2.X) * (p1.Y - p3.Y) - (p1.X - p3.X) * (p1.Y - p2.Y);
39 | return area < 0 ? -area : area;
40 | }
41 | ///
42 | /// 将给定的几何图形组合并为一个组。
43 | ///
44 | /// 要合并集合图形组。
45 | /// 合并得到的集合图形组。
46 | public static GeometryGroup Merge(params GeometryGroup[] geometies)
47 | {
48 | int[] idx = new int[geometies.Length];
49 | for (int i = 0; i < geometies.Length; i++)
50 | {
51 | if (i == 0)
52 | {
53 | idx[i] = geometies[i].SourceGeometryCount;
54 | }
55 | else
56 | {
57 | idx[i] = idx[i - 1] + geometies[i].SourceGeometryCount;
58 | }
59 | }
60 | Geometry[] geoms = new Geometry[idx[idx.Length - 1]];
61 | for (int i = 0; i < geometies.Length; i++)
62 | {
63 | if (i == 0)
64 | {
65 | geometies[i].GetSourceGeometry().CopyTo(geoms, 0);
66 | }
67 | else
68 | {
69 | geometies[i].GetSourceGeometry().CopyTo(geoms, idx[i - 1]);
70 | }
71 | }
72 | return new GeometryGroup(geometies[0].Factory, FillMode.Winding, geoms);
73 | }
74 |
75 | #endregion // 几何操作
76 |
77 | #region 颜色操作
78 |
79 | ///
80 | /// 将指定的 对象转换为等价的
81 | /// 对象。
82 | ///
83 | /// 要转换的 对象。
84 | /// 转换得到的 对象。
85 | public static Color4 ToColor4(this System.Drawing.Color color)
86 | {
87 | uint argb = (uint)color.ToArgb();
88 | // Color4 的 R, G, B, A 是从小端到大端排列。
89 | uint rgba = (argb & 0xFF00FF00) | ((argb >> 16) & 0x000000FF) | ((argb << 16) & 0x00FF0000);
90 | return new Color4(rgba);
91 | }
92 | ///
93 | /// 将指定的 对象转换为等价的 对象。
94 | ///
95 | /// 要转换的 对象。
96 | /// 转换得到的 对象。
97 | public static System.Drawing.Color ToColor(this Color4 color)
98 | {
99 | uint rgba = (uint)color.ToRgba();
100 | // Color4 的 R, G, B, A 是从小端到大端排列。
101 | uint argb = (rgba & 0xFF00FF00) | ((rgba >> 16) & 0x000000FF) | ((rgba << 16) & 0x00FF0000);
102 | return System.Drawing.Color.FromArgb((int)argb);
103 | }
104 |
105 | #endregion // 颜色操作
106 |
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/BugReportForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cyjb.Projects.JigsawGame
2 | {
3 | partial class BugReportForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.lblTitle = new System.Windows.Forms.Label();
32 | this.tbxException = new System.Windows.Forms.TextBox();
33 | this.linkReport = new System.Windows.Forms.LinkLabel();
34 | this.btnClose = new System.Windows.Forms.Button();
35 | this.SuspendLayout();
36 | //
37 | // lblTitle
38 | //
39 | this.lblTitle.AutoSize = true;
40 | this.lblTitle.Location = new System.Drawing.Point(12, 9);
41 | this.lblTitle.Name = "lblTitle";
42 | this.lblTitle.Size = new System.Drawing.Size(161, 12);
43 | this.lblTitle.TabIndex = 0;
44 | this.lblTitle.Text = "游戏出现了无法处理的异常:";
45 | //
46 | // tbxException
47 | //
48 | this.tbxException.Location = new System.Drawing.Point(12, 34);
49 | this.tbxException.Multiline = true;
50 | this.tbxException.Name = "tbxException";
51 | this.tbxException.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
52 | this.tbxException.Size = new System.Drawing.Size(426, 186);
53 | this.tbxException.TabIndex = 1;
54 | //
55 | // linkReport
56 | //
57 | this.linkReport.AutoSize = true;
58 | this.linkReport.Location = new System.Drawing.Point(12, 231);
59 | this.linkReport.Name = "linkReport";
60 | this.linkReport.Size = new System.Drawing.Size(347, 12);
61 | this.linkReport.TabIndex = 2;
62 | this.linkReport.TabStop = true;
63 | this.linkReport.Text = "到 http://www.cnblogs.com/cyjb/p/JigsawGame.html 报告异常";
64 | this.linkReport.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkReport_LinkClicked);
65 | //
66 | // btnClose
67 | //
68 | this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
69 | this.btnClose.Location = new System.Drawing.Point(365, 226);
70 | this.btnClose.Name = "btnClose";
71 | this.btnClose.Size = new System.Drawing.Size(75, 23);
72 | this.btnClose.TabIndex = 3;
73 | this.btnClose.Text = "关闭";
74 | this.btnClose.UseVisualStyleBackColor = true;
75 | //
76 | // BugReportForm
77 | //
78 | this.AcceptButton = this.btnClose;
79 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
81 | this.CancelButton = this.btnClose;
82 | this.ClientSize = new System.Drawing.Size(450, 261);
83 | this.Controls.Add(this.btnClose);
84 | this.Controls.Add(this.linkReport);
85 | this.Controls.Add(this.tbxException);
86 | this.Controls.Add(this.lblTitle);
87 | this.MaximizeBox = false;
88 | this.MinimizeBox = false;
89 | this.Name = "BugReportForm";
90 | this.ShowIcon = false;
91 | this.ShowInTaskbar = false;
92 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
93 | this.Text = "异常报告";
94 | this.ResumeLayout(false);
95 | this.PerformLayout();
96 |
97 | }
98 |
99 | #endregion
100 |
101 | private System.Windows.Forms.Label lblTitle;
102 | private System.Windows.Forms.TextBox tbxException;
103 | private System.Windows.Forms.LinkLabel linkReport;
104 | private System.Windows.Forms.Button btnClose;
105 | }
106 | }
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Renderer/JigsawRenderer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 | using Cyjb.Projects.JigsawGame.Jigsaw;
5 | using SharpDX.Direct2D1;
6 |
7 | namespace Cyjb.Projects.JigsawGame.Renderer
8 | {
9 | ///
10 | /// 拼图的渲染器。
11 | ///
12 | public abstract class JigsawRenderer : IDisposable
13 | {
14 | ///
15 | /// 创建指定类型的拼图渲染器。
16 | ///
17 | /// 拼图渲染器的类型。
18 | /// 设备管理器。
19 | public static JigsawRenderer CreateRenderer(JigsawRendererType rendererType, DeviceManager deviceManager)
20 | {
21 | switch (rendererType)
22 | {
23 | case JigsawRendererType.Effect:
24 | return new JigsawEffectRenderer(deviceManager);
25 | default:
26 | return new JigsawSimpleRenderer(deviceManager);
27 | }
28 | }
29 | ///
30 | /// 设备管理器。
31 | ///
32 | private DeviceManager deviceManager;
33 | ///
34 | /// 需要渲染的拼图碎片列表。
35 | ///
36 | private List currentPieces = new List();
37 | ///
38 | /// 使用指定的设备管理器初始化 类的新实例。
39 | ///
40 | /// 设备管理器。
41 | protected JigsawRenderer(DeviceManager deviceManager)
42 | {
43 | this.deviceManager = deviceManager;
44 | }
45 |
46 | #region IDisposable 成员
47 |
48 | ///
49 | /// 释放对象占用的资源。
50 | ///
51 | public void Dispose()
52 | {
53 | this.Dispose(true);
54 | GC.SuppressFinalize(this);
55 | }
56 | ///
57 | /// 释放对象占用的资源。
58 | ///
59 | /// 是否释放托管资源。
60 | protected virtual void Dispose(bool disposing)
61 | {
62 | ClearResources();
63 | }
64 |
65 | #endregion // IDisposable 成员
66 |
67 | ///
68 | /// 获取拼图渲染器的类型。
69 | ///
70 | public abstract JigsawRendererType RendererType { get; }
71 | ///
72 | /// 获取拼图图片数据。
73 | ///
74 | protected Bitmap Image { get; private set; }
75 | ///
76 | /// 获取 Direct2D 渲染目标。
77 | ///
78 | protected RenderTarget RenderTarget
79 | {
80 | get { return this.deviceManager.RenderTarget; }
81 | }
82 | ///
83 | /// 获取 Direct2D 设备上下文。
84 | ///
85 | protected DeviceContext DeviceContext
86 | {
87 | get { return this.deviceManager.D2DContext; }
88 | }
89 | ///
90 | /// 获取设备管理器。
91 | ///
92 | protected DeviceManager DeviceManager
93 | {
94 | get { return this.deviceManager; }
95 | }
96 | ///
97 | /// 获取需要渲染的拼图碎片列表,以拼图被传入的顺序排列。
98 | ///
99 | protected IList CurrentPieces
100 | {
101 | get { return this.currentPieces; }
102 | }
103 | ///
104 | /// 准备渲染拼图碎片。
105 | ///
106 | /// 拼图使用的图片数据。
107 | /// 所有拼图碎片的集合。
108 | /// 拼图碎片是否可以旋转。
109 | /// 取消任务的通知。
110 | public virtual void PrepareRender(byte[] imageData, JigsawPieceCollection pieces, bool rotatable,
111 | CancellationToken ct)
112 | {
113 | if (imageData == null)
114 | {
115 | throw CommonExceptions.ArgumentNull("imageData");
116 | }
117 | ClearResources();
118 | this.Image = this.deviceManager.LoadBitmapFromBytes(imageData);
119 | }
120 | ///
121 | /// 清除渲染使用的资源。
122 | ///
123 | public virtual void ClearResources()
124 | {
125 | if (this.Image != null)
126 | {
127 | this.Image.Dispose();
128 | this.Image = null;
129 | }
130 | }
131 | ///
132 | /// 渲染指定的拼图碎片。
133 | ///
134 | /// 要绘制的拼图碎片集合。
135 | public void Render(IEnumerable pieces)
136 | {
137 | this.currentPieces.Clear();
138 | this.currentPieces.AddRange(pieces);
139 | Render();
140 | }
141 | ///
142 | /// 渲染拼图碎片。
143 | ///
144 | protected abstract void Render();
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/ThumbForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | namespace Cyjb.Projects.JigsawGame
6 | {
7 | ///
8 | /// 缩略图窗口。
9 | ///
10 | public partial class ThumbForm : ToolForm
11 | {
12 | ///
13 | /// 显示的缩略图。
14 | ///
15 | private Image image;
16 | ///
17 | /// 图片的缩放比例。
18 | ///
19 | private float imageScale;
20 | ///
21 | /// 最小的可用缩放比例。
22 | ///
23 | private float minScale;
24 | ///
25 | /// 图片的当前缩放比例。
26 | ///
27 | private float currentScale;
28 | ///
29 | /// 上一次的鼠标位置。
30 | ///
31 | private Point lastMouseLocation;
32 | ///
33 | /// 图片的 X 坐标。
34 | ///
35 | private float imageX;
36 | ///
37 | /// 图片的 Y 坐标。
38 | ///
39 | private float imageY;
40 | ///
41 | /// 构造函数。
42 | ///
43 | public ThumbForm()
44 | {
45 | InitializeComponent();
46 | }
47 | ///
48 | /// 获取或设置显示的缩略图。
49 | ///
50 | public Image Image
51 | {
52 | get { return this.image; }
53 | set
54 | {
55 | this.image = value;
56 | if (this.image != null)
57 | {
58 | minScale = Math.Min((float)this.ClientRectangle.Width / image.Width,
59 | (float)this.ClientRectangle.Height / image.Height);
60 | imageScale = float.NegativeInfinity;
61 | imageX = imageY = 0f;
62 | }
63 | this.Invalidate();
64 | }
65 | }
66 |
67 | #region 控件事件
68 |
69 | ///
70 | /// 鼠标按下的事件。
71 | ///
72 | private void ThumbForm_MouseDown(object sender, MouseEventArgs e)
73 | {
74 | lastMouseLocation = e.Location;
75 | }
76 | ///
77 | /// 鼠标移动的事件。
78 | ///
79 | private void ThumbForm_MouseMove(object sender, MouseEventArgs e)
80 | {
81 | if (this.image == null)
82 | {
83 | return;
84 | }
85 | if (e.Button == MouseButtons.Left)
86 | {
87 | imageX -= (e.Location.X - lastMouseLocation.X) / this.currentScale;
88 | imageY -= (e.Location.Y - lastMouseLocation.Y) / this.currentScale;
89 | this.Invalidate();
90 | }
91 | else if (e.Button == MouseButtons.Right)
92 | {
93 | float rate = this.currentScale;
94 | this.imageScale = this.currentScale + (e.Location.X - lastMouseLocation.X) / 200.0f;
95 | rate = this.imageScale / rate - 1;
96 | this.imageX += this.ClientRectangle.Width / 2 * rate;
97 | this.imageY += this.ClientRectangle.Height / 2 * rate;
98 | this.Invalidate();
99 | }
100 | lastMouseLocation = e.Location;
101 | }
102 | ///
103 | /// 绘制窗体的事件。
104 | ///
105 | private void ThumbForm_Paint(object sender, PaintEventArgs e)
106 | {
107 | e.Graphics.Clear(JigsawSetting.Default.BackgroundColor);
108 | if (image == null)
109 | {
110 | return;
111 | }
112 | float scale = imageScale;
113 | this.ClientDraggable = false;
114 | if (scale < minScale)
115 | {
116 | scale = minScale;
117 | this.ClientDraggable = true;
118 | }
119 | else if (scale > 4f)
120 | {
121 | scale = 4f;
122 | }
123 | currentScale = scale;
124 | float iw = this.ClientRectangle.Width / scale;
125 | float ih = this.ClientRectangle.Height / scale;
126 | if (imageX < 0)
127 | {
128 | imageX = 0;
129 | }
130 | if (imageX > image.Width - iw)
131 | {
132 | imageX = image.Width - iw;
133 | if (imageX < 0)
134 | {
135 | // 令图片居中对齐。
136 | imageX /= 2;
137 | }
138 | }
139 | if (imageY < 0)
140 | {
141 | imageY = 0;
142 | }
143 | if (imageY > image.Height - ih)
144 | {
145 | imageY = image.Height - ih;
146 | if (imageY < 0)
147 | {
148 | // 令图片居中对齐。
149 | imageY /= 2;
150 | }
151 | }
152 | RectangleF imageRect = new RectangleF(imageX, imageY, iw, ih);
153 | e.Graphics.DrawImage(image, this.ClientRectangle, imageRect, GraphicsUnit.Pixel);
154 | }
155 | ///
156 | /// 窗体大小被改变的事件。
157 | ///
158 | private void ThumbForm_SizeChanged(object sender, EventArgs e)
159 | {
160 | if (this.image == null)
161 | {
162 | return;
163 | }
164 | minScale = Math.Min((float)this.ClientRectangle.Width / image.Width,
165 | (float)this.ClientRectangle.Height / image.Height);
166 | this.Invalidate();
167 | }
168 |
169 | #endregion //控件事件
170 |
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/Path.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Cyjb.Collections.ObjectModel;
4 | using SharpDX;
5 | using SharpDX.Direct2D1;
6 |
7 | namespace Cyjb.Projects.JigsawGame.Shape
8 | {
9 | ///
10 | /// 表示一条路径。
11 | ///
12 | [Serializable]
13 | public sealed class Path : ListBase
14 | {
15 | ///
16 | /// 当前路径包含的图形的数目。
17 | ///
18 | private int figureCount = 1;
19 | ///
20 | /// 使用指定的起始点、重心和权重初始化 类的新实例。
21 | ///
22 | /// 路径的起始点。
23 | /// 当前路径是否为黑色。
24 | public Path(Vector2 start, bool isBlack)
25 | {
26 | this.StartPoint = start;
27 | this.IsBlack = isBlack;
28 | }
29 | ///
30 | /// 获取路径的起始点。
31 | ///
32 | public Vector2 StartPoint { get; private set; }
33 | ///
34 | /// 获取或设置路径的重心。
35 | ///
36 | public Vector2 Center { get; set; }
37 | ///
38 | /// 获取路或设置径的权重。
39 | ///
40 | public float Weight { get; set; }
41 | ///
42 | /// 获取当前路径是否为黑色。
43 | ///
44 | public bool IsBlack { get; private set; }
45 | ///
46 | /// 向当前路径中添加一条直线段。
47 | ///
48 | /// 直线段的终结点。
49 | public void AddLine(Vector2 end)
50 | {
51 | this.Add(new LineSegment(end));
52 | }
53 | ///
54 | /// 向当前路径中添加一条弧线段。
55 | ///
56 | /// 弧线路径段的终结点。
57 | /// 弧线路径段的尺寸。
58 | /// 弧线路径段的旋转角度。
59 | /// 弧线路径段的绘制方向。
60 | /// 弧线路径段是否大于 180 度。
61 | public void AddArc(Vector2 end, Size2F size, float rotationAngel,
62 | SweepDirection sweepDirection, ArcSize arcSize)
63 | {
64 | this.Add(new ArcSegment(end, size, rotationAngel, sweepDirection, arcSize));
65 | }
66 | ///
67 | /// 向当前路径中添加一条三次贝塞尔曲线。
68 | ///
69 | /// 三次贝塞尔曲线段的终结点。
70 | /// 三次贝塞尔曲线路径的第一个控制点。
71 | /// 三次贝塞尔曲线路径的第二个控制点。
72 | public void AddBezier(Vector2 end, Vector2 point1, Vector2 point2)
73 | {
74 | this.Add(new BezierSegment(end, point1, point2));
75 | }
76 | ///
77 | /// 将指定集合中的路径段添加到当前集合中。
78 | ///
79 | /// 要添加的路径段集合。
80 | public void AddRange(IEnumerable other)
81 | {
82 | foreach (PathSegment p in other)
83 | {
84 | this.Add(p);
85 | }
86 | }
87 | ///
88 | /// 根据当前的路径生成几何组。
89 | ///
90 | /// Direct2D 工厂。
91 | /// 生成的几何组。
92 | public GeometryGroup GetGeometryGroup(Factory factory)
93 | {
94 | Geometry[] geometries = new Geometry[this.figureCount];
95 | PathGeometry path = new PathGeometry(factory);
96 | GeometrySink sink = path.Open();
97 | sink.SetFillMode(FillMode.Winding);
98 | sink.BeginFigure(this.StartPoint, FigureBegin.Filled);
99 | int cnt = this.Count;
100 | int idx = 0;
101 | for (int i = 0; i < cnt; i++)
102 | {
103 | EndFigureSegment end = this[i] as EndFigureSegment;
104 | if (end == null)
105 | {
106 | this[i].FillGeometry(sink);
107 | }
108 | else
109 | {
110 | sink.EndFigure(FigureEnd.Closed);
111 | sink.Close();
112 | geometries[idx++] = path;
113 | path = new PathGeometry(factory);
114 | sink = path.Open();
115 | sink.SetFillMode(FillMode.Winding);
116 | sink.BeginFigure(end.EndPoint, FigureBegin.Filled);
117 | }
118 | }
119 | sink.EndFigure(FigureEnd.Closed);
120 | sink.Close();
121 | geometries[idx++] = path;
122 | return new GeometryGroup(factory, FillMode.Winding, geometries);
123 | }
124 | ///
125 | /// 返回当前路径中包含的形状的颜色(黑/白)。
126 | ///
127 | /// 表示颜色的数组。
128 | public bool[] GetColors()
129 | {
130 | bool[] colors = new bool[figureCount];
131 | colors[0] = this.IsBlack;
132 | int cnt = this.Count;
133 | for (int i = 0, idx = 1; i < cnt; i++)
134 | {
135 | EndFigureSegment end = this[i] as EndFigureSegment;
136 | if (end != null)
137 | {
138 | colors[idx++] = end.IsBlack;
139 | }
140 | }
141 | return colors;
142 | }
143 | ///
144 | /// 将指定的路径与当前的路径合并。
145 | ///
146 | /// 要合并的路径。
147 | public void Merge(Path path)
148 | {
149 | float sum = this.Weight + path.Weight;
150 | this.Center = new Vector2((this.Center.X * this.Weight + path.Center.X * path.Weight) / sum,
151 | (this.Center.Y * this.Weight + path.Center.Y * path.Weight) / sum);
152 | this.Weight = sum;
153 | this.Add(new EndFigureSegment(path.StartPoint, path.IsBlack));
154 | this.AddRange(path);
155 | this.figureCount += path.figureCount;
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.18051
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Cyjb.Projects.JigsawGame {
12 | using System;
13 |
14 |
15 | ///
16 | /// 一个强类型的资源类,用于查找本地化的字符串等。
17 | ///
18 | // 此类是由 StronglyTypedResourceBuilder
19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
21 | // (以 /str 作为命令选项),或重新生成 VS 项目。
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// 返回此类使用的缓存的 ResourceManager 实例。
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Cyjb.Projects.JigsawGame.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// 使用此强类型资源类,为所有资源查找
51 | /// 重写当前线程的 CurrentUICulture 属性。
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。
65 | ///
66 | internal static System.Drawing.Bitmap JigsawHelp {
67 | get {
68 | object obj = ResourceManager.GetObject("JigsawHelp", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。
75 | ///
76 | internal static System.Drawing.Bitmap Loading {
77 | get {
78 | object obj = ResourceManager.GetObject("Loading", resourceCulture);
79 | return ((System.Drawing.Bitmap)(obj));
80 | }
81 | }
82 |
83 | ///
84 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。
85 | ///
86 | internal static System.Drawing.Bitmap Settings {
87 | get {
88 | object obj = ResourceManager.GetObject("Settings", resourceCulture);
89 | return ((System.Drawing.Bitmap)(obj));
90 | }
91 | }
92 |
93 | ///
94 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。
95 | ///
96 | internal static System.Drawing.Bitmap ShowBackground {
97 | get {
98 | object obj = ResourceManager.GetObject("ShowBackground", resourceCulture);
99 | return ((System.Drawing.Bitmap)(obj));
100 | }
101 | }
102 |
103 | ///
104 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。
105 | ///
106 | internal static System.Drawing.Bitmap ShowBorderOnly {
107 | get {
108 | object obj = ResourceManager.GetObject("ShowBorderOnly", resourceCulture);
109 | return ((System.Drawing.Bitmap)(obj));
110 | }
111 | }
112 |
113 | ///
114 | /// 查找 System.Drawing.Bitmap 类型的本地化资源。
115 | ///
116 | internal static System.Drawing.Bitmap ShowThumb {
117 | get {
118 | object obj = ResourceManager.GetObject("ShowThumb", resourceCulture);
119 | return ((System.Drawing.Bitmap)(obj));
120 | }
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Renderer/JigsawSimpleRenderer.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using Cyjb.Projects.JigsawGame.Jigsaw;
3 | using SharpDX;
4 | using SharpDX.Direct2D1;
5 |
6 | namespace Cyjb.Projects.JigsawGame.Renderer
7 | {
8 | ///
9 | /// 拼图的简单渲染器。
10 | ///
11 | public sealed class JigsawSimpleRenderer : JigsawRenderer
12 | {
13 | ///
14 | /// 绘制拼图碎片的笔刷。
15 | ///
16 | private BitmapBrush brush;
17 | ///
18 | /// 普通边界的笔刷。
19 | ///
20 | private Color normalColor = Color.Black;
21 | ///
22 | /// 高亮边界的笔刷。
23 | ///
24 | private Color highlightColor = Color.Red;
25 | ///
26 | /// 被选择的边界的笔刷。
27 | ///
28 | private Color selectedColor = Color.Red;
29 | ///
30 | /// 普通边界的笔刷。
31 | ///
32 | private SolidColorBrush normalBrush;
33 | ///
34 | /// 高亮边界的笔刷。
35 | ///
36 | private SolidColorBrush highlightBrush;
37 | ///
38 | /// 被选择时的画笔。
39 | ///
40 | private SolidColorBrush selectedBrush;
41 | ///
42 | /// 使用指定的设备管理器初始化 类的新实例。
43 | ///
44 | /// 设备管理器。
45 | public JigsawSimpleRenderer(DeviceManager deviceManager)
46 | : base(deviceManager)
47 | {
48 | InitBrushes();
49 | }
50 | ///
51 | /// 初始化笔刷。
52 | ///
53 | private void InitBrushes()
54 | {
55 | this.normalBrush = new SolidColorBrush(this.RenderTarget, normalColor);
56 | this.highlightBrush = new SolidColorBrush(this.RenderTarget, highlightColor);
57 | this.selectedBrush = new SolidColorBrush(this.RenderTarget, selectedColor);
58 | }
59 |
60 | #region IDisposable 成员
61 |
62 | ///
63 | /// 释放对象占用的资源。
64 | ///
65 | /// 是否释放托管资源。
66 | protected override void Dispose(bool disposing)
67 | {
68 | this.normalBrush.Dispose();
69 | this.highlightBrush.Dispose();
70 | this.selectedBrush.Dispose();
71 | if (this.brush != null)
72 | {
73 | this.brush.Dispose();
74 | }
75 | base.Dispose(true);
76 | }
77 |
78 | #endregion // IDisposable 成员
79 |
80 | #region 渲染器属性
81 |
82 | ///
83 | /// 获取拼图渲染器的类型。
84 | ///
85 | public override JigsawRendererType RendererType { get { return JigsawRendererType.Simple; } }
86 | ///
87 | /// 获取或设置普通状态的拼图边框颜色。
88 | ///
89 | public Color NormalBorderColor
90 | {
91 | get { return normalColor; }
92 | set
93 | {
94 | normalColor = value;
95 | normalBrush.Color = value;
96 | }
97 | }
98 | ///
99 | /// 获取或设置高亮状态的拼图边框颜色。
100 | ///
101 | public Color HighlightBorderColor
102 | {
103 | get { return highlightColor; }
104 | set
105 | {
106 | highlightColor = value;
107 | highlightBrush.Color = value;
108 | }
109 | }
110 | ///
111 | /// 获取或设置被选择的状态的拼图边框颜色。
112 | ///
113 | public Color SelectedBorderColor
114 | {
115 | get { return selectedColor; }
116 | set
117 | {
118 | selectedColor = value;
119 | selectedBrush.Color = value;
120 | }
121 | }
122 |
123 | #endregion // 渲染器属性
124 |
125 | ///
126 | /// 准备渲染拼图碎片。
127 | ///
128 | /// 拼图使用的图片数据。
129 | /// 所有拼图碎片的集合。
130 | /// 拼图碎片是否可以旋转。
131 | /// 取消任务的通知。
132 | public override void PrepareRender(byte[] imageData, JigsawPieceCollection pieces, bool rotatable,
133 | CancellationToken ct)
134 | {
135 | base.PrepareRender(imageData, pieces, rotatable, ct);
136 | if (this.brush == null)
137 | {
138 | this.brush = new BitmapBrush(this.RenderTarget, this.Image);
139 | }
140 | else
141 | {
142 | this.brush.Bitmap = this.Image;
143 | }
144 | }
145 | ///
146 | /// 清除渲染使用的资源。
147 | ///
148 | public override void ClearResources()
149 | {
150 | base.ClearResources();
151 | if (this.brush != null)
152 | {
153 | this.brush.Dispose();
154 | this.brush = null;
155 | }
156 | }
157 | ///
158 | /// 渲染拼图碎片。
159 | ///
160 | protected override void Render()
161 | {
162 | int idx = CurrentPieces.Count - 1;
163 | for (; idx >= 0; idx--)
164 | {
165 | JigsawPiece piece = CurrentPieces[idx];
166 | if (!piece.Visible)
167 | {
168 | continue;
169 | }
170 | brush.Transform = piece.TransformMatrix;
171 | this.RenderTarget.FillGeometry(piece.Path, brush);
172 | Brush lineBrush = normalBrush;
173 | if ((piece.State & JigsawPieceState.Selected) == JigsawPieceState.Selected)
174 | {
175 | lineBrush = selectedBrush;
176 | }
177 | else if ((piece.State & JigsawPieceState.Highlight) == JigsawPieceState.Highlight)
178 | {
179 | lineBrush = highlightBrush;
180 | }
181 | this.RenderTarget.DrawGeometry(piece.Path, lineBrush, 1);
182 | }
183 | }
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/HelpForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cyjb.Projects.JigsawGame
2 | {
3 | partial class HelpForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.btnClose = new System.Windows.Forms.Button();
32 | this.pbxLink = new System.Windows.Forms.PictureBox();
33 | this.pbxLicense = new System.Windows.Forms.PictureBox();
34 | this.pbxHelpLink = new System.Windows.Forms.PictureBox();
35 | ((System.ComponentModel.ISupportInitialize)(this.pbxLink)).BeginInit();
36 | ((System.ComponentModel.ISupportInitialize)(this.pbxLicense)).BeginInit();
37 | ((System.ComponentModel.ISupportInitialize)(this.pbxHelpLink)).BeginInit();
38 | this.SuspendLayout();
39 | //
40 | // btnClose
41 | //
42 | this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
43 | this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
44 | this.btnClose.Location = new System.Drawing.Point(499, 319);
45 | this.btnClose.Name = "btnClose";
46 | this.btnClose.Size = new System.Drawing.Size(75, 23);
47 | this.btnClose.TabIndex = 4;
48 | this.btnClose.Text = "关闭";
49 | this.btnClose.UseVisualStyleBackColor = true;
50 | //
51 | // pbxLink
52 | //
53 | this.pbxLink.BackColor = System.Drawing.Color.Transparent;
54 | this.pbxLink.Cursor = System.Windows.Forms.Cursors.Hand;
55 | this.pbxLink.Location = new System.Drawing.Point(279, 7);
56 | this.pbxLink.Name = "pbxLink";
57 | this.pbxLink.Size = new System.Drawing.Size(174, 25);
58 | this.pbxLink.TabIndex = 5;
59 | this.pbxLink.TabStop = false;
60 | this.pbxLink.Click += new System.EventHandler(this.pbxLink_Click);
61 | //
62 | // pbxLicense
63 | //
64 | this.pbxLicense.BackColor = System.Drawing.Color.Transparent;
65 | this.pbxLicense.Cursor = System.Windows.Forms.Cursors.Hand;
66 | this.pbxLicense.Location = new System.Drawing.Point(72, 33);
67 | this.pbxLicense.Name = "pbxLicense";
68 | this.pbxLicense.Size = new System.Drawing.Size(380, 25);
69 | this.pbxLicense.TabIndex = 5;
70 | this.pbxLicense.TabStop = false;
71 | this.pbxLicense.Click += new System.EventHandler(this.pbxLicense_Click);
72 | //
73 | // pbxHelpLink
74 | //
75 | this.pbxHelpLink.BackColor = System.Drawing.Color.Transparent;
76 | this.pbxHelpLink.Cursor = System.Windows.Forms.Cursors.Hand;
77 | this.pbxHelpLink.Location = new System.Drawing.Point(212, 327);
78 | this.pbxHelpLink.Name = "pbxHelpLink";
79 | this.pbxHelpLink.Size = new System.Drawing.Size(62, 25);
80 | this.pbxHelpLink.TabIndex = 5;
81 | this.pbxHelpLink.TabStop = false;
82 | this.pbxHelpLink.Click += new System.EventHandler(this.pbxHelpLink_Click);
83 | //
84 | // HelpForm
85 | //
86 | this.AcceptButton = this.btnClose;
87 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
88 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
89 | this.BackgroundImage = global::Cyjb.Projects.JigsawGame.Resources.JigsawHelp;
90 | this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
91 | this.CancelButton = this.btnClose;
92 | this.ClientSize = new System.Drawing.Size(586, 354);
93 | this.Controls.Add(this.pbxLicense);
94 | this.Controls.Add(this.pbxHelpLink);
95 | this.Controls.Add(this.pbxLink);
96 | this.Controls.Add(this.btnClose);
97 | this.DoubleBuffered = true;
98 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
99 | this.MaximizeBox = false;
100 | this.MinimizeBox = false;
101 | this.Name = "HelpForm";
102 | this.ShowIcon = false;
103 | this.ShowInTaskbar = false;
104 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
105 | this.Text = "游戏帮助";
106 | ((System.ComponentModel.ISupportInitialize)(this.pbxLink)).EndInit();
107 | ((System.ComponentModel.ISupportInitialize)(this.pbxLicense)).EndInit();
108 | ((System.ComponentModel.ISupportInitialize)(this.pbxHelpLink)).EndInit();
109 | this.ResumeLayout(false);
110 |
111 | }
112 |
113 | #endregion
114 |
115 | private System.Windows.Forms.Button btnClose;
116 | private System.Windows.Forms.PictureBox pbxLink;
117 | private System.Windows.Forms.PictureBox pbxLicense;
118 | private System.Windows.Forms.PictureBox pbxHelpLink;
119 | }
120 | }
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/HelpForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/LoadingForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/ThumbForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/BugReportForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/NewGameForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/SettingForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | Resources\JigsawHelp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | Resources\Loading.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
128 | Resources\Settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
131 | Resources\ShowBackground.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
132 |
133 |
134 | Resources\ShowBorderOnly.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
135 |
136 |
137 | Resources\ShowThumb.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
138 |
139 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Shape/JigsawShape.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using SharpDX;
3 |
4 | namespace Cyjb.Projects.JigsawGame.Shape
5 | {
6 | ///
7 | /// 拼图形状的抽象基类。
8 | ///
9 | public class JigsawShape
10 | {
11 | ///
12 | /// 创建指定类型的拼图形状。
13 | ///
14 | /// 拼图形状的类型。
15 | /// 指定类型的拼图形状。
16 | public static JigsawShape CreateShape(JigsawShapeType type)
17 | {
18 | switch (type)
19 | {
20 | case JigsawShapeType.Square:
21 | return new JigsawShape();
22 | case JigsawShapeType.StandardCirle:
23 | return new JigsawStandardCircleShape();
24 | case JigsawShapeType.Standard:
25 | return new JigsawStandardShape();
26 | case JigsawShapeType.StandardSmooth:
27 | return new JigsawStandardSmoothShape();
28 | }
29 | return null;
30 | }
31 | ///
32 | /// 拼图分割时的随机化程度(0.0 - 1.0)。
33 | ///
34 | private float randomization = 0.3f;
35 | ///
36 | /// 拼图分割的水平片数。
37 | ///
38 | private int horizontalDimension = 10;
39 | ///
40 | /// 拼图分割的垂直片数。
41 | ///
42 | private int verticalDimension = 10;
43 | ///
44 | /// 拼图的尺寸。
45 | ///
46 | private Size2F size = new Size2F(100, 100);
47 | ///
48 | /// 拼图形状集合。
49 | ///
50 | private List paths = new List();
51 | ///
52 | /// 生成边时需要的随机数个数。
53 | ///
54 | private int randomCount;
55 | ///
56 | /// 创建一个新的拼图划分器。
57 | ///
58 | private JigsawShape()
59 | : this(0)
60 | { }
61 | ///
62 | /// 创建一个新的拼图划分器。
63 | ///
64 | /// 生成边时需要的随机数个数。
65 | protected JigsawShape(int randomCnt)
66 | {
67 | this.randomCount = randomCnt;
68 | }
69 | ///
70 | /// 获取或设置拼图分割时的随机化程度(0.0 - 1.0)。
71 | ///
72 | public float Randomization
73 | {
74 | get { return this.randomization; }
75 | set
76 | {
77 | if (value < 0f || value > 1f)
78 | {
79 | throw CommonExceptions.ArgumentOutOfRange("value", value, 0, 1);
80 | }
81 | else
82 | {
83 | this.randomization = value;
84 | }
85 | }
86 | }
87 | ///
88 | /// 获取或设置拼图分割的水平片数。
89 | ///
90 | public int HorizontalDimension
91 | {
92 | get { return this.horizontalDimension; }
93 | set
94 | {
95 | if (value <= 0)
96 | {
97 | throw CommonExceptions.ArgumentOutOfRange("value", value);
98 | }
99 | this.horizontalDimension = value;
100 | }
101 | }
102 | ///
103 | /// 获取或设置拼图分割的垂直片数。
104 | ///
105 | public int VerticalDimension
106 | {
107 | get { return this.verticalDimension; }
108 | set
109 | {
110 | if (value <= 0)
111 | {
112 | throw CommonExceptions.ArgumentOutOfRange("value", value);
113 | }
114 | this.verticalDimension = value;
115 | }
116 | }
117 | ///
118 | /// 获取或设置拼图的尺寸。
119 | ///
120 | public Size2F Size
121 | {
122 | get { return this.size; }
123 | set
124 | {
125 | if (value.Height <= 0f || value.Width <= 0f)
126 | {
127 | throw CommonExceptions.ArgumentOutOfRange("value", value);
128 | }
129 | this.size = value;
130 | }
131 | }
132 | ///
133 | /// 获取拼图形状集合。
134 | ///
135 | public IList Paths
136 | {
137 | get { return this.paths; }
138 | }
139 | ///
140 | /// 生成拼图形状。
141 | ///
142 | public void GererateJigsawShape()
143 | {
144 | // 拼图尺寸。
145 | float width = Size.Width;
146 | float height = Size.Height;
147 | // 拼图碎片的尺寸。
148 | float pWidth = width / horizontalDimension;
149 | float pHeight = height / verticalDimension;
150 | // 拼图碎片的随机化尺寸。
151 | float rWidth = pWidth * randomization / 3;
152 | float rHeight = pHeight * randomization / 3;
153 | float x, y;
154 | // 最后一行节点。
155 | Vector2[] corners = new Vector2[horizontalDimension + 1];
156 | Vector2 lastPoint = new Vector2();
157 | // 最后一行的边凹凸性。
158 | bool[] borders = new bool[horizontalDimension + 1];
159 | bool lastBorder = false;
160 | // 最后一行的随机数。
161 | float[][] values = new float[horizontalDimension + 1][];
162 | float[] lastValue = null;
163 | for (int i = 0; i <= this.verticalDimension; i++)
164 | {
165 | for (int j = 0; j <= this.horizontalDimension; j++)
166 | {
167 | y = pHeight * i;
168 | if (i > 0 && i < this.verticalDimension && rHeight != 0f)
169 | {
170 | y += (float)((RandomExt.NextDouble() * 2 - 1) * rHeight);
171 | }
172 | x = pWidth * j;
173 | if (j > 0 && j < horizontalDimension && rWidth != 0f)
174 | {
175 | x += (float)((RandomExt.NextDouble() * 2 - 1) * rWidth);
176 | }
177 | Vector2 currentPoint = new Vector2(x, y);
178 | if (i == 0)
179 | {
180 | corners[j] = currentPoint;
181 | }
182 | else if (j == 0)
183 | {
184 | lastPoint = currentPoint;
185 | }
186 | else
187 | {
188 | // 将拼图碎片放置在国际象棋盘上,每片会分别对应黑色和白色。
189 | bool isBlack = (i + j) % 2 == 0;
190 | Path path = new Path(corners[j], isBlack);
191 | // 逆时针添加边。
192 | // 顶边。
193 | if (i == 1)
194 | {
195 | path.AddLine(corners[j - 1]);
196 | }
197 | else
198 | {
199 | AddBorder(path, corners[j], corners[j - 1], !borders[j], values[j]);
200 | }
201 | // 左边。
202 | if (j == 1)
203 | {
204 | path.AddLine(lastPoint);
205 | }
206 | else
207 | {
208 | AddBorder(path, corners[j - 1], lastPoint, !lastBorder, lastValue);
209 | }
210 | // 底边。
211 | if (i == verticalDimension)
212 | {
213 | path.AddLine(currentPoint);
214 | }
215 | else
216 | {
217 | borders[j] = RandomExt.NextBoolean();
218 | values[j] = GenerateRandom();
219 | AddBorder(path, lastPoint, currentPoint, borders[j], values[j]);
220 | }
221 | // 右边。
222 | if (j == horizontalDimension)
223 | {
224 | path.AddLine(corners[j]);
225 | }
226 | else
227 | {
228 | lastBorder = RandomExt.NextBoolean();
229 | lastValue = GenerateRandom();
230 | AddBorder(path, currentPoint, corners[j], lastBorder, lastValue);
231 | }
232 | this.paths.Add(path);
233 | // 计算形状的重心。
234 | Vector2 c1 = SharpDXUtility.GetCenter(corners[j - 1], corners[j], lastPoint);
235 | Vector2 c2 = SharpDXUtility.GetCenter(corners[j], lastPoint, currentPoint);
236 | float w1 = SharpDXUtility.Area(corners[j - 1], corners[j], lastPoint);
237 | float w2 = SharpDXUtility.Area(corners[j], lastPoint, currentPoint);
238 | path.Weight = w1 + w2;
239 | path.Center = new Vector2((c1.X * w1 + c2.X * w2) / path.Weight, (c1.Y * w1 + c2.Y * w2) / path.Weight);
240 | corners[j - 1] = lastPoint;
241 | lastPoint = currentPoint;
242 | if (j == this.horizontalDimension)
243 | {
244 | corners[j] = currentPoint;
245 | }
246 | }
247 | }
248 | }
249 | }
250 | ///
251 | /// 生成指定个数的随机数。
252 | ///
253 | /// 生成的随机数数组。
254 | private float[] GenerateRandom()
255 | {
256 | if (randomCount == 0)
257 | {
258 | return null;
259 | }
260 | float[] randoms = new float[randomCount];
261 | for (int i = 0; i < randomCount; i++)
262 | {
263 | randoms[i] = RandomExt.NextSingle();
264 | }
265 | return randoms;
266 | }
267 | ///
268 | /// 向拼图碎片的路径中添加一条边,路径的当前节点总是在起始点。
269 | ///
270 | /// 路径。
271 | /// 边的起始点。
272 | /// 边的结束点。
273 | /// 该边的凹凸性。
274 | /// 与该条边相关的一组随机数,范围都是 [0, 1)。
275 | protected virtual void AddBorder(Path path, Vector2 startPoint, Vector2 endPoint,
276 | bool border, float[] randoms)
277 | {
278 | path.AddLine(endPoint);
279 | }
280 | }
281 | }
282 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/SettingForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cyjb.Projects.JigsawGame
2 | {
3 | partial class SettingForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.lblBackgroundAlpha = new System.Windows.Forms.Label();
32 | this.tbarBackgroundAlpha = new System.Windows.Forms.TrackBar();
33 | this.lblBackgroundAlphaInfo = new System.Windows.Forms.Label();
34 | this.lblBackgroundColor = new System.Windows.Forms.Label();
35 | this.pbxBackgroundColor = new System.Windows.Forms.PictureBox();
36 | this.backgroundColorDialog = new System.Windows.Forms.ColorDialog();
37 | this.btnClose = new System.Windows.Forms.Button();
38 | this.lblRenderer = new System.Windows.Forms.Label();
39 | this.rbtnSample = new System.Windows.Forms.RadioButton();
40 | this.rbtnEffect = new System.Windows.Forms.RadioButton();
41 | this.lblEffectWarn = new System.Windows.Forms.Label();
42 | ((System.ComponentModel.ISupportInitialize)(this.tbarBackgroundAlpha)).BeginInit();
43 | ((System.ComponentModel.ISupportInitialize)(this.pbxBackgroundColor)).BeginInit();
44 | this.SuspendLayout();
45 | //
46 | // lblBackgroundAlpha
47 | //
48 | this.lblBackgroundAlpha.AutoSize = true;
49 | this.lblBackgroundAlpha.Location = new System.Drawing.Point(12, 17);
50 | this.lblBackgroundAlpha.Name = "lblBackgroundAlpha";
51 | this.lblBackgroundAlpha.Size = new System.Drawing.Size(113, 12);
52 | this.lblBackgroundAlpha.TabIndex = 0;
53 | this.lblBackgroundAlpha.Text = "背景图片不透明度:";
54 | //
55 | // tbarBackgroundAlpha
56 | //
57 | this.tbarBackgroundAlpha.Location = new System.Drawing.Point(131, 12);
58 | this.tbarBackgroundAlpha.Maximum = 100;
59 | this.tbarBackgroundAlpha.Name = "tbarBackgroundAlpha";
60 | this.tbarBackgroundAlpha.Size = new System.Drawing.Size(341, 45);
61 | this.tbarBackgroundAlpha.TabIndex = 0;
62 | this.tbarBackgroundAlpha.TickFrequency = 10;
63 | this.tbarBackgroundAlpha.Value = 30;
64 | this.tbarBackgroundAlpha.Scroll += new System.EventHandler(this.tbarBackgroundAlpha_Scroll);
65 | //
66 | // lblBackgroundAlphaInfo
67 | //
68 | this.lblBackgroundAlphaInfo.AutoSize = true;
69 | this.lblBackgroundAlphaInfo.Location = new System.Drawing.Point(129, 45);
70 | this.lblBackgroundAlphaInfo.Name = "lblBackgroundAlphaInfo";
71 | this.lblBackgroundAlphaInfo.Size = new System.Drawing.Size(23, 12);
72 | this.lblBackgroundAlphaInfo.TabIndex = 1;
73 | this.lblBackgroundAlphaInfo.Text = "30%";
74 | //
75 | // lblBackgroundColor
76 | //
77 | this.lblBackgroundColor.AutoSize = true;
78 | this.lblBackgroundColor.Location = new System.Drawing.Point(30, 69);
79 | this.lblBackgroundColor.Name = "lblBackgroundColor";
80 | this.lblBackgroundColor.Size = new System.Drawing.Size(95, 12);
81 | this.lblBackgroundColor.TabIndex = 3;
82 | this.lblBackgroundColor.Text = "游戏背景颜色 :";
83 | //
84 | // pbxBackgroundColor
85 | //
86 | this.pbxBackgroundColor.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
87 | this.pbxBackgroundColor.Location = new System.Drawing.Point(131, 65);
88 | this.pbxBackgroundColor.Name = "pbxBackgroundColor";
89 | this.pbxBackgroundColor.Size = new System.Drawing.Size(50, 20);
90 | this.pbxBackgroundColor.TabIndex = 4;
91 | this.pbxBackgroundColor.TabStop = false;
92 | this.pbxBackgroundColor.Click += new System.EventHandler(this.pbxBackgroundColor_Click);
93 | //
94 | // backgroundColorDialog
95 | //
96 | this.backgroundColorDialog.AnyColor = true;
97 | //
98 | // btnClose
99 | //
100 | this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
101 | this.btnClose.Location = new System.Drawing.Point(205, 121);
102 | this.btnClose.Name = "btnClose";
103 | this.btnClose.Size = new System.Drawing.Size(75, 23);
104 | this.btnClose.TabIndex = 5;
105 | this.btnClose.Text = "关闭";
106 | this.btnClose.UseVisualStyleBackColor = true;
107 | //
108 | // lblRenderer
109 | //
110 | this.lblRenderer.AutoSize = true;
111 | this.lblRenderer.Location = new System.Drawing.Point(60, 97);
112 | this.lblRenderer.Name = "lblRenderer";
113 | this.lblRenderer.Size = new System.Drawing.Size(65, 12);
114 | this.lblRenderer.TabIndex = 6;
115 | this.lblRenderer.Text = "拼图样式:";
116 | //
117 | // rbtnSample
118 | //
119 | this.rbtnSample.AutoSize = true;
120 | this.rbtnSample.Checked = true;
121 | this.rbtnSample.Location = new System.Drawing.Point(131, 95);
122 | this.rbtnSample.Name = "rbtnSample";
123 | this.rbtnSample.Size = new System.Drawing.Size(47, 16);
124 | this.rbtnSample.TabIndex = 7;
125 | this.rbtnSample.TabStop = true;
126 | this.rbtnSample.Text = "简单";
127 | this.rbtnSample.UseVisualStyleBackColor = true;
128 | this.rbtnSample.CheckedChanged += new System.EventHandler(this.rbtnSample_CheckedChanged);
129 | //
130 | // rbtnEffect
131 | //
132 | this.rbtnEffect.AutoSize = true;
133 | this.rbtnEffect.Location = new System.Drawing.Point(184, 95);
134 | this.rbtnEffect.Name = "rbtnEffect";
135 | this.rbtnEffect.Size = new System.Drawing.Size(47, 16);
136 | this.rbtnEffect.TabIndex = 8;
137 | this.rbtnEffect.Text = "特效";
138 | this.rbtnEffect.UseVisualStyleBackColor = true;
139 | //
140 | // lblEffectWarn
141 | //
142 | this.lblEffectWarn.AutoSize = true;
143 | this.lblEffectWarn.Enabled = false;
144 | this.lblEffectWarn.Location = new System.Drawing.Point(224, 97);
145 | this.lblEffectWarn.Name = "lblEffectWarn";
146 | this.lblEffectWarn.Size = new System.Drawing.Size(161, 12);
147 | this.lblEffectWarn.TabIndex = 9;
148 | this.lblEffectWarn.Text = "(您的电脑不支持特效样式)";
149 | //
150 | // SettingForm
151 | //
152 | this.AcceptButton = this.btnClose;
153 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
154 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
155 | this.CancelButton = this.btnClose;
156 | this.ClientSize = new System.Drawing.Size(484, 157);
157 | this.Controls.Add(this.rbtnEffect);
158 | this.Controls.Add(this.lblEffectWarn);
159 | this.Controls.Add(this.rbtnSample);
160 | this.Controls.Add(this.lblRenderer);
161 | this.Controls.Add(this.btnClose);
162 | this.Controls.Add(this.pbxBackgroundColor);
163 | this.Controls.Add(this.lblBackgroundColor);
164 | this.Controls.Add(this.lblBackgroundAlphaInfo);
165 | this.Controls.Add(this.tbarBackgroundAlpha);
166 | this.Controls.Add(this.lblBackgroundAlpha);
167 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
168 | this.MaximizeBox = false;
169 | this.MinimizeBox = false;
170 | this.Name = "SettingForm";
171 | this.ShowIcon = false;
172 | this.ShowInTaskbar = false;
173 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
174 | this.Text = "游戏设置";
175 | ((System.ComponentModel.ISupportInitialize)(this.tbarBackgroundAlpha)).EndInit();
176 | ((System.ComponentModel.ISupportInitialize)(this.pbxBackgroundColor)).EndInit();
177 | this.ResumeLayout(false);
178 | this.PerformLayout();
179 |
180 | }
181 |
182 | #endregion
183 |
184 | private System.Windows.Forms.Label lblBackgroundAlpha;
185 | private System.Windows.Forms.TrackBar tbarBackgroundAlpha;
186 | private System.Windows.Forms.Label lblBackgroundAlphaInfo;
187 | private System.Windows.Forms.Label lblBackgroundColor;
188 | private System.Windows.Forms.PictureBox pbxBackgroundColor;
189 | private System.Windows.Forms.ColorDialog backgroundColorDialog;
190 | private System.Windows.Forms.Button btnClose;
191 | private System.Windows.Forms.Label lblRenderer;
192 | private System.Windows.Forms.RadioButton rbtnSample;
193 | private System.Windows.Forms.RadioButton rbtnEffect;
194 | private System.Windows.Forms.Label lblEffectWarn;
195 | }
196 | }
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/JigsawSetting.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.18051
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Cyjb.Projects.JigsawGame {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
16 | internal sealed partial class JigsawSetting : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static JigsawSetting defaultInstance = ((JigsawSetting)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new JigsawSetting())));
19 |
20 | public static JigsawSetting Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("0.3")]
29 | public float BackgroundAlpha {
30 | get {
31 | return ((float)(this["BackgroundAlpha"]));
32 | }
33 | set {
34 | this["BackgroundAlpha"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("400, 300")]
41 | public global::System.Drawing.Size ThumbSize {
42 | get {
43 | return ((global::System.Drawing.Size)(this["ThumbSize"]));
44 | }
45 | set {
46 | this["ThumbSize"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("0, 0")]
53 | public global::System.Drawing.Point ThumbLocation {
54 | get {
55 | return ((global::System.Drawing.Point)(this["ThumbLocation"]));
56 | }
57 | set {
58 | this["ThumbLocation"] = value;
59 | }
60 | }
61 |
62 | [global::System.Configuration.UserScopedSettingAttribute()]
63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
64 | [global::System.Configuration.DefaultSettingValueAttribute("True")]
65 | public bool ShowBackground {
66 | get {
67 | return ((bool)(this["ShowBackground"]));
68 | }
69 | set {
70 | this["ShowBackground"] = value;
71 | }
72 | }
73 |
74 | [global::System.Configuration.UserScopedSettingAttribute()]
75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
76 | [global::System.Configuration.DefaultSettingValueAttribute("White")]
77 | public global::System.Drawing.Color BackgroundColor {
78 | get {
79 | return ((global::System.Drawing.Color)(this["BackgroundColor"]));
80 | }
81 | set {
82 | this["BackgroundColor"] = value;
83 | }
84 | }
85 |
86 | [global::System.Configuration.UserScopedSettingAttribute()]
87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
88 | [global::System.Configuration.DefaultSettingValueAttribute("0, 0")]
89 | public global::System.Drawing.Point MainLocation {
90 | get {
91 | return ((global::System.Drawing.Point)(this["MainLocation"]));
92 | }
93 | set {
94 | this["MainLocation"] = value;
95 | }
96 | }
97 |
98 | [global::System.Configuration.UserScopedSettingAttribute()]
99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
100 | [global::System.Configuration.DefaultSettingValueAttribute("0, 0")]
101 | public global::System.Drawing.Size MainSize {
102 | get {
103 | return ((global::System.Drawing.Size)(this["MainSize"]));
104 | }
105 | set {
106 | this["MainSize"] = value;
107 | }
108 | }
109 |
110 | [global::System.Configuration.UserScopedSettingAttribute()]
111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
112 | [global::System.Configuration.DefaultSettingValueAttribute("Normal")]
113 | public global::System.Windows.Forms.FormWindowState MainState {
114 | get {
115 | return ((global::System.Windows.Forms.FormWindowState)(this["MainState"]));
116 | }
117 | set {
118 | this["MainState"] = value;
119 | }
120 | }
121 |
122 | [global::System.Configuration.UserScopedSettingAttribute()]
123 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
124 | [global::System.Configuration.DefaultSettingValueAttribute("0")]
125 | public int Difficulty {
126 | get {
127 | return ((int)(this["Difficulty"]));
128 | }
129 | set {
130 | this["Difficulty"] = value;
131 | }
132 | }
133 |
134 | [global::System.Configuration.UserScopedSettingAttribute()]
135 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
136 | [global::System.Configuration.DefaultSettingValueAttribute("0")]
137 | public int Shape {
138 | get {
139 | return ((int)(this["Shape"]));
140 | }
141 | set {
142 | this["Shape"] = value;
143 | }
144 | }
145 |
146 | [global::System.Configuration.UserScopedSettingAttribute()]
147 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
148 | [global::System.Configuration.DefaultSettingValueAttribute("")]
149 | public string FileName {
150 | get {
151 | return ((string)(this["FileName"]));
152 | }
153 | set {
154 | this["FileName"] = value;
155 | }
156 | }
157 |
158 | [global::System.Configuration.UserScopedSettingAttribute()]
159 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
160 | [global::System.Configuration.DefaultSettingValueAttribute("Effect")]
161 | public string Renderer {
162 | get {
163 | return ((string)(this["Renderer"]));
164 | }
165 | set {
166 | this["Renderer"] = value;
167 | }
168 | }
169 |
170 | [global::System.Configuration.UserScopedSettingAttribute()]
171 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
172 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
173 | public bool ShowThumb {
174 | get {
175 | return ((bool)(this["ShowThumb"]));
176 | }
177 | set {
178 | this["ShowThumb"] = value;
179 | }
180 | }
181 |
182 | [global::System.Configuration.UserScopedSettingAttribute()]
183 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
184 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
185 | public bool ShowBorder {
186 | get {
187 | return ((bool)(this["ShowBorder"]));
188 | }
189 | set {
190 | this["ShowBorder"] = value;
191 | }
192 | }
193 |
194 | [global::System.Configuration.UserScopedSettingAttribute()]
195 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
196 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
197 | public bool Anchor {
198 | get {
199 | return ((bool)(this["Anchor"]));
200 | }
201 | set {
202 | this["Anchor"] = value;
203 | }
204 | }
205 |
206 | [global::System.Configuration.UserScopedSettingAttribute()]
207 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
208 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
209 | public bool Rotatable {
210 | get {
211 | return ((bool)(this["Rotatable"]));
212 | }
213 | set {
214 | this["Rotatable"] = value;
215 | }
216 | }
217 |
218 | [global::System.Configuration.UserScopedSettingAttribute()]
219 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
220 | [global::System.Configuration.DefaultSettingValueAttribute("0.3")]
221 | public float Randomization {
222 | get {
223 | return ((float)(this["Randomization"]));
224 | }
225 | set {
226 | this["Randomization"] = value;
227 | }
228 | }
229 |
230 | [global::System.Configuration.UserScopedSettingAttribute()]
231 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
232 | [global::System.Configuration.DefaultSettingValueAttribute("")]
233 | public string ImageFileName {
234 | get {
235 | return ((string)(this["ImageFileName"]));
236 | }
237 | set {
238 | this["ImageFileName"] = value;
239 | }
240 | }
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Renderer/JigsawRenderPanel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Windows.Forms;
4 | using SharpDX;
5 | using SharpDX.Windows;
6 | using Point = System.Drawing.Point;
7 | using Size = System.Drawing.Size;
8 |
9 | namespace Cyjb.Projects.JigsawGame.Renderer
10 | {
11 | ///
12 | /// 用于渲染拼图游戏的控件。
13 | ///
14 | public sealed class JigsawRenderPanel : RenderControl
15 | {
16 | ///
17 | /// 设备管理器。
18 | ///
19 | private DeviceManager devices;
20 | ///
21 | /// 自动滚动的定时器。
22 | ///
23 | private Timer autoScrollTimer;
24 | ///
25 | /// 是否自动根据鼠标位置滚动。
26 | ///
27 | private bool autoMouseScroll;
28 | ///
29 | /// 拼图自动滚动的时间间隔。
30 | ///
31 | private int autoMouseScrollInterval = 16;
32 | ///
33 | /// 拼图自动滚动的最小距离。
34 | ///
35 | private int autoMouseScrollMargin = 20;
36 | ///
37 | /// 拼图图片至边距的最小距离。
38 | ///
39 | private float jigsawMargin = 100f;
40 | ///
41 | /// 拼图游戏的矩形范围。
42 | ///
43 | private RectangleF jigsawRegion;
44 | ///
45 | /// 拼图图片的尺寸。
46 | ///
47 | private Size2F imageSize;
48 | ///
49 | /// 拼图游戏的缩放比例。
50 | ///
51 | private float jigsawScale = 1f;
52 | ///
53 | /// 拼图游戏的矩形范围被改变的事件。
54 | ///
55 | public event EventHandler JigsawRegionChanged;
56 | ///
57 | /// 拼图游戏的缩放比例被改变之前的事件。
58 | ///
59 | public event EventHandler JigsawScaleChanging;
60 | ///
61 | /// 拼图游戏的缩放比例被改变的事件。
62 | ///
63 | public event EventHandler JigsawScaleChanged;
64 | ///
65 | /// 获取或设置设备管理器。
66 | ///
67 | public DeviceManager Devices
68 | {
69 | get { return this.devices; }
70 | set
71 | {
72 | this.devices = value;
73 | devices.CreateRenderTarget(this);
74 | }
75 | }
76 | ///
77 | /// 获取或设置拼图图片至边距的最小距离。
78 | ///
79 | [Description("拼图图片至边距的最小距离。")]
80 | [Category("Layout")]
81 | [DefaultValue(100f)]
82 | public float JigsawMargin
83 | {
84 | get { return this.jigsawMargin; }
85 | set
86 | {
87 | this.jigsawMargin = value;
88 | this.UpdateSize();
89 | }
90 | }
91 | ///
92 | /// 获取拼图游戏的矩形范围。
93 | ///
94 | [Browsable(false)]
95 | public RectangleF JigsawRegion
96 | {
97 | get { return this.jigsawRegion; }
98 | }
99 | ///
100 | /// 获取或设置拼图图片的尺寸。
101 | ///
102 | [Browsable(false)]
103 | public Size2F ImageSize
104 | {
105 | get { return this.imageSize; }
106 | set
107 | {
108 | this.imageSize = value;
109 | this.UpdateSize();
110 | }
111 | }
112 | ///
113 | /// 获取拼图游戏的缩放比例。
114 | ///
115 | [Browsable(false)]
116 | public float JigsawScale
117 | {
118 | get { return this.jigsawScale; }
119 | }
120 | ///
121 | /// 获取渲染区域的转换矩阵。
122 | ///
123 | [Browsable(false)]
124 | public Matrix3x2 RenderTargetTansform
125 | {
126 | get
127 | {
128 | return Matrix3x2.Translation(this.AutoScrollPosition.X - jigsawRegion.X,
129 | this.AutoScrollPosition.Y - jigsawRegion.Y);
130 | }
131 | }
132 |
133 | #region 尺寸变化
134 |
135 | ///
136 | /// 设置拼图的缩放比例。
137 | ///
138 | /// 缩放比例。
139 | /// 缩放的中心点,是当前的控件坐标。
140 | public void SetJigsawScale(float scale, Point center)
141 | {
142 | EventHandler scaleChanging = this.JigsawScaleChanging;
143 | if (scaleChanging != null)
144 | {
145 | JigsawScaleChangedEventArgs eventArgs = new JigsawScaleChangedEventArgs(scale);
146 | scaleChanging(this, eventArgs);
147 | scale = eventArgs.Scale;
148 | }
149 | if (this.jigsawScale == scale)
150 | {
151 | return;
152 | }
153 | this.jigsawScale = scale;
154 | // 更新尺寸的同时移动滚动条,使缩放的中心点尽可能不变。
155 | float oldWidth = jigsawRegion.Width;
156 | Point scroll = new Point(this.HorizontalScroll.Value + center.X,
157 | this.VerticalScroll.Value + center.Y);
158 | UpdateSize();
159 | // 这里强制重绘一次,防止出现闪烁。
160 | this.Invalidate();
161 | float rate = jigsawRegion.Width / oldWidth;
162 | this.AutoScrollPosition = new Point((int)(scroll.X * rate - center.X), (int)(scroll.Y * rate - center.Y));
163 | EventHandler scaleChanged = this.JigsawScaleChanged;
164 | if (scaleChanged != null)
165 | {
166 | scaleChanged(this, null);
167 | }
168 | }
169 | ///
170 | /// 缩放和滚动拼图,使得图片恰好居中显示在界面中。
171 | ///
172 | public void ShowImage()
173 | {
174 | float sw = this.ClientSize.Width / imageSize.Width;
175 | float sh = this.ClientSize.Height / imageSize.Height;
176 | float scale = 1f;
177 | if (sw < sh)
178 | {
179 | scale = sw;
180 | sw = this.jigsawMargin * scale;
181 | sh = -(this.ClientSize.Height - imageSize.Height * scale) / 2 + this.jigsawMargin * scale;
182 | }
183 | else
184 | {
185 | scale = sh;
186 | sw = -(this.ClientSize.Width - imageSize.Width * scale) / 2 + this.jigsawMargin * scale;
187 | sh = this.jigsawMargin * scale;
188 | }
189 | this.SetJigsawScale(scale, new Point());
190 | this.AutoScrollPosition = new Point((int)sw, (int)sh);
191 | }
192 | ///
193 | /// 控件尺寸改变的事件。
194 | ///
195 | protected override void OnSizeChanged(EventArgs e)
196 | {
197 | if (devices != null)
198 | {
199 | devices.ResizeRenderTarget(this);
200 | this.UpdateSize();
201 | }
202 | base.OnSizeChanged(e);
203 | }
204 | ///
205 | /// 更新拼图的尺寸。
206 | ///
207 | private void UpdateSize()
208 | {
209 | jigsawRegion = new RectangleF(-jigsawMargin * jigsawScale, -jigsawMargin * jigsawScale,
210 | (imageSize.Width + 2 * jigsawMargin) * jigsawScale, (imageSize.Height + 2 * jigsawMargin) * jigsawScale);
211 | Size autoScrollMinSize = new Size(0, 0);
212 | if (jigsawRegion.Width < this.ClientSize.Width)
213 | {
214 | jigsawRegion.Left = -(this.ClientSize.Width - imageSize.Width * this.jigsawScale) / 2;
215 | jigsawRegion.Right = jigsawRegion.Left + this.ClientSize.Width;
216 | }
217 | else
218 | {
219 | autoScrollMinSize.Width = (int)jigsawRegion.Width;
220 | }
221 | if (jigsawRegion.Height < this.ClientSize.Height)
222 | {
223 | jigsawRegion.Top = -(this.ClientSize.Height - imageSize.Height * this.jigsawScale) / 2;
224 | jigsawRegion.Bottom = jigsawRegion.Top + this.ClientSize.Height;
225 | }
226 | else
227 | {
228 | autoScrollMinSize.Height = (int)jigsawRegion.Height;
229 | }
230 | EventHandler jigsawRegionChanged = this.JigsawRegionChanged;
231 | if (jigsawRegionChanged != null)
232 | {
233 | jigsawRegionChanged(this, null);
234 | }
235 | this.AutoScrollMinSize = autoScrollMinSize;
236 | }
237 |
238 | #endregion // 尺寸变化
239 |
240 | #region 坐标映射
241 |
242 | ///
243 | /// 将指定渲染区域的坐标转换为拼图的坐标。
244 | ///
245 | /// 渲染区域的坐标。
246 | /// 拼图的坐标。
247 | public Vector2 PointToJigsaw(Point location)
248 | {
249 | return new Vector2(location.X - this.AutoScrollPosition.X + this.jigsawRegion.X,
250 | location.Y - this.AutoScrollPosition.Y + this.jigsawRegion.Y);
251 | }
252 | ///
253 | /// 将指定的拼图坐标转换为渲染区域的坐标。
254 | ///
255 | /// 拼图坐标。
256 | /// 渲染区域的坐标。
257 | public Point PointToClient(Vector2 location)
258 | {
259 | return new Point((int)(location.X + this.AutoScrollPosition.X - this.jigsawRegion.X),
260 | (int)(location.Y + this.AutoScrollPosition.Y - this.jigsawRegion.Y));
261 | }
262 |
263 | #endregion // 坐标映射
264 |
265 | ///
266 | /// 鼠标滚轮滚动的事件。
267 | ///
268 | protected override void OnMouseWheel(MouseEventArgs e)
269 | {
270 | if (Control.ModifierKeys == Keys.Shift)
271 | {
272 | if (this.HorizontalScroll.Visible)
273 | {
274 | this.AutoScrollPosition = new Point(this.HorizontalScroll.Value - e.Delta / 4,
275 | this.VerticalScroll.Value);
276 | }
277 | }
278 | else if (Control.ModifierKeys == Keys.Control)
279 | {
280 | this.SetJigsawScale(this.jigsawScale + (float)e.Delta / 1200, e.Location);
281 | }
282 | else
283 | {
284 | if (this.VerticalScroll.Visible)
285 | {
286 | this.AutoScrollPosition = new Point(this.HorizontalScroll.Value,
287 | this.VerticalScroll.Value - e.Delta / 4);
288 | }
289 | }
290 | // 屏蔽父控件的鼠标滚轮事件,也不再引发 MouseWheel 事件。
291 | }
292 |
293 | #region 自动滚动
294 |
295 | ///
296 | /// 获取或设置拼图自动滚动的最小距离。
297 | ///
298 | [Description("拼图自动滚动的最小距离。")]
299 | [Category("Layout")]
300 | [DefaultValue(20)]
301 | public int AutoMouseScrollMargin
302 | {
303 | get { return this.autoMouseScrollMargin; }
304 | set { this.autoMouseScrollMargin = value; }
305 | }
306 | ///
307 | /// 获取或设置拼图自动滚动的时间间隔。
308 | ///
309 | [Description("拼图自动滚动的时间间隔。")]
310 | [Category("Behavior")]
311 | [DefaultValue(16)]
312 | public int AutoMouseScrollInterval
313 | {
314 | get { return this.autoMouseScrollInterval; }
315 | set
316 | {
317 | this.autoMouseScrollInterval = value;
318 | if (this.autoScrollTimer != null)
319 | {
320 | this.autoScrollTimer.Interval = value;
321 | }
322 | }
323 | }
324 | ///
325 | /// 获取或设置当前控件是否根据鼠标坐标自动滚动。
326 | ///
327 | [Description("当前控件是否根据鼠标坐标自动滚动。")]
328 | [Category("Behavior")]
329 | [DefaultValue(false)]
330 | public bool AutoMouseScroll
331 | {
332 | get { return this.autoMouseScroll; }
333 | set
334 | {
335 | this.autoMouseScroll = value;
336 | if (this.autoScrollTimer == null)
337 | {
338 | this.autoScrollTimer = new Timer();
339 | this.autoScrollTimer.Interval = autoMouseScrollInterval;
340 | this.autoScrollTimer.Tick += this.UpdateAutoScrollPosition;
341 | }
342 | if (value)
343 | {
344 | this.autoScrollTimer.Start();
345 | }
346 | else
347 | {
348 | this.autoScrollTimer.Stop();
349 | }
350 | }
351 | }
352 | ///
353 | /// 更新自动滚动的位置。
354 | ///
355 | private void UpdateAutoScrollPosition(object sender, EventArgs e)
356 | {
357 | if (this.HorizontalScroll.Visible || this.VerticalScroll.Visible)
358 | {
359 | Point point = this.PointToClient(Control.MousePosition);
360 | int tx = 0, ty = 0;
361 | int tw = this.ClientSize.Width - autoMouseScrollMargin;
362 | int th = this.ClientSize.Height - autoMouseScrollMargin;
363 | if (point.X <= autoMouseScrollMargin)
364 | {
365 | tx = point.X - autoMouseScrollMargin;
366 | }
367 | else if (point.X >= tw)
368 | {
369 | tx = point.X - tw;
370 | }
371 | if (point.Y <= autoMouseScrollMargin)
372 | {
373 | ty = point.Y - autoMouseScrollMargin;
374 | }
375 | else if (point.Y >= th)
376 | {
377 | ty = point.Y - th;
378 | }
379 | if (tx != 0 || ty != 0)
380 | {
381 | this.AutoScrollPosition = new Point(this.HorizontalScroll.Value + tx,
382 | this.VerticalScroll.Value + ty);
383 | this.OnMouseMove(new MouseEventArgs(Control.MouseButtons, 1, point.X, point.Y, 0));
384 | }
385 | }
386 | }
387 |
388 | #endregion // 自动滚动
389 |
390 | }
391 | }
392 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/NewGameForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Drawing.Imaging;
5 | using System.Globalization;
6 | using System.IO;
7 | using System.Windows.Forms;
8 | using Cyjb.Projects.JigsawGame.Shape;
9 |
10 | namespace Cyjb.Projects.JigsawGame
11 | {
12 | ///
13 | /// 新建游戏的窗体。
14 | ///
15 | public partial class NewGameForm : Form
16 | {
17 | ///
18 | /// 游戏图像。
19 | ///
20 | private Image image;
21 | ///
22 | /// 可分割的最小碎片数。
23 | ///
24 | private int minPieceCount;
25 | ///
26 | /// 可分割的最大碎片数。
27 | ///
28 | private int maxPieceCount;
29 | ///
30 | /// 拼图横向分割的块数。
31 | ///
32 | private int horizontalDimension;
33 | ///
34 | /// 拼图纵向分割的块数。
35 | ///
36 | private int verticalDimension;
37 | ///
38 | /// 图片网格的起始 X 位置。
39 | ///
40 | private float netX;
41 | ///
42 | /// 图片网格的起始 Y 位置。
43 | ///
44 | private float netY;
45 | ///
46 | /// 图片网格的宽度。
47 | ///
48 | private float netW;
49 | ///
50 | /// 图片网格的高度。
51 | ///
52 | private float netH;
53 | ///
54 | /// 绘制网格的画笔。
55 | ///
56 | private Pen pen = new Pen(Color.Red);
57 | ///
58 | /// 拼图的所有合理划分。
59 | ///
60 | private IList partitions = new List();
61 | ///
62 | /// 拼图信息。
63 | ///
64 | private JigsawInfo info = new JigsawInfo();
65 | ///
66 | /// 拼图形状。
67 | ///
68 | private JigsawShape shape;
69 | ///
70 | /// 构造函数。
71 | ///
72 | public NewGameForm()
73 | {
74 | InitializeComponent();
75 | picture.BackColor = JigsawSetting.Default.BackgroundColor;
76 | combShape.DisplayMember = "Text";
77 | combShape.ValueMember = "Value";
78 | combShape.DataSource = EnumExt.GetDescValues();
79 | combDifficulty.SelectedIndex = JigsawSetting.Default.Difficulty;
80 | combShape.SelectedIndex = JigsawSetting.Default.Shape;
81 | cbxRotate.Checked = JigsawSetting.Default.Rotatable;
82 | cbxAnchor.Checked = JigsawSetting.Default.Anchor;
83 | tbarRand.Value = (int)(JigsawSetting.Default.Randomization * 100);
84 | tbarRand_Scroll(tbarRand, null);
85 | }
86 | ///
87 | /// 清理所有正在使用的资源。
88 | ///
89 | /// 如果应释放托管资源,为 true;否则为 false。
90 | protected override void Dispose(bool disposing)
91 | {
92 | if (disposing)
93 | {
94 | if (this.components != null)
95 | {
96 | this.components.Dispose();
97 | }
98 | this.pen.Dispose();
99 | if (this.image != null)
100 | {
101 | this.image.Dispose();
102 | }
103 | }
104 | base.Dispose(disposing);
105 | }
106 | ///
107 | /// 获取拼图信息。
108 | ///
109 | public JigsawInfo JigsawInfo { get { return this.info; } }
110 | ///
111 | /// 获取拼图形状。
112 | ///
113 | public JigsawShape JigsawShape { get { return this.shape; } }
114 | ///
115 | /// 浏览图片。
116 | ///
117 | private void btnPic_Click(object sender, EventArgs e)
118 | {
119 | imageOpenDialog.InitFileName(JigsawSetting.Default.ImageFileName);
120 | if (imageOpenDialog.ShowDialog() == DialogResult.OK)
121 | {
122 | JigsawSetting.Default.ImageFileName = imageOpenDialog.FileName;
123 | try
124 | {
125 | image = Image.FromFile(imageOpenDialog.FileName);
126 | }
127 | catch (OutOfMemoryException)
128 | {
129 | MessageBox.Show("不是有效的图片格式", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
130 | return;
131 | }
132 | lblPic.Text = string.Concat("选择图片:", imageOpenDialog.FileName,
133 | MultiplyFormat(image.Width, image.Height));
134 | // 图片缩放后的大小
135 | if (image.Width * picture.Height >= image.Height * picture.Width)
136 | {
137 | netW = picture.Width - 1;
138 | netH = (float)picture.Width * image.Height / image.Width - 1;
139 | netX = 0;
140 | netY = ((float)picture.Height - netH) / 2;
141 | }
142 | else
143 | {
144 | netW = (float)picture.Height * image.Width / image.Height - 1;
145 | netH = picture.Height - 1;
146 | netX = ((float)picture.Width - netW) / 2;
147 | netY = 0;
148 | }
149 | PartitionImage();
150 | tbarDifficulty.Enabled = tbarRand.Enabled = true;
151 | cbxRotate.Enabled = cbxAnchor.Enabled = true;
152 | combDifficulty.Enabled = combShape.Enabled = true;
153 | btnOK.Enabled = true;
154 | }
155 | }
156 | ///
157 | /// 划分游戏图片。
158 | ///
159 | private void PartitionImage()
160 | {
161 | // 图片的合理划分列表。
162 | int[] tmpPartition = new int[maxPieceCount - minPieceCount + 1];
163 | // 合理的划分,纵横比例在图片纵横比例上下 1/3 之间,即拼图碎片的比例不会超过 4:3。
164 | float minRatio = (float)image.Height * 3 / (image.Width * 4);
165 | float maxRatio = (float)image.Height * 4 / (image.Width * 3);
166 | for (int hDim = 2; ; hDim++)
167 | {
168 | // 寻找相应的纵向分割块数。
169 | int minVDim = (int)(hDim * minRatio + 1);
170 | int maxVDim = (int)(hDim * maxRatio);
171 | int startVDim = minPieceCount / hDim;
172 | int endVDim = maxPieceCount / hDim;
173 | if (minVDim > endVDim)
174 | {
175 | break;
176 | }
177 | if (endVDim < maxVDim)
178 | {
179 | maxVDim = endVDim;
180 | }
181 | if (startVDim > minVDim)
182 | {
183 | minVDim = startVDim;
184 | }
185 | for (int vDim = minVDim; vDim <= maxVDim; vDim++)
186 | {
187 | int pieceCount = hDim * vDim;
188 | if (pieceCount < minPieceCount)
189 | {
190 | continue;
191 | }
192 | if (pieceCount > maxPieceCount)
193 | {
194 | break;
195 | }
196 | int oldHDim = tmpPartition[pieceCount - minPieceCount];
197 | if (oldHDim > 0)
198 | {
199 | // 对于相同总块数的不同划分,总是选择最终划分最接近正方形的。
200 | float ratio = ((float)image.Width * pieceCount) / image.Height;
201 | float oldRatio = oldHDim * oldHDim - ratio;
202 | if (oldRatio < 0)
203 | {
204 | oldRatio = -oldRatio;
205 | }
206 | ratio = hDim * hDim - ratio;
207 | if (ratio < 0)
208 | {
209 | ratio = -ratio;
210 | }
211 | if (ratio < oldRatio)
212 | {
213 | tmpPartition[pieceCount - minPieceCount] = hDim;
214 | }
215 | }
216 | else
217 | {
218 | tmpPartition[pieceCount - minPieceCount] = hDim;
219 | }
220 | }
221 | }
222 | partitions.Clear();
223 | for (int i = minPieceCount; i <= maxPieceCount; i++)
224 | {
225 | if (tmpPartition[i - minPieceCount] > 0)
226 | {
227 | partitions.Add(new Partition(i, tmpPartition[i - minPieceCount]));
228 | }
229 | }
230 | tbarDifficulty.Maximum = partitions.Count - 1;
231 | tbarDifficulty_Scroll(this, null);
232 | }
233 | ///
234 | /// 更新游戏难度信息。
235 | ///
236 | private void tbarDifficulty_Scroll(object sender, EventArgs e)
237 | {
238 | Partition partition = partitions[tbarDifficulty.Value];
239 | this.horizontalDimension = partition.HorizontalDimension;
240 | this.verticalDimension = partition.VerticalDimension;
241 | lblPieces.Text = string.Concat("碎片数目:",
242 | partition.PieceCount.ToString(CultureInfo.CurrentCulture),
243 | MultiplyFormat(horizontalDimension, verticalDimension));
244 | picture.Invalidate();
245 | }
246 | ///
247 | /// 图片框大小被改变的事件。
248 | ///
249 | private void picture_Resize(object sender, EventArgs e)
250 | {
251 | if (image == null)
252 | {
253 | return;
254 | }
255 | // 图片缩放后的大小
256 | if (image.Width * picture.Height >= image.Height * picture.Width)
257 | {
258 | netW = picture.Width - 1;
259 | netH = (float)picture.Width * image.Height / image.Width - 1;
260 | netX = 0;
261 | netY = ((float)picture.Height - netH) / 2;
262 | }
263 | else
264 | {
265 | netW = (float)picture.Height * image.Width / image.Height - 1;
266 | netH = picture.Height - 1;
267 | netX = ((float)picture.Width - netW) / 2;
268 | netY = 0;
269 | }
270 | picture.Invalidate();
271 | }
272 | ///
273 | /// 在图像上绘制网格。
274 | ///
275 | private void picture_Paint(object sender, PaintEventArgs e)
276 | {
277 | if (image == null)
278 | {
279 | return;
280 | }
281 | e.Graphics.DrawImage(image, netX, netY, netW, netH);
282 | float start = netY, end = netY + netH;
283 | float pieceW = netW / horizontalDimension;
284 | for (int i = 0; i <= horizontalDimension; i++)
285 | {
286 | e.Graphics.DrawLine(pen, netX + i * pieceW, start, netX + i * pieceW, end);
287 | }
288 | start = netX;
289 | end = netX + netW;
290 | float pieceH = netH / verticalDimension;
291 | for (int i = 0; i <= verticalDimension; i++)
292 | {
293 | e.Graphics.DrawLine(pen, start, netY + i * pieceH, end, netY + i * pieceH);
294 | }
295 | }
296 | ///
297 | /// 难度被改变的事件。
298 | ///
299 | private void combDifficulty_SelectedIndexChanged(object sender, EventArgs e)
300 | {
301 | JigsawSetting.Default.Difficulty = combDifficulty.SelectedIndex;
302 | switch (combDifficulty.SelectedIndex)
303 | {
304 | case 0:
305 | minPieceCount = 2;
306 | maxPieceCount = 200;
307 | break;
308 | case 1:
309 | minPieceCount = 201;
310 | maxPieceCount = 400;
311 | break;
312 | case 2:
313 | minPieceCount = 401;
314 | maxPieceCount = 800;
315 | break;
316 | case 3:
317 | minPieceCount = 801;
318 | maxPieceCount = 1200;
319 | break;
320 | }
321 | tbarDifficulty.Value = 0;
322 | if (image != null)
323 | {
324 | PartitionImage();
325 | }
326 | }
327 | ///
328 | /// 随机程度被改变的事件。
329 | ///
330 | private void tbarRand_Scroll(object sender, EventArgs e)
331 | {
332 | lblRandInfo.Text = tbarRand.Value.ToString(CultureInfo.CurrentCulture) + "%";
333 | }
334 | ///
335 | /// 确定按钮按下的事件。
336 | ///
337 | private void btnOK_Click(object sender, EventArgs e)
338 | {
339 | JigsawSetting.Default.Shape = combShape.SelectedIndex;
340 | JigsawSetting.Default.Anchor = info.AnchorToBackground = cbxAnchor.Checked;
341 | info.AnchorRadius = 5f;
342 | using (MemoryStream stream = new MemoryStream())
343 | {
344 | image.Save(stream, ImageFormat.Png);
345 | stream.Seek(0, SeekOrigin.Begin);
346 | info.ImageData = stream.ToArray();
347 | }
348 | info.Scale = 1f;
349 | info.PieceSum = horizontalDimension * verticalDimension;
350 | JigsawSetting.Default.Rotatable = info.Rotatable = cbxRotate.Checked;
351 | shape = JigsawShape.CreateShape((JigsawShapeType)combShape.SelectedValue);
352 | shape.HorizontalDimension = horizontalDimension;
353 | shape.VerticalDimension = verticalDimension;
354 | JigsawSetting.Default.Randomization = shape.Randomization = (float)tbarRand.Value / 100;
355 | shape.Size = new SharpDX.Size2F(image.Width, image.Height);
356 | this.DialogResult = DialogResult.OK;
357 | }
358 | ///
359 | /// 将指定数字格式化为相乘的格式。
360 | ///
361 | /// 左操作数。
362 | /// 右操作数。
363 | /// 格式化的结果。
364 | private static string MultiplyFormat(int left, int right)
365 | {
366 | return string.Concat(" (", left.ToString(CultureInfo.CurrentCulture), "×",
367 | right.ToString(CultureInfo.CurrentCulture), ")");
368 | }
369 | ///
370 | /// 表示拼图的一个合理划分。
371 | ///
372 | private struct Partition
373 | {
374 | ///
375 | /// 拼图被分割的总块数。
376 | ///
377 | public int PieceCount;
378 | ///
379 | /// 拼图横向分割的块数。
380 | ///
381 | public int HorizontalDimension;
382 | ///
383 | /// 拼图纵向分割的块数。
384 | ///
385 | public int VerticalDimension;
386 | public Partition(int count, int hDim)
387 | {
388 | this.PieceCount = count;
389 | this.HorizontalDimension = hDim;
390 | this.VerticalDimension = count / hDim;
391 | }
392 | }
393 | }
394 | }
395 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/Cyjb.Projects.JigsawGame.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {1D1EF63A-E2E6-4869-81BB-AB049718781F}
8 | WinExe
9 | Properties
10 | Cyjb.Projects.JigsawGame
11 | JigsawGame
12 | v4.5
13 | 512
14 |
15 | false
16 | 发布\
17 | true
18 | Disk
19 | false
20 | Foreground
21 | 7
22 | Days
23 | false
24 | false
25 | true
26 | 0
27 | 1.0.0.%2a
28 | false
29 | true
30 |
31 |
32 | x86
33 | true
34 | full
35 | false
36 | bin\Debug\
37 | DEBUG;TRACE
38 | prompt
39 | 4
40 | ..\..\Cyjb\CyjbRules.ruleset
41 | true
42 | false
43 |
44 |
45 | AnyCPU
46 | pdbonly
47 | true
48 | ..\bin\Release\
49 | TRACE
50 | prompt
51 | 4
52 | ..\..\Cyjb\CyjbRules.ruleset
53 | false
54 |
55 |
56 | JigsawGame.ico
57 |
58 |
59 | true
60 |
61 |
62 | CYJB_Code_Key.snk
63 |
64 |
65 |
66 | False
67 | ..\..\Cyjb\bin\Cyjb.dll
68 |
69 |
70 | False
71 | ..\lib\SharpDX.dll
72 |
73 |
74 | False
75 | ..\lib\SharpDX.Direct2D1.dll
76 |
77 |
78 | ..\lib\SharpDX.Direct3D11.dll
79 |
80 |
81 | False
82 | ..\lib\SharpDX.DXGI.dll
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | Form
94 |
95 |
96 | BugReportForm.cs
97 |
98 |
99 |
100 |
101 |
102 | Form
103 |
104 |
105 | HelpForm.cs
106 |
107 |
108 |
109 |
110 | True
111 | True
112 | JigsawSetting.settings
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | Form
121 |
122 |
123 | LoadingForm.cs
124 |
125 |
126 | Form
127 |
128 |
129 | MainForm.cs
130 |
131 |
132 | Form
133 |
134 |
135 | NewGameForm.cs
136 |
137 |
138 |
139 |
140 |
141 |
142 | UserControl
143 |
144 |
145 |
146 |
147 |
148 | True
149 | True
150 | Resources.resx
151 |
152 |
153 | Form
154 |
155 |
156 | SettingForm.cs
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 | Form
173 |
174 |
175 | ThumbForm.cs
176 |
177 |
178 | Form
179 |
180 |
181 | ToolForm.cs
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 | SettingsSingleFileGenerator
198 | JigsawSetting.Designer.cs
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 | BugReportForm.cs
208 |
209 |
210 | HelpForm.cs
211 |
212 |
213 | LoadingForm.cs
214 |
215 |
216 | MainForm.cs
217 |
218 |
219 | NewGameForm.cs
220 |
221 |
222 | ResXFileCodeGenerator
223 | Resources.Designer.cs
224 |
225 |
226 | SettingForm.cs
227 |
228 |
229 | ThumbForm.cs
230 |
231 |
232 |
233 |
234 | False
235 | Microsoft .NET Framework 4 %28x86 和 x64%29
236 | true
237 |
238 |
239 | False
240 | .NET Framework 3.5 SP1 Client Profile
241 | false
242 |
243 |
244 | False
245 | .NET Framework 3.5 SP1
246 | false
247 |
248 |
249 | False
250 | Windows Installer 4.5
251 | true
252 |
253 |
254 |
255 |
262 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/DeviceManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics.CodeAnalysis;
3 | using System.IO;
4 | using System.Windows.Forms;
5 | using SharpDX;
6 | using SharpDX.Direct2D1;
7 | using SharpDX.Direct3D;
8 | using SharpDX.Direct3D11;
9 | using SharpDX.DXGI;
10 | using SharpDX.IO;
11 | using SharpDX.WIC;
12 | using Bitmap = SharpDX.Direct2D1.Bitmap;
13 | using D2D1AlphaMode = SharpDX.Direct2D1.AlphaMode;
14 | using D2D1Device = SharpDX.Direct2D1.Device;
15 | using D2D1PixelFormat = SharpDX.Direct2D1.PixelFormat;
16 | using D3D11Device = SharpDX.Direct3D11.Device;
17 | using D3D11Device1 = SharpDX.Direct3D11.Device;
18 | using DeviceContext = SharpDX.Direct2D1.DeviceContext;
19 | using DXGIDevice = SharpDX.DXGI.Device;
20 | using DXGIFactory = SharpDX.DXGI.Factory;
21 | using Factory = SharpDX.Direct2D1.Factory;
22 | using PixelFormat = SharpDX.WIC.PixelFormat;
23 |
24 | namespace Cyjb.Projects.JigsawGame
25 | {
26 | ///
27 | /// 设备的管理器。
28 | ///
29 | public sealed class DeviceManager : IDisposable
30 | {
31 |
32 | #region 设备配置
33 |
34 | ///
35 | /// DXGI 格式。
36 | ///
37 | private static readonly Format Format = Format.B8G8R8A8_UNorm;
38 | ///
39 | /// Direct2D 的像素格式。
40 | ///
41 | private static readonly D2D1PixelFormat D2PixelFormat = new D2D1PixelFormat(Format, D2D1AlphaMode.Premultiplied);
42 | ///
43 | /// 像素格式。
44 | ///
45 | private static readonly Guid WICPixelFormat = PixelFormat.Format32bppPBGRA;
46 | ///
47 | /// 桌面的分辨率。
48 | ///
49 | private static Size2F Dpi;
50 | ///
51 | /// 位图的属性。
52 | ///
53 | private static BitmapProperties1 BitmapProps1;
54 |
55 | #endregion // 设备配置
56 |
57 | #region Direct3D 渲染
58 |
59 | ///
60 | /// Direct3D 设备。
61 | ///
62 | private D3D11Device d3DDevice;
63 | ///
64 | /// DXGI 设备。
65 | ///
66 | private DXGIDevice dxgiDevice;
67 | ///
68 | /// DXGI SwapChain。
69 | ///
70 | private SwapChain swapChain;
71 | ///
72 | /// SwapChain 缓冲区。
73 | ///
74 | private Surface backBuffer;
75 | ///
76 | /// 渲染的目标位图。
77 | ///
78 | private Bitmap1 targetBitmap;
79 |
80 | #endregion // Direct3D 渲染
81 |
82 | #region Direct2D 设备
83 |
84 | ///
85 | /// Direct2D 设备。
86 | ///
87 | private D2D1Device d2DDevice;
88 | ///
89 | /// Direct2D 的设备上下文。
90 | ///
91 | private DeviceContext d2DContext;
92 | ///
93 | /// Direct2D 的工厂。
94 | ///
95 | private Factory d2DFactory;
96 | ///
97 | /// Diect2D 渲染目标。
98 | ///
99 | private RenderTarget renderTarget;
100 |
101 | #endregion // Direct2D 设备
102 |
103 | ///
104 | /// Windows 图片组件的工厂。
105 | ///
106 | private ImagingFactory wicFactory;
107 | ///
108 | /// 初始化 类的新实例。
109 | ///
110 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
111 | public DeviceManager()
112 | {
113 | try
114 | {
115 | // 创建 Dierect3D 设备。
116 | this.d3DDevice = new D3D11Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport);
117 | this.dxgiDevice = d3DDevice.QueryInterface().QueryInterface();
118 | // 创建 Direct2D 设备和工厂。
119 | this.d2DDevice = new D2D1Device(dxgiDevice);
120 | this.d2DContext = new DeviceContext(d2DDevice, DeviceContextOptions.None);
121 | this.d2DFactory = this.d2DContext.Factory;
122 | this.wicFactory = new ImagingFactory2();
123 | }
124 | catch
125 | {
126 | this.ClearResources();
127 | try
128 | {
129 | // 创建 D3D 设备异常,则尝试 Direct2D 单线程工厂。
130 | this.d2DFactory = new Factory(FactoryType.SingleThreaded);
131 | this.wicFactory = new ImagingFactory();
132 | }
133 | catch
134 | {
135 | this.ClearResources();
136 | }
137 | }
138 | if (this.d2DFactory != null)
139 | {
140 | Dpi = d2DFactory.DesktopDpi;
141 | BitmapProps1 = new BitmapProperties1(D2PixelFormat, Dpi.Width, Dpi.Height, BitmapOptions.Target);
142 | }
143 | }
144 | ///
145 | /// 获取 Direct2D 的设备上下文。
146 | ///
147 | public DeviceContext D2DContext
148 | {
149 | get { return this.d2DContext; }
150 | }
151 | ///
152 | /// 获取 Direct2D 的工厂。
153 | ///
154 | public Factory D2DFactory
155 | {
156 | get { return this.d2DFactory; }
157 | }
158 | ///
159 | /// 获取 Direct2D 的渲染目标。
160 | ///
161 | public RenderTarget RenderTarget
162 | {
163 | get { return renderTarget; }
164 | }
165 | ///
166 | /// 获取是否支持 Direct3D 设备。
167 | ///
168 | public bool SupportD3D
169 | {
170 | get { return this.d2DContext != null; }
171 | }
172 | ///
173 | /// 获取是否支持 Direct2D 设备。
174 | ///
175 | public bool SupportD2D
176 | {
177 | get { return this.d2DFactory != null; }
178 | }
179 |
180 | #region 渲染器
181 |
182 | ///
183 | /// 使用指定的渲染目标控件创建渲染目标。
184 | ///
185 | /// 渲染的目标控件。
186 | public void CreateRenderTarget(Control control)
187 | {
188 | if (SupportD3D)
189 | {
190 | // 创建 Direct3D SwapChain。
191 | SwapChainDescription swapChainDesc = new SwapChainDescription()
192 | {
193 | BufferCount = 1,
194 | Usage = Usage.RenderTargetOutput,
195 | OutputHandle = control.Handle,
196 | IsWindowed = true,
197 | ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format),
198 | SampleDescription = new SampleDescription(1, 0),
199 | SwapEffect = SwapEffect.Discard
200 | };
201 | this.swapChain = new SwapChain(dxgiDevice.GetParent().GetParent(),
202 | d3DDevice, swapChainDesc);
203 | this.backBuffer = Surface.FromSwapChain(this.swapChain, 0);
204 | this.targetBitmap = new Bitmap1(this.d2DContext, backBuffer);
205 | this.renderTarget = new DeviceContext(this.d2DDevice, DeviceContextOptions.None);
206 | ((DeviceContext)this.renderTarget).Target = targetBitmap;
207 | }
208 | else
209 | {
210 | // 创建 Direct2D 工厂。
211 | // 渲染参数。
212 | RenderTargetProperties renderProps = new RenderTargetProperties
213 | {
214 | PixelFormat = D2PixelFormat,
215 | Usage = RenderTargetUsage.None,
216 | Type = RenderTargetType.Default
217 | };
218 | // 渲染目标属性。
219 | HwndRenderTargetProperties hwndProps = new HwndRenderTargetProperties()
220 | {
221 | Hwnd = control.Handle,
222 | PixelSize = new Size2(control.ClientSize.Width, control.ClientSize.Height),
223 | PresentOptions = PresentOptions.None
224 | };
225 | // 渲染目标。
226 | this.renderTarget = new WindowRenderTarget(d2DFactory, renderProps, hwndProps)
227 | {
228 | AntialiasMode = AntialiasMode.PerPrimitive
229 | };
230 | }
231 | }
232 | ///
233 | /// 调整渲染目标的尺寸。
234 | ///
235 | /// 渲染的目标控件。
236 | public void ResizeRenderTarget(Control control)
237 | {
238 | if (this.swapChain == null)
239 | {
240 | ((WindowRenderTarget)this.renderTarget).Resize(
241 | new Size2(control.ClientSize.Width, control.ClientSize.Height));
242 | }
243 | else
244 | {
245 | ((DeviceContext)this.renderTarget).Target = null;
246 | this.backBuffer.Dispose();
247 | this.targetBitmap.Dispose();
248 | this.swapChain.ResizeBuffers(1, 0, 0, Format, SwapChainFlags.None);
249 | this.backBuffer = Surface.FromSwapChain(this.swapChain, 0);
250 | this.targetBitmap = new Bitmap1(this.d2DContext, backBuffer);
251 | ((DeviceContext)this.renderTarget).Target = targetBitmap;
252 | }
253 | }
254 | ///
255 | /// 开始渲染器的绘制。
256 | ///
257 | public void BeginDraw()
258 | {
259 | this.renderTarget.BeginDraw();
260 | }
261 | ///
262 | /// 结束渲染器的绘制。
263 | ///
264 | public void EndDraw()
265 | {
266 | this.renderTarget.EndDraw();
267 | if (this.swapChain != null)
268 | {
269 | this.swapChain.Present(0, PresentFlags.None);
270 | }
271 | }
272 |
273 | #endregion // 渲染器
274 |
275 | #region 辅助方法
276 |
277 | ///
278 | /// 创建指定尺寸的位图。
279 | ///
280 | /// 要创建位图的尺寸。
281 | /// 创建好的位图。
282 | public Bitmap1 CreateBitmap(Size2 size)
283 | {
284 | return new Bitmap1(this.d2DContext, size, BitmapProps1);
285 | }
286 | ///
287 | /// 从给定的 Byte 数组中加载 Direct2D 位图。
288 | ///
289 | /// 要加载位图的数据。
290 | /// 得到的 Direct2D 位图。
291 | public Bitmap LoadBitmapFromBytes(byte[] data)
292 | {
293 | using (MemoryStream stream = new MemoryStream(data))
294 | {
295 | return LoadBitmapFromStream(stream);
296 | }
297 | }
298 | ///
299 | /// 从给定的流中加载 Direct2D 位图。
300 | ///
301 | /// 要加载位图的流。
302 | /// 得到的 Direct2D 位图。
303 | public Bitmap LoadBitmapFromStream(Stream stream)
304 | {
305 | using (BitmapDecoder decoder = new BitmapDecoder(wicFactory, stream, DecodeOptions.CacheOnLoad))
306 | {
307 | using (FormatConverter formatConverter = new FormatConverter(wicFactory))
308 | {
309 | formatConverter.Initialize(decoder.GetFrame(0), WICPixelFormat);
310 | return Bitmap.FromWicBitmap(this.renderTarget, formatConverter);
311 | }
312 | }
313 | }
314 | ///
315 | /// 将 Direct2D 位图保存到文件中。
316 | ///
317 | /// 要保存的位图。
318 | /// 要保存的文件名。
319 | public void SaveBitmapToFile(Bitmap image, string fileName)
320 | {
321 | using (ImagingFactory2 factory = new ImagingFactory2())
322 | {
323 | using (WICStream stream = new WICStream(factory, fileName, NativeFileAccess.Write))
324 | {
325 | using (BitmapEncoder encoder = new PngBitmapEncoder(factory))
326 | {
327 | encoder.Initialize(stream);
328 | using (BitmapFrameEncode bitmapFrameEncode = new BitmapFrameEncode(encoder))
329 | {
330 | bitmapFrameEncode.Initialize();
331 | int width = image.PixelSize.Width;
332 | int height = image.PixelSize.Height;
333 | bitmapFrameEncode.SetSize(width, height);
334 | Guid wicPixelFormat = WICPixelFormat;
335 | bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat);
336 | using (ImageEncoder imageEncoder = new ImageEncoder(factory, this.d2DDevice))
337 | {
338 | imageEncoder.WriteFrame(image, bitmapFrameEncode,
339 | new ImageParameters(D2PixelFormat, 96, 96, 0, 0, width, height));
340 | bitmapFrameEncode.Commit();
341 | encoder.Commit();
342 | }
343 | }
344 | }
345 | }
346 | }
347 | }
348 |
349 | #endregion // 辅助方法
350 |
351 | #region IDisposable 成员
352 |
353 | ///
354 | /// 清理所有正在使用的资源。
355 | ///
356 | public void Dispose()
357 | {
358 | ClearResources();
359 | GC.SuppressFinalize(this);
360 | }
361 | ///
362 | /// 清理所有正在使用的资源,并设置为 null。
363 | ///
364 | private void ClearResources()
365 | {
366 | if (this.d3DDevice != null)
367 | {
368 | this.d3DDevice.Dispose();
369 | this.d3DDevice = null;
370 | }
371 | if (this.dxgiDevice != null)
372 | {
373 | this.dxgiDevice.Dispose();
374 | this.dxgiDevice = null;
375 | }
376 | if (this.swapChain != null)
377 | {
378 | this.swapChain.Dispose();
379 | this.swapChain = null;
380 | }
381 | if (this.backBuffer != null)
382 | {
383 | this.backBuffer.Dispose();
384 | this.backBuffer = null;
385 | }
386 | if (this.targetBitmap != null)
387 | {
388 | this.targetBitmap.Dispose();
389 | this.swapChain = null;
390 | }
391 | if (this.d2DDevice != null)
392 | {
393 | this.d2DDevice.Dispose();
394 | this.d2DDevice = null;
395 | }
396 | if (this.d2DContext != null)
397 | {
398 | this.d2DContext.Dispose();
399 | this.d2DContext = null;
400 | }
401 | if (this.d2DFactory != null)
402 | {
403 | this.d2DFactory.Dispose();
404 | this.d2DFactory = null;
405 | }
406 | if (this.renderTarget != null)
407 | {
408 | this.renderTarget.Dispose();
409 | this.renderTarget = null;
410 | }
411 | if (this.wicFactory != null)
412 | {
413 | this.wicFactory.Dispose();
414 | this.wicFactory = null;
415 | }
416 | }
417 |
418 | #endregion // IDisposable 成员
419 |
420 | }
421 | }
422 |
--------------------------------------------------------------------------------
/Cyjb.Projects.JigsawGame/MainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cyjb.Projects.JigsawGame
2 | {
3 | partial class MainForm
4 | {
5 | ///
6 | /// 必需的设计器变量。
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | #region Windows 窗体设计器生成的代码
11 |
12 | ///
13 | /// 设计器支持所需的方法 - 不要
14 | /// 使用代码编辑器修改此方法的内容。
15 | ///
16 | private void InitializeComponent()
17 | {
18 | this.components = new System.ComponentModel.Container();
19 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
20 | this.mainToolStrip = new System.Windows.Forms.ToolStrip();
21 | this.newGameTSBtn = new System.Windows.Forms.ToolStripButton();
22 | this.openGameTSBtn = new System.Windows.Forms.ToolStripButton();
23 | this.saveGameTSBtn = new System.Windows.Forms.ToolStripButton();
24 | this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator();
25 | this.showThumbTSBtn = new System.Windows.Forms.ToolStripButton();
26 | this.showBackgroundSTBtn = new System.Windows.Forms.ToolStripButton();
27 | this.showBorderSTBtn = new System.Windows.Forms.ToolStripButton();
28 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
29 | this.settingsTSBtn = new System.Windows.Forms.ToolStripButton();
30 | this.helpTSBtn = new System.Windows.Forms.ToolStripButton();
31 | this.scaleSTBtn = new System.Windows.Forms.ToolStripDropDownButton();
32 | this.finishSTLabel = new System.Windows.Forms.ToolStripLabel();
33 | this.timeSTLabel = new System.Windows.Forms.ToolStripLabel();
34 | this.gameTimer = new System.Windows.Forms.Timer(this.components);
35 | this.gameSaveDialog = new System.Windows.Forms.SaveFileDialog();
36 | this.gameOpenDialog = new System.Windows.Forms.OpenFileDialog();
37 | this.renderPanel = new Cyjb.Projects.JigsawGame.Renderer.JigsawRenderPanel();
38 | this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
39 | this.mainToolStrip.SuspendLayout();
40 | this.SuspendLayout();
41 | //
42 | // mainToolStrip
43 | //
44 | this.mainToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
45 | this.newGameTSBtn,
46 | this.openGameTSBtn,
47 | this.saveGameTSBtn,
48 | this.toolStripSeparator,
49 | this.showThumbTSBtn,
50 | this.showBackgroundSTBtn,
51 | this.showBorderSTBtn,
52 | this.toolStripSeparator1,
53 | this.settingsTSBtn,
54 | this.helpTSBtn,
55 | this.toolStripSeparator2,
56 | this.scaleSTBtn,
57 | this.finishSTLabel,
58 | this.timeSTLabel});
59 | this.mainToolStrip.Location = new System.Drawing.Point(0, 0);
60 | this.mainToolStrip.Name = "mainToolStrip";
61 | this.mainToolStrip.Size = new System.Drawing.Size(584, 25);
62 | this.mainToolStrip.TabIndex = 0;
63 | //
64 | // newGameTSBtn
65 | //
66 | this.newGameTSBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
67 | this.newGameTSBtn.Image = ((System.Drawing.Image)(resources.GetObject("newGameTSBtn.Image")));
68 | this.newGameTSBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
69 | this.newGameTSBtn.Name = "newGameTSBtn";
70 | this.newGameTSBtn.Size = new System.Drawing.Size(23, 22);
71 | this.newGameTSBtn.Text = "新建游戏(Ctrl+N)";
72 | this.newGameTSBtn.Click += new System.EventHandler(this.newGameTSBtn_Click);
73 | //
74 | // openGameTSBtn
75 | //
76 | this.openGameTSBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
77 | this.openGameTSBtn.Image = ((System.Drawing.Image)(resources.GetObject("openGameTSBtn.Image")));
78 | this.openGameTSBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
79 | this.openGameTSBtn.Name = "openGameTSBtn";
80 | this.openGameTSBtn.Size = new System.Drawing.Size(23, 22);
81 | this.openGameTSBtn.Text = "打开游戏(Ctrl+O)";
82 | this.openGameTSBtn.Click += new System.EventHandler(this.openGameTSBtn_Click);
83 | //
84 | // saveGameTSBtn
85 | //
86 | this.saveGameTSBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
87 | this.saveGameTSBtn.Image = ((System.Drawing.Image)(resources.GetObject("saveGameTSBtn.Image")));
88 | this.saveGameTSBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
89 | this.saveGameTSBtn.Name = "saveGameTSBtn";
90 | this.saveGameTSBtn.Size = new System.Drawing.Size(23, 22);
91 | this.saveGameTSBtn.Text = "保存游戏(Ctrl+S)";
92 | this.saveGameTSBtn.Click += new System.EventHandler(this.saveGameTSBtn_Click);
93 | //
94 | // toolStripSeparator
95 | //
96 | this.toolStripSeparator.Name = "toolStripSeparator";
97 | this.toolStripSeparator.Size = new System.Drawing.Size(6, 25);
98 | //
99 | // showThumbTSBtn
100 | //
101 | this.showThumbTSBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
102 | this.showThumbTSBtn.Image = global::Cyjb.Projects.JigsawGame.Resources.ShowThumb;
103 | this.showThumbTSBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
104 | this.showThumbTSBtn.Name = "showThumbTSBtn";
105 | this.showThumbTSBtn.Size = new System.Drawing.Size(23, 22);
106 | this.showThumbTSBtn.Text = "显示缩略图(F2)";
107 | this.showThumbTSBtn.Click += new System.EventHandler(this.showThumbTSBtn_Click);
108 | //
109 | // showBackgroundSTBtn
110 | //
111 | this.showBackgroundSTBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
112 | this.showBackgroundSTBtn.Image = global::Cyjb.Projects.JigsawGame.Resources.ShowBackground;
113 | this.showBackgroundSTBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
114 | this.showBackgroundSTBtn.Name = "showBackgroundSTBtn";
115 | this.showBackgroundSTBtn.Size = new System.Drawing.Size(23, 22);
116 | this.showBackgroundSTBtn.Text = "显示背景图片(F3)";
117 | this.showBackgroundSTBtn.Click += new System.EventHandler(this.showBackgroundSTBtn_Click);
118 | //
119 | // showBorderSTBtn
120 | //
121 | this.showBorderSTBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
122 | this.showBorderSTBtn.Image = global::Cyjb.Projects.JigsawGame.Resources.ShowBorderOnly;
123 | this.showBorderSTBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
124 | this.showBorderSTBtn.Name = "showBorderSTBtn";
125 | this.showBorderSTBtn.Size = new System.Drawing.Size(23, 22);
126 | this.showBorderSTBtn.Text = "显示边框碎片(F4)";
127 | this.showBorderSTBtn.Click += new System.EventHandler(this.showBorderSTBtn_Click);
128 | //
129 | // toolStripSeparator1
130 | //
131 | this.toolStripSeparator1.Name = "toolStripSeparator1";
132 | this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
133 | //
134 | // settingsTSBtn
135 | //
136 | this.settingsTSBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
137 | this.settingsTSBtn.Image = global::Cyjb.Projects.JigsawGame.Resources.Settings;
138 | this.settingsTSBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
139 | this.settingsTSBtn.Name = "settingsTSBtn";
140 | this.settingsTSBtn.Size = new System.Drawing.Size(23, 22);
141 | this.settingsTSBtn.Text = "设置(F5)";
142 | this.settingsTSBtn.Click += new System.EventHandler(this.settingsTSBtn_Click);
143 | //
144 | // helpTSBtn
145 | //
146 | this.helpTSBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
147 | this.helpTSBtn.Image = ((System.Drawing.Image)(resources.GetObject("helpTSBtn.Image")));
148 | this.helpTSBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
149 | this.helpTSBtn.Name = "helpTSBtn";
150 | this.helpTSBtn.Size = new System.Drawing.Size(23, 22);
151 | this.helpTSBtn.Text = "帮助(F1)";
152 | this.helpTSBtn.Click += new System.EventHandler(this.helpTSBtn_Click);
153 | //
154 | // scaleSTBtn
155 | //
156 | this.scaleSTBtn.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
157 | this.scaleSTBtn.Image = ((System.Drawing.Image)(resources.GetObject("scaleSTBtn.Image")));
158 | this.scaleSTBtn.ImageTransparentColor = System.Drawing.Color.Magenta;
159 | this.scaleSTBtn.Name = "scaleSTBtn";
160 | this.scaleSTBtn.Size = new System.Drawing.Size(112, 22);
161 | this.scaleSTBtn.Text = "显示比例:100%";
162 | this.scaleSTBtn.DropDownItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.scaleSTBtn_DropDownItemClicked);
163 | //
164 | // finishSTLabel
165 | //
166 | this.finishSTLabel.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
167 | this.finishSTLabel.Name = "finishSTLabel";
168 | this.finishSTLabel.Size = new System.Drawing.Size(87, 22);
169 | this.finishSTLabel.Text = "完成度:100%";
170 | //
171 | // timeSTLabel
172 | //
173 | this.timeSTLabel.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
174 | this.timeSTLabel.Name = "timeSTLabel";
175 | this.timeSTLabel.Size = new System.Drawing.Size(115, 22);
176 | this.timeSTLabel.Text = "游戏用时:00:00:00";
177 | //
178 | // gameTimer
179 | //
180 | this.gameTimer.Tick += new System.EventHandler(this.UpdateTime);
181 | //
182 | // gameSaveDialog
183 | //
184 | this.gameSaveDialog.DefaultExt = "*.jig";
185 | this.gameSaveDialog.FileName = "SavedJigsaw.jig";
186 | this.gameSaveDialog.Filter = "拼图游戏存档|*.jig";
187 | this.gameSaveDialog.Title = "保存游戏";
188 | //
189 | // gameOpenDialog
190 | //
191 | this.gameOpenDialog.DefaultExt = "*.jig";
192 | this.gameOpenDialog.FileName = "SavedJigsaw.jig";
193 | this.gameOpenDialog.Filter = "拼图游戏存档|*.jig";
194 | this.gameOpenDialog.Title = "打开游戏";
195 | //
196 | // renderPanel
197 | //
198 | this.renderPanel.AutoScroll = true;
199 | this.renderPanel.AutoScrollMinSize = new System.Drawing.Size(200, 200);
200 | this.renderPanel.Dock = System.Windows.Forms.DockStyle.Fill;
201 | this.renderPanel.ImageSize = ((SharpDX.Size2F)(resources.GetObject("renderPanel.ImageSize")));
202 | this.renderPanel.Location = new System.Drawing.Point(0, 25);
203 | this.renderPanel.Name = "renderPanel";
204 | this.renderPanel.Size = new System.Drawing.Size(584, 336);
205 | this.renderPanel.TabIndex = 1;
206 | this.renderPanel.TabStop = false;
207 | this.renderPanel.JigsawScaleChanged += new System.EventHandler(this.renderPanel_JigsawScaleChanged);
208 | this.renderPanel.KeyDown += new System.Windows.Forms.KeyEventHandler(this.renderPanel_KeyDown);
209 | //
210 | // toolStripSeparator2
211 | //
212 | this.toolStripSeparator2.Name = "toolStripSeparator2";
213 | this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
214 | //
215 | // MainForm
216 | //
217 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
218 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
219 | this.ClientSize = new System.Drawing.Size(584, 361);
220 | this.Controls.Add(this.renderPanel);
221 | this.Controls.Add(this.mainToolStrip);
222 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
223 | this.MinimumSize = new System.Drawing.Size(600, 400);
224 | this.Name = "MainForm";
225 | this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
226 | this.Text = "拼图游戏";
227 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
228 | this.SizeChanged += new System.EventHandler(this.MainForm_SizeChanged);
229 | this.Move += new System.EventHandler(this.MainForm_Move);
230 | this.mainToolStrip.ResumeLayout(false);
231 | this.mainToolStrip.PerformLayout();
232 | this.ResumeLayout(false);
233 | this.PerformLayout();
234 |
235 | }
236 |
237 | #endregion
238 |
239 | private System.Windows.Forms.ToolStrip mainToolStrip;
240 | private System.Windows.Forms.ToolStripButton newGameTSBtn;
241 | private System.Windows.Forms.ToolStripButton openGameTSBtn;
242 | private System.Windows.Forms.ToolStripButton saveGameTSBtn;
243 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator;
244 | private System.Windows.Forms.ToolStripButton showThumbTSBtn;
245 | private System.Windows.Forms.ToolStripButton showBackgroundSTBtn;
246 | private System.Windows.Forms.ToolStripButton showBorderSTBtn;
247 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
248 | private System.Windows.Forms.ToolStripButton helpTSBtn;
249 | private System.Windows.Forms.ToolStripButton settingsTSBtn;
250 | private Cyjb.Projects.JigsawGame.Renderer.JigsawRenderPanel renderPanel;
251 | private System.Windows.Forms.ToolStripDropDownButton scaleSTBtn;
252 | private System.Windows.Forms.ToolStripLabel finishSTLabel;
253 | private System.Windows.Forms.Timer gameTimer;
254 | private System.Windows.Forms.ToolStripLabel timeSTLabel;
255 | private System.Windows.Forms.SaveFileDialog gameSaveDialog;
256 | private System.Windows.Forms.OpenFileDialog gameOpenDialog;
257 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
258 |
259 | }
260 | }
261 |
262 |
--------------------------------------------------------------------------------