最近在学习C#WPF,边学习边写了一个拼图的小游戏

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace JigsawGame
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private string currentImageFile;
        private static double jigsawWidthMax = 450.0;
        private double jigsawHeight;
        private Layout layout;
        private Jigsaw currentJigsaw;

public MainWindow()
        {
            InitializeComponent();
            layout = new Layout(2, 2);

currentImageFile = "image/leaf.jpg";

ImageZoom igZoom = new ImageZoom(currentImageFile);
            igZoom.ZoomOutTo(jigsawWidthMax, ImageFormat.Jpeg, "tmp.jpg");

string currentImageFileTmp = "tmp.jpg";

Stream imageStreamSource = new FileStream(currentImageFileTmp, FileMode.Open, FileAccess.Read, FileShare.Read);
            JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
            BitmapSource bitmapSource = decoder.Frames[0];

imagePuzzle.Source = bitmapSource;

Bitmap bitmap = new Bitmap(imageStreamSource);

imageStreamSource.Close();
            File.Delete(currentImageFileTmp);

Jigsaw js = new Jigsaw(
                bitmapSource,
                new System.Windows.Point(200, 15),
                new System.Windows.Size(ScreenUnitConverter.GetScreenWindth() - 230, ScreenUnitConverter.GetScreenHeight() - 130),
                new System.Windows.Point(100, 100),
                new System.Windows.Size(jigsawWidthMax, ScreenUnitConverter.PixelToInch(bitmap.Height)),
                layout);

contentGrid.Children.Add(js);
            currentJigsaw = js;
            jigsawHeight = ScreenUnitConverter.PixelToInch(bitmap.Height);

textBox1.Visibility = System.Windows.Visibility.Hidden;
        }

private void ImageChanged(object sender, MouseButtonEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.Filter = "Image Files|*.jpg;*.bmp;*.Tif;*.Png";
            if (dlg.ShowDialog() == true)
            {
                currentImageFile = dlg.FileName;
            }

ImageZoom igZoom = new ImageZoom(currentImageFile);
            igZoom.ZoomOutTo(jigsawWidthMax, ImageFormat.Jpeg, "tmp.jpg");
            string currentImageFileTmp = "tmp.jpg";

Stream imageStreamSource = new FileStream(currentImageFileTmp, FileMode.Open, FileAccess.Read, FileShare.Read);
            JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
            BitmapSource bitmapSource = decoder.Frames[0];

imageStreamSource.Close();
            File.Delete(currentImageFileTmp);

imagePuzzle.Source = bitmapSource;
            currentJigsaw.Image = bitmapSource;
        }

private void LayoutChanged(object sender, RoutedEventArgs e)
        {
            if (currentJigsaw != null)
            {
                RadioButton rdb = (RadioButton)sender;
                if (e.Source is RadioButton && rdb != other)
                {
                    string sss = rdb.Content.ToString();

layout.RowCount = Convert.ToInt32(sss.Substring(0, sss.LastIndexOf("x")));
                    layout.ColCount = Convert.ToInt32(sss.Substring(sss.LastIndexOf("x") + 1, sss.Length - sss.IndexOf("x") - 1));

currentJigsaw.Layout = layout;
                }
                if (e.Source is RadioButton && rdb == other)
                {
                    string row = tbxLayoutRow.Text;
                    string col = tbxLayoutCol.Text;

layout.RowCount = Convert.ToInt32(row);
                    layout.ColCount = Convert.ToInt32(col);

currentJigsaw.Layout = layout;
                }
            }
        }

private void GroupChanged(object sender, RoutedEventArgs e)
        {
            if (currentJigsaw != null)
            {
                RadioButton rdb = (RadioButton)sender;
                if (e.Source is RadioButton)
                {
                    string sss = rdb.Content.ToString();
                    if (sss == "组   合")
                    {
                        currentJigsaw.Group = true;
                    }
                    else
                    {
                        currentJigsaw.Group = false;
                    }
                }
            }
        }

private void buttonStart_Click(object sender, RoutedEventArgs e)
        {
            if ((string)(buttonStart.Content) == "开  始")
            {
                imagePuzzle.IsEnabled = false;

radioButton2.IsEnabled = false;
                radioButton3.IsEnabled = false;
                radioButton4.IsEnabled = false;
                radioButton5.IsEnabled = false;
                radioButton6.IsEnabled = false;
                other.IsEnabled = false;

rBNGroup.IsEnabled = false;
                rBNNoGroup.IsEnabled = false;

buttonStart.Content = "结  束";
                currentJigsaw.Spread();
            }
            else
            {
                imagePuzzle.IsEnabled = true;

radioButton2.IsEnabled = true;
                radioButton3.IsEnabled = true;
                radioButton4.IsEnabled = true;
                radioButton5.IsEnabled = true;
                radioButton6.IsEnabled = true;
                other.IsEnabled = true;

rBNGroup.IsEnabled = true;
                rBNNoGroup.IsEnabled = true;

buttonStart.Content = "开  始";

currentJigsaw.Reset();
            }
        }
    }
}

Jigsaw.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Effects;

namespace JigsawGame
{
    public class Layout
    {
        public int RowCount;
        public int ColCount;

public Layout()
        {
            RowCount = 2;
            ColCount = 2;
        }

public Layout(int rowCount, int colCount)
        {
            RowCount = rowCount;
            ColCount = colCount;
        }
    }
    /// <summary>
    /// Jigsaw.xaml 的交互逻辑
    /// </summary>
    public partial class Jigsaw : UserControl
    {
        private BitmapSource image;
        private Layout layout;
        private Point position;
        private Size size;
        private bool isGroup;

private SetOfSets<PieceOfJigsaw> children;
        private List<PieceOfJigsaw> availbleChildren;

private Random random = new Random();

public Jigsaw(
            BitmapSource    bitmapSource,
            Point   motherBoardPosition,
            Size    motherBoardSize,
            Point   jigsawPosition,
            Size    jigsawSize,
            Layout lay)
        {
            InitializeComponent();

image = bitmapSource;

Width = motherBoardSize.Width;
            Height = motherBoardSize.Height;
            HorizontalAlignment = HorizontalAlignment.Left;
            VerticalAlignment = VerticalAlignment.Top;
            Margin = new Thickness(motherBoardPosition.X, motherBoardPosition.Y, 0, 0);

position = jigsawPosition;
            size = jigsawSize;

layout = lay;

isGroup = false;

children = new SetOfSets<PieceOfJigsaw>(new CanGroup(isNeighbourhood));
            availbleChildren = new List<PieceOfJigsaw>();

for (int i = 0; i < layout.RowCount; i++)
            {
                for (int j = 0; j < layout.ColCount; j++)
                {
                    ID id = new ID(i, j);

PieceOfJigsaw pOJ = new PieceOfJigsaw(
                        getPOJImage(i,j),
                        new Point(position.X + j * (pOJWidth), position.Y + i * (pOJHeight)),
                        new Size(pOJWidth, pOJHeight),
                        id);

contentGrid.Children.Add(pOJ);
                    children.AddElemet(pOJ);
                    availbleChildren.Add(pOJ);
                    pOJ.IsRotated += new IsRotatedHandler(rotatePieceOfJigsawSet);
                    pOJ.IsTranslated += new IsTranslatedHandler(translatePieceOfJigsawSet);
                    pOJ.IsClicked += new IsClickedHandler(topPieceOfJigsawSet);
                }
            }

textBox1.Visibility = System.Windows.Visibility.Hidden;
        }

public BitmapSource Image
        {
            set
            {
                image = value;

foreach (PieceOfJigsaw pOJ in children.Elements)
                {
                    pOJ.Image = getPOJImage(pOJ.Id.RowIndex, pOJ.Id.ColIndex);
                    pOJ.Reset();
                }
                Group = isGroup;
            }
        }

public Layout Layout
        {
            set
            {
                layout = value;

if (children != null)
                {
                    foreach (PieceOfJigsaw pOJ in children.Elements)
                    {
                        contentGrid.Children.Remove(pOJ);
                    }

children.Clear();

for (int i = availbleChildren.Count; i < layout.ColCount * layout.RowCount; i++)
                    {
                        PieceOfJigsaw pOJ = new PieceOfJigsaw(
                            null,
                            new Point(0, 0),
                            new Size(1, 1),
                            new ID(0, 0));

availbleChildren.Add(pOJ);
                        pOJ.IsRotated += new IsRotatedHandler(rotatePieceOfJigsawSet);
                        pOJ.IsTranslated += new IsTranslatedHandler(translatePieceOfJigsawSet);
                        pOJ.IsClicked += new IsClickedHandler(topPieceOfJigsawSet);
                    }

for (int i = 0; i < layout.RowCount; i++)
                    {
                        for (int j = 0; j < layout.ColCount; j++)
                        {
                            ID id = new ID(i, j);

PieceOfJigsaw pOJ = availbleChildren[i * layout.RowCount + j];
                            pOJ.Id.RowIndex = i;
                            pOJ.Id.ColIndex = j;
                            pOJ.Size = new Size(pOJWidth, pOJHeight);
                            pOJ.Image = getPOJImage(i,j);
                            pOJ.Margin = new Thickness(
                                position.X + j * (pOJWidth),
                                position.Y + i * (pOJHeight),
                                0, 0);
                           
                            contentGrid.Children.Add(pOJ);
                            children.AddElemet(pOJ);

pOJ.Reset();
                        }
                    }
                }
                Group = isGroup;
            }
        }

public bool Group
        {
            set
            {
                isGroup = value;

if (isGroup == true)
                {
                    children.Sets.Clear();
                    children.Group(5);

textBox1.Text += "集合数=";
                    textBox1.Text += children.Sets.Count;
                    textBox1.Text += "\n";
                    foreach (List<PieceOfJigsaw> set in children.Sets)
                    {
                        textBox1.Text += "集合:";
                        foreach (PieceOfJigsaw pOJ in set)
                        {
                            textBox1.Text += pOJ.Id;
                            textBox1.Text += "---";
                        }
                        textBox1.Text += "\n";
                    }
                    drawLineBorder();
                }
                else
                {
                    children.Sets.Clear();
                    foreach (PieceOfJigsaw pOJ in children.Elements)
                    {
                        pOJ.IsBorderLeftVisible = true;
                        pOJ.IsBorderTopVisible = true;
                        pOJ.IsBorderRightVisible = true;
                        pOJ.IsBorderBottomVisible = true;

List<PieceOfJigsaw> set = new List<PieceOfJigsaw>();
                        set.Add(pOJ);
                        children.Sets.Add(set);
                    }
                }
            }
        }

public void Spread()
        {
            Group = isGroup;
            foreach (List<PieceOfJigsaw> set in children.Sets)
            {
                double deltaX = (double)random.Next(0, (int)(2.0 / 3 * Width - size.Width));
                double deltaY = (double)random.Next(0, (int)(2.0 / 3 * Height - size.Height));

double an = (double)random.Next(0, 360);               
               
                foreach (PieceOfJigsaw pOJ in set)
                {
                    pOJ.CenterX = set[0].Margin.Left - pOJ.Margin.Left;
                    pOJ.CenterY = set[0].Margin.Top - pOJ.Margin.Top;

pOJ.Angle = an;

pOJ.TranslateX = deltaX;
                    pOJ.TranslateY = deltaY;
                }
            }
        }

public void Reset()
        {
            foreach (PieceOfJigsaw pOJ in children.Elements)
            {
                pOJ.Reset();
            }
            Group = isGroup;
        }

private double pOJWidth
        {
            get
            {
                return size.Width / layout.ColCount;
            }
        }

private double pOJHeight
        {
            get
            {
                return size.Height / layout.RowCount;
            }
        }
 
        private void rotatePieceOfJigsawSet(PieceOfJigsaw source)
        {
            List<PieceOfJigsaw> currentSet = children.GetSet(source);

double angle = source.Angle;

foreach (PieceOfJigsaw pOJ in currentSet)
            {
                pOJ.Angle = angle;
            }
        }

private void translatePieceOfJigsawSet(PieceOfJigsaw pOJ)
        {
            List<PieceOfJigsaw> currentSet = children.GetSet(pOJ);

foreach (PieceOfJigsaw ig in currentSet)
            {
                ig.TranslateX = pOJ.TranslateX;
                ig.TranslateY = pOJ.TranslateY;
            }

union(currentSet);
        }

private void topPieceOfJigsawSet(PieceOfJigsaw source)
        {
            List<PieceOfJigsaw> currentSet = children.GetSet(source);

foreach (PieceOfJigsaw pOJ in currentSet)
            {
                contentGrid.Children.Remove(pOJ);
                contentGrid.Children.Add(pOJ);
            }
        }

private void union(List<PieceOfJigsaw> currentSet)
        {
            bool found = false;
            List<PieceOfJigsaw> setB = new List<PieceOfJigsaw>();

foreach (PieceOfJigsaw cig in currentSet)
            {
                foreach (List<PieceOfJigsaw> set in children.Sets)
                {
                    if (set != currentSet)
                    {
                        foreach (PieceOfJigsaw sig in set)
                        {
                            if (cig.IsBuddy(sig) == false)
                            {
                                continue;
                            }

found = true;
                            setB = set;

foreach (PieceOfJigsaw igg in set)
                            {
                                igg.TranslateX = cig.TranslateX;
                                igg.TranslateY = cig.TranslateY;

igg.CenterX = currentSet[0].Margin.Left - igg.Margin.Left;
                                igg.CenterY = currentSet[0].Margin.Top - igg.Margin.Top;
                                igg.Angle = currentSet[0].Angle;

}
                            if (found == true) break;
                        }
                    }
                    if (found == true) break;
                }
                if (found == true) break;
            }
            if (found == true)
            {
                children.Union(setB, currentSet);
                foreach (PieceOfJigsaw pOJ in currentSet)
                {
                    pOJ.Animate();
                    pOJ.BorderLeftColor = Brushes.Red;
                    pOJ.BorderRightColor = Brushes.Red;
                    pOJ.BorderTopColor = Brushes.Red;
                    pOJ.BorderBottomColor = Brushes.Red;
                }
                drawLineBorder(currentSet);
            }
        }

private void drawLineBorder(List<PieceOfJigsaw> set)
        {
            foreach (PieceOfJigsaw pOJ in set)
            {
                pOJ.IsBorderBottomVisible = true;
                pOJ.IsBorderLeftVisible = true;
                pOJ.IsBorderRightVisible = true;
                pOJ.IsBorderTopVisible = true;

foreach (PieceOfJigsaw pOJNeighbour in set)
                {
                    if (pOJ == pOJNeighbour)
                    {
                        continue;
                    }

if (pOJ.Id.RowIndex == pOJNeighbour.Id.RowIndex &&
                        pOJ.Id.ColIndex == pOJNeighbour.Id.ColIndex - 1)
                    {
                        pOJ.IsBorderRightVisible = false;
                        pOJNeighbour.IsBorderLeftVisible = false;
                    }
                    else if (pOJ.Id.RowIndex == pOJNeighbour.Id.RowIndex &&
                        pOJ.Id.ColIndex == pOJNeighbour.Id.ColIndex + 1)
                    {
                        pOJ.IsBorderLeftVisible = false;
                        pOJNeighbour.IsBorderRightVisible = false;
                    }
                    else if (pOJ.Id.RowIndex == pOJNeighbour.Id.RowIndex + 1 &&
                        pOJ.Id.ColIndex == pOJNeighbour.Id.ColIndex)
                    {
                        pOJ.IsBorderTopVisible = false;
                        pOJNeighbour.IsBorderBottomVisible = false;
                    }
                    else if (pOJ.Id.RowIndex == pOJNeighbour.Id.RowIndex - 1 &&
                        pOJ.Id.ColIndex == pOJNeighbour.Id.ColIndex)
                    {
                        pOJ.IsBorderBottomVisible = false;
                        pOJNeighbour.IsBorderTopVisible = false;
                    }
                }
            }
        }

private void drawLineBorder()
        {
            foreach (List<PieceOfJigsaw> set in children.Sets)
            {
                drawLineBorder(set);
            }
        }

private bool isNeighbourhood(object pOJ11, object pOJ22)
        {
            PieceOfJigsaw pOJ1 = (PieceOfJigsaw)pOJ11;
            PieceOfJigsaw pOJ2 = (PieceOfJigsaw)pOJ22;

return pOJ1.IsNeighbourhood(pOJ2);
        }

private BitmapSource getPOJImage(int i, int j)
        {
            return new CroppedBitmap(
                image,
                new Int32Rect(
                    j * ScreenUnitConverter.InchToPixel(pOJWidth),
                    i * ScreenUnitConverter.InchToPixel(pOJHeight),
                    ScreenUnitConverter.InchToPixel(pOJWidth),
                    ScreenUnitConverter.InchToPixel(pOJHeight)
                    ));                      
        }
    }
}

PieceOfJigsaw.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;

namespace JigsawGame
{
    public delegate void IsRotatedHandler(PieceOfJigsaw pOJ);
    public delegate void IsTranslatedHandler(PieceOfJigsaw pOJ);
    public delegate void IsClickedHandler(PieceOfJigsaw pOJ);

public class ID
    {
        public int RowIndex;
        public int ColIndex;

public ID(int rowIndex, int colIndex)
        {
            RowIndex = rowIndex;
            ColIndex = colIndex;
        }

public override string ToString()
        {
            return "ID:" + RowIndex + "." + ColIndex;
        }

public string Name()
        {
            return "ID_" + RowIndex + "_" + ColIndex;
        }
    }

/// <summary>
    /// PieceOfJigsaw.xaml 的交互逻辑
    /// </summary>
    public partial class PieceOfJigsaw : UserControl
    {
        public event IsRotatedHandler IsRotated;
        public event IsTranslatedHandler IsTranslated;
        public event IsClickedHandler IsClicked;
       
        public ID Id;

private TranslateTransform Tt;
        private RotateTransform Rt;
       
        private Point   offsetPrevious;
        private bool    isTranslate = false;
        private bool    isRotate = false;

//边界线
        private Line LineLeft;
        private Line LineTop;
        private Line LineRight;
        private Line LineBottom;
       
        //坐标
        private Point LeftTop;
        private Point RightTop;
        private Point RightBottom;
        private Point LeftBottom;

private Storyboard storyboard;

public PieceOfJigsaw(
            BitmapSource bitmapSource,
            Point position,
            Size size,
            ID id)
        {
            InitializeComponent();

image.Source = bitmapSource;

HorizontalAlignment = HorizontalAlignment.Left;
            VerticalAlignment = VerticalAlignment.Top;
            Margin = new Thickness(position.X, position.Y, 0, 0);

Width = size.Width;
            Height = size.Height;
            image.Width = Width;
            image.Height = Height;

Id = id;

Rt = new RotateTransform(0);
            Rt.CenterX = 0;
            Rt.CenterY = 0;

Tt = new TranslateTransform();
            Tt.X = 0;
            Tt.Y = 0;

TransformGroup tg = new TransformGroup();

tg.Children.Add(Rt);//顺序很重要,先旋转再平移
            tg.Children.Add(Tt);
            RenderTransform = tg;

rotateHandle.Visibility = System.Windows.Visibility.Hidden;

initLineBorder();
            calculateCoordinates();
            initStoryBoard();
        }

public BitmapSource Image
        {
            set
            {
                image.Source = value;
            }
        }

public Size Size
        {
            set
            {
                Width = value.Width;;
                Height = value.Height;
                image.Width = Width;
                image.Height = Height;

LineLeft.Y2 = Height;

LineTop.X2 = Width;

LineRight.X1 = Width;
                LineRight.X2 = Width;
                LineRight.Y2 = Height;

LineBottom.Y1 = Height;
                LineBottom.X2 = Width;
                LineBottom.Y2 = Height;

calculateCoordinates();
            }
        }

public double Angle
        {
            get
            {
                return Rt.Angle;
            }

set
            {
                Rt.Angle = value;
                calculateCoordinates();
            }
        }

public double CenterX
        {
            set
            {
                Rt.CenterX = value;               
                calculateCoordinates();
            }
        }

public double CenterY
        {
            set
            {
                Rt.CenterY = value;
                calculateCoordinates();
            }
        }

public double TranslateX
        {
            get
            {
                return Tt.X;
            }

set
            {
                Tt.X = value;
                calculateCoordinates();
            }
        }

public double TranslateY
        {
            get
            {
                return Tt.Y;
            }

set
            {
                Tt.Y = value;
                calculateCoordinates();
            }
        }

public bool IsBorderLeftVisible
        {
            get
            {
                if (LineLeft.Visibility == System.Windows.Visibility.Visible)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

set
            {
                if (value == true)
                {
                    LineLeft.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    LineLeft.Visibility = System.Windows.Visibility.Hidden;
                }
            }
        }

public bool IsBorderRightVisible
        {
            get
            {
                if (LineRight.Visibility == System.Windows.Visibility.Visible)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

set
            {
                if (value == true)
                {
                    LineRight.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    LineRight.Visibility = System.Windows.Visibility.Hidden;
                }
            }
        }

public bool IsBorderTopVisible
        {
            get
            {
                if (LineTop.Visibility == System.Windows.Visibility.Visible)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

set
            {
                if (value == true)
                {
                    LineTop.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    LineTop.Visibility = System.Windows.Visibility.Hidden;
                }
            }
        }

public bool IsBorderBottomVisible
        {
            get
            {
                if (LineBottom.Visibility == System.Windows.Visibility.Visible)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

set
            {
                if (value == true)
                {
                    LineBottom.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    LineBottom.Visibility = System.Windows.Visibility.Hidden;
                }
            }
        }

public Brush BorderLeftColor
        {
            set
            {
                LineLeft.Stroke = value;
            }
        }

public Brush BorderRightColor
        {
            set
            {
                LineRight.Stroke = value;
            }
        }

public Brush BorderTopColor
        {
            set
            {
                LineTop.Stroke = value;
            }
        }

public Brush BorderBottomColor
        {
            set
            {
                LineBottom.Stroke = value;
            }
        }

public void Animate()
        {
            storyboard.Begin(this);
        }

public bool IsNeighbourhood(PieceOfJigsaw pOJ)
        {
            if (Id.RowIndex == pOJ.Id.RowIndex &&
                Id.ColIndex == pOJ.Id.ColIndex - 1)
            {
                return true;
            }
            else if (Id.RowIndex == pOJ.Id.RowIndex &&
                Id.ColIndex == pOJ.Id.ColIndex + 1)
            {
                return true;
            }
            else if (Id.ColIndex == pOJ.Id.ColIndex &&
                Id.RowIndex == pOJ.Id.RowIndex - 1)
            {
                return true;
            }
            else if (Id.ColIndex == pOJ.Id.ColIndex &&
                Id.RowIndex == pOJ.Id.RowIndex + 1)
            {
                return true;
            }
            return false;
        }

public bool IsBuddy(PieceOfJigsaw pOJ)
        {
            double dis1, dis2;
            if (IsBorderRightVisible == true &&
                pOJ.IsBorderLeftVisible == true &&
                Id.RowIndex == pOJ.Id.RowIndex &&
                Id.ColIndex == pOJ.Id.ColIndex - 1)
            {
                dis1 = distance(RightTop, pOJ.LeftTop);
                dis2 = distance(RightBottom, pOJ.LeftBottom);

if (dis1 < 6 && dis2 < 6)
                {
                    return true;
                }
            }
            else if (IsBorderBottomVisible == true &&
                pOJ.IsBorderTopVisible == true &&
                Id.RowIndex == pOJ.Id.RowIndex - 1 &&
                Id.ColIndex == pOJ.Id.ColIndex)
            {
                dis1 = distance(LeftBottom, pOJ.LeftTop);
                dis2 = distance(RightBottom, pOJ.RightTop);
                if (dis1 < 6 && dis2 < 6)
                {
                    return true;
                }
            }
            else if (IsBorderLeftVisible == true &&
                pOJ.IsBorderRightVisible == true &&
                Id.RowIndex == pOJ.Id.RowIndex &&
                Id.ColIndex == pOJ.Id.ColIndex + 1)
            {
                dis1 = distance(LeftTop, pOJ.RightTop);
                dis2 = distance(LeftBottom, pOJ.RightBottom);
                if (dis1 < 6 && dis2 < 6)
                {
                    return true;
                }
            }
            else if (IsBorderTopVisible == true &&
                pOJ.IsBorderBottomVisible == true &&
                Id.RowIndex == pOJ.Id.RowIndex + 1 &&
                Id.ColIndex == pOJ.Id.ColIndex)
            {
                dis1 = distance(LeftTop, pOJ.LeftBottom);
                dis2 = distance(RightTop, pOJ.RightBottom);
                if (dis1 < 6 && dis2 < 6)
                {
                    return true;
                }
            }
            return false;
        }

public void Reset()
        {
            Angle = 0;
            CenterX = 0;
            CenterY = 0;
            TranslateX = 0;
            TranslateY = 0;
            IsBorderLeftVisible = true;
            IsBorderRightVisible = true;
            IsBorderTopVisible = true;
            IsBorderBottomVisible = true;
            BorderLeftColor = Brushes.Snow;
            BorderRightColor = Brushes.Snow;
            BorderTopColor = Brushes.Snow;
            BorderBottomColor = Brushes.Snow;
        }

private void mouseEnter(object sender, MouseEventArgs e)
        {
            rotateHandle.Visibility = System.Windows.Visibility.Visible;
            rotateHandle.Margin = new Thickness(Width / 2, Height / 2, 0, 0);
            rotateHandle.Width = 8;
            rotateHandle.Height = 8;
        }

private void mouseLeave(object sender, MouseEventArgs e)
        {
            isRotate = false;
            isTranslate = false;
            rotateHandle.Visibility = System.Windows.Visibility.Hidden;
        }

private void mouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.Source is Ellipse)
            {
                isRotate = true;
                offsetPrevious = Mouse.GetPosition(this);
            }
            else
            {
                isTranslate = true;
                offsetPrevious = Mouse.GetPosition(null);
            }

IsClicked(this);
        }

private void mouseMove(object sender, MouseEventArgs e)
        {           
            if (isRotate == true)
            {               
                Point offset = Mouse.GetPosition(this);

double alpha = Math.Atan((offset.Y - Rt.CenterY) / (offset.X - Rt.CenterX));
                double beta = Math.Atan((offsetPrevious.Y - Rt.CenterY) / (offsetPrevious.X - Rt.CenterX));
                double deltaAngle = alpha - beta;
                deltaAngle *= 180 / Math.PI;
                deltaAngle += Rt.Angle;

deltaAngle %= 360;
                deltaAngle += 360;
                deltaAngle %= 360;

if (deltaAngle < 3 || deltaAngle > 357)
                {
                    deltaAngle = 0;
                }
                Angle = deltaAngle;
               
                IsRotated(this);
            }
            else if (isTranslate == true)
            {
                Point offset = Mouse.GetPosition(null);

double deltaX = offset.X - offsetPrevious.X;
                double deltaY = offset.Y - offsetPrevious.Y;

TranslateX += deltaX;
                TranslateY += deltaY;

offsetPrevious = offset;

IsTranslated(this);
            }
        }

private void mouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            isRotate = false;
            isTranslate = false;
        }
       
        private void initLineBorder()
        {
            double borderThickness = ScreenUnitConverter.PixelToInch(1);

LineLeft = new Line();
            LineLeft.X1 = 0;
            LineLeft.Y1 = 0;
            LineLeft.X2 = 0;
            LineLeft.Y2 = Height;
            LineLeft.Stroke = Brushes.Snow;
            LineLeft.StrokeThickness = borderThickness;
            LineLeft.Visibility = Visibility.Visible;

LineTop = new Line();
            LineTop.X1 = 0;
            LineTop.Y1 = 0;
            LineTop.X2 = Width;
            LineTop.Y2 = 0;
            LineTop.Stroke = Brushes.Snow;
            LineTop.StrokeThickness = borderThickness;
            LineTop.Visibility = Visibility.Visible;

LineRight = new Line();
            LineRight.X1 = Width;
            LineRight.Y1 = 0;
            LineRight.X2 = Width;
            LineRight.Y2 = Height;
            LineRight.Stroke = Brushes.Snow;
            LineRight.StrokeThickness = borderThickness;
            LineRight.Visibility = Visibility.Visible;

LineBottom = new Line();
            LineBottom.X1 = 0;
            LineBottom.Y1 = Height;
            LineBottom.X2 = Width;
            LineBottom.Y2 = Height;
            LineBottom.Stroke = Brushes.Snow;
            LineBottom.StrokeThickness = borderThickness;
            LineBottom.Visibility = Visibility.Visible;

POJGrid.Children.Add(LineLeft);
            POJGrid.Children.Add(LineTop);
            POJGrid.Children.Add(LineRight);
            POJGrid.Children.Add(LineBottom);
        }

private void calculateCoordinates()
        {
            if (LineBottom.IsVisible == false &&
                LineLeft.IsVisible == false &&
                LineRight.IsVisible == false &&
                LineTop.IsVisible == false)
            {
                return;
            }

double x0 = Rt.CenterX + Margin.Left;
            double y0 = Rt.CenterY + Margin.Top;
            y0 = -y0;

double x1 = Margin.Left;
            double y1 = Margin.Top;
            y1 = -y1;

double gama = (360 - Rt.Angle) * Math.PI / 180;
            LeftTop.X = x0 + (x1 - x0) * Math.Cos(gama) - (y1 - y0) * Math.Sin(gama) + Tt.X;
            LeftTop.Y = -1 * (y0 + (x1 - x0) * Math.Sin(gama) + (y1 - y0) * Math.Cos(gama)) + Tt.Y;

x1 = Margin.Left + Width;
            y1 = Margin.Top;
            y1 = -y1;
            gama = (360 - Rt.Angle) * Math.PI / 180;
            RightTop.X = x0 + (x1 - x0) * Math.Cos(gama) - (y1 - y0) * Math.Sin(gama) + Tt.X;
            RightTop.Y = -1 * (y0 + (x1 - x0) * Math.Sin(gama) + (y1 - y0) * Math.Cos(gama)) + Tt.Y;

x1 = Margin.Left + Width;
            y1 = Margin.Top + Height;
            y1 = -y1;
            gama = (360 - Rt.Angle) * Math.PI / 180;
            RightBottom.X = x0 + (x1 - x0) * Math.Cos(gama) - (y1 - y0) * Math.Sin(gama) + Tt.X;
            RightBottom.Y = -1 * (y0 + (x1 - x0) * Math.Sin(gama) + (y1 - y0) * Math.Cos(gama)) + Tt.Y;

x1 = Margin.Left;
            y1 = Margin.Top + Height;
            y1 = -y1;
            gama = (360 - Rt.Angle) * Math.PI / 180;
            LeftBottom.X = x0 + (x1 - x0) * Math.Cos(gama) - (y1 - y0) * Math.Sin(gama) + Tt.X;
            LeftBottom.Y = -1 * (y0 + (x1 - x0) * Math.Sin(gama) + (y1 - y0) * Math.Cos(gama)) + Tt.Y;
        }

private void initStoryBoard()
        {
            Name = Id.Name();
            this.RegisterName(Name, this);

DoubleAnimation pOJAnimation = new DoubleAnimation();
            pOJAnimation.From = 1.0;
            pOJAnimation.To = 0.0;
            pOJAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
            pOJAnimation.AutoReverse = true;
            storyboard = new Storyboard();
            Storyboard.SetTargetName(pOJAnimation, Name);
            Storyboard.SetTargetProperty(pOJAnimation, new PropertyPath(PieceOfJigsaw.OpacityProperty));

storyboard.Children.Add(pOJAnimation);
        }

private double distance(Point p1, Point p2)
        {
            return Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y));
        }
    }
}



我的第一个C#程序-智能拼图游戏相关推荐

  1. 我的第一个C#程序-智能拼图图示

    智能拼图图示

  2. 拼图java代码_Java制作智能拼图游戏原理及代码

    今天突发奇想,想做一个智能拼图游戏来给哄女友. 需要实现这些功能 第一图片自定义 第二宫格自定义,当然我一开始就想的是3*3 4*4 5*5,没有使用3*5这样的宫格. 第三要实现自动拼图的功能,相信 ...

  3. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个可拖动的拼图游戏动画效果~适合初学者~超简单~ |it前端开发

    b站视频演示效果: [web前端特效源码]使用HTML5+CSS3+JavaScript制作一个可拖动的拼图游戏动画效果~适合初学者~超简单~ |前端开发|IT软件 效果图: 完整代码: <!D ...

  4. python抽奖游戏_利用Python写一个抽奖程序,解密游戏内抽奖的秘密

    原标题:利用Python写一个抽奖程序,解密游戏内抽奖的秘密 前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 极客 ...

  5. 智能拼图游戏 问题 求解

    最近想编个程序,用于拼图游戏的电脑拼图.程序语言为VB,作业范围为9格和16格.通过拼图软件掌握了拼图的规律,并可用编程语言描述. 但是在编程的过程中,发现任意的图片排布不一定能够拼出全图.于是我开始 ...

  6. 用Android Studio做一个超好玩的拼图游戏,附送超详细注释的源码

    文章目录 一.项目概述 二.开发环境 三.需求分析 四.实现过程 1.拼图游戏布局绘制 2.拼图游戏时间计时 3.拼图游戏打乱显示 4.拼图游戏碎片位置切换 5.拼图游戏成功的条件 6.拼图游戏重新开 ...

  7. python抽奖教程_利用Python写一个抽奖程序,解密游戏内抽奖的秘密|python基础教程|python入门|python教程...

    https://www.xin3721.com/eschool/pythonxin3721/ 分析需求 我们先整理下思路,目标是什么?目标是要写一个抽奖程序,那么抽奖程序的核心是什么?当然是如何判断一 ...

  8. 用Python做一个超好玩的拼图游戏,0基础也能包你学会,附送超详细注释的源码~

    导语 你所认为的python........                                                              python & bor ...

  9. 一个菜鸟程序员的游戏开发心得

    对于一个只在大学期间学习了JavaScript,实习期间学习了点HTML.CSS的菜鸟,做游戏对我而言是一件想都不敢想的事情,后有幸被公司安排参与一款HTML5游戏的开发,才使我真正第一次与游戏来了次 ...

最新文章

  1. 播客#47:劳伦斯·布拉德福德
  2. raptor算法流程图例题_raptor程序设计例题参考答案
  3. Google搜索引擎的十大应用
  4. 用jamon来监控你的sql执行效率
  5. Linux安装rpc监控系统资源
  6. Linux 7.x 防火墙端口
  7. 基于JAVA+Spring+MYSQL的码头船只出行管理系统
  8. web安全day24:一文读懂Linux系统安装软件的几种方法
  9. 基于nvidia的ffmpeg编解码加速
  10. 华三交换机配置vrrp_h3c vrrp配置实例
  11. 计算机开题报告课题来源,开题报告课题来源该怎么写
  12. canvas绘制图片时宽高2倍
  13. 字节面试算法题:用集合中的数凑小于target的最大数(Java实现,各类用例均通过)
  14. 计算机本科毕业后还可以当音乐人吗,我想考计算机研究生 但是我音乐鉴赏不及格拿可能不到毕业证 那我还能报考研究生吗?...
  15. Java波斯王子时之沙攻略_《波斯王子:时之砂》剧情攻略
  16. be seen doing和be seen to do的区别
  17. 对不起,我就是传说中的 10 倍工程师”
  18. typora上传图片
  19. H5项目中通过iframe引入语音导览解决微信jsapi关于同一级域名二级域名跨域问题解决方案
  20. snakeyaml 简介、中文文档、中英对照文档 下载

热门文章

  1. Eclipse 是什么?
  2. 比较日期大小的js代码分享
  3. 网页设计作业 开心网旅游(11页) web前端期末大作业 html+css+javascript网页设计实例
  4. DMS、RDS、OLAP简介
  5. 算法之顺序查找【C语言】
  6. 【网络教程】如何删除微软云Microsoft Azure绑定的信用卡(解绑信用卡)
  7. $.messager的使用笔记
  8. 项目里面导入外部字体
  9. php百分数正则,php半小时精通正则表达式
  10. 精通正则表达式第三章:正则表达式的特性和流派概览