Space Orbs. Small screen saver.
#1
Here's a little screen saver showing pulsating orbs over a starry background with plasma clouds.  I was playing around some old code, turned it into something new. Tested and runs OK under Windows and Linux.

- Dav 

Code: (Select All)

'=============
'SpaceOrbs.bas
'=============
'Screensaver of Orbs pulsating in space
'Coded by Dav for QB64-PE, AUGUST/2023

RANDOMIZE TIMER

SCREEN _NEWIMAGE(1000, 640, 32)


'=== orb settings

orbs = 60 'number of orbs on screen
OrbSizeMin = 5 'smallest size an orb can get
OrbSizeMax = 60 'largest size an orb can get

DIM OrbX(orbs), OrbY(orbs), OrbSize(orbs), OrbGrowth(orbs)


'=== generate some random orb values

FOR i = 1 TO orbs
    OrbX(i) = RND * _WIDTH 'x pos
    OrbY(i) = RND * _HEIGHT 'y pos
    OrbSize(i) = OrbSizeMin + (RND * (OrbSizeMax - OrbSizeMin)) 'orb size
    OrbGrowth(i) = INT(RND * 2) 'way orb is changing, 0=shrinking, 1=growing
NEXT


'=== make a space background image

FOR i = 1 TO 100000
    PSET (RND * _WIDTH, RND * _HEIGHT), _RGBA(0, 0, RND * 255, RND * 225)
NEXT
FOR i = 1 TO 1000
    x = RND * _WIDTH: y = RND * _HEIGHT
    LINE (x, y)-(x + RND * 3, y + RND * 3), _RGBA(192, 192, 255, RND * 100), BF
NEXT


'=== grab screen image for repeated use

back& = _COPYIMAGE(_DISPLAY)


DO

    '=== place starry background first

    _PUTIMAGE (0, 0), back&


    '=== draw moving plasma curtain next

    t = TIMER
    FOR x = 0 TO _WIDTH STEP 3
        FOR y = 0 TO _HEIGHT STEP 3
            b = SIN(x / (_WIDTH / 2) + t + y / (_HEIGHT / 2))
            b = b * (SIN(1.1 * t) * (_HEIGHT / 2) - y + (_HEIGHT / 2))
            LINE (x, y)-STEP(2, 2), _RGBA(b / 3, 0, b, RND * 25), BF
        NEXT: t = t + .085
    NEXT


    '=== now process all the orbs

    FOR i = 1 TO orbs

        '=== draw orb on screen

        FOR y2 = OrbY(i) - OrbSize(i) TO OrbY(i) + OrbSize(i) STEP 3
            FOR x2 = OrbX(i) - OrbSize(i) TO OrbX(i) + OrbSize(i) STEP 3
                'make gradient plasma color
                IF SQR((x2 - OrbX(i)) ^ 2 + (y2 - OrbY(i)) ^ 2) <= OrbSize(i) THEN
                    clr = (OrbSize(i) - (SQR((x2 - OrbX(i)) * (x2 - OrbX(i)) + (y2 - OrbY(i)) * (y2 - OrbY(i))))) / OrbSize(i)
                    r = SIN(6.005 * t) * OrbSize(i) - y2 + OrbSize(i) + 255
                    g = SIN(3.001 * t) * OrbSize(i) - x2 + OrbSize(i) + 255
                    b = SIN(2.001 * x2 / OrbSize(i) + t + y2 / OrbSize(i)) * r + 255
                    LINE (x2, y2)-STEP(2, 2), _RGBA(clr * r, clr * g, clr * b, 5 + RND * 15), BF
                END IF
            NEXT
        NEXT

        '=== change orb values

        'if orb is shrinking, subtract from size, else add to it
        IF OrbGrowth(i) = 0 THEN OrbSize(i) = OrbSize(i) - 1 ELSE OrbSize(i) = OrbSize(i) + 1
        'if orb reaches maximum size, switch growth value to 0 to start shrinking now
        IF OrbSize(i) >= OrbSizeMax THEN OrbGrowth(i) = 0
        'if orb reaches minimum size, switch growth value to 1 to start growing now
        IF OrbSize(i) <= OrbSizeMin THEN OrbGrowth(i) = 1
        'creates the shakiness. randomly adjust x/y positions by +/-3 each
        IF INT(RND * 2) = 0 THEN OrbX(i) = OrbX(i) + 3 ELSE OrbX(i) = OrbX(i) - 3
        IF INT(RND * 2) = 0 THEN OrbY(i) = OrbY(i) + 3 ELSE OrbY(i) = OrbY(i) - 3

    NEXT

    _DISPLAY

    _LIMIT 15

LOOP UNTIL INKEY$ <> ""


Find my programs here in Dav's QB64 Corner
Reply
#2
Although I'm not that eager for this kind of stuff to be turned into screensavers...

Great work! It's making all the programmers of hundreds of raytracers blushing to match the grass!
Reply
#3
Mesmerizing. Cool!
Software and cathedrals are much the same — first we build them, then we pray.
QB64 Tutorial
Reply
#4
Nice job!  

Slowly scrolling the stars would create a parallax effect and would be a nice improvement.
Reply
#5
Thanks, ya'll for trying it.  Yeah, scrolling stars would be a nice touch.  Would have to change the alpha stuff to make it work.  Will play with that idea.

- Dav

Find my programs here in Dav's QB64 Corner
Reply
#6
I do not believe that I have seen anything like this... Either THIS example is very unique or it could be another proof that my ancient grey-matter is actually failing...  Regardless... it is indeed VERY cool....
May your journey be free of incident. Live long and prosper.
Reply
#7
Thanks, @johnno56.

Adding the scrolling stars image presented a problem.  Lost all the lazy-haze look to it because of the stars image draws.  Had to resort to a _PUTIMAGE screen blur trick at the end to bring blurriness back somewhat.  I prefer the old look, but moving stars does add another interest.   Here's the new one with moving star background.

- Dav

Code: (Select All)

'=============
'SpaceOrbs2.bas
'=============
'Screesaver of Orbs pulsating in space
'Coded by Dav for QB64-PE, AUGUST/2023

'v2 - added scrolling stars background
'  - orbs get new x/y position after shrinking away
'  - had to change alpha values of plasma cloud and orbs,
'    because of scrolling stars background.  It's different.
'  - Uses _PUTIMAGE screen trick to blur final _DISPLAY

Randomize Timer

Screen _NewImage(1000, 640, 32)


'=== orb settings

orbs = 60 'number of orbs on screen
OrbSizeMin = 5 'smallest size an orb can get
OrbSizeMax = 60 'largest size an orb can get

Dim OrbX(orbs), OrbY(orbs), OrbSize(orbs), OrbGrowth(orbs), OrbDir(orbs)


'=== generate some random orb values

For i = 1 To orbs
    OrbX(i) = Rnd * _Width 'x pos
    OrbY(i) = Rnd * _Height 'y pos
    OrbSize(i) = OrbSizeMin + (Rnd * (OrbSizeMax - OrbSizeMin)) 'orb size
    OrbGrowth(i) = Int(Rnd * 2) 'way orb is changing, 0=shrinking, 1=growing
    OrbDir(i) = Int(Rnd * 4) 'random direction orb can drift (4 different ways)
Next


'=== make a space background image

For i = 1 To 100000
    PSet (Rnd * _Width, Rnd * _Height), _RGBA(0, 0, Rnd * 255, Rnd * 225)
Next
For i = 1 To 1000
    x = Rnd * _Width: y = Rnd * _Height
    Line (x, y)-(x + Rnd * 3, y + Rnd * 3), _RGBA(192, 192, 255, Rnd * 175), BF
Next


'=== grab screen image for repeated use

back& = _CopyImage(_Display)

BackX = 0

Do

    '=== scroll starry background first

    _PutImage (BackX, 0)-(BackX + _Width, _Height), back&
    _PutImage (BackX - _Width, 0)-(BackX, _Height), back&
    BackX = BackX + 4: If BackX >= _Width Then BackX = 0


    '=== draw moving plasma curtain next

    t = Timer
    For x = 0 To _Width Step 3
        For y = 0 To _Height Step 3
            b = Sin(x / (_Width / 2) + t + y / (_Height / 2))
            b = b * (Sin(1.1 * t) * (_Height / 2) - y + (_Height / 2))
            Line (x, y)-Step(2, 2), _RGBA(b / 3, 0, b, 50), BF
        Next: t = t + .085
    Next


    '=== now process all the orbs

    For i = 1 To orbs

        '=== draw orb on screen

        For y2 = OrbY(i) - OrbSize(i) To OrbY(i) + OrbSize(i) Step 3
            For x2 = OrbX(i) - OrbSize(i) To OrbX(i) + OrbSize(i) Step 3
                'make gradient plasma color
                If Sqr((x2 - OrbX(i)) ^ 2 + (y2 - OrbY(i)) ^ 2) <= OrbSize(i) Then
                    clr = (OrbSize(i) - (Sqr((x2 - OrbX(i)) * (x2 - OrbX(i)) + (y2 - OrbY(i)) * (y2 - OrbY(i))))) / OrbSize(i)
                    r = Sin(6.005 * t) * OrbSize(i) - y2 + OrbSize(i) + 255
                    g = Sin(3.001 * t) * OrbSize(i) - x2 + OrbSize(i) + 255
                    b = Sin(2.001 * x2 / OrbSize(i) + t + y2 / OrbSize(i)) * r + 255
                    Line (x2, y2)-Step(2, 2), _RGBA(clr * r, clr * g, clr * b, 30 + Rnd * 25), BF
                End If
            Next
        Next

        '=== change orb values

        'if orb is shrinking, subtract from size, else add to it
        If OrbGrowth(i) = 0 Then OrbSize(i) = OrbSize(i) - 1 Else OrbSize(i) = OrbSize(i) + 1
        'if orb reaches maximum size, switch growth value to 0 to start shrinking now
        If OrbSize(i) >= OrbSizeMax Then OrbGrowth(i) = 0
        'if orb reaches minimum size, switch growth value to 1 to start growing now
        'and reset x/y pos
        If OrbSize(i) <= OrbSizeMin Then
            OrbGrowth(i) = 1
            OrbX(i) = Rnd * _Width
            OrbY(i) = Rnd * _Height
        End If
        'creates the shakiness. randomly adjust x/y positions by +/-3 each
        If Int(Rnd * 2) = 0 Then OrbX(i) = OrbX(i) + 3 Else OrbX(i) = OrbX(i) - 3
        If Int(Rnd * 2) = 0 Then OrbY(i) = OrbY(i) + 3 Else OrbY(i) = OrbY(i) - 3

        'drift orb in  1 of 4 directions we generated, and +x,-x,+y,-y to it.
        If OrbDir(i) = 0 Then OrbX(i) = OrbX(i) + 2 'drift right
        If OrbDir(i) = 1 Then OrbX(i) = OrbX(i) - 2 'drift left
        If OrbDir(i) = 2 Then OrbY(i) = OrbY(i) + 2 'drift down
        If OrbDir(i) = 3 Then OrbY(i) = OrbY(i) - 2 'drift up

        'below handles if ball goes off screen, let it dissapear completely
        If OrbX(i) > _Width + OrbSize(i) Then OrbX(i) = -OrbSize(i)
        If OrbX(i) < -OrbSize(i) Then OrbX(i) = _Width + OrbSize(i)
        If OrbY(i) > _Height + OrbSize(i) Then OrbY(i) = -OrbSize(i)
        If OrbY(i) < -OrbSize(i) Then OrbY(i) = _Height + OrbSize(i)

    Next

    '== screen blur trick to make it more misty looking

    tmpback& = _CopyImage(_Display)
    _SetAlpha 50, , tmpback&
    _PutImage (-1, 0), tmpback&: _PutImage (1, 0), tmpback&
    _PutImage (0, -1), tmpback&: _PutImage (0, 1), tmpback&
    _PutImage (-1, -1), tmpback&: _PutImage (1, -1), tmpback&
    _FreeImage tmpback&

    _Display

    _Limit 15

Loop Until InKey$ <> ""


Find my programs here in Dav's QB64 Corner
Reply
#8
Thumbs Up 
Yes I like this 2nd version Smile
b = b + ...
Reply
#9
QBJS version with accidental shooting star effect:



(This is a good example to save for testing future performance enhancements.)
Reply
#10
Wow, the qbjs version looks even better to me. Smile 

By the way @dbox, you may use any of my posted stuff for your qbjs code examples if you want.   qbjs is simply great.

- Dav

Find my programs here in Dav's QB64 Corner
Reply




Users browsing this thread: 5 Guest(s)