如何将试用体验添加到 XNA Framework 应用程序

2012/2/9

本主题演示如何在 XNA Framework 应用程序中实现试用体验。我们在此系列中创建的游戏具有有效演示试用体验所需的所有功能。游戏基础结构已就绪。我们已添加冲突检测,可以检测用户何时点按围绕屏幕弹跳的方块图形对象。我们将多个级别添加到游戏和一个记分板中,可以显示当前分数和当前级别。最后一步是添加试用体验。如果当前许可证为试用许可证,那么本主题实现的试用体验将限制用户可以玩的级数。使用 Guide.IsTrialMode 属性确定应用程序正在运行的模式。

执行此步骤之前,您需完成以下主题。

  1. 如何创建 XNA Framework 应用程序

  2. 如何将冲突检测添加到 XNA Framework 应用程序

  3. 如何将级别添加到 XNA Framework 应用程序

  4. 如何显示 XNA Framework 应用程序的记分板

注意注意:

以下过程中的步骤用于 Visual Studio 2010 Express for Windows Phone。 当您使用用于 Visual Studio 2010 Professional 或 Visual Studio 2010 Ultimate 的插件时,您可能会看到菜单命令或窗口布局中的一些微小改变。

此示例使用基于级别的试用限制。这意味着玩家可以玩的级数取决于游戏是试用许可证还是完整许可证。使用 Guide 类的 Guide.IsTrialMode 属性来完成许可证类型检查。

将试用体验添加到游戏中

  1. 在本节中,将提示用户购买应用程序。用户正在接受提示时最好暂停游戏。在 Game1 类中,添加以下代码。这些方法设置指示是否暂停游戏的标志。此标志在 Update 方法中使用,下一步中有具体介绍。

    
            private bool paused = false;
            private bool pausedForGuide = false;
    
            private void BeginPause(bool UserInitiated)
            {
                paused = true;
                pausedForGuide = !UserInitiated;
            }
    
            private void EndPause()
            {
                pausedForGuide = false;
                paused = false;
            }
    
    
  2. “Game1.cs”Update 方法中,检查是否已经暂停游戏。在此处使用前一步已经定义的 paused 标志。使用以下代码替换“Game1.cs”方法中的 Update

    
            /// <summary>
            /// Allows the game to run logic such as updating the world,
            /// checking for collisions, gathering input, and playing audio.
            /// </summary>
            /// <param name="gameTime">Provides a snapshot of timing values.</param>
            protected override void Update(GameTime gameTime)
            {
                // Allow the game to exit.
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
                    ButtonState.Pressed)
                    this.Exit();
    
                // If the game is paused, there is no need to update the game.
                if (!paused)
                {
                    while (TouchPanel.IsGestureAvailable)
                    {
                        GestureSample gs = TouchPanel.ReadGesture();
                        if (gs.GestureType == GestureType.Tap)
                        {
                            CheckForTouchCollision(gs.Position);
                        }
                    }
    
                    // Move the sprite around.
                    UpdateSprite(gameTime, ref spritePosition, ref spriteSpeed);
                    base.Update(gameTime);
                }
            }
    
    

    如您在前面代码中所见,现在手势检查和 Update 命令已包装在对 paused 的检查中。如果暂停游戏,我们不想继续更新游戏。

  3. 使用以下代码替换“Game1”类的 GoToNextLevel 方法中的代码。

    
            private void GoToNextLevel()
            {
                // Are all levels completed?
                if (currentLevel == levels.Count)
                {
                    // The game is over.
                    // In this example, we just let the user continue to replay the last level.
                    ResetGameCounters();
                }
                else
                {
                    if (Guide.IsTrialMode)
                    {
                        // Pause the game while the user is prompted.
                        BeginPause(false);
    
                        // MessageBox will have "OK" and "Cancel" buttons.
                        List<String> mbList = new List<string>();
                        mbList.Add("OK");
                        mbList.Add("Cancel");
                            
                        // BeginShowMessageBox is asynchronous. We define the method PromptPurchase as the callback.
                        Guide.BeginShowMessageBox("Level 1 Complete", "Click OK to buy the game.", mbList, 0, 
                                                    MessageBoxIcon.None, PromptPurchase, null);
                    }
                    else
                    {
                        // A Full license was found, so move to the next level
                        currentLevel++;
                        spriteSpeed = levels[currentLevel - 1];
                        ResetGameCounters();
                        
                    }
                }
            }
    
    
    

    前面代码执行以下操作:

    • 首先,检查用户是否已完成游戏的所有级别。如果已完成游戏的所有级别,将重设游戏计数器并且用户可以继续进行最后一级的游戏。此示例中没有定义游戏结束体验。

    • 如果用户仍有要玩的级别,将调用 Guide.IsTrialMode 来确定当前许可证类型。如果游戏有完整许可证,将遍历其他代码路径并且游戏继续进行下一级别。

    • 如果游戏正在运行的是试用许可证,那么将提示用户购买游戏。若要执行此操作,首先使用前面已经添加的 BeginPause 方法暂停游戏。然后,构造一个包含“确定”“取消”两个按钮的消息框。调用 Guide.BeginShowMessageBox 方法,并在 PromptPurchase 方法中传递,在下一节中具体定义。BeginShowMessageBox 是异步的,所以最好在收到用户响应前暂停游戏。PromptPurcahseBeginShowMessage 的回调方法。在完成 BeginShowMessageBox 调用时将调用它,这将在用户关闭屏幕上的 MessageBox 时发生。

  4. Game1 类中,添加以下方法。这是调用 Guide.BeginShowMessageBox 的回调,已经在前一步中介绍了。此处,完成 MessageBox 操作并且为值检查结果。如果结果有一个值,则它将与用户所按的按钮索引相等。由于该示例中的消息框有两个按钮,则可能的结果值为 0(“确定”)和 1(“取消”)。如果用户点按“确定”,则会转到游戏的商城页面,在那里他们可以购买该游戏以及众多其他商品。如果用户点按消息框中的“取消”,则重设计数器并且允许用户继续玩第一级游戏。

    注意注意:

    对未发布到 Windows Phone 商城 的应用程序调用方法 Guide.ShowMarketplace 时,将显示错误信息。如果此错误的错误代码是 805a0194,则该调用在应用程序发布后就会成功并正常运行。应用程序发布之后,Guide.ShowMarketplace 将自动在 Windows Phone 商城 客户端应用程序中检测应用程序的唯一 ID,并启动正确的详细信息页面。

    
            private void PromptPurchase(IAsyncResult ar)
            {
                // Complete the ShowMessageBox operation and get the index of the button that was clicked.
                int? result = Guide.EndShowMessageBox(ar);
    
                // Clicked "OK", so bring the user to the application's Marketplace page to buy the application.
                if (result.HasValue && result == 0)
                {
                    Guide.ShowMarketplace(PlayerIndex.One);
                }
                else
                {
                    // User did not want to go to the Marketplace to buy the application.
                    // Stay at level one.
                    ResetGameCounters();
                }
    
                // Resume the game if it had been paused.
                if (paused || pausedForGuide)
                    EndPause();
            }
    
    
    

前面部分检查了游戏的许可证,确定是作为试用版对游戏进行限制还是给用户提供完整体验。Guide.IsTrialMode 用于检查当前游戏许可证。由于游戏还没有发布,没有与之关联的许可证并且调用 Guide.IsTrialMode 总是返回 false。若要在应用程序发布前测试试用模式,必须模拟试用模式。Guide 类包含此目的属性 SimulateTrialMode,以下过程中将介绍它的用途。

在游戏中模拟试用模式

  • “Game1.cs”“Game1”构造函数中,添加以下代码行。将 SimulateTrialMode 属性设置为 true 时,调用 Guide.IsTrialMode 总是返回 true。这样,可以测试您游戏的试用模式功能。以下代码行包装在 DEBUG 条件编译指令中。这意味着仅在生成项目并在调试模式下运行时编译此代码。这是确保绝不将此测试功能发布到 Windows Phone 商城 的安全方法。

    
    #if DEBUG
                Guide.SimulateTrialMode = true;
    #endif
    
    

测试游戏的试用体验

  1. 通过选择“调试 | 启动调试”菜单命令运行应用程序。这将打开模拟器窗口并启动该应用程序。您将看到一个围绕屏幕弹跳的图形。

  2. 如果在模拟器上运行游戏,请在图形围绕屏幕弹跳时用鼠标左键单击它。如果在实际的手机设备上运行游戏,请在方块图形围绕屏幕弹跳时用您的手指点按它。观察屏幕上的“分数”字段,您每次成功触摸图形后,该分数将递增。

  3. 持续点按图形,直到获得五分为止。这是每一轮游戏冲突的硬编码数。

  4. 此时,第一级已经完成并且出现邀请您购买游戏的消息。单击“确定”

  5. 稍后,将出现一个名为“MARKETPLACE ERROR”的新屏幕。如果在此页面中显示的错误代码是 805a0194,则游戏已经成功启动 Windows Phone 商城 客户端应用程序。在已发布的应用程序中,游戏的实际 Windows Phone 商城 页面将替换此屏幕。以下映像显示将接收的错误页面。

    MarketplaceDetailTask.Show() 错误
  6. 点按该页面上的“关闭”。游戏重新启动第一级且仍处于试用模式下。

  7. 在完整许可证模拟中测试游戏存在多个选项。这些选项包括:

    • 通过选择“调试 | 开始执行(不调试)”菜单命令运行应用程序。这将导致用发布配置编译游戏,并且 Guide.IsTrial 将返回 false。这将打开模拟器窗口并启动该应用程序。您将看到一个围绕屏幕弹跳的图形。

    • 临时更改 Guide.SimulateTrialMode = false,然后通过选择“调试 | 启动调试”菜单命令来运行应用程序。这与前面的选项具有相同的结果,导致游戏中的 Guide.IsTrial 检查返回 false,因此模拟运行完整许可证的游戏。

    使用前面的两种方法都将导致游戏以模拟完整许可证的方式运行,您可以继续玩游戏并从第一级移到第三级观察其移动,随着级别的更改图形移动的速度将加快。

以下映像显示运行游戏的屏幕截图。横向操作游戏。注意映像右上方的记分板和屏幕底部的方块图形。

AP_Con_XNATrialApplicationUI Screenshot

显示: