日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Win2D 中的游戏循环:CanvasAnimatedControl

發布時間:2024/1/1 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Win2D 中的游戏循环:CanvasAnimatedControl 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Win2D 是 DirectX 的一個高層封裝,提供了極大 DirectX 性能的同時,又具有很好用的 API 設計。

用 Win2D 除了能做出高性能的視覺效果之外,還可以輕而易舉地搭建一個游戲循環出來。使用 Win2D 的游戲循環,你可以直接做出一個簡單的游戲出來。


本文內容

      • 使用 Win2D 做出來的游戲
      • 準備工作
      • Win2D 中的畫布控件
      • CanvasAnimatedControl
      • CanvasAnimatedControl 在游戲中的使用
      • CanvasAnimatedControl 中 CreateResources 事件
        • 參考資料

使用 Win2D 做出來的游戲

我在 GitHub 上開源了我正在做的一個基于 Win2D 的小游戲 —— GravityMaze,可以翻譯為重力迷宮。本意是使用手機的重力感應器借助于自然重力的方式玩這款游戲,不過考慮到 Windows 10 Mobile 的手機太少,用戶數量太少,其實我還是直接展示 UWP 桌面版好了。使用方向鍵可以控制桌面的傾斜角度,以便間接控制小球的運動方向。

當然,我自己是有一部 Lumia 950XL 的,你可以在 使用 Windows 10 中的加速度計(Accelerometer,重力傳感器) 一文中看到它的身影。


▲ 重力迷宮

這張圖的紅色背景是我自己拍攝的,所以絕不可能存在版權問題。

準備工作

要使用 Win2D 進行簡單的游戲開發,你需要先配置好一些 UWP 的開發環境,并且在你的項目中安裝 Win2D.uwp 的 NuGet 包。閱讀 win10 uwp win2d 入門 看這一篇就夠了 - 林德熙 了解如何在你的項目中安裝 Win2D,并且了解 Win2D 基本的知識。

Win2D 中的畫布控件

Win2D 中的畫布有 CanvasControl、CanvasVirtualControl 和 CanvasAnimatedControl。

  • CanvasControl 用于進行一次性繪制,或者那些不常更新的畫面內容。例如進行軟件的 UI 繪制,或者軟件中所得圖形的繪制。
  • CanvasVirtualControl 適用于在一個很大的畫面中,只顯示一個小部分的情況。例如顯示大地圖的一部分,或者顯示大量超界的筆跡內容。
  • CanvasAnimatedControl 適用于顯示頻繁更新的畫面。典型的例子就是游戲。

CanvasAnimatedControl

我們使用 CanvasAnimatedControl 來做游戲循環,因為這是 Win2D 這幾個控件中最適合做游戲循環的控件了。

要在你的項目中使用 CanvasAnimatedControl,你需要在 XAML 中添加 using:Microsoft.Graphics.Canvas.UI.Xaml:

<Page x:Class="Walterlv.GravityMaze.Pages.GamePage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:xaml="using:Microsoft.Graphics.Canvas.UI.Xaml"><xaml:CanvasAnimatedControl Update="OnUpdate" Draw="OnDraw" /> </Page>

然后,我們訂閱 CanvasAnimatedControl 的兩個事件:

  • Update
    • 用于更新游戲中的數據,更新參考的是游戲時間線。
  • Draw
    • 用于繪制游戲的內容。

這是游戲循環最必要的兩個事件了,其他雖然也是需要的,但也可以不寫。

private MazeGame _game;private void OnUpdate(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEventArgs e) {// 根據時間線更新游戲數據。_game.Update(e.Timing); }private void OnDraw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs e) {// 繪制游戲畫面。using (var ds = e.DrawingSession){_game.Draw(ds);} }

CanvasAnimatedControl 在游戲中的使用

你在我的 GamePage 中其實看不到對 Update 和 Draw 事件的實際使用,因為我把它們都封裝到了 MazeGame 中了。

有些信息需要注意:

  • Update 和 Draw 運行于相同的線程,但都不是主線程;所以你不可以從這里去獲取主線程中的 UI 資源。
  • 正常情況下 Update 調用一次之后,Draw 就會調用一次;但如果當前運行緩慢,那么多次 Update 調用之后才會調用一次 Draw。
  • 如果 UWP 窗口最小化了,那么只會調用 Update 方法,而不會調用 Draw 方法。

  • ▲ 線程

    在 GravityMaze 重力迷宮中,主要是 Player 也就是你在上面動圖中看到的那個小球需要在 Update 中更新數據,其他其實只需要畫就好了。Update 中我需要計算速度、加速度以及進行碰撞檢測。

    private void OnUpdate(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEventArgs e) {var seconds = timing.ElapsedTime.TotalSeconds;// 1. 根據重力感應器或者鍵盤計算這一幀桌面的傾斜角度。// 2. 計算這一傾角帶來的加速度。// 3. 計算是否跌入黑洞。// 4. 將加速度疊加阻力。// 5. 計算此速度和加速度下的位置。// 6. 進行邊緣檢測和碰撞檢測。 }

    而在 Draw 中,只繪制了那個球:

    private void OnDraw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs e) {// 繪制游戲畫面。using (var ds = e.DrawingSession){ds.FillEllipse(_xPosition, _yPosition, _radius, _radius, Colors.Gray);} }

    事實上你在上面動圖看到的球并不是一個毫無生機的灰球,而是一個具有特效的半透明塑料彈球。你可以閱讀 使用 Win2D 繪制帶圖片紋理的圓(或橢圓) 了解如何繪制這樣的塑料彈球。

    CanvasAnimatedControl 中 CreateResources 事件

    CanvasAnimatedControl 中還有 CreateResources 事件,對更復雜的游戲循環有所幫助。當需要創建資源的時候會引發此事件。

    第一次使用的時候就需要創建資源;除此之外,如果設備丟失,也需要創建資源。閱讀 Win2D 官方文章系列翻譯 - 處理設備丟失 - void2 - 博客園 了解更多關于設備丟失的內容。

    private CanvasBitmap _boardMaterial;private async void OnCreateResources(CanvasAnimatedControl sender, CanvasCreateResourcesEventArgs e) {// 其中,GameCanvas 是 XAML 中 CanvasAnimatedControl 的名稱。_boardMaterial = await CanvasBitmap.LoadAsync(GameCanvas, new Uri("{ms-appx:///Assets/Game/Boards/table.jpg}")); }

    這里的 _boardMaterial 就是你在上面動圖中看到的后面那張紅色背景。

    這樣,便可以在需要的時候創建資源。

    不過,這時你需要在 Draw 中先判空再繪制。

    private void OnDraw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs e) {using (var ds = e.DrawingSession){// 其中,FullBounds 是 Rect 類型,我在 Page 的 SizeChanged 中給它賦的值。if (_boardMaterial != null){ds.DrawImage(_boardMaterial, FullBounds);}else{ds.FillRectangle(FullBounds, Colors.White);}} }

    你也可以使用事件參數 CanvasCreateResourcesEventArgs 來追蹤這個異步加載任務,這樣能夠在繪制之前確保資源被加載完畢。

    private async void OnCreateResources(CanvasAnimatedControl sender, CanvasCreateResourcesEventArgs e) {e.TrackAsyncAction(CreateResourcesAsync().AsAsyncAction());async Task CreateResourcesAsync(){_boardMaterial = await CanvasBitmap.LoadAsync(GameCanvas, new Uri("{ms-appx:///Assets/Game/Boards/table.jpg}"));} }

    參考資料

    • win10 uwp win2d 入門 看這一篇就夠了 - 林德熙
    • win10 uwp win2d CanvasVirtualControl 與 CanvasAnimatedControl - 林德熙
    • win10 uwp 螢火蟲效果 - 林德熙

    總結

    以上是生活随笔為你收集整理的Win2D 中的游戏循环:CanvasAnimatedControl的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。