Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: Shockwave on April 18, 2007

Title: 2D Starfield
Post by: Shockwave on April 18, 2007
This is one of the programs that Codeman wanted to see.
This is really simple, and just a 2D starfield, it is fully commented, a tutorial to accompany this will follow soon.

Code: [Select]
'
'             FREEBASIC 2D STARFIELD USING TINYPTC FOR CODEMAN
'                          Tutorial Coming Soon!
'
'         This program makes a very simple 5 layer parallax starfield
'
'
' Please use the extended version of Tinyptc by Rbraz when you use this listing
' it will run far too fast otherwise!!!!!!
'
'-------------------------------------------------------------------------------


'   Fixed Size Arrays, All Variables must be declared;

    OPTION STATIC
    OPTION EXPLICIT
   

'   Include the tinyptc library. Uncomment line for windowed mode.

  '  #DEFINE PTC_WIN
    #INCLUDE "TINYPTC.BI"   
   
'-------------------------------------------------------------------------------
'   Variable Definitions.
'-------------------------------------------------------------------------------
'   CONST Means Constant Value, cannot be changed in the program.
'   CONST is recognised by all parts of the program, ie. it is treated
'         as a global variable.
'   INTEGER Means a whole number with no fraction part, no decimal
'           point in other words

    CONST XRES AS INTEGER = 640:' Screen Width In Pixels.
    CONST YRES AS INTEGER = 480:' Screen Height In Pixels.
   

'   DIM SHARED means create a global variable as integer (whole number)
'              "BUFFER" IS A 1 DIMENSIONAL ARRAY OF (XRES * YRES) Elements.

    DIM SHARED AS INTEGER BUFFER ( XRES * YRES ):' The Screen Array.

'   This is how we define a variable;

    DIM SHARED AS INTEGER NUMBER_OF_STARS = 1000:' How many stars to have.
   
    DIM SHARED AS INTEGER SX(NUMBER_OF_STARS):' WILL STORE X POS
    DIM SHARED AS INTEGER SY(NUMBER_OF_STARS):' WILL STORE Y POS
    DIM SHARED AS INTEGER SS(NUMBER_OF_STARS):' WILL STORE SPEED
   
'-------------------------------------------------------------------------------
'   Subroutine Definitions.. We Need 2, One to set up the starfield
'   And one to draw / move it.
'-------------------------------------------------------------------------------   
   
    DECLARE SUB SET_STARS():' SET UP STARFIELD
    DECLARE SUB DO_STARS():'  MOVE / DRAW STARS ETC.
   
'   This is how we call a subroutine;
   
    SET_STARS():' Set Star Positions and speed.

'   Open The Screen;

    IF (PTC_OPEN("STARFIELD",XRES,YRES)=0) THEN
    END-1
    END IF

'
'   Main Loop;
'

WHILE (1)
   
    DO_STARS():' Do the starfield
    PTC_UPDATE@BUFFER(0):' Update Screen
    ERASE BUFFER:' Clear Screen
   
WEND
END

'
' Do The Starfield;
'
SUB DO_STARS()

'   PLEASE NOTE THE VARIABLE "SL"
'   ALTHOUGH THIS VARIABLE NAME IS THE SAME AS IN THE OTHER SUB, IT IS
'   A COMPLETELY SEPERATE VARIABLE, AS IT IS A LOCAL VARIABLE :-)
'   GENERALLY IT IS BAD PROGRAMMING PRACTICE TO DO WHAT I HAVE DONE HERE
'   YOU SHOULD GIVE THE LOOP A PREFIX LIKE DO_STARS_SL
'
    DIM AS INTEGER SL :' Used as a pointer in loop.
   
    FOR SL=1 TO NUMBER_OF_STARS
       
    SX(SL)=SX(SL)+SS(SL) : ' Move Star
   
    IF SX(SL) > XRES THEN SX(SL)=SX(SL)-XRES :' reset it if off screen
   
    IF SX(SL)>0 AND SX(SL)<XRES THEN:' Check if onscreen before drawing
   
    'Draw in the correct colour according to speed.
    IF SS(SL) =1 THEN BUFFER (SX(SL) + ( SY(SL) * XRES) ) = &H444444
    IF SS(SL) =2 THEN BUFFER (SX(SL) + ( SY(SL) * XRES) ) = &H777777
    IF SS(SL) =3 THEN BUFFER (SX(SL) + ( SY(SL) * XRES) ) = &HAAAAAA
    IF SS(SL) =4 THEN BUFFER (SX(SL) + ( SY(SL) * XRES) ) = &HCCCCCC
    IF SS(SL) =5 THEN BUFFER (SX(SL) + ( SY(SL) * XRES) ) = &HFFFFFF
   
    END IF   

    NEXT
   
END SUB

'-------------------------------------------------------------------------------
' THIS SIMPLY MAKES A RANDOM X AND Y LOCATION FOR EACH STAR
'-------------------------------------------------------------------------------
SUB SET_STARS()
   
'   Because this is being dimensioned inside a sub, the variable SL
'   is inaccessible by any other part of the program, it will only work in
'   THIS sub.

    DIM AS INTEGER SL:' Loop counter variable
   
    for SL = 1 TO NUMBER_OF_STARS
       
        SX(SL) = INT(RND(1) * XRES):' GENERATE AND STORE NUMBER BETWEEN 0 AND XRES
        SY(SL) = INT(RND(1) * YRES):' GENERATE AND STORE NUMBER BETWEEN 0 AND YRES
        SS(SL) = INT(RND(1) * 5) + 1:' RANDOM SPEED
    NEXT
   
END SUB
Title: Re: 2D Starfield
Post by: Paul on April 18, 2007
Nice work shocky, the coments are GOOD and really explains everything.

One thing though, i don't know if it would make it better to use reals instead of integers. then the starts could move at bigger variety of speeds.


 
Title: Re: 2D Starfield
Post by: benny! on April 18, 2007
Yup. Well done, Shocky!
Title: Re: 2D Starfield
Post by: p01 on April 18, 2007
Paul: If you want float position/speed you definitely need antialiasing. I suggest you to check Hugo Elias' site (http://freespace.virgin.net/hugo.elias/), and especially the Starfields (http://freespace.virgin.net/hugo.elias/graphics/x_stars.htm) and Wu particles (http://freespace.virgin.net/hugo.elias/graphics/x_wupixl.htm) pages.
Title: Re: 2D Starfield
Post by: CoDeMaN on April 18, 2007
Cheers Shockwave m8 .. Delivered as promised :)
Title: Re: 2D Starfield
Post by: Shockwave on April 19, 2007
Nice work shocky, the coments are GOOD and really explains everything.

One thing though, i don't know if it would make it better to use reals instead of integers. then the starts could move at bigger variety of speeds.

If I was making this intro for myself I certainly would do that, in fact I'd go further and make them proper 3D, even if they are scrolling horizontally, but this is deliberately as simple as possible as it's for absolute beginners in Freebasic.