Simple starfield system and functions-in-type example.

Previous topic - Next topic

Hatonastick

Allows you to create a scrolling starfield in any direction and within a restricted area on the screen (bit like a window).  Created for my Time Pilot style game.  Thought I'd lost it, but just found it hiding in an archive.  Mostly useful as an example (not the best, see Mr TA Toads for that) of simple OOP-like usage of types.

Example:
Code (glbasic) Select
GLOBAL Stars AS Starfield
GLOBAL Dir = 90
GLOBAL sx, sy
GETSCREENSIZE sx, sy
Stars.Setup(sx, sy, 4, 8, 100)
Stars.On()

WHILE TRUE
  HandleKeys()
  Stars.Draw(0, 0, Dir)
  SHOWSCREEN
WEND
END

FUNCTION HandleKeys:
  // Left cursor key.
  IF KEY(203) = TRUE
    Dir = Dir + 4
  // Right cursor key.
  ELSEIF KEY(205) = TRUE
    Dir = Dir - 4
  ENDIF
  RollAngle(Dir)
ENDFUNCTION

FUNCTION RollAngle: BYREF a
  IF a < 0
    a = 360 + a
  ELSEIF a > 359
    a = a - 360
  ENDIF
ENDFUNCTION

// Star structure.
TYPE Star
  X
  Y
  Speed
  Color
ENDTYPE

// Define our starfield.  This isn't really necessary to be honest, I've just
// done it this way to make it possible for a game to have more than one
// starfield defined.
TYPE Starfield
  Active
  Width
  Height
  MinSpeed
  MaxSpeed
  Number
  Table[] AS Star

  // Create the initial starfield.
  // Where:
  // width, height = dimensions of the 'window' the starfield is being drawn in.
  // minspeed, maxspeed = the minimum and maximum speed stars can move at.
  // number = number of stars to draw.
  FUNCTION Setup: width, height, minspeed, maxspeed, number
    LOCAL i, c

    // Initialize starfield data.
    self.Width = width
    self.Height = height
    self.MinSpeed = minspeed
    self.MaxSpeed = maxspeed
    self.Number = number
    DIM self.Table[number]

    // Initialize the starfield array.
    FOREACH i IN self.Table[]
      // Randomize the stars starting position.
      i.X = RND(self.Width - 1)
      i.Y = RND(self.Height - 1)
      i.Speed = RND(self.MaxSpeed - self.MinSpeed) + self.MinSpeed
      // Grayscale the stars.
      c = 100 + RND(100)
      i.Color = RGB(c,c,c)
    NEXT
  ENDFUNCTION

  // Draws and generates a starfield 'window'.
  // Where:
  // x, y = the top left corner of the starfield 'window' that we will be
  //        drawing.
  // direction = the direction in which the starfield will be moving.
  FUNCTION Draw: x, y, direction
    LOCAL i, tx, ty

    // Only carry this out if the starfield is turned on.
    IF self.Active = FALSE THEN RETURN

    FOREACH i IN self.Table[]
      // Scroll starfield in given direction.
      i.X = i.X - (i.Speed * COS(direction))
      i.Y = i.Y + (i.Speed * SIN(direction))

      // Star is off the screen, relocate back to the beginning
      // and randomise its new position.
      IF i.X < 0
        i.X = self.Width - 1
        i.Y = RND(self.Height - 1)
      ELSEIF i.X >= self.Width
        i.X = 0
        i.Y = RND(self.Height - 1)
      ENDIF

      IF i.Y < 0
        i.Y = self.Height - 1
        i.X = RND(self.Width - 1)
      ELSEIF i.Y >= self.Height
        i.Y = 0
        i.X = RND(self.Width - 1)
      ENDIF

      // Draw the star, but only if it is on the screen.
      tx = x + i.X
      ty = y + i.Y
      IF tx > 0 AND tx < self.Width AND ty > 0 AND ty < self.Height
        SETPIXEL tx, ty, i.Color
      ENDIF
    NEXT
  ENDFUNCTION

  // Toggle starfield on.
  FUNCTION On:
    self.Active = TRUE
  ENDFUNCTION

  // Turn starfield off.
  FUNCTION Off:
    self.Active = FALSE
  ENDFUNCTION

  // Returns TRUE if starfield is on or FALSE if starfield is off.
  FUNCTION Status:
    RETURN self.Active
  ENDFUNCTION
ENDTYPE
Mat. 5: 14 - 16

Android: Toshiba Thrive Tablet (3.2), Samsung Galaxy Tab 2 (4.1.2).
Netbook: Samsung N150+ Netbook (Win 7 32-bit + Ubuntu 11.10).
Desktop: Intel i5 Desktop with NVIDIA GeForce GTX 460 (Win 8.1 64-bit).

fuzzy70

Very nice   :good:, I just made a starfield gen the other day with layers for simple parallax effect. Never thought of adding the functions into the type though so thats my next project  :D

Code (glbasic) Select
TYPE Tstar
x#
y#
layer%
ENDTYPE

CONSTANT maxlayers%=10
GLOBAL stars[] AS Tstar
GLOBAL starlayers%,starcolour%[]


FUNCTION createstars: layers%,staramount%,lowcolour%=50,highcolour%=255
LOCAL loop%,starloop%,colourscale
REDIM starcolour%[10]

starlayers=layers
colourscale=(highcolour-lowcolour)/layers

FOR loop=0 TO layers-1
starcolour%[loop]=RGB(highcolour-(loop*colourscale),highcolour-(loop*colourscale),highcolour-(loop*colourscale))
FOR starloop=1 TO staramount
addstars(RND(screenwidth),RND(screenheight),loop)
NEXT
NEXT
ENDFUNCTION

FUNCTION addstars: x%,y%,layer%
LOCAL additem AS Tstar
IF layer<maxlayers
additem.x = x
additem.y = y
additem.layer = layer
DIMPUSH stars[],additem
ENDIF
ENDFUNCTION

FUNCTION movestars: dx#,dy#

FOR loop%=0 TO BOUNDS(stars[],0)-1
stars[loop].x=stars[loop].x+(dx/stars[loop].layer)
stars[loop].y=stars[loop].y+(dy/stars[loop].layer)

IF stars[loop].x<0
stars[loop].x=stars[loop].x+screenwidth
stars[loop].y=RND(screenheight)
ENDIF
IF stars[loop].x>screenwidth
stars[loop].x=screenwidth-stars[loop].x
stars[loop].y=RND(screenheight)
ENDIF
IF stars[loop].y<0
stars[loop].y=stars[loop].y+screenheight
stars[loop].x=RND(screenwidth)
ENDIF
IF stars[loop].y>screenheight
stars[loop].y=screenheight-stars[loop].y
stars[loop].x=RND(screenwidth)
ENDIF

NEXT
ENDFUNCTION

FUNCTION showstars:
FOR loop%=0 TO BOUNDS(stars[],0)-1
SETPIXEL stars[loop].x,stars[loop].y,starcolour[stars[loop].layer]
NEXT
ENDFUNCTION


Lee
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)