Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Bouncy "Screen Saver" Program
#1
Way back in the early '90s I was playing around with QuickBasic 2 - weren't we all? - I never even progressed to 4.5.  At that time I created a Screen Menu Program - didn't we all? - and as part of that I spent many a happy hour creating a screen saver.  This had a few variants - didn't we all do that? - one of which was "Bouncy".  This was a text smiley character (ASC 2) bouncing around in a grid.

I archive it here for historical reasons.  But coming back to it, I looked at the code and thought "what garbled unstructured mess".  Actually that's usually my coding methodology - just see how things pan out, add bits as seem attractive.  This code is obviously Screen 0 - obviously anybody with a scrap of sense (@Pete not in this Venn diagram section) wouldn't dream of using Screen 0 today, so whilst at it I produced a 32-bit graphics version.

The old code is not only messy (and gibberish in places), I couldn't fathom out parts, so started from scratch.  The PE version has similar behaviour to the old but is not an exact replica.  The only feature worthy of discussion is the real-time image manipulation.  Really, I should have spent time re-learning _MEM object processing, but the graphics are so low-level that I cheated and just used PSET.

A point of interest is the wave propagation in the fixed cross images.  A wave propagates from the top left (x,y origin) in a outward flowing circle.  The wave propagation equation is: h(r,t) = A*SIN((2π/λ)*(r-v*t)) where A is the amplitude, λ is the wavelength and v is the propagation velocity.

Unzip the file and extract the folder into your PEQB64 directory.  In the IDE make sure that you have the Run Option “Save EXE in source folder” checked.

.zip   Bouncy.zip (Size: 6.09 MB / Downloads: 10)

Bouncy.bas - original QB2 program
Code: (Select All)
' Bouncy Program - Free Standing from a 1980's QB2 Screen Menu Program on an MS-DOS Desktop

COMMON SHARED true%, false%, mat%(), matb%(), noCrosses%
true% = -1: false% = 0
DIM mat%(25, 80), matb%(8, 1)
RANDOMIZE (TIMER)
phil% = true% ': noCrosses% = 0
WHILE phil% = true%: CALL bouncy(phil%, CHR$(176)): WEND
END


SUB bouncy (stot%, s$) STATIC
    COLOR 8: CLS: CALL clearmat
    posn% = 9 + 2 * INT(RND * 35): noise% = false%: esc% = 500 + INT(RND * 2000)
    x1% = 4 + CINT(RND * 4): y1% = 10 + CINT(RND * 7): cr% = 1 + INT(RND * 6)
    xstep% = 10: ystep% = 9 + CINT(RND): fcol% = 9 + INT(RND * 7): vv% = 0
    cxrow% = INT(cr% / 7): x% = x1% + xstep% * cxrow% + 2: y% = y1% + 3 'cr% & cxrow% are complete jibberish
    z = (x% + y%) / 2: doit% = true%: k$ = "": counton% = true%: bounce% = 0
    xmove% = 1: ymove% = 1: blocky% = 0: h% = 7 + INT(RND * 6): h$ = ""
    st1% = true%: stc% = 0: brick% = 12 + INT(RND * 100): gloop% = 0
    IF INT(z) <> z THEN posn% = posn% + 1
    FOR n% = 1 TO 25
        mat%(n%, 1) = 1: mat%(n%, 80) = 1
        LOCATE n%, 1: PRINT CHR$(254);
        LOCATE n%, 80: PRINT CHR$(254);
    NEXT n%
    FOR n% = 2 TO 79
        mat%(25, n%) = 1: mat%(1, n%) = 1
    NEXT n%
    xt$ = STRING$(78, CHR$(254))
    LOCATE 25, 2: PRINT xt$;
    LOCATE 1, 2: PRINT xt$;
    FOR a% = 1 TO 12
        xrow% = INT(a% / 7): yrow% = a% - 6 * xrow% - 1
        IF a% <> h% THEN
            xb% = x1% + xstep% * xrow%: yb% = y1% + ystep% * yrow%
            CALL extras(xb%, yb%, 1): CALL cross(CHR$(197), xb%, yb%)
            h$ = h$ + CHR$(a% + 64)
        ELSE
            xa% = x1% + xstep% * xrow%: ya% = y1% + ystep% * yrow%
            hh$ = CHR$(a% + 64)
        END IF
    NEXT a%
    start! = TIMER
    WHILE doit% = true%
        IF (RND <= 0.4 AND noCrosses% >= 2 AND blocky% = 0) THEN CALL delBlock
        IF st1% = false% THEN
            pp% = 1 + INT(RND * 11): h% = ASC(MID$(h$, pp%, 1)) - 64
            MID$(h$, pp%) = hh$: hh$ = CHR$(h% + 64)
            xrow% = INT(h% / 7): yrow% = h% - 6 * xrow% - 1
            xa% = x1% + xstep% * xrow%: ya% = y1% + ystep% * yrow%
            CALL extras(xa%, ya%, 0)
            CALL cross(" ", xa%, ya%)
            st1% = true%: stc% = 0: brick% = 12 + INT(RND * 100)
        ELSEIF stc% = brick% THEN
            counton% = true%
            FOR i% = 2 TO 3: FOR j% = 1 TO 6
                    IF mat%(xa% + i% - 1, ya% + j% - 1) = 1 THEN counton% = false%
            NEXT j%: NEXT i%
            FOR j% = 3 TO 4: FOR i% = 1 TO 4 STEP 3
                    IF mat%(xa% + i% - 1, ya% + j% - 1) = 1 THEN counton% = false%
            NEXT i%: NEXT j%
            IF counton% = true% THEN
                COLOR 8: CALL cross(CHR$(197), xa%, ya%): st1% = false%
                CALL extras(xa%, ya%, 1): stc% = 0
            END IF
        ELSE
            stc% = stc% + 1
        END IF
        IF bounce% <> 0 THEN
            LOCATE x%, y%: PRINT " ";
            mat%(x%, y%) = 0
        END IF
        IF mat%(x% + xmove%, y% + ymove%) = 0 THEN
            'moveok% = true%
        ELSEIF (x% + xmove% = 1) AND mat%(x% - xmove%, y% + ymove%) = 0 THEN
            xmove% = -1 * xmove%
            IF noise% = true% THEN SOUND 6000, 0.05
        ELSEIF mat%(x% + xmove%, y% - ymove%) = 0 THEN
            ymove% = -1 * ymove%
            IF noise% = true% THEN SOUND 6000, 0.05
        ELSEIF mat%(x% - xmove%, y% + ymove%) = 0 THEN
            xmove% = -1 * xmove%
            IF noise% = true% THEN SOUND 6000, 0.05
        ELSEIF mat%(x% - xmove%, y% - ymove%) = 0 THEN
            xmove% = -1 * xmove%: ymove% = -1 * ymove%
            IF noise% = true% THEN SOUND 6000, 0.05
        ELSE
            doit% = false%: gloop% = 5
            IF x% > 19 THEN x% = x% - 3
            IF y% > 57 THEN y% = y% - 22
            CALL byebye(x%, y%)
        END IF
        IF doit% = true% THEN
            bounce% = bounce% + 1: blocky% = blocky% + 1
            IF blocky% = 7 THEN blocky% = 0
            x% = x% + xmove%: y% = y% + ymove%: mat%(x%, y%) = 1
            COLOR fcol%: LOCATE x%, y%: PRINT CHR$(2);
            IF (RND < 0.45 AND noCrosses% <= 7 AND blocky% = 0) THEN
                vv% = vv% + 1: IF vv% = 8 THEN vv% = 1
                COLOR vv%: CALL newBlock(s$)
            END IF
            WHILE doit% = true% AND TIMER < start! + 0.03 '52
                k$ = INKEY$
                IF k$ <> "" THEN
                    doit% = false%
                    IF ASC(k$) <> 0 THEN
                        stot% = false%
                    ELSEIF ASC(RIGHT$(k$, 1)) = 68 THEN
                        doit% = true%
                        IF noise% = true% THEN
                            noise% = false%
                        ELSE
                            noise% = true%
                        END IF
                    ELSEIF ASC(RIGHT$(k$, 1)) <> 64 THEN
                        stot% = false%
                    END IF
                END IF
            WEND
            start! = TIMER
            IF bounce% = 18000 THEN
                doit% = false%
            ELSEIF bounce% = esc% THEN
                mat%(1, posn%) = 0: COLOR 8
                LOCATE 1, posn% - 7: PRINT "ESCAPE" + CHR$(26) + " ";
            END IF
            IF x% = 1 THEN
                IF y% > 59 THEN y% = 59
                doit% = false%: gloop% = 3
                CALL byebye(2, y%)
            END IF
        END IF
    WEND
    mat%(x%, y%) = 0
    FOR a% = 1 TO 12
        xrow% = INT(a% / 7): yrow% = a% - 6 * xrow% - 1
        xb% = x1% + xstep% * xrow%: yb% = y1% + ystep% * yrow%
        CALL extras(xb%, yb%, 0)
    NEXT a%
    WHILE (TIMER < start! + 2 + gloop%) AND stot% = true%
        k$ = INKEY$: IF k$ <> "" THEN stot% = false%
    WEND
    COLOR 7, 0: CLS: CALL clearmat
END SUB


SUB byebye (topRow%, leftCol%) STATIC
    COLOR 23
    l1$ = CHR$(201) + STRING$(18, 205) + CHR$(187)
    l2$ = CHR$(186) + "    Bye-bye !!    " + CHR$(186)
    l3$ = CHR$(200) + STRING$(18, 205) + CHR$(188)
    LOCATE topRow%, leftCol%: PRINT l1$;
    LOCATE topRow% + 1, leftCol%: PRINT l2$;
    LOCATE topRow% + 2, leftCol%: PRINT l3$;
    'FOR n% = 1 TO 2: BEEP: NEXT n%
END SUB


SUB extras (n%, m%, apollo%) STATIC
    FOR i% = n% + 1 TO n% + 2
        FOR b% = m% TO m% + 5
            mat%(i%, b%) = apollo%
        NEXT b%
    NEXT i%
    FOR j% = m% + 2 TO m% + 3
        mat%(n%, j%) = apollo%: mat%(n% + 3, j%) = apollo%
    NEXT j%
END SUB


SUB clearmat STATIC
    noCrosses% = 0
    FOR a% = 1 TO 8: CALL matwrite(a%, 0): NEXT a%
END SUB


SUB matwrite (n%, zeus%) STATIC
    FOR i% = matb%(n%, 0) + 1 TO matb%(n%, 0) + 2
        FOR b% = matb%(n%, 1) TO matb%(n%, 1) + 5
            mat%(i%, b%) = zeus%
        NEXT b%
    NEXT i%
    FOR j% = matb%(n%, 1) + 2 TO matb%(n%, 1) + 3
        mat%(matb%(n%, 0), j%) = zeus%: mat%(matb%(n%, 0) + 3, j%) = zeus%
    NEXT j%
END SUB


SUB newBlock (ss$) STATIC
    x0% = 2 + INT(20 * RND): y0% = 2 + INT(73 * RND)
    touch% = true% 'check if overlap on existing cross
    WHILE touch% = true%
        touch% = false%
        FOR i% = 2 TO 3: FOR j% = 1 TO 6 'STEP 5
                IF mat%(x0% + i% - 1, y0% + j% - 1) = 1 THEN touch% = true%
        NEXT j%: NEXT i%
        FOR j% = 3 TO 4: FOR i% = 1 TO 4 STEP 3
                IF mat%(x0% + i% - 1, y0% + j% - 1) = 1 THEN touch% = true%
        NEXT i%: NEXT j%
        IF touch% = true% THEN
            x0% = 2 + INT(20 * RND): y0% = 2 + INT(73 * RND)
        END IF
    WEND
    CALL cross(ss$, x0%, y0%)
    noCrosses% = noCrosses% + 1
    matb%(noCrosses%, 1) = y0%: matb%(noCrosses%, 0) = x0%
    CALL matwrite(noCrosses%, 1)
END SUB


SUB delBlock STATIC
    CALL cross(" ", matb%(1, 0), matb%(1, 1))
    noCrosses% = noCrosses% - 1: CALL matwrite(1, 0)
    IF noCrosses% >= 1 THEN
        FOR n% = 1 TO noCrosses%
            matb%(n%, 1) = matb%(n% + 1, 1): matb%(n%, 0) = matb%(n% + 1, 0)
        NEXT n%
    END IF
END SUB


SUB cross (s$, i%, j%) STATIC
    LOCATE i%, j% + 2: PRINT STRING$(2, s$);: LOCATE i% + 1, j%: PRINT STRING$(6, s$);
    LOCATE i% + 2, j%: PRINT STRING$(6, s$);: LOCATE i% + 3, j% + 2: PRINT STRING$(2, s$);
END SUB
   


Bouncy PE.bas - Present version
Code: (Select All)
' Bouncy Program :- 32-bit screen version by Magdha 2026-01-08
' Adapted from QB2 version with different bounce and timing conditions
' At least this code should be easier to understand
' X- horizontal, Y- Vertical (downwards), (0,0) top left

CONST False = 0, True = NOT False
CONST Lambda! = 20, PropVelocity! = 0.09, Amplitude%% = 80
DIM Mat%%(80, 25), MatCross%%(6, 4), MatCrosses%%(22, 1), Velocities%%(4, 1), FreeCrossImages&(10, 1)

_TITLE "Bouncy PE"

RANDOMIZE (TIMER)

RESTORE ReadData
'Define the structure of the crosses
FOR J%% = 1 TO 4
    FOR I%% = 1 TO 6
        READ Dum%%
        IF Dum%% <> 0 THEN MatCross%%(I%%, J%%) = True
    NEXT I%%
NEXT J%%
'Define the velocity vector (vx & vy)
FOR N%% = 1 TO 4
    READ Velocities%%(N%%, 0)
    READ Velocities%%(N%%, 1)
NEXT N%%

'Initial Conditons
DoBounce%% = True
EscapePosition%% = 9 + 2 * INT(RND * 35)
EscapeCount% = 0
CanEscape%% = False
IsTrapped%% = False

DoNoises%% = False '!!! TBF

EscapeTime% = 9000 + INT(RND * 5000)
WaveCount% = 0

SayByeByeSooty%% = False
k$ = ""

Vector%% = 1 'Movement of Bouncy
FixedCross%% = 0
BCount%% = 0
FCount%% = 0
NoFreeCrosses%% = 0


Y1%% = 4 + CINT(RND * 4) 'Static crosses
X1%% = 10 + CINT(RND * 7)
Ystep%% = 10
Xstep%% = 9 + CINT(RND)
FOR N%% = 11 TO 16
    MatCrosses%%(N%%, 0) = X1%% + (N%% - 11) * Xstep%%
    MatCrosses%%(N%%, 1) = Y1%%
NEXT N%%
FOR N%% = 17 TO 22
    MatCrosses%%(N%%, 0) = X1%% + (N%% - 17) * Xstep%%
    MatCrosses%%(N%%, 1) = Y1%% + Ystep%%
NEXT N%%

BounceY%% = Y1%% + 3 + Ystep%% * INT(RND * 2)
BounceX%% = X1%% + 4 + Xstep%% * INT(RND * 6)
PosnX% = 12 * BounceX%%
PosnY% = 21 * BounceY%%
'Define Initial Bouncy Position Occupied
Mat%%(BounceX%%, BounceY%%) = True
'Define Border Cells Occupied
FOR J%% = 0 TO 25
    Mat%%(0, J%%) = True
    Mat%%(79, J%%) = True
NEXT J%%
FOR I%% = 0 TO 80
    Mat%%(I%%, 24) = True
    Mat%%(I%%, 0) = True
NEXT I%%

'Add Fixed Crosses to grid
FOR N%% = 11 TO 22
    FOR I%% = 1 TO 6
        FOR J%% = 1 TO 4
            IF MatCross%%(I%%, J%%) THEN Mat%%(MatCrosses%%(N%%, 0) + I%% - 1, MatCrosses%%(N%%, 1) + J%% - 1) = True
        NEXT J%%
    NEXT I%%
NEXT N%%

'Images - All Hardware
TempImage& = _NEWIMAGE(72, 84, 32)
_DEST TempImage&
LINE (24, 0)-(48, 83), _RGB32(255, 0, 0), BF
LINE (0, 21)-(71, 62), _RGB32(255, 0, 0), BF
FixedCrossImage& = MakeHardware&(TempImage&)
TempImage& = _LOADIMAGE("Smiley2.jpg", 32)
TempImage1& = _NEWIMAGE(12, 21, 32)
_DEST TempImage1&
_PUTIMAGE , TempImage&
Smiley& = MakeHardware&(TempImage1&)
_FREEIMAGE TempImage&
TempImage& = _NEWIMAGE(500, 400, 32)
_DEST TempImage&
_FONT _LOADFONT("cyberbit.ttf", 60, "BOLD")
COLOR _RGB32(255, 255, 255), _RGB32(0, 0, 150)
CLS
LINE (0, 0)-(499, 399), _RGB32(255, 215, 0), B
LINE (1, 1)-(498, 398), _RGB32(255, 215, 0), B
LINE (3, 3)-(496, 396), _RGB32(255, 215, 0), B
LINE (4, 4)-(495, 395), _RGB32(255, 215, 0), B
_PRINTSTRING (100, 100), "Bouncy Says"
_PRINTSTRING (100, 200), "  Bye-bye"
Cheerio& = MakeHardware&(TempImage&)
TempImage& = _NEWIMAGE(960, 525, 32)
_DEST TempImage&
COLOR _RGB32(192, 192, 220), _RGB32(0, 65, 0)
CLS
'LINE (12, 0)-(947, 20), , BF
LINE (0, 504)-(959, 524), , BF
LINE (0, 0)-(11, 524), , BF
LINE (948, 0)-(959, 524), , BF
Background& = MakeHardware&(TempImage&)
TempImage& = _NEWIMAGE(936, 21, 32)
_DEST TempImage&
COLOR _RGB32(192, 192, 220), _RGB32(0, 65, 0)
CLS
LINE (0, 0)-(935, 20), , BF
TopLine& = MakeHardware&(TempImage&)
TempImage& = _NEWIMAGE(936, 21, 32)
_DEST TempImage&
COLOR _RGB32(255, 255, 255), _RGBA32(0, 0, 0, 0)
_PRINTSTRING (435, 3), CHR$(27) + " Escape " + CHR$(26)
FOR H% = 3 TO 18 STEP 5
    FOR G% = 5 TO 430 STEP 5
        PSET (G%, H%)
    NEXT G%
    FOR G% = 519 TO 929 STEP 5
        PSET (G%, H%)
    NEXT G%
NEXT H%
EscapeLine& = MakeHardware&(TempImage&)

'Screen (hardware images only)
SCREEN _NEWIMAGE(960, 525, 32)
_DEST 0
_DISPLAYORDER _HARDWARE ', _SOFTWARE
_SCREENMOVE 50, 70

AtStart! = TIMER
WHILE DoBounce%%
    _LIMIT 60

    'Display Images
    'Background
    _PUTIMAGE (0, 0), Background&
    'Fixed Crosses
    FOR N%% = 11 TO 22
        IF N%% <> FixedCross%% THEN
            _FREEIMAGE FixedCrossImage&
            TempImage& = _NEWIMAGE(72, 84, 32)
            _DEST TempImage&
            FOR I%% = 0 TO 71
                FOR J%% = 0 TO 83
                    IF (I%% >= 24 AND I%% <= 48 AND J%% >= 0 AND J%% <= 83) OR (I%% >= 0 AND I%% <= 71 AND J%% >= 21 AND J%% <= 62) THEN
                        Xcross% = MatCrosses%%(N%%, 0) * 12 + I%%
                        YCross% = MatCrosses%%(N%%, 1) * 21 + J%%
                        Rad! = SQR(Xcross% * Xcross% + YCross% * YCross%)
                        WaveHeight~%% = CINT(Amplitude%% * SIN((2 * _PI / Lambda!) * (Rad! - PropVelocity! * WaveCount%))) + 1.5 * Amplitude%% 'Always positive
                        COLOR _RGB32(WaveHeight~%%, 0.5 * WaveHeight~%%, 0.5 * WaveHeight~%%)
                        PSET (I%%, J%%)
                    END IF
                NEXT J%%
            NEXT I%%
            FixedCrossImage& = MakeHardware&(TempImage&)
            _PUTIMAGE (MatCrosses%%(N%%, 0) * 12, MatCrosses%%(N%%, 1) * 21), FixedCrossImage&
        END IF
    NEXT N%%
    'Free Crosses
    IF NoFreeCrosses%% > 0 THEN
        FOR N%% = 1 TO NoFreeCrosses%%
            _PUTIMAGE (MatCrosses%%(N%%, 0) * 12, MatCrosses%%(N%%, 1) * 21), FreeCrossImages&(N%%, 1)
        NEXT N%%
    END IF
    'Escape Label
    IF CanEscape%% THEN
        _PUTIMAGE (12, 0), EscapeLine&
    ELSE
        _PUTIMAGE (12, 0), TopLine&
    END IF
    'Bouncy
    _PUTIMAGE (PosnX%, PosnY%), Smiley&
    'Completion Banner
    IF SayByeByeSooty%% THEN
        ToEnd% = ToEnd% + 1
        _PUTIMAGE (230, 62), Cheerio&
        IF ToEnd% = 300 THEN DoBounce%% = False
    END IF
    _DISPLAY

    'Timings Counts
    'Wave Propagation and Time Limit
    WaveCount% = WaveCount% + 1
    IF WaveCount% = 16000 THEN SayByeByeSooty%% = True
    'The Speed which Bouncy moves
    BCount%% = BCount%% + 1
    IF BCount%% = 8 THEN BCount%% = 0
    'Count to when Bouncy can escape at the top
    IF NOT CanEscape%% THEN
        EscapeCount% = EscapeCount% + 1
        IF EscapeCount% = EscapeTime% THEN
            FOR N%% = 1 TO 36
                Mat%%(N%%, 0) = False
            NEXT N%%
            FOR N%% = 44 TO 78
                Mat%%(N%%, 0) = False
            NEXT N%%
            CanEscape%% = True
        END IF
    END IF

    IF BounceY%% = 0 THEN
        'Bouncy Escapes and then program will terminate after a pause
        SayByeByeSooty%% = True
    ELSE
        'Crosses Positions, Bouncy Position & Movement
        IF BCount%% = 0 THEN
            'Find if Bouncy can move and in which direction
            IF IsTrapped%% THEN
                'If Bouncy is trapped, wait until a path is clear
                Vector%% = 1
                WHILE Vector%% <= 4 AND IsTrapped%%
                    IF NOT Mat%%(BounceX%% + Velocities%%(Vector%%, 0), BounceY%% + Velocities%%(Vector%%, 1)) THEN
                        IsTrapped%% = False
                        Mat%%(BounceX%%, BounceY%%) = False
                        BounceX%% = BounceX%% + Velocities%%(Vector%%, 0)
                        BounceY%% = BounceY%% + Velocities%%(Vector%%, 1)
                        PosnX% = 12 * BounceX%%
                        PosnY% = 21 * BounceY%%
                        Mat%%(BounceX%%, BounceY%%) = True
                    ELSE
                        Vector%% = Vector%% + 1
                    END IF
                WEND
            ELSE
                'Look for possible movements
                PossMoves%% = 0
                FOR N%% = 4 TO 1 STEP -1
                    IF NOT Mat%%(BounceX%% + Velocities%%(N%%, 0), BounceY%% + Velocities%%(N%%, 1)) THEN
                        PossMoves%% = PossMoves%% + 1
                        PossVector%% = N%%
                    END IF
                NEXT N%%
                IF NOT Mat%%(BounceX%% + Velocities%%(Vector%%, 0), BounceY%% + Velocities%%(Vector%%, 1)) THEN
                    'Nothing in the way - Just Carry On
                    PossMoves%% = 4 'Just a marker
                ELSEIF PossMoves%% = 0 THEN
                    'Can't move
                    IsTrapped%% = True
                    Vector%% = 0
                ELSEIF PossMoves%% = 1 THEN
                    'Only 1 possible move
                    Vector%% = PossVector%%
                ELSE
                    '2 or 3 possible moves
                    'Look for reflection backwards and reflection bounce
                    IF NOT Mat%%(BounceX%% - Velocities%%(Vector%%, 0), BounceY%% - Velocities%%(Vector%%, 1)) AND NOT Mat%%(BounceX%%, BounceY%% + Velocities%%(Vector%%, 1)) AND NOT Mat%%(BounceX%% + Velocities%%(Vector%%, 0), BounceY%%) THEN
                        'Reflect backwards
                        Vector%% = Vector%% + 2
                        IF Vector%% > 4 THEN Vector%% = Vector%% - 4
                    ELSEIF Mat%%(BounceX%% + Velocities%%(Vector%%, 0), BounceY%%) AND NOT Mat%%(BounceX%% - Velocities%%(Vector%%, 0), BounceY%% + Velocities%%(Vector%%, 1)) THEN
                        'Reflect off solid (bounce)
                        SELECT CASE Vector%%
                            CASE 1
                                Vector%% = 2
                            CASE 2
                                Vector%% = 1
                            CASE 3
                                Vector%% = 4
                            CASE 4
                                Vector%% = 3
                        END SELECT
                    ELSEIF Mat%%(BounceX%%, BounceY%% + Velocities%%(Vector%%, 1)) AND NOT Mat%%(BounceX%% + Velocities%%(Vector%%, 0), BounceY%% - Velocities%%(Vector%%, 1)) THEN
                        'Reflect off solid (bounce)
                        SELECT CASE Vector%%
                            CASE 1
                                Vector%% = 4
                            CASE 2
                                Vector%% = 3
                            CASE 3
                                Vector%% = 2
                            CASE 4
                                Vector%% = 1
                        END SELECT
                    ELSE
                        Vector%% = PossVector%%
                    END IF
                END IF
                IF PossMoves%% > 0 THEN
                    'Bouncy Can Move
                    Mat%%(BounceX%%, BounceY%%) = False
                    BounceX%% = BounceX%% + Velocities%%(Vector%%, 0)
                    BounceY%% = BounceY%% + Velocities%%(Vector%%, 1)
                    PosnX% = 12 * BounceX%%
                    PosnY% = 21 * BounceY%%
                    Mat%%(BounceX%%, BounceY%%) = True
                    'After Bouncy has moved deal with the Fixed Crosses
                    'Create/Remove Fixed Cross
                    IF FixedCross%% = 0 THEN
                        IF RND > 0.9 THEN
                            'Remove a fixed cross
                            FixedCross%% = 11 + INT(12 * RND)
                            FOR I%% = 1 TO 6
                                FOR J%% = 1 TO 4
                                    IF MatCross%%(I%%, J%%) THEN Mat%%(MatCrosses%%(FixedCross%%, 0) + I%% - 1, MatCrosses%%(FixedCross%%, 1) + J%% - 1) = False
                                NEXT J%%
                            NEXT I%%
                        END IF
                    ELSE
                        IF RND > 0.9 THEN
                            'Fill fixed cross space
                            'Have to check if occupied
                            CanReplace%% = True
                            FOR I%% = 1 TO 6
                                FOR J%% = 1 TO 4
                                    IF Mat%%(MatCrosses%%(FixedCross%%, 0) + I%% - 1, MatCrosses%%(FixedCross%%, 1) + J%% - 1) THEN CanReplace%% = False
                                NEXT J%%
                            NEXT I%%
                            IF CanReplace%% THEN
                                FOR I%% = 1 TO 6
                                    FOR J%% = 1 TO 4
                                        IF MatCross%%(I%%, J%%) THEN Mat%%(MatCrosses%%(FixedCross%%, 0) + I%% - 1, MatCrosses%%(FixedCross%%, 1) + J%% - 1) = True
                                    NEXT J%%
                                NEXT I%%
                                FixedCross%% = 0
                            END IF
                        END IF
                    END IF
                END IF
            END IF
            'The Free Crosses
            FCount%% = FCount%% + 1
            IF FCount%% = 4 THEN
                FCount%% = 0
                'Create/Delete Free Cross
                IF (RND <= 0.4 AND NoFreeCrosses%% >= 4) THEN
                    'Delete an existing Free Cross
                    'Remove from grid:
                    FOR I%% = 1 TO 6
                        FOR J%% = 1 TO 4
                            IF MatCross%%(I%%, J%%) THEN Mat%%(MatCrosses%%(1, 0) + I%% - 1, MatCrosses%%(1, 1) + J%% - 1) = False
                        NEXT J%%
                    NEXT I%%
                    'Change down & remove crosses
                    FOR N%% = 2 TO NoFreeCrosses%%
                        MatCrosses%%(N%% - 1, 0) = MatCrosses%%(N%%, 0)
                        MatCrosses%%(N%% - 1, 1) = MatCrosses%%(N%%, 1)
                        _FREEIMAGE (FreeCrossImages&(N%% - 1, 1))
                        FreeCrossImages&(N%% - 1, 1) = _COPYIMAGE(FreeCrossImages&(N%%, 0), 33)
                    NEXT N%%
                    _FREEIMAGE (FreeCrossImages&(NoFreeCrosses%%, 1))
                    _FREEIMAGE (FreeCrossImages&(NoFreeCrosses%%, 0))
                    NoFreeCrosses%% = NoFreeCrosses%% - 1
                ELSEIF (RND < 0.45 AND NoFreeCrosses%% <= 9) OR NoFreeCrosses%% <= 3 THEN
                    'Create a Free Cross
                    'Find a position where the grid is not occupied
                    NoFreeCrosses%% = NoFreeCrosses%% + 1
                    CanCreate%% = False
                    WHILE NOT CanCreate%%
                        MatCrosses%%(NoFreeCrosses%%, 0) = 1 + INT(RND * 73)
                        MatCrosses%%(NoFreeCrosses%%, 1) = 1 + INT(RND * 20)
                        CanCreate%% = True
                        FOR I%% = 1 TO 6
                            FOR J%% = 1 TO 4
                                IF Mat%%(MatCrosses%%(NoFreeCrosses%%, 0) + I%% - 1, MatCrosses%%(NoFreeCrosses%%, 1) + J%% - 1) THEN CanCreate%% = False
                            NEXT J%%
                        NEXT I%%
                    WEND
                    'Add to grid
                    FOR I%% = 1 TO 6
                        FOR J%% = 1 TO 4
                            IF MatCross%%(I%%, J%%) THEN Mat%%(MatCrosses%%(NoFreeCrosses%%, 0) + I%% - 1, MatCrosses%%(NoFreeCrosses%%, 1) + J%% - 1) = True
                        NEXT J%%
                    NEXT I%%
                    'Create new image & convert to hardware for display
                    'Running image manipulations are done in software
                    FreeCrossImages&(NoFreeCrosses%%, 0) = _NEWIMAGE(72, 84, 32)
                    _DEST FreeCrossImages&(NoFreeCrosses%%, 0)
                    Red~%% = INT(RND * 150)
                    Green~%% = 70 + INT(RND * 186)
                    Blue~%% = 100 + INT(RND * 156)
                    LINE (24, 0)-(48, 83), _RGB32(Red~%%, Green~%%, Blue~%%), BF
                    LINE (0, 21)-(71, 62), _RGB32(Red~%%, Green~%%, Blue~%%), BF
                    COLOR _RGB32(75, 0, 0), _RGB32(Red~%%, Green~%%, Blue~%%)
                    _PRINTSTRING (22, 28), "QB64"
                    _PRINTSTRING (30, 44), "PE"
                    FreeCrossImages&(NoFreeCrosses%%, 1) = _COPYIMAGE(FreeCrossImages&(NoFreeCrosses%%, 0), 33)
                END IF
            END IF
        END IF
    END IF

    'Keyboard Input - Esc to Quit
    k$ = INKEY$
    IF k$ <> "" THEN
        IF ASC(k$) = 27 THEN SayByeByeSooty%% = True 'DoBounce%% = False
    END IF
    k$ = ""

WEND
SYSTEM

ReadData:
DATA 0,0,1,1,0,0
DATA 1,1,1,1,1,1
DATA 1,1,1,1,1,1
DATA 0,0,1,1,0,0

DATA 1,1,-1,1,-1,-1,1,-1

FUNCTION MakeHardware& (Imagename&)
    MakeHardware& = _COPYIMAGE(Imagename&, 33)
    _FREEIMAGE Imagename&
END FUNCTION

   


The video shows the running Bouncy PE program.
Running Program Excerpt
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)