I have 2 graphics I draw onto a form.
1 Graphic is a Randomly Generated Star Field, these stars move, and are updated every tick on a timer(50ms)
Once the stars have been drawn/updated a cockpit is overlayed onto this image to give the appearance of moving through space.
The problem I am having is that the stars are drawn onto the cockpit of the previous iteration of the loop giving the allusion that the stars are in the ship.
I have not a clue how to solve this and would love any advice. I have tried making it redraw the cockpit after it updates each star, this just makes updating the stars take too long.
One option is to kill each star once it reaches the edge of the cockpit's "window" I fear though that this would cause an equal problem with delay as it would have to check many conditons as the cockpit window is not even in shape.
A friend has suggested double buffering - I have only ever came across this as an option in VS to Enable or Disable.
Code for Generating, Updating, Deleting Stars
Imports System.Threading
Module Stars
Dim black As Brush = Brushes.Black
Dim rand As New Random()
'Public iSpeed As Integer = 1
' 0 1 2 3 4 5
Private stars(maxStars, 5) As Integer 'Tracks positon of stars {state, x, y, size, speed, direction}
Private oldStars(maxStars, 5) As Integer
Public Sub UpdateStars() 'ByRef g As Graphics
If Warping = True Then
WarpEffect()
ElseIf iSpeed <> 0 Then
DrawStars()
T2.Join()
T2 = New Thread(AddressOf CopyStars)
T2.Start()
'GenStar()
T2.Join()
T2 = New Thread(AddressOf GenStar)
T2.Start()
'MoveStars()
T3.Join()
T3 = New Thread(AddressOf MoveStars)
T3.Start()
ElseIf iSpeed = 0 Then
DrawStars()
End If
End Sub
Private Sub CopyStars()
For y = 0 To maxStars - 1
For u = 0 To 4
oldStars(y, u) = stars(y, u)
Next
Next
End Sub
Public Sub Turn()
'T1.Join()
'T1 = New Thread(AddressOf ResetView)
'T1.Start()
'EraseStars()
ResetView()
End Sub
Public Sub Warp()
'Call starfield reset
End Sub
Private Sub ResetView() 'Used when switching between sectors/turning
T2.Join()
T2 = New Thread(AddressOf VirtualUpdateStars)
T2.Start()
T2.Join()
End Sub
Private Sub VirtualUpdateStars()
Dim angle As Double
For count = 0 To maxStars - 1 Step 1 '"Discards" all stars
stars(count, 0) = 0
Next
For ticker = 0 To 1000
GenStar()
For count = 0 To maxStars - 1 Step 1
If stars(count, 0) = 1 Then
angle = stars(count, 5) * Math.PI / 180
stars(count, 1) = stars(count, 1) + (Math.Cos(angle) * stars(count, 4) * 3 * (iSpeed + 1))
stars(count, 2) = stars(count, 2) + (Math.Sin(angle) * stars(count, 4) * 3 * (iSpeed + 1))
End If
If stars(count, 1) > 1024 Or stars(count, 1) < 0 Or stars(count, 2) > 780 Or stars(count, 2) < 0 Then
stars(count, 0) = 0
End If
Next
Next
CopyStars()
End Sub
Private Sub GenStar() 'Call via T2
Dim count As Short = 0
While (stars(count, 0) = 1 And count < maxStars - 1) 'First empty slot in array
count += 1
End While
stars(count, 1) = xMid
stars(count, 2) = yMid
stars(count, 3) = rand.Next(4) + 1 'Size coefficient
stars(count, 4) = rand.Next(3) + 1 'Speed coefficient
stars(count, 5) = rand.Next(360) 'Angle in degrees, used instead of radians such that array could remain as integers
stars(count, 0) = 1 'star exists
'count = 0
End Sub
Private Sub MoveStars() 'Call via T2
Dim angle As Double
For count = 0 To maxStars - 1 Step 1
If stars(count, 0) = 1 Then
angle = stars(count, 5) * Math.PI / 180
stars(count, 1) = stars(count, 1) + (Math.Cos(angle) * stars(count, 4) * (iSpeed + 1) * iSpeed)
stars(count, 2) = stars(count, 2) + (Math.Sin(angle) * stars(count, 4) * (iSpeed + 1) * iSpeed)
End If
If stars(count, 1) > 1024 Or stars(count, 1) < 0 Or stars(count, 2) > 780 Or stars(count, 2) < 0 Then
stars(count, 0) = 0
End If
Next
End Sub
Private Sub DrawStars() 'Call via T2
Dim dist As Short
Dim size As Short
Dim radius As Short
Dim white As Brush = Brushes.White
Dim black As Brush = Brushes.Black
Dim g As Graphics = GameView.getG
' g.FillRectangle(black, 0, 0, GameView.Width, GameView.Height)
For count = 0 To maxStars - 1 Step 1
If oldStars(count, 0) = 1 Then
dist = Math.Sqrt((oldStars(count, 1) - xMid) ^ 2 + (oldStars(count, 2) - yMid) ^ 2)
size = oldStars(count, 3) * dist / 50
radius = size / 2
g.FillEllipse(black, oldStars(count, 1) - radius, oldStars(count, 2) - radius, size, size)
End If
If stars(count, 0) = 1 Then
dist = Math.Sqrt((stars(count, 1) - xMid) ^ 2 + (stars(count, 2) - yMid) ^ 2)
size = stars(count, 3) * dist / 50
radius = size / 2
g.FillEllipse(white, stars(count, 1) - radius, stars(count, 2) - radius, size, size)
End If
Next
drawUI()
End Sub
Private Sub WarpEffect()
Dim black As Brush = Brushes.Black
Dim p As Pen
GameView.getG().FillRectangle(black, 0, 0, GameView.Width, GameView.Height)
'Gen(Star)
T2.Join()
T2 = New Thread(AddressOf GenStar)
T2.Start()
'Move(stars)
T2.Join()
T2 = New Thread(AddressOf MoveStars)
T2.Start()
For count = 0 To maxStars - 1 Step 1
If stars(count, 0) = 1 Then
p = New Pen(Color.FromArgb(rand.Next(254), rand.Next(254), rand.Next(254), rand.Next(254)), rand.Next(5) + 5)
GameView.getG().DrawLine(p, xMid, yMid, stars(count, 1), stars(count, 2))
End If
Next
End Sub
End Module
Code for Drawing the UI
Public Sub drawUI()
g = GameView.CreateGraphics()
g.DrawImage(UI, 0, 0)
End Sub
Main Form Code
Imports System.Threading
Public Class MainGameView
Private Sub MainGameView_Load(sender As Object, e As EventArgs) Handles MyBase.Load
StartThreads()
Turn()
GameTick.Start()
End Sub
Public Function getG() ' function used to get the G for creating the graphics.
Return Me.CreateGraphics()
End Function
Private Sub GameTick_Tick(sender As Object, e As EventArgs) Handles GameTick.Tick
UpdateStars() ' has to be in the main thread.
End Sub
End Class
I am sorry that its alot of code - it seems quite an obnoxiously large amount of code, but I didn't want any potential helpers to think that I was wanting them to provide the whole answer, and I think it is always best to post some code.
Any help would be appreciated, especially in regards to if Double Buffering is the way to go.
Thank you in advance.