2016-05-02 2 views
1

私は惑星の軌道を示す重力シミュレーションを作成しています。各惑星は動くときに痕跡が残っていて、動的な配列に格納されています。しかし、トレールが長くなると、フレームレートが低下するため、毎回塗装イベントが描画される必要があります。配列が1000ドットを超えると最初のドットを削除したい。動的配列から特定のサイズになったときの最初の項目の削除

これはペイントイベントのコードである:私はタイマーでこのコードを追加してみました

trailDots += 1 
ReDim Preserve planet.trailX(trailDots) 
ReDim Preserve planet.trailY(trailDots) 
planet.trailX(trailDots) = planet.displayX 
planet.trailY(trailDots) = planet.displayY 

For drawTrail As Integer = 0 To planet.trailX.Count - 1 
    e.Graphics.DrawEllipse(trailcolour, planet.trailX(drawTrail), planet.trailY(drawTrail), 1, 1) 'Draw a pixel at the planet's current location 
Next 

そして、これは1秒間に60回ティックタイマーイベントでありますダニ:

If trailDots > 1000 Then 
    trailDots -= 1 
    ReDim Preserve planet.trailX(trailDots - 1) 
    ReDim Preserve planet.trailY(trailDots - 1) 
End If 

しかし、トレイルが1000ドットに達すると、シミュレーションは "IndexOutOfRan geetExceptionが処理されていませんでした。 "planet.trailX(trailDots)= planet.displayX"

これを修正するにはどうすればよいですか?

+1

[循環バッファ](https://en.wikipedia.org/wiki/Circular_buffer)を実装する方がよいと思います。これにより、アレイを再調整する必要がなくなります。 –

+0

配列を使用する代わりに、リストを使用するほうが良いかもしれません。こうすることで、最後に項目を追加することができます.1000ドットになると、項目0を削除します。別の変数を使用してドット数を追跡​​することで、リストの.countプロパティを使用できます。ドットを表示するには、For Eachループを使用してリストを繰り返します。簡単:) –

答えて

1

まず、あなたは最も古い要素ではなく最新の要素を削除すると思います。

とにかく、それがクラッシュする理由は、最初にtrailDotsを1つ減らしてから、trailDots - 1にリダイレクトして2つの要素で効果的に縮小するからです。これを修正するために以下の変更を行うことができます。

If trailDots > 1000 Then 
    trailDots -= 1 
    ReDim Preserve planet.trailX(trailDots) 
    ReDim Preserve planet.trailY(trailDots) 
End If 

また、trailDotsを0に初期化して次の変更を行うことをお勧めします。

planet.trailX(trailDots - 1) = planet.displayX 
planet.trailY(trailDots - 1) = planet.displayY 

しかし、Andew氏によると、この問題に循環バッファを使用する必要があります。

関連する問題