タイトルが示すように、私が作ったゲームについて質問しています。これをスピードアップしたいと思います。それはかなり一般的な質問です。だからここにあります:私はあなたが円であり、敵があなたに向かってくる正方形であるプログラムを作りました。スペースを押して撮影すると、矢印キーを使用して移動したり、ピックアップがあったりするなど、ヒットするたびにポイントを獲得できます。
ただし、次のように描画されるプレースホルダー円は使用しなくなりました。
e.Graphics.FillEllipse(Brushes.Orange,Player)
ここでのプレーヤーは、プレーヤーを定義する長方形です。そこで、グラフィックを置き換えるために、地球(プレーヤー)と宇宙船(敵)のJPEG画像をダウンロードしました。私はそれを使って描いた:
e.Graphics.DrawImage(ImgEarth,Player.X,Player.Y,Player.Width,Player.Height)
敵を描くための同じテクニック。
しかし、結果は非常に動きの遅いエイリアンです。それは遅いタイマーか何かではありませんが(私はそこに約2つ同時に動作しています)、FPSは貧弱です。それは私のシステムかもしれませんが、私がチェックしたとき、それは〜10MBのメモリしか必要としませんでした。VB.NETは、他のいくつかの言語(C ++、C#)ほど高速ではないため、ゲーム作成にはあまり適していませんが、FPSを犠牲にすることなくこれらを描画できる方法はありますか?
それが役に立ったら、私はGeForce8400MGSを搭載した1.66GHzプロセッサを持っています。(私の意見では、これと同じくらい単純なことにはかなりの能力があります)
編集:私はダブルバッファリングを使用しています。Me.DoubleBuffered = True
。ImgEarthは310x310の画像です。フォーム上では50x50として描画されるため、縮小してみます。これは良い点です。
さて、これがForm1.Paintの手順全体です。その後、すべて説明します。
e.Graphics.DrawImage(ImageEarth, Player.x,Player.y,Player.Width,Player.Height)
'Projectiles
Dim i As Integer = 0
Do
If Current_Projectile(i).IsEmpty = False Then e.Graphics.FillRectangle(Brushes.Red, Current_Projectile(i))
i += 1
Loop Until i = UBound(Current_Projectile)
i = 0
Do
If Advanced_Projectiles(i).IsEmpty = False Then e.Graphics.FillRectangle(Brushes.Green, Advanced_Projectiles(i))
i += 1
Loop Until i = UBound(Advanced_Projectiles)
i = 0
Do
If Pickups(i).IsEmpty = False Then
If PickUpType = 0 Then e.Graphics.FillEllipse(Brushes.Green, Pickups(i))
If PickUpType = 1 Then e.Graphics.FillEllipse(Brushes.Red, Pickups(i))
If PickUpType = 2 Then e.Graphics.FillEllipse(Brushes.Yellow, Pickups(i))
End If
i += 1
Loop Until i = UBound(Pickups)
'Objects
i = 0
Do
If Objects(i).IsEmpty = False Then e.Graphics.FillRectangle(Brushes.Blue, Objects(i))
i += 1
Loop Until i = UBound(Objects)
わかった。Current_Projectileは、プレーヤーによって発射された発射体(弾丸)に関するデータを格納する配列です。次に、高度な発射体は、前者のより「強力な」バージョンを発射することを除いて、同じです。Pickupsは、プレーヤーに向けて発射されているピックアップに関するデータを格納する配列です。その色は別のサブルーチンで決定されます。最後に、objects(i)は、発射された敵の長方形に関するデータを格納する配列です。
編集2:さて、あなたたちがTimer.Tick手順を必要とするかもしれないと考えました。
タイマーはTmr_Mainと呼ばれ、ゲーム中に発生するすべての約90%を処理します。ほとんどの作業を個々のサブルーチンに委任しますが、一部はタイマー自体で実行されます。これは、フォーム全体で2番目に洗練されたコードブロックです。ここにあります:
Dim i As Integer = 0
CollisionDetect()
CheckForDead()
If ReadyToReset = True Then ResetInt += 1
If ResetInt = 80 Then
ResetPowerUps()
ReadyToReset = False
ResetInt = 0
End If
'Projectiles(Bullets)
i = 0
Do
If Current_Projectile(i).IsEmpty = False Then
Current_Projectile(i).X += Projectile_Speed
If Current_Projectile(i).X > Me.Width Then
Current_Projectile(i) = Nothing
No_Of_Projectiles -= 1
End If
End If
i += 1
Loop Until i = UBound(Current_Projectile)
'Advanced Projectiles
i = 0
Do
If Advanced_Projectiles(i).IsEmpty = False Then
Advanced_Projectiles(i).X += AdvProjectile_Speed
End If
If Advanced_Projectiles(i).X >= Me.Width Then
Advanced_Projectiles(i) = Nothing
End If
i += 1
Loop Until i = UBound(Advanced_Projectiles)
'Pickups
GeneratePickups()
i = 0
Do
If Pickups(i).IsEmpty = False Then
Pickups(i).X -= Pickup_Speed
End If
If Pickups(i).X < 0 Then
Pickups(i) = Nothing
End If
i += 1
Loop Until i = UBound(Pickups)
LblScore.Text = "Score: " & Score
CheckForWin()
Me.Invalidate()
さて、もう一度、上からすべてを説明します。CollisionDetect()
ゲーム全体で何が何にヒットしたかを評価するためのロジックが含まれています。これには、プレーヤーとピックアップ、プレーヤーとオブジェクト、オブジェクトと発射物、オブジェクトと高度な発射物、オブジェクトとプレーヤーが含まれます。次に、ピックアップが使用されているかどうかを評価します。プレーヤーがピックアップをヒットすると、ブール値がtrueに設定されます。これは、このタイマーが繰り返されるたびに、変数に1つ追加されることを意味しますResetInt
。これが80、または4秒(50msタイマー)に達すると、ピックアップの効果がリセットされます。さらに、ブール値はfalseであるため、同じことは二度と行われません。
次に、フォーム上のすべてのオブジェクトを移動します。これらには、オブジェクト、発射物、ピックアップが含まれます。また、「パス」の終わりに到達したかどうかもチェックします(つまり、発射物が右に十分に移動した場合、ゲームから削除されます)。
最後に、プレイヤーが勝ったかどうかをチェックし、スコアについてプレイヤーに知らせるラベルを更新します。その後、再描画します。
アイデア?