说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

创建一个Windows Phone 7推箱子益智游戏

HTML文档下载 WORD文档下载 PDF文档下载
现在我们用Windows Phone 7创造一个益智游戏,使用Silverlight和XNA框架音频API的功能。

 

作者:Daniel Vaughan

 

下载源代码

 

介绍

 现在我们用Windows Phone 7创造一个益智游戏,使用Silverlight和XNA框架音频API的功能。

 

入门

 

安装WP7的工具

安装vs 2010 

安装程序将自动下载并安装所需的组件。

如果你想使用的Expression Blend 4 WP7的拓展,下载并安装Expression Blend 。

一旦安装过程完成后,重新启动Visual Studio 2010中。

 

游戏界面

这是主要的用户界面 PhoneApplicationPage。当你创建一个新的 Windows Phone 应用程序这是默认的代码。

 

PageOrientation

Windows Phone应用程式中一个重要的问题是与之匹配的布局方向,特别是检测到方向变化时,如何使我们的UI与之匹配。 PhoneApplicationPage有一个可设置的属性命名SupportedOrientations。该枚举值可以是横排(PORTRAIT)或竖排(LANDSCAPE),或者是PortraitOrLandscape的。分配给它一个值,无论是在XAML或代码中,我们可以控制应用程序如何能变换。我们采用PortraitOrLandscape,因为我希望用户根据自己的意愿自由选择。

一个值得注意的是,从用户代码设置方向是不可能的,因为它被标记为SecurityCritical。

 

SecurityCritical是大多数Silverlight开发人员熟悉的属性。 

请注意,这是Silverlight的安全,并没有具体到 Windows Phone。 

 

从反射,我们可以观察到Page.Orientation不是一个依赖项属性,(也不会引发Page.Orientation PropertyChanged事件),绑定到PhoneApplicationPage属性不会带到其它地方。

 

方向转换

我们可以简单地在OrientationChanged事件中处理,但我没有简单地这样做,而是在MainPage里创建依赖属性,当OrientationChanged事件发生时被调用。我创建了一个IValueConverter,当Page.Orientation属性改变,改变TextBlock的Visibility。

 

 

<TextBlock Visibility="{Binding ElementName=Page, Path=PageOrientation,     Converter={StaticResource OrientationToVisibilityConverter}, 				ConverterParameter= Landscape}" .../>
以下代码从OrientationToVisibilityConverter中摘录,展示了转换器改变PageOrientation来改变Visibility的值。

 

 

public object Convert(object value, Type targetType, 		object parameter, CultureInfo culture){	var orientation = (PageOrientation)value;	string showWhenOrientation = parameter.ToString().ToLower();	bool show = false;	switch (orientation)	{		case PageOrientation.Portrait:		case PageOrientation.PortraitDown:		case PageOrientation.PortraitUp:			show = showWhenOrientation == "vertical";			break;		case PageOrientation.Landscape:		case PageOrientation.LandscapeLeft:		case PageOrientation.LandscapeRight:			show = showWhenOrientation == "landscape";			break;	}	return show ? Visibility.Visible : Visibility.Collapsed;}
使用XNA Framework的音频API
我惊喜的是我们可以容易的使用XNA框架来播放音效。需要即时播放。被警告,但它有挑剔的格式。我发现,只有PCM格式的WAV文件提供了支持。我用GoldWave保存所有到PCM格式的音频。对于较长的片段,如果用MP3,更有意义,但你需要使用MediaElement控件。
所有的声音效果在MainPage.xaml.cs中的代码定义处,以下是代码演示:
readonly SoundEffect footStepSoundEffect = 	SoundEffect.FromStream(TitleContainer.OpenStream("Audio/Footstep.wav"));
然后我们可以向这样播放声音效果:
footStepSoundEffect.Play();
MainPage实例化过程中,有一个Game实例作为其指定DataContext。
主要是控制其所有活动数据绑定和游戏属性的变化。 MainPage如下所示:
<phoneNavigation:PhoneApplicationPage     x:Class="DanielVaughan.Sokoban.UI.MainPage"    x:Name="Page"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;		assembly=Microsoft.Phone.Controls.Navigation"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     xmlns:controls="clr-namespace:DanielVaughan.Sokoban.UI"     mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"    SupportedOrientations="PortraitOrLandscape"    FontFamily="{StaticResource PhoneFontFamilyNormal}"    FontSize="{StaticResource PhoneFontSizeNormal}"    Foreground="{StaticResource PhoneForegroundBrush}" Orientation="Landscape">    <phoneNavigation:PhoneApplicationPage.Resources>        <controls:OrientationToVisibilityConverter 		x:Key="OrientationToVisibilityConverter" />        <Style x:Key="CenterLabels" TargetType="TextBlock">            <Setter Property="Foreground" Value="White"/>            <Setter Property="FontSize" Value="18"/>            <Setter Property="VerticalAlignment" Value="Center"/>        </Style>        <Style x:Key="ToolBarWebdings" TargetType="Button">            <Setter Property="Background">                <Setter.Value>                    <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">                        <GradientStop Color="#FF9AFF95" Offset="0.21"/>                        <GradientStop Color="#FF5DD757" Offset="0.589"/>                        <GradientStop Color="#FF99FF93" Offset="1"/>                    </LinearGradientBrush>                </Setter.Value>            </Setter>            <Setter Property="FontFamily" Value="Webdings"/>            <Setter Property="Foreground" Value="White"/>            <Setter Property="Padding" Value="5 "/>        </Style>        <Style x:Key="OrdinaryButton" TargetType="Button">            <Setter Property="Background">                <Setter.Value>                    <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">                        <GradientStop Color="#FF9AFF95" Offset="0.21"/>                        <GradientStop Color="#FF5DD757" Offset="0.589"/>                        <GradientStop Color="#FF99FF93" Offset="1"/>                    </LinearGradientBrush>                </Setter.Value>            </Setter>            <Setter Property="Foreground" Value="White"/>            <Setter Property="Padding" Value="5 "/>        </Style>    </phoneNavigation:PhoneApplicationPage.Resources>    <Grid x:Name="LayoutRoot" Background="White">                <Grid.RowDefinitions>            <RowDefinition Height="Auto"/>            <RowDefinition Height="*"/>        </Grid.RowDefinitions>                       <controls:BackgroundControl Opacity=".3" />        <Border VerticalAlignment="Top" Grid.Row="0" Height="60"                  BorderBrush="#FFFFE63E" CornerRadius="10,10,10,10" 		BorderThickness="2,2,2,2" Margin="0,0,0,0">            <Border.Background>                <LinearGradientBrush EndPoint="0.5,-1.389" 		StartPoint="0.5,2.389" SpreadMethod="Pad">                    <GradientStop Color="#FFFF9900" Offset="1"/>                    <GradientStop Color="#FFFF9900" Offset="0.58"/>                    <GradientStop Color="#FFFFFFFF" Offset="0"/>                </LinearGradientBrush>            </Border.Background>            <Grid>                               <Rectangle Stroke="{x:Null}" Margin="5,3,5,18"                            RadiusX="10" RadiusY="10" Opacity="0.41">                    <Rectangle.Fill>                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">                            <GradientStop Color="#FFECECEC" Offset="0"/>                            <GradientStop Color="#FFFFFFFF" Offset="1"/>                        </LinearGradientBrush>                    </Rectangle.Fill>                </Rectangle>                <StackPanel Height="50" x:Name="stackPanel1" Margin="15,0,5,0"                             VerticalAlignment="Center" HorizontalAlignment="Stretch"                             Width="Auto"  Orientation="Horizontal">                    <TextBlock VerticalAlignment="Center" 			Foreground="White" Text="Code:" TextWrapping="Wrap"/>                                        <TextBox Text="{Binding Path=LevelCode, Mode=OneWay}"                             x:Name="textBox_LevelCode" MaxLength="5"                             Opacity="0.4" Width="110" TextAlignment="Center"                             VerticalAlignment="Center"                              HorizontalContentAlignment="Center"                              GotFocus="TextBox_LevelCode_GotFocus"                              LostFocus="TextBox_LevelCode_LostFocus"                              KeyUp="TextBox_LevelCode_KeyUp"                             Background="White" />                    <Button Style="{StaticResource ToolBarWebdings}" 			Margin="0,-10,0,0" Height="10" Content=""                            Click="Button_Undo_Click"/>                    <Button Style="{StaticResource ToolBarWebdings}" 			Margin="0,-10,0,0" Height="10" Content=""                            Click="Button_Redo_Click"/>                    <TextBlock Visibility="{Binding ElementName=Page, 			Path=PageOrientation,                             Converter={StaticResource OrientationToVisibilityConverter}, 			ConverterParameter=Landscape}"                        VerticalAlignment="Center" HorizontalAlignment="Center"                                TextAlignment="Center" Foreground="White" 				Text="Alien Sokoban"                                FontFamily="Tahoma" FontSize="36" Margin="45,0,0,0"/>                </StackPanel>                <Grid HorizontalAlignment="Right">                    <StackPanel Orientation="Horizontal">                        <StackPanel VerticalAlignment="Center">                            <StackPanel Orientation="Horizontal">                                <TextBlock Style="{StaticResource CenterLabels}" 				Text="Level "/>                                <TextBlock x:Name="label_LevelNumber"                                            Style="{StaticResource CenterLabels}"                                            Text="{Binding Path=Level.LevelNumber}"/>                                <TextBlock Style=				"{StaticResource CenterLabels}" Text="/"/>                                <TextBlock Style="{StaticResource CenterLabels}" 				Text="{Binding Path=LevelCount}"/>                            </StackPanel>                            <StackPanel Orientation="Horizontal">                                <TextBlock Style="{StaticResource CenterLabels}" 				Text="Moves "/>                                <TextBlock x:Name="label_Moves" 				Style="{StaticResource CenterLabels}"                                            Text="{Binding Path=Level.Actor.MoveCount}"/>                            </StackPanel>                        </StackPanel>                        <Button Style="{StaticResource ToolBarWebdings}" 				Margin="0,-8,0,0"                                 Height="10" x:Name="button_RestartLevel" Width="80"                                 Click="Button_RestartLevel_Click"                                 IsTabStop="False"  Content=""                                HorizontalAlignment="Right" >                            <ToolTipService.ToolTip>                                <ToolTip Content="Restart"></ToolTip>                            </ToolTipService.ToolTip>                        </Button>                    </StackPanel>                </Grid>            </Grid>        </Border>        <!-- The Game grid. -->        <Border Grid.Row="1" Padding="5" BorderBrush="#919292" CornerRadius="12"                 BorderThickness="0" Background="Transparent">            <Grid x:Name="grid_Game" />        </Border>        <Grid x:Name="textBlock_PressAnyKey"               Background="#006DCAC1"              HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.RowSpan="2">            <StackPanel VerticalAlignment="Center" HorizontalAlignment="Stretch"                         Background="#556DCAC1">                <TextBlock x:Name="feedbackControl"                            VerticalAlignment="Center"                           HorizontalAlignment="Center" Text="TextBlock" FontSize="32"/>                <Button Style="{StaticResource OrdinaryButton}" Content="Continue"                         VerticalAlignment="Center" HorizontalAlignment="Center"                        Click="Button_Continue_Click"/>                 </StackPanel>        </Grid>    </Grid>    </phoneNavigation:PhoneApplicationPage>
在MainPage的InitializeLevel方法中,每个网格用CellControl填充:
void InitialiseLevel(){	cellControls.Clear();	commandManager.Clear();	grid_Game.Children.Clear();	grid_Game.RowDefinitions.Clear();	grid_Game.ColumnDefinitions.Clear();	for (int i = 0; i < Game.Level.RowCount; i++)	{		grid_Game.RowDefinitions.Add(new RowDefinition());	}	for (int i = 0; i < Game.Level.ColumnCount; i++)	{		grid_Game.ColumnDefinitions.Add(new ColumnDefinition());	}	var cellSize = CalculateCellSize();		for (int row = 0; row < Game.Level.RowCount; row++)	{		for (int column = 0; column < Game.Level.ColumnCount; column++)		{			Cell cell = Game.Level[row, column];			cell.PropertyChanged += cell_PropertyChanged;			CellControl cellControl = new CellControl(cell);			cellControl.MaxHeight = cellControl.MaxWidth = cellSize;			cellControl.Click += Cell_Click;			Grid.SetColumn(cellControl, column);			Grid.SetRow(cellControl, row);			grid_Game.Children.Add(cellControl);			cellControls.Add(cellControl);		}	}	/* Play the intro audio clip. */	PlayAudioClip(introSoundEffect);	/* Listen for actor property changes. */	//Game.Level.Actor.PropertyChanged += Actor_PropertyChanged;	RefreshGameGrid();}
通常,我不会建议把这样的UI逻辑代码放在代码的旁边,因为我更喜欢使用MVVM方法。 然而权宜之计,我就用这个方法。
该CellControl被分配给一个游戏网格,显示效果由单元格的状态而定。 如果它被认为是一堵墙,它显示一个灰色正方形等。
Phone屏幕键盘
Windows Phone 7允许开发者在用户打开屏幕键盘时指定数据类型。这也是上下文敏感的,TextBox获得焦点时,TextBox将被放大。使用InputScope使键盘更适合于正在输入的数据。
例如,要指定一个默认的屏幕键盘,需应用InputScope到该TextBox 。
<TextBox>   <TextBox.InputScope>     <InputScope>       <InputScope.Names>         <InputScopeName NameValue="EmailNameOrAddress"/>       </InputScope.Names>     </InputScope>   </TextBox.InputScope> </TextBox>
通过使用EmailNameOrAddress NameValue,键盘包含了.com 和 @等字符。
以下是一些有效取值:
SIP 布局XAML 或枚举值SIP 描述
DefaultDefault, and other standard input scope values标准 QWERTY 键盘
TextText带特性的text,如自动更正和单词建议。
WebUrl URL
E-mail addressEmailSmtpAddress e-mail 地址
E-mail name or addressEmailNameOrAddress 电子邮件名称或地址
MapsMaps搜索在地图上的位置
Phone numberTelephoneNumber电话号码
SearchSearch搜索查询
SMS contactNameOrPhoneNumber短信
ChatChat文字输入,使用智能功能,如缩写

 

 

结论

 

在这篇文章中,我们已经看到了如何使用Silverlight 3创建一个Windows Phone益智游戏。 我们看到了PageOrientation和如何将其应用于控制布局。 我们根据上下文可以选择不同的键盘,我们还简要接触了XNA Framework的音频API,它可以用来播放声音效果。

 

这个平台的未来,我很兴奋。 花费了一个短暂的时间后,我已经有宾至如归的感觉。 我希望这个项目对你非常有用。 如果是的话,那么我会很感激,如果你能反馈一下,这会帮助我,使我的下一篇文章更好。

 

 

IntentService实现原理及内部代码 AsyncTask实现原理和内部代码 Neither user nor current process错误 ListView的右边滚动滑块启用方法 Live Wallpaper动态壁纸开发 控制软键盘显示和隐藏 设置Activity大小不再全屏原理 Android面试题,看看你基础如何? Android Canvas绘图抗锯齿解决方法 Android xliff和字符串资源 android.hardware.USB类介绍 Android开发经验谈之应用间数据共享 android_asset这个URL详细使用方法 Android 2.3系统自带高清UI图标下载 设置ScrollView滚动条的颜色 WakeLock使用方法示例代码 Concurrent并发库常见问题总结 Android数据库SQLite性能优化技巧 Android开发之Java设计模式基础篇 Android开发之Java设计模式入门篇 Android开发之Java设计模式 Android开发之Java并发包集合类性能分析 Android开发之Java集合类性能分析 Android开发之Java虚拟机原理和内存分配 Android开发之Java基础系列教程目录 Android Theme主题样式开发注意点 Android 3.0开发用的平板推荐 android.resource://这个Uri你知道吗 ADT插件的10.0.1必须要Eclipse 3.5才能升级 Android线程优先级设置方法 Android Zip文件解压缩代码 怎么把表中的列约束为唯一的? 一个编程论坛 从没见过的问题!!!晕了!! 安装问题,请指教! C++的应用是什么意思呢? 得到上传文件大小的问题,解决高分相送!! R6中的问题!高手请进!高分求救! 一个电子书籍下载和编程论坛 请问怎么在vb中调用纯c接口的api并实现多线程 如何在一个很大的文件中删除一段数据?不用拷贝的方法 the C++ programing language里的两个小问题!!! 找在没行带checkbutton的listbox控件类 我可怜的QQ被盗了~~有什么密码破译软件取回QQ的密码吗 VARIANT结构中,如何通过pvarVal指针来获得串口传来的二进制流?? 天啊,这就是《程序员》? 编译java程序需要哪些工具,菜鸟提问. how to use *.pak?? ★在数据窗口中如何同时实现多行操作,如update或delete多行。 请问oracle8i的下载问题! 请问MSDN.net 中文版光盘出了吗??????????????????????? 关于STRING的问题 在IE中程序运行有错误?请指点! JB8做个BMP,奇怪问题 有谁知道*.dns用什么软件打开吗,急!!! 大家给我推荐一个delphi源码网站 Oracle8.17的安装问题,请大家帮忙,急呀!谢谢! csv文件存储求助 问个关于checkboxlist控件的用法! 客户端通过Session Bean 调用 Local EntityBean的问题. 启动j2ee的问题--j2ee -verbose 那里能够下载破解的install shield 5.0 or 5.5 or 6.0? 我想搞网络游戏开发,请教各位的意见 如何在接受表单的ASP文件中,去知晓是这个表单中的哪个'确认按钮'被按下了?? 我的数据库打不开了!!! 连接MySQL数据库服务器? 有谁可以推荐几个国外的比较热的asp论坛,多谢! 我是一个菜鸟,想学asp,希望前辈给指条路 有人知道工程硕士是怎么回事吗?和普通的有什么不同啊,可以考普通的博士吗?谢谢阿 access数据库为何备份出错? 有了主键,还需要建立索引吗?解决送分。 在Oracle的逻辑数据库结构中有个概念叫"范围"的是什么意思呀? 能将javascript改写成其它语言吗? 为什么动态创建的控件不能保存? HelpProvider控件的问题 如何把几个dbf表中的数据导到一个表中? 软件汉化有几种方法呢? 各位大虾,求助,在线急等! 看看我能放多少分.... 急啊,我刚买的电脑就出问题了~~~~ 大虾有没有《人月神话》的电子版啊? 天那,资源泄漏 穆尔西受审质疑审判合法性 埃及民众意发改委:雾霾天气几乎常态化 通过5-雾霾影响生殖能力,不能当成“雷语”加拿大一名刑满性犯罪者潜逃至美国又面日本一企业官员疑挪用24亿日元 被同消息称利比亚首都发生激烈交火 枪声持新加坡拟开发路边停车电子收费新系统孙杨可自选拘留时间 新女友浮出水面亦日本一企业官员疑挪用24亿日元 被同加拿大一名刑满性犯罪者潜逃至美国又面麻生积极扩大外国游客免税品范围 以吸塑料袋威胁欧洲环境 欧盟计划对其征收盘点孙杨这些年惹的事 无证驾驶 耍大叙反对派内讧致战场节节败退 全国联盟胜选五周年,奥巴马光环黯淡法媒曝萨科齐下台后电子档案遭非法侦察巴塔发誓要为马哈苏德报仇 卡尔扎伊批世界十大主权基金美媒:中国不买美债 美经济会怎样中国人美国买房热中的冷思考北极航道将成“新马六甲海峡”———专省纪委通报9起因履行管党治党责任不力李迅雷:不来一场次贷危机那样的挤泡沫农家院坝上党课台股19日开盘跌10点 为9316点台铁手扶梯高峰时段因负载过重故障伤人民生实事民情实录 | 是绿道 也是家象妈妈:小孩子,不要玩水,去,一边呆《中庸》为何成为儒释道三教合流的中心大校:中国军机频出动 日机伴飞将耗光两岸青年共说中华文化传承:向下“扎根张召忠称歼-31可上航母 遭另一位专民调:过半美国人不相信网络攻击帮助特三大股指小幅低开 沪指跌0.07%权许小年:经济建设绝不能搞群众运动,警四川现先秦聚落遗址 全国罕见美跨性别9岁童登《国家地理杂志》探讨统计局:11月下半月70城中11城房来疯直播总裁张宏涛:从玩的角度做颠覆经济蓝皮书呼吁推进个税改革 尽快实施谷歌的新野心意欲解决人类死亡问题,1这位中国富豪说“我比较了国际上,税收
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘