本文章是由機器翻譯。

Windows Phone SDK 7.1

建置 'Mango' 向

安德路 Whitechapel

下載程式碼範例

"Mango"是 Windows Phone SDK 7.1 版本,而且當然真是美味熱帶水果名稱內部程式碼名稱。有很多種,您可以使用 mangoes-例如,在派形、 salads 和雞尾酒範圍。Mango 也稱為提供好幾個健康的好處,它有個有趣的文化特性故事。在本文中我將檢查 Mangolicious,mangoes 相關的 Windows Phone SDK 7.1 應用程式。應用程式提供一系列 mango 的配方,雞尾酒及內容,但真正的目的是要一同來探索一些大型的新功能,在 7.1 版本中,特別是:

  • 本機資料庫,並 LINQ to SQL
  • 第二個方塊,並在深層連結
  • Silverlight/XNA 整合

應用程式的使用者經驗很簡單: 主頁面提供了 panorama,與在第一個 panorama 項目]、 [動態的季節的配方和雞尾酒第二個項目,以及一些簡單的 「 關於 」 資訊進行第三個項目中,選取功能表中所示圖 1


[圖 1 Mangolicious Panorama 主頁面

[季節性會反白顯示] 功能表和區段中的項目作為瀏覽其他網頁應用程式中的連結。大部份的頁面是直接使用 Silverlight 網頁,而且一頁專門用來整合式的 XNA 遊戲。以下是建置此應用程式,從開始到完成所需的工作的摘要:

  1. 在 Visual Studio 中建立基本的解決方案。
  2. 獨立建立資料庫的配方,cocktail 和事實資料。
  3. 更新應用程式使用的資料庫,並公開 (公開) 為資料繫結。
  4. 建立各種 UI 分頁,因此資料繫結它們。
  5. 將第二個方塊功能設定為允許使用者配方項目釘選到行動電話的起始頁。
  6. 應用程式中納入 XNA 遊戲。

建立方案

這個應用程式中,我將使用 Visual Studio 的 Windows Phone Silverlight 及 XNA 應用程式範本。這麼做會產生的方案包含三個專案。這些總結在 [重新命名之後, 圖 2

[圖 2 專案中的 Windows Phone Silverlight 並 XNA 方案

專案 描述
MangoApp 包含電話應用程式本身,以預設的 MainPage 和第二個 GamePage。
GameLibrary 基本上是空的專案具有所有正確的參考,但沒有程式碼。少,它會包含內容的專案內容的參考。
GameContent 空白內容專案,來保存所有的遊戲資產 (影像、 音效檔等等)。

建立資料庫和 DataContext 類別

Windows Phone SDK 7.1 版引入了用於本機資料庫的支援。也就是應用程式可以將資料儲存在電話上的本機資料庫檔案 (SDF)。建議的方法是在程式碼,以供應用程式本身或透過不同的協助應用程式建置這只是為了建立資料庫中建立的資料庫。讓應用程式中的資料庫中案例,您將會建立最或建立的所有資料只在應用程式執行時。Mangolicious 應用程式中,我有靜態資料,而我可以預先填入資料庫。

若要這樣做,我將建立個別的資料庫建立者協助應用程式,從簡單的 Windows Phone 應用程式範本開始。若要在資料庫中建立程式碼,我必須衍生自 DataContext,在 System.Data.Linq 組件的自訂電話版本中定義的類別。在建立該資料庫協助應用程式和主應用程式使用的資料庫,則可以使用這個相同的 DataContext 類別。在 [協助應用程式中,我必須指定資料庫位置在隔離儲存區,因為那是我可以從電話應用程式要寫入的唯一位置。類別也會包含一組資料表欄位的每個資料庫資料表:

public class MangoDataContext : DataContext
{
  public MangoDataContext()
    : base("Data Source=isostore:/Mangolicious.sdf") { }
 
  public Table<Recipe> Recipes;
  public Table<Fact> Facts;
  public Table<Cocktail> Cocktails;
}

沒有程式碼中的資料表類別與資料庫中的資料表之間的一對一對應。 資料行屬性對應到資料庫中資料表的資料行,並包含資料庫結構描述屬性,例如資料型別和大小 (INT、 NVARCHAR 等等),不論欄位可能是 null,無論是索引鍵資料行,依此類推。 我定義資料表的所有其他資料表中的類別資料庫中相同的方式,如所示的圖 3

[圖 3 定義資料表類別

[Table]
public class Recipe
{
  private int id;
  [Column(
    IsPrimaryKey = true, IsDbGenerated = true,
    DbType = "INT NOT NULL Identity", CanBeNull = false,
    AutoSync = AutoSync.OnInsert)]
  public int ID
  {
    get { return id; }
    set
    {
      if (id != value)
      {
        id = value;
      }
    }
  }
 
  private string name;
  [Column(DbType = "NVARCHAR(32)")]
  public string Name
  {
    get { return name; }
    set
    {
      if (name != value)
      {
        name = value;
      }
    }
  }?
...
additional column definitions omitted for brevity
}

儘管如此,在 [協助應用程式,並使用標準的模型-檢視-ViewModel (MVVM) (UI) 的方法,我現在需要溝通的檢視,並使用 DataContext 類別模型 (資料) 的 ViewModel 類別。 ViewModel 有 DataContext 欄位和一組資料表的資料 (食譜、 事實和雞尾酒) 的集合。 資料是靜態的那麼簡單清單 <T> 在此集合就足夠了。 同樣地,我只需要取得 屬性存取子不 設定修飾詞 (請參閱 圖 4)。

[圖 4 定義在 ViewModel 中的資料表資料的集合屬性

public class MainViewModel
{
  private MangoDataContext mangoDb;
 
  private List<Recipe> recipes;
  public List<Recipe> Recipes
  {
    get
    {
      if (recipes == null)
      {
        recipes = new List<Recipe>();
      }
    return recipes;
    }
  }
 
    ...
additional table collections omitted for brevity
}

我也會公開的公用方法,我可以從 UI 叫用的-實際建立的資料庫和所有的資料。 在這種方法,我會建立資料庫本身如果它不存在,並且再依次建立每個資料表填入每一個靜態的資料。 比方說,若要建立 [食譜] 資料表,我要建立多個類別的執行個體配方,對應至資料列中的資料表。新增 DataContext ; 從集合中的所有資料列然後,最後認可至資料庫的資料。 事實 」 與 「 雞尾酒資料表使用相同的模式 (請參閱圖 5)。

[圖 5 建立資料庫的

public void CreateDatabase()
{
  mangoDb = new MangoDataContext();
  if (!mangoDb.DatabaseExists())
  {
    mangoDb.CreateDatabase();
    CreateRecipes();
    CreateFacts();
    CreateCocktails();
  }
}
 
private void CreateRecipes()
{
  Recipes.Add(new Recipe
  {
    ID = 1,
    Name = "key mango pie",
    Photo = "Images/Recipes/MangoPie.jpg",
    Ingredients = "2 cans sweetened condensed milk, ¾ cup fresh key lime juice, ¼ cup mango purée, 2 eggs, ¾ cup chopped mango.",
    Instructions = "Mix graham cracker crumbs, sugar and butter until well distributed.
Press into a 9-inch pie pan.
Bake for 20 minutes.
Make filling by whisking condensed milk, lime juice, mango purée and egg together until blended well.
Stir in fresh mango.
Pour filling into cooled crust and bake for 15 minutes.",
    Season = "summer"
  });
 
    ...
additional Recipe instances omitted for brevity
 
  mangoDb.Recipes.InsertAllOnSubmit<Recipe>(Recipes);
  mangoDb.SubmitChanges();
}

按一下 [協助應用程式中適當的時候,可能是在按鈕處理常式-我接著叫用這個 CreateDatabase 方法。 當我執行的協助程式 (無論是在模擬器或實體裝置上) 時,資料庫檔案將會建立應用程式的隔離儲存區中。 最後一項工作是擷取該檔案到桌面,以供主應用程式中可以使用。 [隔離的存放裝置總管] 若要這樣做,我使用工具中,Windows 電話 SDK 7.1 所隨附的命令列工具。 要從模擬器的隔離儲存區的快照集交給桌面命令如下:

"C:\Program Files\Microsoft SDKs\Windows Phone\v7.1\Tools\IsolatedStorageExplorerTool\ISETool" ts xd {e0e7e3d7-c24b-498e-b88d-d7c2d4077a3b} C:\Temp\IsoDump

此指令會假定工具會安裝在標準的位置。 參數將會說明圖 6

[圖 6 隔離的存放裝置總管命令列參數

參數 描述
ts "指揮快照式"(從隔離儲存區下載到桌面)。
xd 簡稱為 XDE (也就是模擬器)。
{} e0e7e3d7-c24b-498e-b88d-d7c2d4077a3b 協助應用程式的產品識別碼。 這會列在 WMAppManifest.xml,而每個應用程式各有不同。
C:\Temp\IsoDump 您想要複製快照集,在桌面上任何有效的路徑。

我需要解壓縮到桌面的 SDF 檔案,現在正在使用協助應用程式已完成,可以將我注意到所要使用此資料庫的 Mangolicious 應用程式。

使用資料庫

Mangolicious 應用程式中,我會將 SDF 檔案加入至專案,並將也相同自訂 DataContext 類別加入至方案中,有數個細微的變更。 在 Mangolicious,我不需要寫入資料庫,因此我可以將它直接從應用程式的安裝資料夾。 因此,連接字串是與協助應用程式中稍有不同的。 此外,Mangolicious 會定義 SeasonalHighlights 資料表中的程式碼。 在資料庫中沒有任何對應的 SeasonalHighlight 資料表。 相反地,此程式碼的資料表會提取資料,這兩個基礎資料庫資料表 (配方和雞尾酒) 並用來填入季節性會反白顯示的 panorama 項目。 下列兩項變更是唯一的差異在於 DataContext 類別中的資料庫建立協助應用程式之間的 Mangolicious 資料庫使用應用程式:

public class MangoDataContext : DataContext
{
  public MangoDataContext()
    : base("Data Source=appdata:/Mangolicious.sdf;File Mode=read only;") { }
 
  public Table<Recipe> Recipes;
  public Table<Fact> Facts;
  public Table<Cocktail> Cocktails;
  public Table<SeasonalHighlight> SeasonalHighlights;
}

Mangolicious 應用程式也需要 ViewModel 類別,而且我可以使用協助應用程式的 ViewModel 類別做為起點。 我需要 DataContext] 欄位和清單 <T> 系列資料表格的集合屬性。 在頂端,我要加入記錄目前到來時,建構函式中計算出來的字串] 屬性:

public MainViewModel()
{
  season = String.Empty;
  int currentMonth = DateTime.Now.Month;
  if (currentMonth >= 3 && currentMonth <= 5) season = "spring";
  else if (currentMonth >= 6 && currentMonth <= 8) season = "summer";
  else if (currentMonth >= 9 && currentMonth <= 11) season = "autumn";
  else if (currentMonth == 12 || currentMonth == 1 || currentMonth == 2)
    season = "winter";
}

在 ViewModel 中的重要方法是 LoadData 的方法。 在這裡,我會初始化資料庫並執行 LINQ SQL 透過 DataContext [我的記憶體中集合的查詢。 的資料載入到 我無法在這個時候,預先載入所有的三個資料表,但是我想要啟動效能最佳化,除非否則相關的頁面實際上瀏覽您延遲載入的資料。 唯一資料我必須啟動時載入是 SeasonalHighlight 資料表的資料,因為這會顯示在首頁上。 為此,我會有兩個查詢,以符合目前到來時,並新增結合的資料列加入集合中,會設定中所示的配方和雞尾酒資料表中選取 [只有資料列圖 7

[圖 7 資料在啟動時載入

public void LoadData()
{
  mangoDb = new MangoDataContext();
  if (!mangoDb.DatabaseExists())
  {
    mangoDb.CreateDatabase();
  }
 
  var seasonalRecipes = from r in mangoDb.Recipes
                        where r.Season == season
                        select new { r.ID, r.Name, r.Photo };
  var seasonalCocktails = from c in mangoDb.Cocktails
                          where c.Season == season
                          select new { c.ID, c.Name, c.Photo };
 
  seasonalHighlights = new List<SeasonalHighlight>();
  foreach (var v in seasonalRecipes)
  {
    seasonalHighlights.Add(new SeasonalHighlight {
      ID = v.ID, Name = v.Name, Photo = v.Photo, SourceTable="Recipes" });
  }
  foreach (var v in seasonalCocktails)
  {
    seasonalHighlights.Add(new SeasonalHighlight {
      ID = v.ID, Name = v.Name, Photo = v.Photo, SourceTable = "Cocktails" });
  }
 
  isDataLoaded = true;
}

我可以使用類似 LINQ SQL 查詢來建立個別的 LoadFacts、 LoadRecipes 和 LoadCocktails 方法,可用於在啟動之後載入視其各自的資料。

建立 UI

主網頁是由三個 PanoramaItems 與 Panorama 所組成。 第一個項目是由應用程式的主功能表所提供的清單方塊所組成。 當使用者選取其中一個清單方塊項目時,我瀏覽到對應的網頁-也就是集合] 頁面的配方,事實以及雞尾酒-或遊戲的頁面。 之前瀏覽,我確定食譜、 事實或是雞尾酒集合中載入相對應的資料:

switch (CategoryList.SelectedIndex)
{
  case 0:
    App.ViewModel.LoadRecipes();
    NavigationService.Navigate(
      new Uri("/RecipesPage.xaml", UriKind.Relative));
    break;
 
...
additional cases omitted for brevity
}

當使用者選取在 UI [季節性會反白顯示] 中的清單中的項目時,我檢查選取的項目,以查看它是否配方或 Cocktail,並再瀏覽個別的配方或 Cocktail 頁面,如所示傳遞做為瀏覽查詢字串的一部分的項目識別碼圖 8

[圖 8 可供選季節性的反白顯示清單

SeasonalHighlight selectedItem =
  (SeasonalHighlight)SeasonalList.SelectedItem;
String navigationString = String.Empty;
if (selectedItem.SourceTable == "Recipes")
{
  App.ViewModel.LoadRecipes();
  navigationString =
    String.Format("/RecipePage.xaml?ID={0}", selectedItem.ID);
}
else if (selectedItem.SourceTable == "Cocktails")
{
  App.ViewModel.LoadCocktails();
  navigationString =
    String.Format("/CocktailPage.xaml?ID={0}", selectedItem.ID);
}
NavigationService.Navigate(
  new System.Uri(navigationString, UriKind.Relative));

使用者可以瀏覽上的主頁面] 功能表的三個清單的網頁。每個頁面資料繫結至其中一個集合中的 ViewModel 來顯示項目的清單: 食譜]、 [事實或雞尾酒。每個網頁都有簡單的清單方塊的清單中的每個項目其中包含相片利用圖像控制項和 TextBlock 項目的名稱。例如, 圖 9 FactsPage 會顯示。


[圖 9 的有趣事實,其中一個 [集合清單] 頁面

當使用者從 [食譜]、 [事實或雞尾酒清單中選取的個別項目時,我瀏覽到個別的配方,事實宣告或 Cocktail 網頁,傳下瀏覽查詢字串中個別的項目 ID。同樣地,這些分頁是幾乎完全相同分散到三種型別中,每個提供影像和以下的一些文字。請注意我不要定義明確的資料繫結一併樣式,但是,但是它們都是使用 TextWrapping = 自動換行。這是藉由宣告 TextBlock 中的樣式 App.xaml.cs:

<Style TargetType="TextBlock" BasedOn="{StaticResource
  PhoneTextNormalStyle}">
  <Setter Property="TextWrapping" Value="Wrap"/>
</Style>

這結果是在方案中不會明確地定義自己的樣式,任何 TextBlock 會隱含地改用這一個。隱含的樣式設定為另一個一部分 Silverlight 4 Windows Phone SDK 7.1 所引進的新功能。

針對每個網頁的程式碼後置很簡單。在 OnNavigatedTo 覆寫時,我從查詢字串中擷取個別的項目識別碼,找出從 ViewModel 集合和資料繫結至這個項目]。RecipePage 的程式碼也比其他更複雜,額外的程式碼,在這個頁面中所有相定位在頁面的頂端右手邊角的 HyperlinkButton。這可想見人圖 10


[圖 10 A 配方頁面與 [固定] 按鈕

第二個方塊

當使用者按下的"pin"HyperlinkButton 在個別的 [食譜] 頁面上時,我固定該項目並排顯示在 [行動電話的起始頁上。釘選的動作會將使用者帶到起始頁,則會停用應用程式。並排顯示經過 pin 處理之後,如此一來,當它動畫會定期如所示,翻轉之間擺在前方和上一步], 圖 11圖 12


[圖 11 釘選配方並排顯示 (正面)


[圖 12 釘選配方並排顯示 (上一步)

接下來,使用者可以請點一下這個已釘選的並排顯示,直接巡覽至該應用程式中的項目。當牠到達網頁時,"pin"按鈕將可以 「 移除 」 影像。[開始] 如果他不固定頁面時,將會從頁面上,移除,而且應用程式會繼續。

以下是如何運作。在 RecipePage 的 OnNavigatedTo 覆寫之後執行標準的工作,來判斷哪一個特定的配方,資料,繫結,我制定我可以使用稍後做為 URI 本頁的字串:

thisPageUri = String.Format("/RecipePage.xaml?ID={0}", recipeID);

按一下 [處理常式"pin"按鈕,先檢查,看看是否並排顯示此頁已經存在,而且如果不是,我現在建立它。 在按鈕 我要建立使用目前的配方資料區塊: 影像和名稱。 我也將單一的靜態映像,和靜態文字-並排的備份。 在此同時,我利用這個機會來重繪按鈕本身,而使用 「 移除 」 的映像。 按一下 [如果,相反地,該方塊存在,然後我必須處於處理常式,因為使用者選擇取消釘選項方塊。 我在此情況下,刪除方塊,並如所示,重繪請使用 「 固定 」 的映像, 圖 13

圖 13 釘選與正在解除固定頁面

private void PinUnpin_Click(object sender, RoutedEventArgs e)
{
  tile = ShellTile.ActiveTiles.FirstOrDefault(
    x => x.NavigationUri.ToString().Contains(thisPageUri));
  if (tile == null)
  {
    StandardTileData tileData = new StandardTileData
    {
      BackgroundImage = new Uri(
        thisRecipe.Photo, UriKind.RelativeOrAbsolute),
      Title = thisRecipe.Name,
      BackTitle = "Lovely Mangoes!",
      BackBackgroundImage =
        new Uri("Images/BackTile.png", UriKind.Relative)
    };
 
    ImageBrush brush = (ImageBrush)PinUnpin.Background;
    brush.ImageSource =
      new BitmapImage(new Uri("Images/Unpin.png", UriKind.Relative));
    PinUnpin.Background = brush;
    ShellTile.Create(
      new Uri(thisPageUri, UriKind.Relative), tileData);
  }
  else
  {
    tile.Delete();
    ImageBrush brush = (ImageBrush)PinUnpin.Background;
    brush.ImageSource =
      new BitmapImage(new Uri("Images/Pin.png", UriKind.Relative));
    PinUnpin.Background = brush;
  }
}

請注意是否使用者點選以跳至 [食譜] 頁面上,已釘選的方塊,然後按下電話的硬體上一步] 按鈕,他會結束應用程式完全。這是可能令人混淆,因為使用者通常會希望他將只能結束之應用程式當他按下從首頁中,不能從任何其他網頁。不過,另外也可以在某種 「 家用 」 按鈕的網頁上提供配方來允許使用者巡覽回到應用程式的其餘部分。[上一步] 不幸的是,這可能也會造成混淆,因為當使用者到達的主頁面,並按下,他只會在上一步的已釘選配方頁面上,而不是結束應用程式之外。基於這個理由,雖然 「 家用 」 機制並不難達成,它會是您應該仔細權衡之前將它的行為。

將合併 XNA 遊戲

您還記得我最初建立應用程式做為 Windows Phone 的 Silverlight,XNA 應用程式的解決方案。這讓我三個專案。我先前使用的主要 MangoApp 来建置之專案的非遊戲功能。GameLibrary 專案就像""Silverlight MangoApp 和 XNA GameContent 之間。它是專案中參考 MangoApp,並依序會參考 GameContent 專案。必須沒有進一步的作業。有兩個以我的電話應用程式中納入遊戲所需的主要工作:

  • 增強的 GamePage 類別,在 MangoApp 專案以包含所有遊戲的邏輯。
  • 強化 GameContent 專案,以提供遊戲 (無程式碼變更) 中的影像和聲音。

查看簡短的增強功能整合 Silverlight 並 XNA 為專案所產生的視覺 Studio,要注意的第一件事,是 App.xaml 宣告 SharedGraphicsDeviceManager。這會管理 Silverlight 並 XNA 的執行階段時變更螢幕的共用。這個物件也是在專案中其他的 AppServiceProvider 類別的唯一理由。這個類別用來快取共用的圖形裝置 
manager,如此即可在 Silverlight] 與 [XNA 應用程式需要的任何項目。應用程式類別具有 [AppServiceProvider] 欄位中,而且它還會公開 XNA 整合的某些其他屬性: ContentManager 和 GameTimer。這些會全部初始化新的 InitializeXnaApplication 方法,連同 GameTimer,這用來幫浦 XNA 訊息佇列。

有趣的工作是如何整合在 Silverlight 電話應用程式中的有 XNA 遊戲。遊戲本身是實際比較不有趣的。因此,本練習中,而非從頭撰寫完成遊戲沒有把,我會調整現有的遊戲,明確地說,XNA 遊戲教學上 AppHub: bit.ly/h0ZM4o

在 [我的適應,我有 cocktail 的 shaker,表示播放程式中的類別的程式碼,就會引發速連入的 mangoes (敵人)。我叫用 mango,它會中斷開啟,並變形為 mangotini。每個 mango 叫用會增加 100 到分數。每當 cocktail 的 shaker 與 mango,播放程式] 欄位的力量會縮小 10。當欄位強度歸零時,遊戲就會結束。[上一頁] 使用者也可以結束遊戲在任何時候按電話上的按鈕,如預期般運作。[圖 14遊戲會顯示正在進行中。


[圖 14 XNA 遊戲在進行中

我不需要進行任何變更 (幾乎是空的) 的 GamePage.xaml。相反地,所有的工作是在程式碼後置。如所述起始此 GamePage 類別的程式碼,會產生的 Visual Studio 圖 15

[圖 15 GamePage 起始程式碼

欄位/方法 用途 所需的變更
ContentManager 載入及管理的內容生命週期中內容的管線。 加入程式碼以使用其來載入影像 
and 音效。
GameTimer 遊戲會在 XNA 遊戲模式中,執行動作更新的時機和觸發繪製事件,這些事件都受到計時器。 保持不變。
SpriteBatch 用來繪製材質 XNA。 加入程式碼使用這個在繪圖的方法來繪製遊戲的物件 (玩家、 敵人、 射出、 爆炸等等)。
GamePage 建構函式 會建立一個計時器並將其更新並進行繪製的事件,OnUpdate 和 OnDraw 方法連結。 保留計時器的程式碼,並另外初始化遊戲的物件。
OnNavigatedTo 設定共用 XNA,Silverlight 之間的圖形並啟動計時器。 保留的共用和計時器的程式碼,並另外載入遊戲時,包括任何先前的狀態從 
isolated 的存放區中的內容。
OnNavigatedFrom 停止計時器,並會關閉 XNA 
graphics 共用。 保留計時器,並共用程式碼,並另外儲存遊戲的分數及隔離儲存區的玩家生命值。
OnUpdate (空的),處理 
GameTimer.Update 事件。 加入程式碼來計算遊戲物件的變更 
 (玩家位置、 數目和及位置的敵人、 彈藥爆炸)。
OnDraw (空的),處理 
GameTimer.Draw 事件。 加入程式碼來繪製遊戲物件、 分數和玩家生命值。

遊戲是 AppHub 的教學課程,其中包含兩個專案的直接適應: 藍遊戲專案] 和 [ShooterContent content 專案。內容包含影像和聲音檔。雖然它並不會影響應用程式程式碼,我可以變更這些檔案來配合 mango 佈景主題,我的應用程式,而這是只取代 PNG 和 WAV 檔案的問題。必要的 (程式碼) 的變更都在藍遊戲專案。從遊戲類別遷移至 Silverlight/XNA 的指導原則位於 AppHub: bit.ly/iHl3jz

首先,我必須將藍遊戲專案檔案複製到我現有的 MangoApp 專案。此外,我將 ShooterContent 內容檔複製到我現有的 GameContent 專案。[圖 16摘述藍遊戲專案中現有的類別。

[圖 16 藍遊戲類別

類別 用途 所需的變更
動畫 建立不同的小精靈,在遊戲中的動畫: 播放程式,敵軍的物件、 射出及其爆炸。 消除 GameTime。
敵人 表示 
user 豬敵方物件小精靈。[我的適應。 的這些會是 mangoes,在 消除 GameTime。
Game1 遊戲控制的類別。 GamePage 類別進行合併。
ParallaxingBackground 建立定域機組的背景影像,以提供一種 3D 視差效果的動畫。 附註。
播放程式 小精靈,表示使用者在 
game 中的字元。[我的適應 cocktail shaker。 這就是在 消除 GameTime。
程式 只有當 Windows 或 Xbox 遊戲的目標使用。 未使用。無法刪除。
彈藥 小精靈,表示播放程式就會引發的敵人射出。 附註。

若要將這一局結合至 [我的電話應用程式中,我需要在 GamePage 類別中進行下列變更:

  • Game1 類別的所有欄位都複製到 GamePage 類別。GamePage 建構函式,也在 Game1.Initialize 方法複製欄位初始設定。
  • 將複製的 LoadContent 方法和所有的方法,來新增及更新的敵人、 彈藥爆炸。這些都需要的任何變更。
  • 擷取所有的 GraphicsDeviceManager,改為使用 GraphicsDevice 屬性的用法。
  • 解壓縮至 GamePage.OnUpdate 和 OnDraw 的計時器事件處理常式的 Game1.Update 及繪圖的方法中的程式碼。

傳統的 XNA 遊戲會建立新的 GraphicsDeviceManager,雖然我會將 SharedGraphicsDeviceManager 的 GraphicsDevice 屬性,公開 (公開),也就是我真的只需要有電話應用程式中。為了簡化作業,我會在 [我的 GamePage 類別快 GraphicsDevice 的參考取作為資料欄位。

在標準的 XNA 遊戲中,更新] 和 [繪圖方法都是虛擬的方法基底的 Microsoft.Xna.Framework.Game 類別中覆寫。不過,整合式的 Silverlight/XNA 應用程式中,GamePage 類別不被衍生自 XNA 遊戲類別,因此我必須擷取更新] 和 [繪圖中的程式碼,並將它插入到 OnUpdate 和 OnDraw 事件處理常式。請注意,有些遊戲的物件類別 (例如動畫、 敵人和播放程式)、 更新並進行繪製方法和某些更新程式所呼叫的的協助專家方法接受 GameTime 參數。這定義在 Microsoft.Xna.Framework.Game.dll,且它應該通常被視為錯誤如果 Silverlight 應用程式中包含這個組件的任何參考。GameTime 參數完全取代兩個 Timespan 屬性 — TotalTime 和 ElapsedTime-從傳入 OnUpdate 和 OnDraw 的計時器事件處理常式的 GameTimerEventArgs 物件所公開。除了從 GameTime,我可以連接埠未變更的繪圖程式碼。

原始的更新方法會測試遊樂器狀態,並有條件地呼叫 Game.Exit。因此它必須不移植到新的方法,就不能用整合式的 Silverlight/XNA 應用程式:

//if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
//{
//    // this.Exit();
//}

新的更新方法就比呼叫其他方法更新各種遊戲物件控管一點。 遊戲已經結束了,但只會更新播放程式、 敵人、 衝突、 射出及其爆炸播放程式是否仍在執行時,即使可以,我就會更新 parallaxing 背景。 這些協助程式方法計算的數字和各種不同的遊戲物件的位置。 需要排除 GameTime 的使用,這些可以全部移植超過保持不變,有一個例外狀況:

private void OnUpdate(object sender, GameTimerEventArgs e)
{
  backgroundLayer1.Update();
  backgroundLayer2.Update();
 
  if (isPlayerAlive)
  {
    UpdatePlayer(e.TotalTime, e.ElapsedTime);
    UpdateEnemies(e.TotalTime, e.ElapsedTime);
    UpdateCollision();
    UpdateProjectiles();
    UpdateExplosions(e.TotalTime, e.ElapsedTime);
  }
}

UpdatePlayer 方法不會需要少許的潤飾。 在遊戲的原始版本中,當播放程式的健康情況卸除成 0,它已經重設為 100,這意味著遊戲執行不限次數迴圈。 在 [我的適應,當播放程式的健康情況降到零,我設定旗標設為 false。 我測試 OnUpdate 方法和 OnDraw 此旗標。 在 OnUpdate,旗標值會決定,就不會計算到的物件 ; 所做的變更在 OnDraw,它會判斷是否要繪製的物件,或是繪製最後得分"完了"螢幕:

private void UpdatePlayer(TimeSpan totalTime, TimeSpan elapsedTime)
{
...unchanged code omitted for brevity.
if (player.Health <= 0)
  {
    //player.Health = 100;
    //score = 0;
    gameOverSound.Play();
    isPlayerAlive = false;
  }
}

我已在本文中討論了如何開發應用程式,針對數個新的功能,在 Windows Phone SDK 7.1: 本機資料庫,LINQ to SQL、 第二個方塊,並更深層的連結速度和 Silverlight/XNA 整合。7.1 版提供了許多較新的功能和增強功能,現有的功能。如需詳細資訊,請參閱下列連結:

Mangolicious 應用程式的最終版本會出現在 Windows Phone 服務商場,在 bit.ly/nuJcTA (附註: Zune 軟體所需的存取)。本範例使用 Windows Phone 工具對 Silverlight 的附註 (免費下載,位於 bit.ly/qiHnTT)。

Andrew Whitechapel* 超過 20 年一直為開發人員和目前 Windows Phone 小組,負責應用程式平台的核心部分的運作方式與專案經理。*

因為有到下列的技術專家來檢閱這份文件: Nick Gravelyn, Brian HudsonHimadri Sarkar