首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VB中游戏的制作与优化

VB中游戏的制作与优化
EN

Stack Overflow用户
提问于 2015-05-16 11:17:19
回答 2查看 598关注 0票数 1

这更多的是一个一般性的问题,而不是一个与特定项目相关的问题。从我在学校开始学习编程开始,我们就一直使用VB语言。我想发展我的技能,做一些很酷的项目。最近,我做了一些小游戏,甚至进入了路德姆32。

然而,我一直遇到的一个大问题是,当我的游戏变得更加复杂,有更多的元素给他们(特别是增加图片框的数量),他们变得痛苦地缓慢。在我进入Ludum的时候,几乎所有的评论都谈到了游戏是如何开始的,但是随着时间的推移,开始变得越来越慢。

下面是一些我目前正在制作的pacman风格游戏的截图:

游戏有2个AI (橙色)和1个玩家(绿色)

同样的游戏有3个人工智能(橙色)和1个玩家(绿色),大约15行代码。

正如你在第二个截图中看到的,再加上一个AI (15行代码和一个图片框),游戏的FPS减半。我希望有人能帮助解释在VB中优化游戏的更好方法。

游戏详情:

  • 认可机构和球员都是画盒。
  • 我使用计时器来使用.left和.top语句来控制它们的运动。
  • 我使用了4个计时器(一个只用于FPS)
  • 我使用地形上的图片框进行碰撞(使用.bounds.intersectswith语句,这些语句位于定时器中的常数循环上)

如果有人需要进一步的信息,请直接问。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-16 14:08:59

PictureBox是一个方便的控件。方便和速度是对立的目标,没有控制做任何事情强迫你做正确的事情。你必须注意的事情,按照它们对渲染速度的影响顺序:

  • 它会自动重新调整图像大小,以适应控件和您所要求的SizeMode。它采用了一种高质量的重标度算法,能够产生尽可能好的图像,它消耗了大量的cpu周期。为了不使用太多的内存,它每次画自己的时候都这样做。您必须避免这种情况,只需使用SizeMode = Normal避免此成本。这通常意味着在分配image属性之前,您必须自己对图像进行预缩放。
  • 图像的像素格式非常非常重要。只有一个是快速的,允许位图直接复制到视频适配器的帧缓冲区,而不必进行转换。这是任何现代机器上的PixelFormat.Format32bppPArgb。这几乎不是你用绘画程序创建的位图的像素格式。在分配Image属性之前,需要进行转换。重要的是,32bppPArgb图像呈现的速度是所有其他图像的10倍。
  • 它通过将BackColor设置为Color.Transparent来支持透明性。首先让父程序将自己绘制到控制窗口中,然后在其上绘制图像。这是必须避免的,它超过了一倍的渲染时间。设置PictureBox.Size以匹配图像大小。如果您需要图像中的透明性,那么根本不要使用PictureBox,而是在父事件处理程序中调用e.Graphics.DrawImage()。
  • PictureBox不便于资源管理,它不占用分配给Image的位图的所有权。忘记调用映像的very ()方法是非常常见的。在某些情况下,这可能会导致应用程序消耗大量内存并导致减速。您通常注意到您的FPS下降后,玩了一段时间的游戏。您必须在FormClosed事件处理程序中或在重新分配图像属性时编写Dispose()调用。

还有一些额外的速度增长,你无法摆脱PictureBox。在这个列表的最上面是将图像存储在视频适配器的内存中,而不是机器的主RAM中。视频RAM比主RAM快得多,所以位图复制要快得多。这需要DirectX,这是游戏编程中非常常见的选择。SharpDX和SlimDX库非常流行。

一些帮助您处理这些子弹的代码:

代码语言:javascript
复制
Public Shared Sub GenerateFastImage(pbox As PictureBox, img As Image, ownsImage As Boolean)
    '' Calculate effective size, like SizeMode = AutoSize
    Dim zoom = Math.Min(CDbl(pbox.ClientSize.Width) / img.Width, _
                         CDbl(pbox.ClientSize.Height) / img.Height)
    Dim size = New Size(CInt(zoom * img.Width), CInt(zoom * img.Height))
    Dim pos = New Point((pbox.ClientSize.Width - size.Width) \ 2, _
                        (pbox.ClientSize.Height - size.Height) \ 2)
    '' Generate 32bppPArgb image
    Dim bmp = New Bitmap(pbox.ClientSize.Width, pbox.ClientSize.Height, _
                         System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
    Using gr = Graphics.FromImage(bmp)
        gr.Clear(pbox.BackColor)
        gr.DrawImage(img, New Rectangle(pos, size),
                     New Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel)
    End Using
    '' Dispose images
    If ownsImage Then
        If pbox.Image IsNot Nothing Then pbox.Image.Dispose()
        img.Dispose()
    End If
    pbox.Image = bmp
    pbox.SizeMode = PictureBoxSizeMode.Normal
End Sub

如果显示在图片框中的图像没有在程序中的任何其他地方使用,则为ownsImage参数传递True。此方法的示例使用情况:

代码语言:javascript
复制
Public Sub New()
    InitializeComponent()
    GenerateFastImage(PictureBox1, My.Resources.Player, True)
    GenerateFastImage(PictureBox2, My.Resources.Monster, True)
End Sub
票数 5
EN

Stack Overflow用户

发布于 2015-05-17 09:06:10

这个问题激起了我的兴趣,尽管我对VB知之甚少。我最初来自游戏背景(但在90年代早期,在模式13hVGA图形、Borland、程序集、AdLib合成器等的时代),我想用一个更一般的答案来解决您的问题的更一般的方面。

据我所知,你正在使用这些视觉形式元素来模拟游戏精灵和瓷砖。我猜你是在做动画,包括随着时间的推移改变x/y的位置类型属性,交换图像之类的东西,动态创建新的控件等等。

我的建议,可能会有一些反VBish的风险,就是不要。对于游戏来说,这种高级控制和形式元素实际上会让你的生活更加艰难。在某些方面,这些高级的、事件驱动的系统比以前更难使用,当时我们只是用运行循环的全屏应用程序直接操作视频内存。这类游戏更多地受益于同步、集中处理,而不是异步、分散处理,在这种处理中,代码分散在您控制范围之外的事件中。

对于这类复古风格的街机游戏,您需要一个具有“主循环”的结构,如下所示(简化):

代码语言:javascript
复制
while the game is running:
    process input and game logic
    draw frame (to offscreen buffer if you can afford it)
    swap/copy your hidden buffer to front, visible one

如果您能够在VB中找到一种获得这种结构的方法,并使用绘图库手动完成自己的绘图(如果它可以完成诸如快速α闪电偶之类的事情,那么它将使您的生活变得更加轻松。)

例如,主循环可能不适合于严重事件驱动的系统,我怀疑VB适合这一类。但是,例如,您可能需要将所有这些高级计时器合并成一个定时器,以模拟游戏循环。多个定时器往往会使一切保持同步变得困难。

在游戏中,当涉及到时间和绘图时,你想成为一个控制狂,它会给你更多的优化空间(例如:使用网格或四叉树等加速结构来避免屏幕外物体多馀的绘图调用,除了快速碰撞检测外,还有最少的检查)。

除了空白屏幕/窗口和一组好的、快速的绘图例程之外,您不需要更多的渲染功能。

例如,你不想在游戏中有两个敌人,其中一个在一个帧中移动一个像素,另一个在下一个帧中移动一个像素,如果它们都同时移动的话。这给人一种僵硬而奇怪的感觉,这种感觉感觉不太正确,如果你不能准确地控制画图/刷新是如何逐帧完成的话,这可能是很难避免的。

成为控制狂,掌握你自己的绘图和输入处理与帧-帧控制,我实际上建议它将使你的生活更容易,并有助于扩大你的视野,使更多的动态游戏。

最后,我建议看看人们是如何为任天堂和Atari这样的游戏机编写游戏的,以及人们今天是如何继续这种趋势的。在这个主题上应该有一些很好的资源,我建议从主游戏循环的概念开始,以及如何绘制、动画和碰撞。他们不会用一堆画框和计时器来做这件事,例如,并不是因为当时他们没有那种奢侈,而是因为这样的事情会成为障碍。

在好的一面,你不需要写组装代码,这些天,使酷的2D游戏,漂亮流畅的精灵动画和一个良好的帧率。您可以使用高级解释器编写它们,只要您的绘图库和可能的声音库/混音器是快速的,您就会很好。你只想确定的是,你完全掌握了要画什么,什么时候画。你想要那种主回路的心态。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30274969

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档