2012-04-18 3 views
2

タイトルが示唆するように、スピードアップしたいゲームについて質問しています。それはかなり一般的な質問です。だからここにあります: 私はあなたが円であり、敵があなたに来ているスクエアであるプログラムを作った。スペースを押して撮影すると、打つたびにポイントを得ることができます。矢印キーを使って移動したり、ピックアップなどがあります。VB.NETで作られたゲームをスピードアップするには

このように描かれたプレースホルダサークルは使用しません。

e.Graphics.FillEllipse(Brushes.Orange,Player) 

ここにプレーヤを定義する四角形があります。だから、グラフィックを置き換えようとすると、地球(プレイヤー)vs宇宙船(敵)のJPEG画像をダウンロードしました。私はそれを使用して描いた:

e.Graphics.DrawImage(ImgEarth,Player.X,Player.Y,Player.Width,Player.Height) 

と同様の敵を描画するためのテクニック。

しかし、エイリアンの動きは非常に遅いです。それは遅いタイマーか何か(私はそこに同時に働いている約2を持っていますが)が悪いFPSです。それは私のシステムかもしれませんが、私がチェックしたときには〜10MBのメモリしかかかりませんでした。 VB.NETは他の言語(C++、C#)と同じくらい高速ではないので、ゲーム作成の選択肢ではありませんが、FPSを犠牲にすることなくこれらを描画できる方法はありますか?

もし私が助けてくれれば、私はGeForce 8400M GSを搭載した1.66GHzのプロセッサを持っています。 (これは私の意見ではこれほど簡単なものにかなり可能です)

EDIT:ダブルバッファリングを使用します。 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は、プレーヤーに向けて発射されているピックアップに関するデータを格納する配列です。その色は別のサブルーチンで決定されます。最後に、オブジェクト(i)は、あなたに発射される敵の四角形に関するデータを格納する配列です。

EDIT 2:さて、Timer.Tickプロシージャが必要な場合があります。

タイマーはTmr_Mainと呼ばれ、ゲーム中に起こっていることの約90%を処理します。ほとんどの作業を個々のサブルーチンに委譲しますが、タイマー自体で実行されるものもあります。これはフォーム全体で2番目に洗練されたコードブロックです。ここでは、次のとおりです。

薄暗い私は整数= 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に設定されます。これは、このタイマーの各反復が変数ResetIntに追加されることを意味します。これが80または4秒(50msタイマー)に達すると、ピックアップのエフェクトがリセットされます。さらに、ブール値はfalseであるため、同じことを繰り返すことはありません。

次に、フォーム上のすべてのオブジェクトを移動します。これらには、オブジェクト、投射物、ピックアップが含まれます。また、彼らは彼らの 'パス'の終わりに達しているかどうかをチェックします(つまり、発射体が十分に遠くにある場合、それはゲームから取り除かれます)。

最後に、プレイヤーが勝ったかどうかをチェックし、スコアをプレイヤーに知らせるラベルを更新します。次に、それが再描画されます。

アイデア?

+1

グラフィックスのレンダリングに使用されているテクノロジと同じように、言語についてあまり違いはありません(C#とVB.NETは.NET言語が似ているため同等です)。たとえば、VB.NETでXNA(ゲームを開発するためのプラットフォーム)用にコーディングすることができ、Windowsフォーム内のGDI +描画はゲーム用ではなくグラフィックスカードを利用しないため、ゲームはより速く実行されます。例。 –

+0

上記で指摘したように、XNAはより良い選択です。しかし、あなたの現在のアプリケーションを改善するために、私の考えは 'ImgEarth'を扱う方法にあるでしょう。あなたの代表的なラインの周りにもっとコードを含めることができますか?あなたの全体のOnPaintオーバーライド(またはあなたの図面に使用している他のメソッド)を追加する時点までは? –

+2

あなたのイメージはどれくらい大きいですか?あなたはそれをどれだけ大きく描いているのですか?スケーリングの問題かもしれません。画像がもっと大きければ、あらかじめ描画したいサイズにスケーリングしてみてください。それ以外の場合は、再描画するたびにスケーリングする必要があります。 – mafafu

答えて

3

いくつかのアイデアを試してみる...最低でも任意の非効率的な自動型変換から離れてご案内します

(1)を使用しOption Strict On

(2)Do ... Loop Until i = UBound(...)の代わりにFor i = 0 To UBound(...) - 1を使用してください(ループ中に配列に要素が追加または削除されることが実際にある場合を除きます)。 ForUBoundに一度だけコールし、Doはすべての繰り返しでそれを呼び出すでしょう。さらに良い点は、UBoundの代わりにLengthの配列メンバーを使用してみませんか?これらIf文のテストPickUpTypeについては

(3)、もし-のElseIfはしごで行く:すべての後に

If PickUpType = 0 Then 
    e.Graphics.FillEllipse(Brushes.Green, Pickups(i)) 
ElseIf PickUpType = 1 Then 
    e.Graphics.FillEllipse(Brushes.Red, Pickups(i)) 
ElseIf PickUpType = 2 Then 
    e.Graphics.FillEllipse(Brushes.Yellow, Pickups(i)) 
End If 

を、PickUpType = 0あれば、なぜ時間を無駄にPickUpType = 1PickUpType = 2と?

(4)Withhttp://msdn.microsoft.com/en-us/library/wc500chb(v=vs.100).aspx)の実験。代わりに:

If Advanced_Projectiles(i).IsEmpty = False Then 
    Advanced_Projectiles(i).X += AdvProjectile_Speed 
End If 

試してみてください。

With Advanced_Projectiles(i) 
    If Not .IsEmpty Then 
     .X += AdvProjectile_Speed 
    End If 
End With 

(5)あなたが(例えばUBound関数など)Microsoft.VisualBasic名前空間のうち何も(一定ではない)を使用している場合は、探してみてくださいフレームワークのより「標準的な」部分で同じことを達成する方法です。 Microsoft.VisualBasicには不要なレイヤーやVB6の追加機能があります。

1

ダブルバッファリングを使用する必要があります。ここでゲームのイベントなどに応じてペイントと描画をメモリ内のビットマップに実行します。次に、OnPaintでそのバックバッファの画面に対して1つのblitを実行します。

関連する問題