`
tansitongba
  • 浏览: 503812 次
文章分类
社区版块
存档分类
最新评论

Silverlight.XNA(C#)跨平台3D游戏研发手记:(六)向Windows Phone移植之框架构建

 
阅读更多

海量的美术、庞大而繁杂的人员与资源配备使得网游和端游开发难度系数高居不下;移动开发时代的来临为游戏设计师们提供了第三条绿色通道,这是一次愈加趋近梦想的迅捷契机。

作为一个专情的人,深爱着C#,毋庸置疑的原因;于是,我也爱上了Windows Phone,爱上了C#在Silverlight.XNA中放荡的游走;因为它的存,使得代码移植在页游、端游与手游之间显得格外畅快淋漓。

今天,打开的不仅是一扇门,更是通往美丽新世界的崭新道路;握紧了,战士,你手中那无比锋利的C#,鞭笞吧!XAML,神秘的游戏世界正等待您来探索。

轻轻的,我步入了这个陌生而又激动的新圣域,困惑悄然而生:该如何开启Windows Phone游戏开发这个潘多拉之盒?

Sprite,精灵,永恒不变的游戏灵魂铸就者,生命万象之密匙;从精灵的起源去探究创世之初尤能缅怀我的虔诚。

翻开上帝之书MSDN,古老的文字向人类印示着Windows Phone游戏精灵的两种主要创生方式:Silverlight的UElement和XNA中的Texture2D。性能方面,后者绝对专业;不过相对于效率而言,前者则更为出色。彷徨中的我恍然大悟,其实一切真想早已被远古神器Visual Studio 2010暴露得一览无余,抹去岁月的尘土,赫然印着:基于Silverlight与XNA的无缝集成打造最完美之解决方案:

通过Silverlight(Blend)制作游戏界面,XNA实现游戏对象的绘制,双管齐下。开发者不仅能够延续传统.NET基于事件驱动的低耦合编程模式,同时也能享受到XNA高性能的图形绘制与渲染;正如MSDN所述,Silverlight与XNA的完美结合带来的是开发“效率”与“性能”质的飞跃

由此我们也不难看出,目前的Silverlight不论是作为浏览器插件,还是Windows Phone的主要开发工具,其与XNA融合构建.NET开发者最熟悉的事件驱动架构已成为主流趋势;本节作为系列Demo向Windows Phone平台移植的第一步,我将向大家详细讲解如何搭建游戏的主体框架。

一)配置开发环境

安装Windows Phone SDK 7.1

二)新建游戏项目

打开Visual Studio,点击文件->新建->项目->选择模板 Silverlight for Windows Phone中的“Windows Phone Silverlight和XNA应用程序”,这里我取名叫SLXnaGame:

三)分析解决方案

在解决方案管理器SLXnaGame项目中第一眼看到.xaml顿时泪流满面,无比熟悉的App.xaml以及主页面MainPage.xaml和游戏场景页面GamePage.xaml让所有Silverlight游戏开发者倍感亲切:

四)核心框架搭建

新项目默认为我们打开了MainPage.xaml的前端部分,除了左边垂直摆放着一个偌大的Windows Phone模型外,右边那一长串的xaml再熟悉不过了。由于SLG游戏以水平方向呈现效果更好,因此我们不妨对这个所见即所得的展示窗口进行一些调整,并以一张很炫的图片作为游戏的封面:

如上图,xaml代码中我们可以通过SupportedOrientations="Landscape" Orientation="LandscapeLeft" 设置Windows Phone模拟器横向显示;当然,如果不需要观看预览(比如后面讲到的GamePage),我们也可以在后台cs文件中编写this.SupportedOrientations = SupportedPageOrientation.Landscape; 实现同样的效果。另外,游戏中所有Silverlight控件所用到的图片资源均统一存放在SLXnaGame项目的(新建)Resource文件夹中,这样我们便可通过如下xaml代码实现图片装载:Source="/SLXnaGame;component/Resource/UI/FrontPage.jpg" 除此之外,为了构建更为灵活的游戏框架,同样可以仿造之前Silverlight游戏教程的做法,编写一个名为Global.cs的全局辅助类存放于SLXnaGameLib(控件类库)项目中:

Global
namespaceSlXnaDemoLib{

///<summary>
///全局(数据和方法)
///</summary>
publicstaticclassGlobal{

///<summary>
///主项目名
///</summary>
staticstringProjectName=Application.Current.GetType().Assembly.FullName.Split(',')[0];

///<summary>
///项目Resource资源路径
///</summary>
publicstaticstringProjectPath(stringuri){
returnstring.Format("/{0};component/Resource/{1}",ProjectName,uri);
}

///<summary>
///获取项目Resource中的位图
///</summary>
///<paramname="uri">路径</param>
///<returns></returns>
publicstaticBitmapImageGetImage(stringuri){
returnnewBitmapImage(newUri(ProjectPath(uri),UriKind.Relative));
}
}
}

注意,这里需要添加对System.Windows.dll动态链接库的引用:右键点击SLXnaGameLib项目中的引用->添加引用->选择System.Windows

到此为止,游戏初始界面制作完毕,按F5调试运行;正常情况下我们将看到前面精心设计好的游戏初始画面,此时细心的朋友肯定会注意到一个特殊的警告提示:

由于Silverlight与XNA的兼容模式是从7.1开始才有的新模板,其本质由7.0衍生而来。编译后会发现警告提示“无法引用项目‘SLXnaGameLib’”,但实际上SLXnaGame项目还是能够使用的,如果出现由于兼容问题导致可能出现的无法找到命名空间或类名,可删除对这个SLXnaGameLib的引用后重新再引用一次即可永久解决问题。此处稍作说明提醒大家无需紧张,框架之间的协调问题在后续版本中将进一步完善。

回到正题,接下来我们点击“点击开始”这个闪烁的按钮便会跳转到项目默认自带的第二个页面:GamePage.xaml。对于新手来说,MainPage.xaml是如何通过点击Button实现跳转的呢?机关就在MainPage.xaml左边的小箭头上:

熟悉Silverlight的朋友都清楚,Silverlight中的用户控件(页面)都是以两个文件partial的形式存在:前台(.xaml)和后台(.cs)。常规的做法是通过在前台注册Button的Click="Button_Click"事件,并于后台编写相应代码实现页面之间的点击跳转功能。

//简单的按钮单击事件处理程序可使我们转至第二页
privatevoidButton_Click(objectsender,RoutedEventArgse){
NavigationService.Navigate(newUri("/GamePage.xaml",UriKind.Relative));
}

接下来我们将目标转向第二个页面,首先打开GamePage.xaml,赫然写着“不需要XAML内容……”,其实我想说:…哥还是留个Canvas吧,哈哈。

继续打开GamePage.cs,终于来到了我们游戏框架的核心部分。默认的代码有些凌乱,稍做调整后我们不妨先对比一下它与标准的XNA游戏中的Game1.cs有什么区别:

做过XNA开发的朋友是否有种豁然开朗的感觉 (新手朋友们可以参考一下XNA的游戏开发机制)。把Silverlight.XNA(以下简称SL.XNA)中的OnNavigatedTo()和OnNavigatedFrom()分别看做是纯XNA中的LoadContent()和UnloadContent(),两者相似度几乎一模一样,只是SL.XNA模式通过一个timer实现了游戏的主循环;注意了,这个timer可是XNA线程框架中的GameTimer,因此我们无需担忧其性能方面的问题:

至于绘图方面,SL.XNA和纯XNA在代码方面几乎是无缝移植。比如我们希望绘制字体,完全可以一字不差的照搬现有的XNA教程中的字体示例;而音乐和音效的播放则同样,将mp3或wav等音频资源加入到SLXnaGameLibContent资源项目中,然后编写一样的代码实现一模一样的功能(注意,mp3和wav的资源存放形式不同,播放方式亦不同):

音乐播放
SoundEffectsound;
Songsong;

//构造函数
publicMainPage(){
InitializeComponent();
this.Loaded+=newRoutedEventHandler(MainPage_Loaded);
}

voidMainPage_Loaded(objectsender,EventArgse){
content=(Application.CurrentasApp).Content;
song=content.Load<Song>("Media/MySong");
MediaPlayer.Play(song);
}

//简单的按钮单击事件处理程序可使我们转至第二页
privatevoidButton_Click(objectsender,RoutedEventArgse){
sound=content.Load<SoundEffect>("Audio/MyAudio");
sound.Play();
NavigationService.Navigate(newUri("/GamePage.xaml",UriKind.Relative));
}

到此有朋友要问了:仅仅是调用了XNA中的字体和音乐,与纯XNA又有何区别?Silverlight控件呈现问题甚至还不需要字体呢,干嘛非得多次一举给XNA加个Silverlight壳?

别急,接下来便是Silverlight与XNA交互实现的关键:UIElementRenderer

就像本文开头所述那样,完美的交互必须是Silverlight的UElement和XNA的Texture2D之间的非跨线程交互操作,大家不妨先看看最终的实现代码:

UIElementRendererelementRenderer;
publicGamePage(){
InitializeComponent();
this.SupportedOrientations=SupportedPageOrientation.Landscape;
this.LayoutUpdated+=GamePage_LayoutUpdated;
....
}

///<summary>
///允许页面绘制自身。
///</summary>
privatevoidDraw(objectsender,GameTimerEventArgse){
graphicsDevice.Clear(Color.CornflowerBlue);
elementRenderer.Render();//通过elementRenderer呈现Silverlight中的UElement
spriteBatch.Begin();
spriteBatch.Draw(elementRenderer.Texture,Vector2.Zero,Color.White);//通过XNA的形式将elementRenderer整体绘制出来
spriteBatch.End();
}

///<summary>
///创建一个可以被XNA绘制的Silverlight-UI展示器UIElementRenderer
///</summary>
voidGamePage_LayoutUpdated(objectsender,EventArgse){
if(ActualWidth>0&&ActualHeight>0&&elementRenderer==null){
elementRenderer=newUIElementRenderer(this,(int)ActualWidth,(int)ActualHeight);
}
}

其实,UIElementRenderer的原理便是将Silverlight中的UElement对象以XNA的绘制形式在Draw()方法中画出来,真想大白:不论是Silverlight的东西还是XNA的东西,所有能看得到的对象最终都将以XNA的形式绘制出来,这也是成就SL.XNA模式得以完美兼具“效率”与“性能”的根本原因。

接下来我们也来俗一把,分别用Silverlight的TextBlock和XNA的Font编写Hello Game:

protectedoverridevoidOnNavigatedTo(NavigationEventArgse){
//设置图形设备的共享模式以启用XNA呈现
graphicsDevice.SetSharingMode(true);
//创建可以用来绘制纹理的新SpriteBatch。
spriteBatch=newSpriteBatch(graphicsDevice);
//TODO:使用this.content在此处加载游戏内容
textBlock=newTextBlock(){Text="HelloGame,I,mSilverlightTextBlock"};
LayoutRoot.Children.Add(textBlock);//将textBlock添加进Canvas画布中
Canvas.SetLeft(textBlock,10);Canvas.SetTop(textBlock,20);//设置textBlock在画布中的绝对位置
font=content.Load<SpriteFont>("Font/MyFont");

timer.Start();
base.OnNavigatedTo(e);
}

///<summary>
///允许页面绘制自身。
///</summary>
privatevoidDraw(objectsender,GameTimerEventArgse){
graphicsDevice.Clear(Color.CornflowerBlue);
elementRenderer.Render();//通过elementRenderer呈现Silverlight中的UElement
spriteBatch.Begin();
spriteBatch.Draw(elementRenderer.Texture,Vector2.Zero,Color.White);//通过XNA的形式将elementRenderer整体绘制出来
spriteBatch.DrawString(font,"HelloGame,I,mXNAFont",newVector2(20,55),Color.Yellow);//第三个参数代表绘制的绝对位置
spriteBatch.End();
}

默认情况下,后Draw的对象显示在最顶层;当然,如果你想动态更改他们之间的层级深度关系,可以使用Draw方法的其他形态,比如:

值得一提的是,如上面代码所示UIElementRenderer对象创建于GamePage_LayoutUpdated事件中,它的第一个UIElement类型参数为this,即指整个GamePage页面(UserControl):

试想一下,如果换成是一个Image或者ListBox等控件呢?高度自由的UIElementRenderer给了我们SL.XNA游戏开发无限遐想空间,不是吗?

至此,资源布局及代码结构这些毛坯级也是最核心的框架构建完毕,无论您是单纯的Silverlight开发者,或者XNA游戏开发者,亦或者两者通杀型,这个框架都能为你提供可无限拓展的高性能空间。下一节,我将继续为大家深入讲解SL.XNA中的控件交互,关注哦,^ ^。

本节源码下载地址:SLXnaGame1.zip

手记小结:本节非常详细的为大家讲解了如何从0开始一步步搭建基于Silverlight.XNA游戏框架;新手、老手,又或者你擅长的是Silverlight、WPF或XNA;对于初出茅庐的Windows Phone开发者来说这都是一篇开卷有益的启蒙之章,包括后续的更多章节,旨在通过自身的开发经历让朋友们高效率的掌握Windows Phone开发中关于C#、xaml、Silverlight、XNA等多方面知识。毕竟,一个人的能力与时间极其有限,卓越而经典的游戏需要更多的开发者参与进来,相信我们的共同努力可以铸成属于中国人辉煌的游戏江山!

推荐参考:NowpaperWilliams关于Windows Phone的游戏开发博客。

分享到:
评论

相关推荐

    Windows Phone 10. XNA 3D 模型浏览器

    Windows Phone提供了两种不同的用户界面编程模型:Silverlight 和 XNA。Silverlight是最常用的应用程序开发方式,应用程序可以使用控件、显示很多数据。XNA是2D和3D游戏开发方式。当年您也可以使用Silverlight来写...

    Microsoft Silverlight Edition: Programming Windows Phone 7

    作者 Charles Petzold 通过这本书向读者介绍了如何使用 C# 编程语言结合 Silverlight 和 XNA 2D 框架来开发 Windows Phone 7 应用程序的基础知识。 #### 书籍内容概览 本书由微软出版社出版,并得到了微软公司的...

    Microsoft.Xna.GameStudio.dll

    如果新建Windows Phone Game项目报错: vstemplate文件引用的向导类"Microsoft.Xna.GameStudio.Wizards.MultiProjectWizard"在程序集"Microsoft.Xna.GameStudio,Version=4.0.0.0,Culture=naeutral,PublicKeyToken=6d...

    Packt.Windows.Phone.7.XNA.Cookbook.2012

    《Packt.Windows.Phone.7.XNA.Cookbook.2012》这本书是针对Windows Phone 7平台,利用XNA框架进行游戏和图形应用开发的一本实战指南。它旨在帮助开发者掌握XNA在Windows Phone 7上的应用技巧,提供了一系列实用的...

    Packtpub.Windows.Phone.7.Silverlight.Cookbook.Aug.2011.rar

    Windows Phone 7是微软在2010年推出的一款智能手机操作系统,它为开发者提供了丰富的开发平台,包括Silverlight和XNA两种主要的开发框架。Silverlight是.NET Framework的一个轻量级版本,用于创建富媒体和交互式用户...

    Packt.Building.your.First.Mobile.Game.using.XNA4.2013

    本书《Packt.Building.your.First.Mobile.Game.using.XNA4.2013》是一本关于如何使用XNA 4.0开发工具为Windows Phone 7平台构建你的第一个3D手机游戏的快速、实践指南。书中详细介绍了Windows Phone 7平台下3D游戏...

    Windows_Phone_7入门经典-使用Silverlight和XNA开发Windows_Phone应用

    ### Windows Phone 7入门经典-使用Silverlight和XNA开发Windows Phone应用 #### 知识点一:Windows Phone 7操作系统及其特点 - **历史背景**:随着iPhone和Android的出现,微软意识到需要一个全新的手机操作系统来...

    Windows Phone开发-XNA基础

    2. **跨平台性**:XNA具有良好的跨平台支持能力,开发者可以在不同平台上轻松移植游戏,无需大量修改代码。 3. **高效的开发与执行效率**:XNA通过提供简洁的API和工具集,极大地提高了开发效率。同时,它的优化设计...

    C#,XNA框架开发的小游戏

    在IT领域,游戏开发是一项充满创意和技术挑战的任务,而C#和XNA框架的结合为小型游戏的开发提供了一个高效且易上手的平台。本文将深入探讨如何使用Visual Studio 2008、C#语言以及XNA框架来开发小游戏。 首先,C#是...

    Wrox.Professional.Windows.Phone.7.Game.Development.Creating.Games.using.XNA.Game.Studio.4.2011

    通过阅读本书,读者不仅可以学到如何使用XNA Game Studio 4构建游戏,还能深入了解Windows Phone 7平台的特性和优势。无论是初学者还是经验丰富的开发者,都能从这本书中获得宝贵的启示和灵感。

    Sams.Microsoft.XNA.Game.Studio.3.0.Unleashed.Feb.2009.rar

    《Sams.Microsoft.XNA.Game.Studio.3.0.Unleashed.Feb.2009》这本书主要聚焦于微软的XNA Game Studio 3.0,这是一个为游戏开发者提供的强大工具集,允许开发者使用C#编程语言创建跨平台的游戏,包括Windows桌面、...

    Building.XNA.2.0.Games.A.Practical.for.Independent.Game.Development

    XNA框架是微软为简化游戏开发而推出的一套工具集和技术平台,它支持多种编程语言如C#,并且兼容Windows、Xbox 360等多个平台。本书《Building XNA 2.0 Games: A Practical Guide for Independent Game Development》...

    Wiley.XNA.3D.Primer(含源码)

    《Wiley.XNA.3D.Primer》是一本专注于XNA框架3D编程的书籍,包含源码资源,为读者提供了深入学习3D游戏开发的机会。XNA是微软推出的一个开发平台,主要用于创建Windows和Xbox 360的游戏,特别适合初学者和业余开发者...

    XNA 3D 小游戏

    在IT领域,XNA是一个微软推出的开发框架,主要用于创建跨平台的游戏,特别是在Windows、Xbox 360和Zune设备上。XNA利用.NET Framework的C#编程语言,为开发者提供了一套全面的工具集,使游戏开发变得更加便捷。这款...

    Microsoft XNA 4.x Framework的开源跨平台 MonoGame.zip

    该框架的目标是使XNA可以更容易地开发跨平台游戏,并且可以进行代码的高效复用。一次编写,随处运行 MonoGame目前支持iOS,Android,Windows(包括OpenGL和DirectX),Mac OS X,Linux,Windows 8 Store,Windows ...

Global site tag (gtag.js) - Google Analytics