热门标签 | 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博客团队)
本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此段声明,且在文章页面显著位置给出原文连接,否则保留追究法律责任的权利。

推荐阅读
  • 基于iSCSI的SQL Server 2012群集测试(一)SQL群集安装
    一、测试需求介绍与准备公司计划服务器迁移过程计划同时上线SQLServer2012,引入SQLServer2012群集提高高可用性,需要对SQLServ ... [详细]
  • 本文通过基准测试(Benchmark)对.NET Core环境下Thrift和HTTP客户端的微服务通信性能进行对比分析。基准测试是一种评估系统或组件性能的方法,通过运行一系列标准化的测试来衡量其表现。 ... [详细]
  • VB.net 进程通信中FindWindow、FindWindowEX、SendMessage函数的理解
    目录一、代码背景二、主要工具三、函数解析1、FindWindow:2、FindWindowEx:3、SendMessage: ... [详细]
  • 本文介绍了 Android 开发中常用的滚动视图组件 ScrollView 和 HorizontalScrollView 的基本用法和注意事项,帮助开发者更好地处理屏幕内容超出显示范围的情况。 ... [详细]
  • WPF项目学习.一
    WPF项目搭建版权声明:本文为博主初学经验,未经博主允许不得转载。一、前言记录在学习与制作WPF过程中遇到的解决方案。使用MVVM的优点是数据和视图分离,双向绑定,低耦合,可重用行 ... [详细]
  • 本文介绍了如何查看PHP网站及其源码的方法,包括环境搭建、本地测试、源码查看和在线查找等步骤。 ... [详细]
  • PHP 5.5.31 和 PHP 5.6.17 安全更新发布
    PHP 5.5.31 和 PHP 5.6.17 已正式发布,主要包含多个安全修复。强烈建议所有用户尽快升级至最新版本以确保系统安全。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 高端存储技术演进与趋势
    本文探讨了高端存储技术的发展趋势,包括松耦合架构、虚拟化、高性能、高安全性和智能化等方面。同时,分析了全闪存阵列和中端存储集群对高端存储市场的冲击,以及高端存储在不同应用场景中的发展趋势。 ... [详细]
  • 一个建表一个执行crud操作建表代码importandroid.content.Context;importandroid.database.sqlite.SQLiteDat ... [详细]
  • 为什么多数程序员难以成为架构师?
    探讨80%的程序员为何难以晋升为架构师,涉及技术深度、经验积累和综合能力等方面。本文将详细解析Tomcat的配置和服务组件,帮助读者理解其内部机制。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • 本文将带你快速了解 SpringMVC 框架的基本使用方法,通过实现一个简单的 Controller 并在浏览器中访问,展示 SpringMVC 的强大与简便。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
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社区 版权所有