WPF特效-拼图游戏

原文: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:

可以通过提前设定矩阵碎片样式的固定模式得到所有切图,也可以随机生成每个碎片,每个片的形状通过检索左侧右边是否凹凸和上侧碎片下边是否凹凸获得。我的碎片化效果如下图。

原文地址:https://www.cnblogs.com/lonelyxmas/p/9472693.html

时间: 2024-10-08 20:05:42

WPF特效-拼图游戏的相关文章

拼图游戏 v1.1

原文:拼图游戏 v1.1 我一直对拼图游戏比较有兴趣,市面上卖的所谓“1000块拼图”也玩过不少,不过玩那个太占地方,后来也不再买了,同时也就萌生了在电脑上玩拼图的想法. 现在虽然有很多拼图游戏,但能大多数只能支持几十或几百块拼图,很少能支持上千块拼图的游戏. 后来,我就利用 Direct2D 自己实现了一个拼图游戏,可以流畅的支持最高 1200 块的拼图(更高其实也可以支持,但是感觉已经足够了),拼图碎片之间也可以自动吸附,还可以设置吸附到背景.游戏界面如图 1 所示. 图 1 游戏界面 一.

一款html拼图游戏详解

本文是爱编程原创翻译,转载请看清文末的转载要求,谢谢合作! 游戏介绍 这篇文章是献给web游戏开发者用简单的开发工具开发一款游戏.此文介绍了用html.css.javascript只需简单和几个步骤开发一款2d游戏.在这里,我要呈现给大家如何创建一款拼图游戏,在这个游戏中你可以拖动小图块来拼成完整的大图. 点击这里查看游戏效果. 游戏规则 游戏规则非常简单,你只要拖动被切碎的图片块来组成完整的大图.需要用正确的方法才能最终拼成完整的图片.在游戏中拖动小图片的次数将被统计下来.所以.应该尽量用最少

Vue.js实现拼图游戏

Vue.js实现拼图游戏 之前写过一篇<基于Vue.js的表格分页组件>的文章,主要介绍了Vue组件的编写方法,有兴趣的可以访问这里进行阅读:http://www.cnblogs.com/luozhihao/p/5516065.html 前言 为了进一步让大家了解Vue.js的神奇魅力,了解Vue.js的一种以数据为驱动的理念,本文主要利用Vue实现了一个数字拼图游戏,其原理并不是很复杂,效果图如下: demo展示地址为:https://luozhihao.github.io/vue-puzz

Entanglement Web App(六边拼图游戏)

插件介绍: 对常常面对电脑工作的朋友们来说,一款能够让你们放松的游戏是必不可少的,今天为大家推荐一款度过休闲时光的小游戏.纠缠是gopherwood工作室为您做的六边拼图的益智游戏,试着使最长的路成为可能.旋转和放置六角形瓷砖蚀刻路径,以延长您的路径,而不运行到墙上. 使用说明: 将Entanglement Web App(六边拼图游戏)添加至chrome,并在应用中启动它. 功能介绍: - 挑战模式;你可以不断挑战自己或者他人的记录.- 樱花小树林:一个完全新的游戏游戏模式的纠缠!你有一个宽敞

JavaScript写一个拼图游戏

拼图游戏的代码400行, 有点多了, 在线DEMO的地址是:打开: 因为使用canvas,所以某些浏览器是不支持的: you know: 为什么要用canvas(⊙o⊙)?  因为图片是一整张jpg或者png, 我们要用把图片导入到canvas画布, 然后再调用上下文context的getImageData方法, 把图片处理成小图, 这些小图就作为拼图的基本单位: 如何判断游戏是否结束, 或者说如何判断用户拼成的大图是正确的? 我们就要在刚刚生成的小图上面添加自定义属性, 后期在小图被移动后再一

拼图游戏(数码还原游戏)算法的研究

将问题一般化,在M*N的方格里有M*N-1个不同元素和一个空元素,只有空元素可以与上下左右相邻的元素交换位置.M*N方格中M*N-1个元素和一个空元素的位置确定一个图形.拼图游戏的问题是:一个图形经过一连串的交换能否得到另一个图形,如何得到.从交换方式的可逆性看出这种关系满足等价三性质,如果图形A通过交换变成图形B我们则称它们是等价的.把M*N-1个元素用1至M*N-1编号,空元素编号0.然后展成一个排列.每个图形对应一个排列.确定了展开方式,图形和排列是一一对应的.这里用到的展开方式是行优先的

类似拼图游戏设计

客户端设计 1.如何绘制? 分上下两层,下层为最终图片,上层尺寸和下层一致,并将上层分割为 m 行 n 列的方格. 2.方格位置如何设定? m 行 n 列的方格,设定左上角坐标为(0,0),那么最右下角坐标为( (m-1) , (n-1) ). 3.如何定义方格对象,及方格拥有什么方法和属性? 方格Pane有4个属性: locationX,locationY,PaneState,visitor. (locationX,locationY)组成方格位置信息: PaneState包含3种状态,VIS

程序设计 之 C#实现《拼图游戏》 (下) 原理篇

前言:在 http://www.cnblogs.com/labixiaohei/p/6698887.html 程序设计 之 C#实现<拼图游戏>(上),上传了各模块代码,而在本文中将详细剖析原理,使读者更容易理解并学习,程序有诸多问题,欢迎指出,共同学习成长! 正文: 拼图是一个非常经典的游戏,基本每个人都知道他的玩法,他的开始,运行,结束.那么,当我们想要做拼图的时候如何入手呢?答案是:从现实出发,去描述需求(尽量描述为文档),当我们拥有了全面的需求,就能够提供可靠的策略,从而在代码中实现,

拼图游戏(数码还原游戏)的实现

一.游戏规则 首先,这里的拼图游戏是滑块拼图,类似于华容道,游戏者通过移动拼图块将拼图还原为初始形状.关于拼图,常见的有3x3,4x4,多的以至于有16x16不等.一般块数越多拼图越复杂. 这里对游戏规则进行较严格的定义: 1. 游戏初始化时,将图形分为nxn个正方形块,随机摆放在原图形位置.一般以原图形右下角的一块为空白块,已进行移动.这里初始化时,也令新图形的右下角为空. 2. 游戏中,拼图的移动只能向空白块移动.从移动方向来说,有两种情况,分别是横移与纵移. 3. 游戏的胜利条件是将打乱的