標籤:clock 中心 try void alt enter release 一個 通過
原文:WPF特效-拼圖遊戲
此文主要描述我實現片段化的便捷過程。
步驟1:
? ?選取參考圖如下(百度圖庫搜的):
步驟2:
? ?根據或者模型構建貝茲路徑,為了方便查看效果,可以設定控制點,Console.WriteLine或直接UI上顯示的方式記錄最終座標,如:
?
?中的紅線,為兩條貝茲路徑,左側的位置我已經通過控制點的方式調好。 Gif為我調整上方第二條貝塞爾的示意。
步驟3:
?當上方右側的第二條貝茲路徑也調整好後,就已經相當於調整好了所有的四條邊。
? 具體原理為:最上方的一條線繞著最右邊的頂點逆時針旋轉90度即可得到右側的線。右側的線以最下方的點逆時針旋轉90度就是下方的線。左側的線也通過旋轉下方的線得到。唯一需要做的就是抽一個某個點圍繞中心點逆時針旋轉90度後得到新點的函數。
<Canvas Width="448" Height="448" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="160" x:Name="CvMainZm" Background="Transparent"> <Path Stroke="Red" StrokeThickness="1" Fill="Blue" x:Name="Path1Zm"> <Path.Data> <PathGeometry> <PathGeometry.Figures> <PathFigureCollection> <PathFigure StartPoint="96, 96"> <PathFigure.Segments> <PathSegmentCollection> <BezierSegment x:Name="Bezier1Zm" Point1="286 62" Point2="96 176" Point3="224 192"/> <BezierSegment x:Name="Bezier2Zm" Point1="352 176" Point2="162 62" Point3="352 96"/> <BezierSegment x:Name="Bezier3Zm" Point3="448 224"/> <BezierSegment x:Name="Bezier4Zm" Point3="352 352"/> <BezierSegment x:Name="Bezier5Zm" Point3="224 266"/> <BezierSegment x:Name="Bezier6Zm" Point3="96 352"/> <BezierSegment x:Name="Bezier7Zm" Point3="0 224"/> <BezierSegment x:Name="Bezier8Zm" Point3="96 96"/> </PathSegmentCollection> </PathFigure.Segments> </PathFigure> </PathFigureCollection> </PathGeometry.Figures> </PathGeometry> </Path.Data> </Path> </Canvas>
如我的範例程式碼,我通過步驟1得到了 上方線的兩條Bezier線的值,直接寫入xaml中。(註:我提前根據步驟一的樣本圖,給出了每條Bezier的終點,即Point3)
<BezierSegment x:Name="Bezier1Zm" Point1="286 62" Point2="96 176" Point3="224 192"/> <BezierSegment x:Name="Bezier2Zm" Point1="352 176" Point2="162 62" Point3="352 96"/>
旋轉設定右側線操作:
private void SetRightFirstBezier() { Point oPoint1 = this.Bezier2Zm.Point1; Point oPoint2 = this.Bezier2Zm.Point2; Point oOrigin = this.Bezier2Zm.Point3; Point oNew = this.CarouselPointAnticlockwise(oPoint1, oOrigin); Point oNew2 = this.CarouselPointAnticlockwise(oPoint2, oOrigin); this.Bezier3Zm.Point1 = oNew2; this.Bezier3Zm.Point2 = oNew; } private void SetRightSecondBezier() { Point oPoint1 = this.Bezier1Zm.Point1; Point oPoint2 = this.Bezier1Zm.Point2; Point oOrigin = this.Bezier2Zm.Point3; Point oNew = this.CarouselPointAnticlockwise(oPoint1, oOrigin); Point oNew2 = this.CarouselPointAnticlockwise(oPoint2, oOrigin); this.Bezier4Zm.Point1 = oNew2; this.Bezier4Zm.Point2 = oNew;}
// 繞頂點旋轉得到新點座標private Point CarouselPointAnticlockwise(Point oPoint, Point oOrigin){? ? double dY = oOrigin.Y - oPoint.Y;? ? double dX = oOrigin.X - oPoint.X;? ? double dXAdd = dX - dY;? ? double dYAdd = dX + dY;? ? double dNewX = oPoint.X + dXAdd;? ? double dNewY = oPoint.Y + dYAdd;? ? return new Point(dNewX, dNewY);}
下方和左方以此類推。 這樣通過後台點旋轉的旋轉計算處理就可得到所有的Bezier。實現效果如。
步驟4:
通過步驟3得到的Path與RectangleGeometry進行組合,設定成不同片段的Clip屬性即可得到所有用到的片段,如下:
組合過程中,部分片段的Clip可通過其他片段的Clip直接翻轉或者順時針、逆時針旋轉直接得到。如:
?<CombinedGeometry x:Key="KeyPieceType4"?
? ? ? ? ? ? ? ? ? ? ? ? ? Geometry1="{StaticResource KeyPieceType1}">
? ? ? ? ? ? <CombinedGeometry.Transform>
? ? ? ? ? ? ? ? <TransformGroup>
? ? ? ? ? ? ? ? ? ? <ScaleTransform ScaleX="-1" CenterX="224" ScaleY="-1" CenterY="224" />
? ? ? ? ? ? ? ? ? ? <RotateTransform Angle="-90" CenterX="224" CenterY="224"/>
? ? ? ? ? ? ? ? </TransformGroup>
? ? ? ? ? ? </CombinedGeometry.Transform>
? ? ? ? </CombinedGeometry>
步驟5:
可以通過提前設定矩陣片段樣式的固定模式得到所有切圖,也可以隨機產生每個片段,每個片的形狀通過檢索左側右邊是否凹凸和上側片段下邊是否凹凸獲得。我的片段化效果如。
WPF特效-拼圖遊戲