1,105,578 Community Members

Drawing Graphics On To A Form Problems

Member Avatar
dhatsah
Newbie Poster
21 posts since Oct 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 1 [?]
Skill Endorsements: 0 [?]
 
0
 

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.

You
This article has been dead for over three months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article