Inheritance: IDisposable, ISerializable
Esempio n. 1
0
        /// <summary>
        /// 将指定的拼图碎片与当前的拼图碎片合并。不检查两个拼图碎片是否可以被合并。
        /// </summary>
        /// <param name="piece">要合并的拼图碎片。</param>
        public void Merge(JigsawPiece piece)
        {
            // 更新相邻拼图碎片信息。
            foreach (JigsawPiece p in piece.neighbors)
            {
                p.neighbors.Remove(piece);
                p.neighbors.Add(this);
            }
            this.neighbors.UnionWith(piece.neighbors);
            this.neighbors.Remove(this);
            // 更新形状。
            float sum = this.shape.Weight + piece.shape.Weight;

            this.offset = new Vector2((this.offset.X * this.shape.Weight + piece.offset.X * piece.shape.Weight) / sum,
                                      (offset.Y * this.shape.Weight + piece.offset.Y * piece.shape.Weight) / sum);
            this.shape.Merge(piece.shape);
            // 更新路径。
            GeometryGroup newGroup = SharpDXUtility.Merge(this.originalPath, piece.originalPath);

            this.originalPath.Dispose();
            this.originalPath = newGroup;
            this.CalculateMatrix();
            this.UpdatePath();
            if (piece.PieceType == JigsawPieceType.Border)
            {
                this.pieceType = JigsawPieceType.Border;
            }
            piece.Dispose();
        }
Esempio n. 2
0
        /// <summary>
        /// 判断指定的拼图碎片是否可以与当前碎片合并。
        /// </summary>
        /// <param name="piece">要判断合并的拼图碎片。</param>
        /// <param name="radius">允许进行吸附的半径。</param>
        /// <returns>是否能合并。</returns>
        public bool CanMerge(JigsawPiece piece, float radius)
        {
            if (piece == this)
            {
                return(true);
            }
            if (piece.rotate != this.rotate)
            {
                return(false);
            }
            // 在拼图坐标系下比较 (0, 0) 点的距离。
            Vector2 point = new Vector2();

            return(radius * radius >= Vector2.DistanceSquared(this.PointToJigsaw(point), piece.PointToJigsaw(point)));
        }
		/// <summary>
		/// 将指定的拼图碎片与当前的拼图碎片合并。不检查两个拼图碎片是否可以被合并。
		/// </summary>
		/// <param name="piece">要合并的拼图碎片。</param>
		public void Merge(JigsawPiece piece)
		{
			// 更新相邻拼图碎片信息。
			foreach (JigsawPiece p in piece.neighbors)
			{
				p.neighbors.Remove(piece);
				p.neighbors.Add(this);
			}
			this.neighbors.UnionWith(piece.neighbors);
			this.neighbors.Remove(this);
			// 更新形状。
			float sum = this.shape.Weight + piece.shape.Weight;
			this.offset = new Vector2((this.offset.X * this.shape.Weight + piece.offset.X * piece.shape.Weight) / sum,
				(offset.Y * this.shape.Weight + piece.offset.Y * piece.shape.Weight) / sum);
			this.shape.Merge(piece.shape);
			// 更新路径。
			GeometryGroup newGroup = SharpDXUtility.Merge(this.originalPath, piece.originalPath);
			this.originalPath.Dispose();
			this.originalPath = newGroup;
			this.CalculateMatrix();
			this.UpdatePath();
			if (piece.PieceType == JigsawPieceType.Border)
			{
				this.pieceType = JigsawPieceType.Border;
			}
			piece.Dispose();
		}
		/// <summary>
		/// 判断指定的拼图碎片是否可以与当前碎片合并。
		/// </summary>
		/// <param name="piece">要判断合并的拼图碎片。</param>
		/// <param name="radius">允许进行吸附的半径。</param>
		/// <returns>是否能合并。</returns>
		public bool CanMerge(JigsawPiece piece, float radius)
		{
			if (piece == this)
			{
				return true;
			}
			if (piece.rotate != this.rotate)
			{
				return false;
			}
			// 在拼图坐标系下比较 (0, 0) 点的距离。
			Vector2 point = new Vector2();
			return radius * radius >= Vector2.DistanceSquared(this.PointToJigsaw(point), piece.PointToJigsaw(point));
		}
		/// <summary>
		/// 返回指定拼图碎片的阴影位图。
		/// </summary>
		/// <param name="piece">要获取阴影位图的拼图碎片。</param>
		/// <returns>指定拼图碎片的阴影位图。</returns>
		private Tuple<Bitmap, Vector2> GetShadow(JigsawPiece piece)
		{
			Tuple<Bitmap, Vector2> tuple;
			if (!shadowCache.TryGetValue(piece.OriginalPath, out tuple))
			{
				// 移除已被释放的拼图碎片。
				Geometry disposedGeom = null;
				if ((disposedGeom = shadowCache.Keys.FirstOrDefault(g => g.IsDisposed)) != null)
				{
					shadowCache.Remove(disposedGeom);
				}
				RectangleF bounds = piece.OriginalPath.GetBounds();
				Size2 size = new Size2((int)bounds.Width + ShadowPadding * 2, (int)bounds.Height + ShadowPadding * 2);
				using (Bitmap1 source = DeviceManager.CreateBitmap(size))
				{
					Bitmap1 target = DeviceManager.CreateBitmap(size);
					// 设置特效的输入。
					shadowEffect.SetInput(0, source, true);
					// 阴影的偏移。
					Vector2 offset = new Vector2(bounds.Left - ShadowPadding, bounds.Top - ShadowPadding);
					using (TransformedGeometry tGeom = new TransformedGeometry(this.DeviceContext.Factory,
						piece.OriginalPath, Matrix3x2.Translation(-offset.X, -offset.Y)))
					{
						// 将拼图碎片绘制到位图上。
						this.DeviceContext.Target = source;
						this.DeviceContext.BeginDraw();
						this.DeviceContext.Clear(Color.Transparent);
						this.DeviceContext.FillGeometry(tGeom, blackBrush);
						this.DeviceContext.EndDraw();

						// 将添加特效后的拼图碎片绘制到位图上。
						this.DeviceContext.Target = target;
						this.DeviceContext.BeginDraw();
						this.DeviceContext.DrawImage(shadowEffect);
						this.DeviceContext.EndDraw();

						tuple = new Tuple<Bitmap, Vector2>(target, offset);
						shadowCache.Add(piece.OriginalPath, tuple);
					}
				}
			}
			return tuple;
		}
		/// <summary>
		/// 鼠标移动。
		/// </summary>
		private void renderPanel_MouseMove(object sender, MouseEventArgs e)
		{
			Vector2 loc = renderPanel.PointToJigsaw(e.Location);
			if (isDraging)
			{
				// 拖动被选中的拼图碎片
				Drag(loc);
				lastMousePoint = loc;
			}
			else if (isSelecting)
			{
				// 选择图片。
				if (lastMousePoint.X < loc.X)
				{
					selectRect.Left = lastMousePoint.X;
					selectRect.Right = loc.X;
				}
				else
				{
					selectRect.Left = loc.X;
					selectRect.Right = lastMousePoint.X;
				}
				if (lastMousePoint.Y < loc.Y)
				{
					selectRect.Top = lastMousePoint.Y;
					selectRect.Bottom = loc.Y;
				}
				else
				{
					selectRect.Top = loc.Y;
					selectRect.Bottom = lastMousePoint.Y;
				}
				selectedPieces.Clear();
				selectedPieces.AddRange(pieces.GetPiece(selectRect));
			}
			else
			{
				// 鼠标经过时高亮拼图碎片
				if (lastPiece != null)
				{
					lastPiece.State &= ~JigsawPieceState.Highlight;
				}
				lastPiece = pieces.GetPiece(loc);
				if (lastPiece != null && !lastPiece.Frozen)
				{
					lastPiece.State |= JigsawPieceState.Highlight;
				}
			}
			InvalidateAll();
		}
		/// <summary>
		/// 检查当前拼图碎片能否与其它拼图碎片合并。
		/// </summary>
		private void CheckAnchor()
		{
			int finished = this.FinishedPercent;
			lastPiece = pieces.Merge(lastPiece, gameInfo.AnchorRadius);
			// 移除被合并的拼图碎片。
			this.selectedPieces.IntersectWith(pieces);
			// 吸附到正确的位置。
			if (gameInfo.AnchorToBackground && lastPiece.Rotate == 0)
			{
				float tx = lastPiece.Offset.X;
				float ty = lastPiece.Offset.Y;
				if ((tx * tx + ty * ty) <= gameInfo.AnchorRadius * gameInfo.AnchorRadius)
				{
					lastPiece.Frozen = true;
					lastPiece.Offset = new Vector2();
					pieces.BringToBack(lastPiece);
				}
			}
			pieces.CollectInRectangle(renderPanel.JigsawRegion, this.selectedPieces);
			if (selectedPieces.SingleSelected)
			{
				selectedPieces.Clear();
			}
			renderPanel.AutoMouseScroll = false;
			gameChanged = true;
			if (this.FinishedPercent != finished)
			{
				UpdateFinishedPercent();
			}
		}
		/// <summary>
		/// 鼠标弹起。
		/// </summary>
		private void renderPanel_MouseUp(object sender, MouseEventArgs e)
		{
			renderPanel.Cursor = Cursors.Default;
			if (e.Button == MouseButtons.Left)
			{
				if (isDraging)
				{
					// 鼠标弹起,放下拼图碎片。
					StopDrag();
					CheckAnchor();
				}
				else if (isSelecting)
				{
					isSelecting = false;
				}
				// 把拼图碎片放到最底层。
				if (Control.ModifierKeys == Keys.Control)
				{
					if (lastPiece != null)
					{
						pieces.BringToBack(lastPiece);
					}
				}
			}
			else if (e.Button == MouseButtons.Right && gameInfo.Rotatable)
			{
				// 右键旋转
				Vector2 loc = renderPanel.PointToJigsaw(e.Location);
				lastPiece = pieces.GetPiece(loc);
				if (lastPiece != null && !lastPiece.Frozen)
				{
					pieces.BringToFront(lastPiece);
					if (Control.ModifierKeys == Keys.Control)
					{
						lastPiece.Rotate = (lastPiece.Rotate + 270) % 360;
					}
					else
					{
						lastPiece.Rotate = (lastPiece.Rotate + 90) % 360;
					}
					CheckAnchor();
				}
			}
			InvalidateAll();
		}
		/// <summary>
		/// 鼠标按下。
		/// </summary>
		private void renderPanel_MouseDown(object sender, MouseEventArgs e)
		{
			isSelecting = false;
			if (e.Button == MouseButtons.Left)
			{
				lastMousePoint = renderPanel.PointToJigsaw(e.Location);
				lastPiece = pieces.GetPiece(lastMousePoint);
				if (lastPiece != null && lastPiece.Frozen)
				{
					lastPiece = null;
				}
				if (lastPiece == null)
				{
					selectedPieces.Clear();
					isSelecting = true;
					selectRect = new RectangleF(lastMousePoint.X, lastMousePoint.Y, 0f, 0f);
				}
				else
				{
					renderPanel.Cursor = Cursors.Hand;
					if (!selectedPieces.Contains(lastPiece))
					{
						// 拖动单个拼图碎片
						selectedPieces.Clear();
						selectedPieces.Add(lastPiece);
					}
					StartDrag();
					renderPanel.AutoMouseScroll = true;
				}
			}
			else
			{
				selectedPieces.Clear();
			}
			InvalidateAll();
		}