一个游戏应该有情节发展,这时随着用户交互,屏幕内容会变化。
游戏循环
在游戏中,我们初始化、维持并取消一个循环,游戏循环在必要时能给我们渲染屏幕内容的机会。一般情况下,游戏开始的时候,初始化游戏循环, 一般地情况下,当游戏启动的时候游戏循环初始化,然后通过休眠和根据需要循环返回来维持循环,直到游戏终止。
这个技术提供动作游戏最大的灵活性和快速反应性。我们现在来实现一个用于我们足球游戏的游戏循环。假定这个游戏有很多级别。
|
private void DoGameLoop() m_gxOn = this.CreateGraphics(); do DoLevel(); // Ready the game for the next level // End game loop // Dispose the on-screen graphics as we don't need it anymore m_gxOn.Dispose(); // Ready the game for next time around private void DoLevel() while ((alive) && (levelNotCompleted)) Application.DoEvents(); // Process game parameters and render game // Regulate the rate of rendering (fps) |
注意,每次我们在循环返回之前,在循环中调用Application.DoEvents(),我们这么做的目的是与系统保持主动联系,并且处理事件队列中等待处理的消息。这是很必要的,因为当我们的应用程序处于一个循环中的时候,我们基本上失去了处理任何来自系统的消息的能力;除非我们明确调用 Application.DoEvents(),否则我们的应用程序不会响应系统事件,并且可能产生不希望有的副作用。
游戏循环中要考虑的另一个问题是渲染速率。大部分的游戏动画需要至少8 - 10帧每秒。相比较之下,典型的动画电影渲染速度是14 - 30帧每秒。
一个简单的帧速率调节技术就是确定需要的每秒帧以及循环中休眠(1000/fps)毫秒。但是我们也需要计算处理所使用的时间,否则我们的渲染速率将要比预期的要低。处理时间可能会相当长,尤其在较慢的硬件上,因为它要进行高成本的操作,比如处理用户输入,渲染游戏等等。
| Thread.Sleep(Math.Abs(tickLast + (1000 / fps) - Environment.TickCount)); tickLast = Environment.TickCount; |
定时回话
另一种技术是建立一个周期性地回话的系统计时器。就象游戏循环一样,定时器一般在游戏开始和定时信号事件(每隔一定时间发生)被处理的时候实例化,直到游戏结束。
我们选择了游戏循环这个简单的比喻,是因为我们让系统为我们处理定时器。我们只要处理定时器回话,然后通过每次重画一帧的方法让游戏进展下去。而且,我们不必担心会消耗完事件队列。
但是我们必须小心选择定时器的定时信号间隔,因为它决定了我们游戏的帧速率。
在游戏循环技术中,两个定时信号之间的时间间隔是完全被我们的控制的,而且前面我们也可以看到,这很容易考虑处理时间。另一方面,定时回话意味着时间间隔不能改变。 所以我们要么把定时间隔设置的足够大,以便能够完全处理每个回话;要么调节定时信号的处理过程,通过明确地掌握处理定时信号和根据维持节奏需要而跳过定时信号的时间。
使用定时器回话的一个主要缺点就是我们要依赖操作系统定时器的分辨率。最小定时信号间隔可能取决于定时器最大可能的分辨率。 在Pocket PC上这可能是一个限制因素,因为在Pocket PC上,时间分辨率很低,就是说用在本方法中的fps也很低。而且,操作系统定时事件的优先权相当低,意味着游戏的响应度也很低。
如果不管这些限制的话,这个技术最适用于慢进度的游戏,在这些游戏里帧速率并不是最重要的。比如说,屏幕保护程序。
|
private void StartTimer () // Create and hold onto on-screen graphics object // Specify the timer callback method // Start the timer // Init game params such as level protected void OnTick(object sender, EventArgs e) if (processTick) private void EndTimer () // Dispose timer // Dispose the on-screen graphics as we don't need it anymore m_gxOn.Dispose(); // Ready the game for next time around |
注意:当游戏结束的时候,你必须去除定时器。
注意没有必要调用Application.DoEvents(),因为我们既不使用循环,也不截取任何系统事件,事实上,定时器回话也正是另一种系统事件。而且,注意大部分游戏工作程序被压入OnTimerTick()事件处理程序。收藏 http://www.qqread.com/dotnet/u292184000.html
更多内容请看游戏开发、网络游戏攻略、.NET Framework新手入门专题,或进入讨论组讨论。
相关专题
- 游戏开发 (2107篇文章)
- 网络游戏攻略 (4329篇文章)
- .NET Framework新手入门 (132篇文章)
- .NET移动与嵌入式技术 (5950篇文章)
- .NET开发手册 (5652篇文章)
- 电信运营商专栏 (4024篇文章)
- Wlan组网----家庭专题 (4184篇文章)
- 网络游戏开发 (141篇文章)
- 游戏策划 (287篇文章)
- 程序设计 (226篇文章)
- vb.net入门——ToolBar 控件的使用 (267次浏览)
- vb.net入门——OpenFileDialog 组件的使用 (75次浏览)
- vb.net入门——FontDialog 组件的使用 (52次浏览)
- vb.net用Graphics画一个五角星 (46次浏览)
- vb.net入门——FolderBrowserDialog 组件的使 (45次浏览)
- vb.net绘制干扰点 (44次浏览)
- vb.net入门——ColorDialog 组件的使用 (41次浏览)
- vb.net巧用ToolTip控件获取鼠标坐标 (39次浏览)
- 用vb.net创建一个鼠标绘图程序 (39次浏览)
- vb.net入门——SaveFileDialog 组件的使用 (38次浏览)



