65.9K
CodeProject 正在变化。 阅读更多。
Home

Meteor Madness

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2012年10月22日

CPOL

8分钟阅读

viewsIcon

18111

Meteor Madness 提交给应用创新大赛。

引言

Meteor Madness 是一款 Windows 8 风格的游戏,专为第三代超极本独特的跨界特性而设计。它具有双模式输入,允许玩家直接通过触摸屏或使用更传统的键盘方式进行游戏。该游戏积极鼓励玩家同时使用这两种输入机制,并对每种类型的输入进行奖励。这种方法使程序可以在平板电脑和台式机上使用,但在触摸屏超极本上,它提供了一种体验,可以温和地引导用户从键盘转向触摸屏。一段展示基本游戏玩法的三分钟视频可在 YouTube 上的 Meteor Madness Gameplay 找到。

Sample Image - maximum width is 600 pixels

背景

Meteor Madness 是一款《Asteroids》致敬游戏,我最初在 12 年前使用 Visual Basic 编写。它源于一个关于 Visual Basic 能否用于制作 30 fps 街机风格游戏的赌约。我算是赢了那个赌约,但不得不直接调用一些 Win32 API 和 DirectX 来实现。此后,我将 Meteor Madness 移植到了半打个平台,作为学习每个平台的工具。它经历了移植到 .NET,然后 Silverlight,然后 Windows Phone 7,最终到 Windows 8 的过程。然而,它从未发布过。

Meteor Madness 的这一迭代是对早期版本的重大重写。它深受 Windows 8 平台的影响,这是我通过 Charles Petzold 的书《Programming Windows 6th Edition》学习到的。此外,将 Meteor Madness 扩展为一个带有可解锁内容和各种道具的现代街机射击游戏,其灵感来自于 Jesse Schell 的精彩游戏编程书籍《The Art of Game Design: A book of lenses》。

游戏机制

游戏分为两种不同的玩法:经典模式和街机模式。

Sample Image - maximum width is 600 pixels

经典模式相当接近《Asteroids》的原始玩法。飞船一次只能发射一发子弹,唯一的道具是超空间。但与原版不同的是,飞船可以像玩家点击或敲击一样快速发射,并且超空间机制确保玩家返回一个没有小行星的空间区域(至少一两秒钟……)。此外,出现的敌人只有一种类型,得分也只有 250 分,以防止在原版中常用的“狩猎”策略。

Sample Image - maximum width is 600 pixels

街机模式在此基础上进行了扩展,增加了一系列道具,使游戏速度更快、得分更高、弹药更足。目前有超空间、下一关、导弹和三连射等道具,还有八个道具正在开发中。这些道具在游戏中的不同事件中解锁。例如,当玩家累计得分达到 50,000 分时,三连射道具就会解锁。这是玩家最有可能遇到的第一个道具。

超空间

在开发过程中,最酷的功能是超空间机制。回想起小时候玩《Asteroids》时的沮丧,我希望向玩家展示飞船从超空间出来的位置。没有什么比因为没看到飞船在哪里出来就被小行星撞毁而损失一个四分之一美元更糟糕的了。

期望的效果是让飞船周围的空间随着飞船一起扭曲。这需要两个单独的动画,无法使用 XAML 中的故事板进行脚本编写。要显示飞船从超空间返回,飞船周围的星星应该缓慢地动画式地朝向事件视界移动,然后快速地“弹出”,带有一点点弹性过载。飞船在动画进行到 0.85 秒时出现,此时星星已恢复到原始位置,并且在弹性效果之前。下左图显示了每颗星星朝向事件视界的畸变函数。距离远的星星畸变小于距离近的星星,以完成效果。这类似于《黑客帝国》结尾时,尼奥展现其矩阵肌肉的效果。

Sample Image - maximum width is 600 pixels

进入超空间时的动画是一个锦上添花的功能,对游戏玩法并非必需。然而,我不能没有另一个。对于这个效果,使用了第二个图作为位移函数,飞船几乎立即消失,然后空间以较长的周期弹性回弹。

一段超空间动画的片段可在 YouTube 上的 Meteor Madness Hyperspace 找到。

双输入游戏玩法

游戏有两种主要的玩法模式:舵手模式和舰长模式。玩家无需选择这些模式,游戏在进行过程中动态决定。每种模式都有其相对的优势,并且预计拥有相应硬件的玩家会同时使用这两种模式。随着玩家在游戏中的进步,当游戏认为有用时会显示额外的提示。这些提示与他们作为舵手和舰长的进展相对应。

在舵手模式下,玩家通过直接输入方式与屏幕上的飞船互动,通过键盘控制飞船的旋转、推进和射击。这与 1980 年代街机中存在的原始游戏机制一致。它反馈及时且直接,并提供卓越的飞行体验。然而,飞船瞄准的准确性会受到影响,因为对特定角度的瞄准需要瞬时的精确控制。

Sample Image - maximum width is 600 pixels

另一方面,舰长模式使用触摸屏进行输入。通过点击屏幕,玩家扮演舰长,飞船会转向请求的方向并射击。多次点击会排队一系列命令,飞船将遵从这些命令。这不需要玩家点击目标,事实上,精确地提前瞄准目标是必要的。然而,此模式的精确度远高于键盘控制。飞行是通过拖动飞船到新位置来实现的,新位置由一个瞄准标记指示。除非被另一个命令打断,否则飞船将自动飞到该位置。

Sample Image - maximum width is 600 pixels

最后,玩家可能在单次游戏中同时使用这两种形式的输入。当这种情况发生时,玩家被认为是在“掌舵的舰长”。

如果玩家在一个模式下进行了大量游戏,游戏将继续提醒他们另一个游戏模式是可用的。

上述每种模式都有与其分离的高分系统。这是为了鼓励玩家尝试每种游戏风格,而不是只玩他们目前最擅长的模式。

关于代码

整个项目均使用 C# 和 Visual Studio 及 Expression Blend 编写。

Expression Blend 使添加菜单的动画序列变得极其简单。我最近在工作时接触了 Android、iOS 和 Windows Phone 7,使用 Blend 进行动画处理的差异很难低估。它在所有方面都非常出色。例如,在选择“新游戏”菜单时,小行星会分解成经典模式和街机模式两个子菜单。整个动画仅用六行 XAML 声明为一个视觉状态(当然,Blend 完成了繁重的工作)。

<VisualState x:Name="NewGameExpanded">
  <Storyboard>
    <DoubleAnimation Duration="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="NewGameClassicMenu" d:IsOptimized="True" To="0"/>
    <DoubleAnimation Duration="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="NewGameClassicMenu" d:IsOptimized="True" To="0"/>
    <DoubleAnimation Duration="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="NewGameClassicMenu" d:IsOptimized="True" To="1"/>
    <DoubleAnimation Duration="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="NewGameArcadeMenu" d:IsOptimized="True" To="1"/>
    <DoubleAnimation Duration="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="NewGameArcadeMenu" d:IsOptimized="True" To="0"/>
    <DoubleAnimation Duration="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="NewGameArcadeMenu" d:IsOptimized="True" To="0"/>
  </Storyboard>
</VisualState>

总共有 364 个双重动画!想象一下,如果没有 Blend 的支持,要实现这一切该有多难。

代码的另一个有趣方面是 Windows 8 风格应用程序中处理存储系统的新机制。此模型中的应用程序运行的信任级别比传统桌面低得多。最值得注意的是缺乏对文件系统的访问。然而,新模型使得使用 ApplicationData.Current.RoamingSettings 功能保存和加载设置变得异常简单。

例如,游戏有一组功能,这些功能会根据游戏过程中发生的各种事件而被锁定或解锁。当玩家总共获得 50,000 分时,三连射功能就会被解锁。届时,调用 Features.UnlockFeature(FeatureType.TripleShot) 将确保玩家在拥有游戏期间都能使用三连射(其中 FeatureType 是一个枚举)。Features 的完整实现如下所示。

    public static class Features {

        public static bool IsFeatureLocked(FeatureType feature) {
            var keyName = feature.ToString();
            if(Dictionary.ContainsKey(keyName) == false || Dictionary[keyName] == null) {
                return true;
            }
            return Dictionary[keyName].ToString() != UnlockedKeyString;
        }

        public static void UnlockFeature(FeatureType feature) {
            var keyName = feature.ToString();
            Dictionary[keyName] = UnlockedKeyString;
        }
        
        private static IPropertySet Dictionary {
            get {
                return ApplicationData.Current.RoamingSettings.Values;
            }
        }

        private const string UnlockedKeyString = "Unlocked";

    }

这里的窍门是漫游设置中提供的字典。读取和写入此设置的值将自动将数据存储在用户的计算机上,如果他们有 Microsoft Live 帐户,还会将其同步到云端。此外,如果用户登录到多台计算机,这些设置会自动在计算机之间复制。因此,我在台式机上解锁的功能可以在我的笔记本电脑上使用,反之亦然。

未来

目前,该应用程序正处于游戏测试阶段,大约一个月左右可以完成。一些仍需关注的关键问题是应用程序在与 Windows 8 一同发布的各种硬件上如何运行。我的开发环境有一对 23 英寸屏幕,其中一个是一款戴尔触摸屏。不幸的是,该触摸屏技术陈旧,响应不灵敏,远不如电容式触摸屏。此外,新的 ARM 处理器可能需要一些此版本中未包含的性能调整。

从游戏性角度来看,还有额外的道具需要添加,以及一个高分服务器和游戏内的排行榜。

历史

2012-10-21 原始应用创新大赛提交

© . All rights reserved.