1

私は現在、Graphics クラスを使用してほとんどのゲーム オブジェクトを描画するゲーム (vb.net 内) を作成していますが、パフォーマンスの古い問題に遭遇しました。遅延に対処するために、ゲームの速度を上げようと試みることができるように、ゲームの品質を自動的に下げるコードをいくつか追加しました。これはある程度機能しますが、それでも、より多くの「敵」がより高いレベル。私はグラフィックス クラスにまったく慣れていないので (数日前に使い始めたばかりです)、ゲームのスピードアップに役立つことがわかっている唯一のことは、アンチ エイリアシングをオフにすることと、タイマー間隔を下げることです (これが私のゲームをほぼ制御します)。リフレッシュ レート)、前の方法以外に、ゲームのパフォーマンスを向上させる方法はありますか?

ゲームのスクリーンショット... スクリーンショット

これまでのコードは次のとおりです(品質調整ビットは下部にあります)。

Public Class Form1

Private keysPressed As New HashSet(Of Keys)
Private firstRun As Boolean = True
Private mouseDownB As Boolean = False
Private newLevel As Boolean = True
Private randomColour As New Random
Private RandomEnemyX As New Random
Private RandomEnemyY As New Random
Private RandomEnemySide As New Random
Private life As Integer = 5
Private score As String = 0
Private playerX As Integer = 403
Private playerY As Integer = 206
Private totaltEnemyCount As Integer = 10
Private enemyCount As Integer = 0
Private enemyX(0) As Integer
Private enemyY(0) As Integer
Private enemyID(0) As Integer
Private EX As Integer = 0
Private EY As Integer = 0
Private ES As Integer = 0
Private enemyMoved As Integer
Private enemySpeed As Integer = 1
Private enemyAttacked As Integer = 0
Private enemyActive As Integer = 0
Private levelNumber As Long = 0
Private FPS As Integer = 40
Private g1 As Graphics
Private enemyCountIncrease As Boolean = True
Private enemySpeedIncrease As Boolean = False

Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    g1 = Me.CreateGraphics
    g1.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias                           
End Sub

Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
    mouseDownB = True
End Sub

Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
    mouseDownB = False
End Sub

Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    If e.KeyCode = Keys.Left Then
        keysPressed.Add(Keys.Left)
    ElseIf e.KeyCode = Keys.Up Then
        keysPressed.Add(Keys.Up)
    ElseIf e.KeyCode = Keys.Right Then
        keysPressed.Add(Keys.Right)
    ElseIf e.KeyCode = Keys.Down Then
        keysPressed.Add(Keys.Down)
    End If
End Sub

Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
    keysPressed.Remove(e.KeyCode)
End Sub
'''''''''''''''''''''''''Random colour generator''''''''''''''''''''''''''''
Private Function R() As String
    Return randomColour.Next(0, 255)
End Function

Private Function G() As String
    Return randomColour.Next(0, 255)
End Function

Private Function B() As String
    Return randomColour.Next(0, 255)
End Function
'''''''''''''''''''''''''Random location generator''''''''''''''''''''''''''''
Private Function X() As String
    Return RandomEnemyX.Next(0, 494)
End Function

Private Function Y() As String
    Return RandomEnemyY.Next(24, 348)
End Function
'''''''''''''''''''''''''Main display & player generation''''''''''''''''''''''''''''''''
Private Sub mainPaint(sender As Object, e As EventArgs) Handles Timer1.Tick
    Timer1.Interval = FPS
    Dim ST As New Stopwatch
    ST.Start()
    If firstRun = True Then
        levelNumber = levelNumber + 1
        g1.DrawString("Level " & levelNumber, New Font("DigifaceWide", 64, GraphicsUnit.Pixel), New SolidBrush(Color.FromArgb(191, R, G, B)), X, Y)
        g1.DrawRectangle(New Pen(Color.FromArgb(128, R, G, B)), 0, 0, 884, 24)
        g1.FillEllipse(New SolidBrush(Color.FromArgb(128, R, G, B)), playerX, playerY, 24, 24)
        g1.FillRectangle(New SolidBrush(Color.FromArgb(128, R, G, B)), 0, 0, 884, 24)
        g1.DrawString("Life: 5", New Font("DigifaceWide", 20, GraphicsUnit.Pixel), New SolidBrush(Color.FromArgb(191, R, G, B)), 2, 0)
        g1.DrawString("Score: 0", New Font("DigifaceWide", 20, GraphicsUnit.Pixel), New SolidBrush(Color.FromArgb(191, R, G, B)), 100, 0)
        firstRun = False
    End If
    '''''''''''''''''''''''''''''''Move player''''''''''''''''''''''''''''''
    If keysPressed.Contains(Keys.Left) Then
        If playerX > 0 Then
            playerX = playerX - 5
            g1.FillEllipse(New SolidBrush(Color.FromArgb(128, R, G, B)), playerX, playerY, 24, 24)
        End If
    ElseIf keysPressed.Contains(Keys.Up) Then
        If playerY > 24 Then
            playerY = playerY - 5
            g1.FillEllipse(New SolidBrush(Color.FromArgb(128, R, G, B)), playerX, playerY, 24, 24)
        End If
    ElseIf keysPressed.Contains(Keys.Right) Then
        If playerX < 860 Then
            playerX = playerX + 5
            g1.FillEllipse(New SolidBrush(Color.FromArgb(128, R, G, B)), playerX, playerY, 24, 24)
        End If
    ElseIf keysPressed.Contains(Keys.Down) Then
        If playerY < 388 Then
            playerY = playerY + 5
            g1.FillEllipse(New SolidBrush(Color.FromArgb(128, R, G, B)), playerX, playerY, 24, 24)
        End If
    End If
    '''''''''''''''''''''''''''''''Laser generation'''''''''''''''''''''''''''''''''''''
    If mouseDownB = True Then
        g1.DrawLine(New Pen(Color.FromArgb(102, R, G, B)), playerX + 12, playerY + 12, Control.MousePosition.X - Me.Bounds.X, Control.MousePosition.Y - Me.Bounds.Y)
    End If
    ''''''''''''''''''''''''''''''''Enemy generation - New level''''''''''''''''''''''''''''''''''''
    If newLevel = True Then
        levelNumber = levelNumber + 1
        Do While enemyCount < totaltEnemyCount
            Dim i As Integer = 0
            ReDim enemyID(0)
            Do While enemyID.Length <= totaltEnemyCount
                EX = RandomEnemyX.Next(0, 872)
                EY = RandomEnemyY.Next(24, 400)
                ES = RandomEnemySide.Next(0, 4)
                ReDim Preserve enemyID(i + 1)
                enemyID(i) = 1
                ReDim Preserve enemyX(i + 1)
                ReDim Preserve enemyY(i + 1)
                If ES = 0 Then 'Left side
                    enemyX(i) = 0
                    enemyY(i) = EY
                ElseIf ES = 1 Then 'Top side
                    enemyX(i) = EX
                    enemyY(i) = 24
                ElseIf ES = 2 Then 'Right side
                    enemyX(i) = 872
                    enemyY(i) = EY
                ElseIf ES = 3 Then 'Bottom side
                    enemyX(i) = EX
                    enemyY(i) = 400
                End If
                g1.FillEllipse(New SolidBrush(Color.FromArgb(128, Color.Red)), enemyX(i), enemyY(i), 12, 12)
                enemyCount = enemyID.Length
                enemyActive = enemyActive + 1
                i = i + 1
            Loop
        Loop
        newLevel = False
    End If
    ''''''''''''''''''''''''''''''''Enemy attacked''''''''''''''''''''''''''''''''''''''''
    Dim iii As Integer = 0
    Do While iii < totaltEnemyCount
        If (((Control.MousePosition.X - Me.Location.X) > enemyX(iii))) And ((Control.MousePosition.X - Me.Location.X) < (enemyX(iii) + 16)) And ((Control.MousePosition.Y - Me.Location.Y) > enemyY(iii)) And ((Control.MousePosition.Y - Me.Location.Y) < (enemyY(iii) + 16)) Then
            If mouseDownB = True Then
                enemyID(iii) = -1
                enemyX(iii) = -1
                enemyY(iii) = -1
                enemyActive = enemyActive - 1
                enemyCount = enemyCount - 1
            End If
        End If
        iii = iii + 1
    Loop
    ''''''''''''''''''''''''''''''''Move enemy'''''''''''''''''''''''''''''
    Dim ii As Integer = 0
    Do While enemyMoved < totaltEnemyCount
        If enemyActive < 1 Then
            enemyCount = 0
            newLevel = True
            If enemyCountIncrease = True Then
                totaltEnemyCount = totaltEnemyCount + 50
            ElseIf enemySpeedIncrease = True Then
                enemySpeed = enemySpeed + 1
            End If
            g1.DrawString("Level " & levelNumber, New Font("DigifaceWide", 64, GraphicsUnit.Pixel), New SolidBrush(Color.FromArgb(191, R, G, B)), X, Y)
            Exit Sub
        End If
        If enemyID(ii) = -1 Then
            GoTo skipMove
        End If
        If (enemyX(ii) - (playerX + 4)) < 0 Then 'Enemy on left
            enemyX(ii) = enemyX(ii) + enemySpeed
        End If
        If (enemyX(ii) - (playerX + 4)) > 0 Then 'Enemy on right
            enemyX(ii) = enemyX(ii) - enemySpeed
        End If
        If (enemyY(ii) - (playerY + 4)) < 0 Then 'Enemy above
            enemyY(ii) = enemyY(ii) + enemySpeed
        End If
        If (enemyY(ii) - (playerY + 4)) > 0 Then 'Enemy below
            enemyY(ii) = enemyY(ii) - enemySpeed
        End If
        g1.FillEllipse(New SolidBrush(Color.FromArgb(51, Color.Red)), enemyX(ii), enemyY(ii), 12, 12)
skipMove:
        enemyMoved = enemyMoved + 1
        ii = ii + 1
    Loop
    enemyMoved = 0
    ''''''''''''''''''''''QDSA - Quality Depentant Speed Adjustment''''''''''''''''''''
    ST.Stop()
        Dim elapTick As Decimal = ST.ElapsedTicks
        If elapTick < 5000 Then 'Slow down
            FPS = FPS + 1
            enemySpeedIncrease = False
            g1.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            enemyCountIncrease = True
        ElseIf elapTick > 5000 Then 'Speed up
            If FPS > 1 Then
                FPS = FPS - 1
            End If
            g1.SmoothingMode = Drawing2D.SmoothingMode.None
            enemyCountIncrease = False
            If enemySpeed < 4 Then
                enemySpeedIncrease = True
            Else
                enemySpeedIncrease = False
            End If
        End If
End Sub
End Class
4

1 に答える 1

4

WPF が古代のテクノロジと比較してどれほど強力で美しく、高速であるかを理解していただくために、必要なものと同様のサンプル WPF プロジェクトを作成しました。

次のようになります。

ここに画像の説明を入力

ここにすべてを掲載するにはコードが多すぎるため、完全なソースを含む RAR ファイルへのリンクを次に示します。

メインの UI XAML は次のとおりです。

<Window x:Class="SamsGameSample.MainWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SamsGameSample"
        Title="SamsGameSample"
        PreviewKeyDown="Window_PreviewKeyDown"
        PreviewKeyUp="Window_PreviewKeyUp"
        SizeChanged="Window_SizeChanged"
        WindowState="Maximized">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:Player}">
            <Ellipse Fill="Green" Stroke="Black" Height="{Binding Size.Height}" Width="{Binding Size.Width}"/>
        </DataTemplate>

        <DataTemplate DataType="{x:Type local:Enemy}">
            <Ellipse Fill="Red" Stroke="Black" Height="{Binding Size.Height}" Width="{Binding Size.Width}"/>
        </DataTemplate>
    </Window.Resources>

    <DockPanel>
        <DockPanel.Background>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0" Opacity=".6">
                <GradientStop Color="Blue" Offset="0"/>
                <GradientStop Color="Red" Offset=".5"/>
                <GradientStop Color="Green" Offset="1"/>
            </LinearGradientBrush>
        </DockPanel.Background>
        <StackPanel Orientation="Horizontal" Background="#70000000" DockPanel.Dock="Top">
            <TextBlock Text="{Binding Lives, StringFormat='Lives: {0}'}" Margin="10" Foreground="AliceBlue"/>
            <TextBlock Text="{Binding Score, StringFormat='Score: {0}'}" Margin="10" Foreground="AliceBlue"/>
        </StackPanel>
        <ItemsControl ItemsSource="{Binding GameObjects}" x:Name="GameArea">
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="Canvas.Left" Value="{Binding Location.X}"/>
                    <Setter Property="Canvas.Top" Value="{Binding Location.Y}"/>
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas IsItemsHost="True"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </DockPanel>
</Window>
  • 私のプロジェクトのコードの量 (およびそのクリーンさ) を、winforms でほとんどすべてを行うために必要な複数のハックと比較してください。
  • また、パフォーマンスと解像度の独立性を比較します。
于 2013-04-15T16:10:35.317 に答える