C#开发WPF/Silverlight动画及游戏系列教程(Game Course):(二十三)自适应性窗口化与全屏化(WPF Only)
上一节中曾有提到,检测系统架构是否合理的评判标准之一就是系统的拓展性。在.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来得干脆?这涉及到窗口自适应用户电脑分辨率的问题。如果您的电脑是4:3类型的分辨率,如800*600、1024*768、1280*960等这样的传统分辨率,你大可以直接设置WindowWidth=800、WindowHeight=600;但是用户的电脑如果是宽屏的(如16:9等),此时设置窗口模式尺寸为800*600将导致全屏化切换错误。一般网络游戏中会给予几个或多个可选分辨率让用户自行设置窗口化/全屏化切换,这些切换的实现基于对系统分辨率及刷新率进行更改的基础上;而WPF中实现起来简单多了,不需要再去调用WindowsAPI更改系统设置而是直接通过修改窗体自身属性WindowStyle与WindowState轻松实现,具体方法如下:
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)即可。通过此方法实现的窗口化与全屏化的效果图如下: