内容简介:Win2D 是 DirectX 的一个高层封装,提供了极大 DirectX 性能的同时,又具有很好用的 API 设计。用 Win2D 除了能做出高性能的视觉效果之外,还可以轻而易举地搭建一个游戏循环出来。使用 Win2D 的游戏循环,你可以直接做出一个简单的游戏出来。我在 GitHub 上开源了我正在做的一个基于 Win2D 的小游戏 —— GravityMaze,可以翻译为重力迷宫。本意是使用手机的重力感应器借助于自然重力的方式玩这款游戏,不过考虑到 Windows 10 Mobile 的手机太少,用户
Win2D 是 DirectX 的一个高层封装,提供了极大 DirectX 性能的同时,又具有很好用的 API 设计。
用 Win2D 除了能做出高性能的视觉效果之外,还可以轻而易举地搭建一个游戏循环出来。使用 Win2D 的游戏循环,你可以直接做出一个简单的游戏出来。
使用 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 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 官方文章系列翻译 - 处理设备丢失 - void² - 博客园 了解更多关于设备丢失的内容。
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 萤火虫效果 - 林德熙
本文会经常更新,请阅读原文: https://walterlv.com/post/game-loop-of-win2d-canvas-animated-control.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接:https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com) 。
以上所述就是小编给大家介绍的《Win2D 中的游戏循环:CanvasAnimatedControl》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 游戏制作之路(35)从开始菜单切换到游戏循环
- 008.Python循环for循环
- 006.Python循环语句while循环
- 007.Python循环语句while循环嵌套
- 观点 | 激励循环——加密算法如何实际修复现有激励循环
- 数组常见的遍历循环方法、数组的循环遍历的效率对比
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
html转js在线工具
html转js在线工具
RGB HSV 转换
RGB HSV 互转工具