Parallax Stars Demo

This is a little program I wrote to make a pseudo-3D star field effect. You can move around the field using the arrow keys.
All the star code is in a module, so you can draw a star field onto any object that supports the methods used.

Download the program here

Here's the source code:

This code goes on Form1

Dim ScrollSpeed As Integer

Private Sub Form_KeyDown(KeyCode As IntegerShift As Integer)
  'When a key is pressed clear the old stars,

  KillStars Form1

  'Then see which key was pressed, and move the stars accordingly
  Select Case KeyCode
    Case vbKeyUp
      'Up Arrow
      MoveStars Form1"Up"ScrollSpeed
    Case vbKeyDown
      'Down Arrow
      MoveStars Form1"Down"ScrollSpeed
    Case vbKeyLeft
      'Left Arrow
      MoveStars Form1"Left"ScrollSpeed
    Case vbKeyRight
      'Right Arrow
      MoveStars Form1"Right"ScrollSpeed
    Case vbKeySpace
      'Space bar
      MoveStars Form1"Forward"ScrollSpeed
    Case vbKeyControl
      'Ctrl key
      MoveStars Form1"ForwardM"ScrollSpeed
  End Select
  ' Then draw the new stars
  DrawStars Form1
End Sub

Private Sub Form_Load()
  'Before the form is shown
  'Set the number of stars in the field
  NumberOfStars = 100
  'Set a number to be the top parallax level (doesn't really matter what)
  Levels = 5
  'Initialise the star field on Form1

  InitialiseStarField Form1

  'Set the scrolling speed
  'This is the number of units the top parallax level moves per MoveStars cycle
  ScrollSpeed = 50
End Sub

Private Sub Form_MouseMove(Button As IntegerShift As IntegerX As SingleY As Single)
  'When you move the mouse, update global MousePos array with the new position
  'Used for "ForwardM" movement
  MousePos(0= X
  MousePos(1= Y
End Sub

Private Sub Form_Resize()
  'When the form is resized/maximised
  'Delete the old star field

  KillStars Form1
  'Reinitialise everything for new form size

  InitialiseStarField Form1

End Sub


This goes in Module1

'Dynamic array to hold stars
Dim Stars() As Single
'Public variables so they can be set from outside the module
Public NumberOfStars As Integer
Public Levels As Integer
Public MousePos(1As Single

'Initialises the star field on the object passed
Public Sub InitialiseStarField(TargetObject As Object)
  'Redimention stars array to have 3 (0-2) values for each star
  ReDim Stars(NumberOfStars2)
  'Set graphic attributes for the target object
  With TargetObject
    .BackColor = vbBlack
    .ForeColor = vbWhite
    .AutoRedraw = True
  End With
  'Populate stars array with stars
  For n = 0 To NumberOfStars
    'For every star in the array
    Randomize
    'Stars(n,0) is the parallax level of the star (0 - Levels)
    'Set random level
    Stars(n0= (Rnd * Levels)
    Randomize
    'Stars(n,1) is the X coordinate
    'Set to a random position inside the form (0 - Width of form)
    Stars(n1= (Rnd * Form1.ScaleWidth)
    Randomize
    'Stars(n,2) is the Y coordinate
    'Set to a random position inside the form (0 - Height of form)
    Stars(n2= (Rnd * Form1.ScaleHeight)

  Next n
  'Draw the star field
  DrawStars TargetObject
End Sub

'Moves stars. Is passed TargetObject for wrapping measurement.
Public Sub MoveStars(TargetObject As ObjectDirection As StringAmount As Integer)
  'Find out what direction to move the stars
  Select Case Direction
    Case "Right"
      'For each star
      For n = 0 To NumberOfStars
        'Star X coord = Star X coord + (Parallax level * Amount)
        'Results in higher parallax level moving more, therefore appearing closer
        Stars(n1= Stars(n1+ Stars(n0* Amount
        'If the X coord is more than the object width then wrap the star around to the other side of the object
        If Stars(n1> TargetObject.ScaleWidth Then Stars(n1= 0
      Next n
    Case "Left"
      'Same as Right, but the other way round
      For n = 1 To NumberOfStars
        Stars(n1= Stars(n1- Stars(n0* Amount
        If Stars(n1< 0 Then Stars(n1= TargetObject.ScaleWidth
      Next n
    Case "Up"
      'Same as Left/Right but with Y and object height
      For n = 1 To NumberOfStars
        Stars(n2= Stars(n2- Stars(n0* Amount
        If Stars(n2< 0 Then Stars(n2= TargetObject.ScaleHeight
      Next n
    Case "Down"
      For n = 1 To NumberOfStars
        Stars(n2= Stars(n2+ Stars(n0* Amount
        If Stars(n2> TargetObject.ScaleHeight Then Stars(n2= 0
      Next n
    Case "Forward"
      'Straight forward motion
      For n = 1 To NumberOfStars
        'The star moves further away form the X and Y centers of the object
        'the further away it is already, giving a sense of perspective and forward movement
        Stars(n1= Stars(n1+ (Stars(n1- TargetObject.ScaleWidth / 2/ 10
        Stars(n2= Stars(n2+ (Stars(n2- TargetObject.ScaleHeight / 2/ 10
        'If a star leaves the screen, put it back in a random position on the object
        If Stars(n1> TargetObject.ScaleWidth Or Stars(n1< 0 Then Stars(n1= Rnd * TargetObject.ScaleWidth
        If Stars(n2> TargetObject.ScaleHeight Or Stars(n2< 0 Then Stars(n2= Rnd * TargetObject.ScaleHeight
      Next n
    Case "ForwardM"
      'Forward motion, following the mouse
      For n = 1 To NumberOfStars
        'Same as "Forward", but uses the mouse position for reference
        'instead of the object center (see Form_MouseMove)
        Stars(n1= Stars(n1+ (Stars(n1- MousePos(0)) / 10
        Stars(n2= Stars(n2+ (Stars(n2- MousePos(1)) / 10
        If Stars(n1> TargetObject.ScaleWidth Or Stars(n1< 0 Then Stars(n1= Rnd * TargetObject.ScaleWidth
        If Stars(n2> TargetObject.ScaleHeight Or Stars(n2< 0 Then Stars(n2= Rnd * TargetObject.ScaleHeight
      Next n
  End Select
End Sub

Public Sub KillStars(TargetObject As Object)
  For n = 1 To NumberOfStars
    'For each star, draw it black, so it disappears
    'Must be called before MoveStars
    TargetObject.PSet (Stars(n1), Stars(n2)), vbBlack
  Next n
End Sub

Public Sub DrawStars(TargetObject As Object)
  For n = 1 To NumberOfStars
    'For each star, draw it white, so it appears.
    TargetObject.PSet (Stars(n1), Stars(n2)), vbWhite
  Next n
End Sub