热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#开发WPF/Silverlight动画及游戏系列教程(GameTutorial):(二十三)自适应性窗口化与全屏化(WPFOnly)

上一节中曾有提到,检测系统架构是否合理的评判标准之一就是系统的拓展性。在.NET网站应用中,一个优秀的架构可以在不同数据库之间相互转换,可以与不同的银行接口轻松对接,可以随意集成各种插件,而实

    上一节中曾有提到,检测系统架构是否合理的评判标准之一就是系统的拓展性。在.NET网站应用中,一个优秀的架构可以在不同数据库之间相互转换,可以与不同的银行接口轻松对接,可以随意集成各种插件,而实现这些仅仅需要对局部进行小小手术而已;同样的,在游戏设计中,窗口化与全屏化的自适应完美切换同样是对游戏架构合理性的严肃考验,Are you ready

    游戏窗口化与全屏化之间的切换方式有两种,第一种为仅对可视范围面积进行扩大与缩小而不缩放所有对象物体的尺寸。此方式在本游戏设计中实现起来非常简单,我们首先添加一个按钮作为测试按钮,然后为其添加ChangeWindowMode事件,接着定义四个变量分别记录全屏时的尺寸与窗口化时的尺寸:        double ScreenWidth, ScreenHeight, WindowWidth, WindowHeight并来在游戏初始化对它们进行赋值:

        private void InitializeGameSetting() {

            //设置尺寸

            ScreenWidth = SystemParameters.PrimaryScreenWidth;

            ScreenHeight = SystemParameters.PrimaryScreenHeight;

            WindowWidth = 800;

            WindowHeight = ScreenHeight * WindowWidth / ScreenWidth; //根据屏幕分辨率计算出窗口模式下高度

            ……

        }

    前三个属性都很好理解,而第四个WindowHeight为什么非要用公式来计算出值而不是直接取600来得干脆?这涉及到窗口自适应用户电脑分辨率的问题。如果您的电脑是43类型的分辨率,如800*6001024*7681280*960等这样的传统分辨率,你大可以直接设置Window; mso-hansi-font-family: 'Times New Roman'">、Window; mso-hansi-font-family: 'Times New Roman'">;但是用户的电脑如果是宽屏的(如169等),此时设置窗口模式尺寸为800*600将导致全屏化切换错误。一般网络游戏中会给予几个或多个可选分辨率让用户自行设置窗口化/全屏化切换,这些切换的实现基于对系统分辨率及刷新率进行更改的基础上;而WPF中实现起来简单多了,不需要再去调用WindowsAPI更改系统设置而是直接通过修改窗体自身属性WindowStyleWindowState轻松实现,具体方法如下:

        private void ChangeWindowMode(object sender, RoutedEventArgs e) {

            Button button = e.Source as Button;

            string mode = button.Content.ToString();

            if (mode == "全屏") {

                this.WindowStyle = WindowStyle.None;

                this.WindowState = WindowState.Maximized;

                button.COntent= "窗口";

            } else if (mode == "窗口") {

                this.WindowStyle = WindowStyle.SingleBorderWindow;

                this.WindowState = WindowState.Normal;

                button.COntent= "全屏";

            }

        }

    需要切换全屏时,我们只需要将窗口的标题栏与边框去掉(WindowStyle.None),并且设置窗口模式为最大化(WindowState.Maximized)即可;而如果需要将游戏窗口化则只需将窗口模式设置为单边框窗口(WindowStyle.SingleBorderWindow)并还原窗口(WindowState.Normal)即可。通过此方法实现的窗口化与全屏化的效果图如下:

    第二种方式我称之为按比例缩放模式,顾名思义,使用此模式进行切换时,所有的对象包括人物,地图,障碍物等东西均进行等比例的放大/缩小。实现此方法,首要任务是进行需求分析:在切换时,什么属性在发生变化了?当然是游戏中的一切内容它们自身及子内容的尺寸在改变。这里要特别说明的是,在前面的章节中,障碍物均为正方形,只用一个GridSize来定义它的边长;但是要是用户电脑是宽屏的,那么缩放时必须以使用矩形作为基础单元格,因此将GridSize拆分成GridSizeXGridSizeY两个变量分别代表单元格的宽与高,惟有这样才能胜任按比例缩放窗口的工作。那么根据此原理,我进行如下编写实现该模式下的窗口模式切换方法:

        double ratioX, ratioY; //定义X,Y方向上的缩放比例

        ///

        /// 改变游戏窗口尺寸(缩放窗口)

        ///

        /// 当前窗口宽

        /// 当前窗口高

        /// 新窗口宽

        /// 新窗口高

        private void ChangeWindowSize(double currentWidth, double currentHeight, double newWidth, double newHeight) {

            //主角的Storyboard停止(这很重要)

            Leader.Action = Actions.Stop;

            Leader.Direction = 4;

            if (storyboard != null) { storyboard.Stop(); }

            //计算缩放比例

            ratioX = newWidth / currentWidth;

            ratioY = newHeight / currentHeight;

            //缩放障碍物

            GridSizeX *= ratioX;

            GridSizeY *= ratioY;

            Carrier.Width = ActualWidth * ratioX;

            Carrier.Height = ActualHeight * ratioY;

            //所有精灵、地图等对象进行象素缩放

            for (int i = 0; i

                if (Carrier.Children[i] is QXObject) {

                    QXObject Obj = Carrier.Children[i] as QXObject;

                    Obj.X *= ratioX;

                    Obj.Y *= ratioY;

                    Obj.Width_ *= ratioX;

                    Obj.Height_ *= ratioY;

                    Obj.CenterX *= ratioX;

                    Obj.CenterY *= ratioY;

                    if (Obj is QXSpirit) {

                        QXSpirit Spirit = Obj as QXSpirit;

                        //缩放文字

                        Spirit.Describtion.Height *= ratioY;

                        Spirit.Describtion.SetValue(Canvas.TopProperty, (double)Spirit.Describtion.GetValue(Canvas.TopProperty) * ratioY);

                        Spirit.Faction.FontSize *= ratioX;

                        Spirit.Clan.FontSize *= ratioX;

                        Spirit.SName.FontSize *= ratioX;

                    }

                }

            }

        }

    首先计算出XY方向的缩放比例ratioXratioY,然后遍历所有对象物体与尺寸有关的属性进行“乘以”缩放比例操作。这样仅仅二十来行代码,即实现了对窗口中的所有对象物体的按比例缩放。大家不妨在不同的分辨率下或不同尺寸的显示器上进行此缩放操作测试,结果都是很完美的:

    这里需要特别说明的是,WPF是基于矢量的图形引擎,但是如果您使用的是像素图片,例如本例中的角色与地图,那么它同样会被基于像素进行拉伸,因为它并未被转换成矢量图。

    本节内容很简单,但是简单的背后是不为人知的烦琐与枯燥的调试。大家或许会因自觉本节内容毫无价值而十分恼火,但是我想告诉大家的是,不要小看了这不起眼的功能与调试,它不仅仅是对系统架构的一次有力考验(如果架构存在缺陷,就算勉强实现了表面上的窗口切换,角色一旦移动起来将会导致系统及画面漏洞百出);同时,就好比现在的网站需要符合W3C标准,需要同时兼容IEFIREFOX一样,软件是做给客户用的,一款软件能够满足各种各样不同客户的使用需求,这才是价值两个字的深层体现。本节没有诗情画意的知识描述,只为一下节的华丽登场做好铺垫:帅气的主角将不再孤单:怪物们都出来吧!敬请关注。

WPF/Silverlight
作者: 深蓝色右手
出处: http://alamiye010.cnblogs.com/
教程目录及源码下载: 点击进入( 欢迎加入WPF/Silverlight小组  WPF/Silverlight博客团队)
本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此段声明,且在文章页面显著位置给出原文连接,否则保留追究法律责任的权利。

推荐阅读
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • MongoDB用户验证auth的权限设置及角色说明
    本文介绍了MongoDB用户验证auth的权限设置,包括readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase、cluster相关的权限以及root权限等角色的说明和使用方法。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
author-avatar
yaoyinghua2012
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有