StarScrolling

BlitzMax Forums/BlitzMax Programming/StarScrolling

Here is a little StarScrolling demo

Graphics 800,600,32,60

Type star1
Field x,y
End Type

Global star1_list:TList=New TList

For Local i=1 To 200

Local st1:star1=New star1
star1_list.AddLast st1
st1.x=Rnd(0,800)
st1.y=Rnd(0,600)

Next

Type star2
Field x,y
End Type

Global star2_list:TList=New TList

For Local j=1 To 150

Local st2:star2=New star2
star2_list.AddLast st2
st2.x=Rnd(0,800)
st2.y=Rnd(0,600)

Next

Type star3
Field x,y
End Type

Global star3_list:TList=New TList

For Local k=1 To 100

Local st3:star3=New star3
star3_list.AddLast st3
st3.x=Rnd(0,800)
st3.y=Rnd(0,600)

Next

Local winkel
Local beam

While Not KeyHit(KEY_ESCAPE) 'Escape

Cls

For st1:star1=EachIn star1_list
SetColor 155,155,155
Plot st1.x,st1.y
st1.x:-1
If st1.x<0 Then
st1.x=800
EndIf
Next
For st2:star2=EachIn star2_list
SetColor 175,175,175
Plot st2.x,st2.y
st2.x:-2
If st2.x<0 Then
st2.x=800
EndIf
Next
For st3:star3=EachIn star3_list
SetColor 255,255,255
Plot st3.x,st3.y
st3.x:-3
If st3.x<0 Then
st3.x=800
EndIf
Next

Flip
   
Wend

Yay. Scrolling stars.

Here's a OO version I adapted from some B3D code of mine. It also lets you change scroll direction.


' ********************************************
' OO 2D Parallax Star Field Example
' Hold mouse button down to change direction
' ********************************************

Strict

Graphics 800,600,32

Local stars:StarField = StarField.create()
Local player:Ship = Ship.create()

' ---------
' mainloop
' ---------
While Not KeyHit(KEY_ESCAPE)
    Cls
    player.update()
    stars.update(player.x, player.y, player.z)

    Flip
    FlushMem   
Wend

End


' ===============
' Player Ship
' ===============
Type Ship

    Field x:Float,y:Float,z:Float = 1
    Field xspeed:Float = .05
    Field yspeed:Float = 0

    ' ----------------
    ' constructor
    ' ----------------
    Function create:Ship()
        Local s:Ship = New Ship
        Return s
    End Function

    ' -----------------------------------
    ' read user input and update position
    ' -----------------------------------
    Method update()

        If MouseDown(1)
            xspeed:+ (MouseX() - (GraphicsWidth()*.5)) *.00001
            yspeed:+ (MouseY() - (GraphicsHeight()*.5)) *.00001
        End If
        x:+xspeed
        y:+yspeed

    End Method

End Type


' =================
' Star Field Object
' =================
Type StarField

    Field starList:TList = CreateList()

    ' -----------
    ' constructor
    ' -----------
    Function create:StarField(amount=64)

        Local sf:StarField = New StarField

        For Local i = 1 To 8
            For Local s = 1 To amount
                Local x = Rnd(0,GraphicsWidth())
                Local y = Rnd(0,GraphicsHeight())
                Local z = Rnd( (i*8)-4,(i*8)+4 )
                Local intensity = (i * 32) - 1
                sf.starList.addLast(Star.create(x,y,z,intensity))
            Next
        Next

        Return sf

    End Function

    ' --------------------------------------------
    ' update all stars relative to player position 
    ' --------------------------------------------
    Method update(x:Float,y:Float,z:Float=1)
        x = Abs ( (x * z) + 10000)
        y = Abs ( (y * z) + 10000)
        For Local s:Star = EachIn starList
            s.render(x,y)
        Next

    End Method

End Type


' ======================
' Individual star object
' ======================
Type Star

    Field x:Float,y:Float,z:Float
    Field intensity

    ' -----------
    ' constructor
    ' -----------
    Function create:Star(x:Float,y:Float,z:Float,intensity)

        Local s:Star = New Star
            s.x = x
            s.y = y
            s.z = z
            s.intensity = intensity
        Return s

    End Function

    ' ----------------------------
    ' draw star relative to offset
    ' ----------------------------
    Method render(xoffset:Float,yoffset:Float)

        SetColor intensity,intensity,intensity
        Plot GraphicsWidth() - Abs ((x+xoffset*z) Mod GraphicsWidth()), GraphicsHeight() - Abs ((y+yoffset*z) Mod GraphicsHeight())

    End Method

End Type




/me wonders if plot is as fast as writepixelfast ? Seems to be fast enough anyway.

Ohh year this is cool?

Nice ,thanks for sharing.

Cool. Reminds me of the earlier days of the Amiga demo scene, scrolling starfields were all the rage and very often had 3 or so layers of parallax like in this demo.

I have no idea if plot is as fast as writepixelfast, since I don't know about blitz3d or blitzplus ... but plot isnt' as fast as it could be. The Plot command is just a higher-level wrapper for a peice of OpenGL or DirectX code.

e.g.

glBegin(GL_POINTS)
glVertex2i(100,100)
glEnd(GL_POINTS)

Would plot a single point in OpenGL. You could put more vertexes in between the begin and end and it'd be more efficient than having a set of those for every point. You also get rid of any overhead from jumping to the routine as you call the `Plot` function.

Here is one more starfield routin.

'Star Demo

Graphics 800,600,0

strnr:Int = 1500 'amount of stars
spinn:Int = 20 'amount of spinn. Turn off = 0

Local rad[strnr]
Local angle[strnr]
Local spd[strnr]

For i = 0 To strnr
	rad[i]=Rnd(280) + 20
	angle[i]=Rnd(65535)
	spd[i]=Rnd(5)+1
Next

Repeat
Cls 
For i=0 To strnr
	xp=400+(Sin((2*angle[i])*(Pi/360))*rad[i])
	yp=300+(Cos((2*angle[i])*(Pi/360))*rad[i])
	
	If xp < 0 Or xp > 800 Or yp < 0 Or yp > 600
		rad[i]=Rnd(40) + 20
		angle[i]=Rnd(65535)
		spd[i]=Rnd(5)+1
	EndIf
	
	rad[i] = rad[i] + spd[i]
	angle[i] = angle[i] + spinn
	
	If spd[i]=1 Then SetColor(100,100,100)
	If spd[i]=2 Then SetColor(130,130,130)
	If spd[i]=3 Then SetColor(170,170,170)
	If spd[i]=4 Then SetColor(210,210,210)
	If spd[i]=5 Then SetColor(255,255,255)
	Plot(xp,yp)
Next

Flip()
FlushMem()
Until KeyHit(KEY_ESCAPE)
End


Sveinung

Right on guys! Thanks for all the good code! Nice to have in my "code nuggets" folder of goodies. :)

Nice.

There can never be enough starfield routines imo ;-), so here's another B3D conversion...

' ---------------------------
' 3D Starfield demo
' ---------------------------

Strict
Graphics 800,600


Global stars:TList = CreateList()

' create a whole bunch of stars
init3DStars(2000)

Local speed:Float = .25

While Not KeyHit(KEY_ESCAPE)

    Cls
    ' update and display stars
    update3DStars(speed)
    If KeyDown(KEY_UP) speed:+.01
    If KeyDown(KEY_DOWN) speed:-.01

    Flip
    FlushMem

Wend

End

' =====================
' Star object
' =====================

Type Star3D

  Field xPos#, yPos#, zPos# ' 3d coords
  Field zVel#               ' velocity

  Method init()

      xPos = Rnd (-500, 500) 
      yPos = Rnd (-500, 500)
      zPos = Rnd (100, 1000) 
      zVel = Rnd (0.5, 5)

  End Method

End Type


' --------------------------------------
' initialise all stars 
' --------------------------------------

Function init3DStars(count=500)

  ' create star objects and stick them in a list
  For Local i = 0 To count
      Local s:Star3D = New Star3D
      s.init()
      stars.addLast(s)
  Next

End Function


' --------------------------------------
' update star positions & draw
' --------------------------------------

Function update3DStars(speed:Float)

  For Local s:Star3D = EachIn stars

    ' move star
    s.zPos = s.zPos - (s.zVel*speed)

    ' convert 3d into 2d coords
    Local x = ((s.xPos / s.zPos) * 100) + (GraphicsWidth() *.5)
    Local y = ((s.yPos / s.zPos) * 100) + (GraphicsHeight() *.5)
     
    ' And set star brightness based on 3d distance
    Local c = ( (255 - ((s.zPos * 255) *.001) ) * s.zVel ) *.2
 
    If (x < 0) Or (x > GraphicsWidth()) Or (y < 0) Or (y > GraphicsHeight() ) Or (s.zPos < 1) 
        s.init() ' reset star if it's gone out of sight
    Else
        SetColor c,c,c
        Plot x,y
    End If

  Next

End Function


very nice guys, awsome stuff

Hello.

What about:
graphics 800,600,0

type starstype
 field x
 field y
end type

global stars:starstype[50]

for i = 0 to 49
  stars[i] = new starstype
  stars[i].x = rand(800)
  stars[i].y = rand(400)
next

while not keydown(key_escape)
cls
for i = 0 to 49
 setcolor 192,192,192
 if rand(100)<5 then setcolor 255,255,255
 drawtext "*",stars[i].x, stars[i].y
next

setcolor 255,255,255
drawoval 256,128,64,64
flip
wend
end


Not tested but it should whup everyone else's routines I reckon.

Goodbye.

Looks like C64 Basic Style......

Hello.

I don't know what you could possibly mean!!! That's class, man!

[quote]There can never be enough starfield routines imo ;-)[\quote]

Ok, perhaps there can ;oD

Goodbye.

Thanks all.

Sveinung, your code doesn't run, out of bounds array error.

@DannyD
OOOPS...Sorry about that. Had no debugger on...
Should be like this
'Star Demo

Graphics 800,600,0

strnr:Int = 1500 'amount of stars
spinn:Int = 20 'amount of spinn. Turn off = 0

Local rad[strnr]
Local angle[strnr]
Local spd[strnr]

For i = 0 To strnr-1
	rad[i]=Rnd(280) + 20
	angle[i]=Rnd(65535)
	spd[i]=Rnd(5)+1
Next

Repeat
Cls 
For i=0 To strnr-1
	xp=400+(Sin((2*angle[i])*(Pi/360))*rad[i])
	yp=300+(Cos((2*angle[i])*(Pi/360))*rad[i])
	
	If xp < 0 Or xp > 800 Or yp < 0 Or yp > 600
		rad[i]=Rnd(40) + 20
		angle[i]=Rnd(65535)
		spd[i]=Rnd(5)+1
	EndIf
	
	rad[i] = rad[i] + spd[i]
	angle[i] = angle[i] + spinn
	
	If spd[i]=1 Then SetColor(100,100,100)
	If spd[i]=2 Then SetColor(130,130,130)
	If spd[i]=3 Then SetColor(170,170,170)
	If spd[i]=4 Then SetColor(210,210,210)
	If spd[i]=5 Then SetColor(255,255,255)
	Plot(xp,yp)
Next

Flip()
FlushMem()
Until KeyHit(KEY_ESCAPE)
End


Sveinung

Dude they all rule! Thanks guys!

Nice !