In the spirit of Terry's Tutorials - GUARDIAN Alien Space Ship Game
#11
So now the little alien dudes have sensors, and can keep from flying into one another. No collisions, so no sound effects needed for this demo. For fun, this demo runs 15 multi-color space ships. I guess it's Pride month on Alpha Centauri, but whatever...

The ships can now go off screen and return at some point near the exit. That's a nice escape feature for further development plans. Remember you can use left Ctlr to speed things up and left Alt to slow things down. Oh, and I made the bottom of the screen to be the surface of the planet, so the alien ships were taught to just bounce back up if they near the surface.

Stage 6)

Code: (Select All)
DIM SHARED top, bottom, left, right, s_delay
a = 120: b = 42
WIDTH a, b
_SCREENMOVE 0, 0
top = 3: bottom = _HEIGHT: left = 0: right = _WIDTH
msg$ = "Alien space ship movement demo."
LOCATE 1, (right - left) \ 2 - LEN(msg$) \ 2
PRINT msg$;
LOCATE 1, 2: PRINT STRING$(_WIDTH, "_");
s_delay = 100
DO
    _LIMIT 30
    k$ = INKEY$
    IF _KEYDOWN(100306) THEN IF s_delay - 5 > 0 THEN s_delay = s_delay - 5: LOCATE 1, 2: PRINT "Speed delay ="; s_delay / 100; "    ";
    IF _KEYDOWN(100308) THEN IF s_delay < 500 THEN s_delay = s_delay + 5: LOCATE 1, 2: PRINT "Speed delay ="; s_delay / 100; "    ";
    IF LEN(k$) THEN SOUND 1000, .1
    IF k$ = CHR$(27) THEN END
    alien_move
LOOP

offscreen:
IF ERR = 5 THEN er = -1: RESUME NEXT
PRINT "Opps, you have an error"; ERR
END

SUB alien_move:
    STATIC alien$, a_y(15), a_x(15), olda_y(15), olda_x(15), inertia(15), ran(15), ran_y(15), ran_x(15), oldran(15), z5, z6, itr, alien_ship_max
    IF alien$ = "" THEN
        alien$ = "-<>-": alien_ship_max = 15 ' Sets number of space ships and initiates attack.
        CALL explosion ' Loads sound files on first call.
    END IF
    IF ABS(z5 - TIMER) > s_delay / 1000 THEN ' Time delay.
        DO
            itr = itr + 1: IF itr > alien_ship_max THEN itr = 1 ' Needed to offset the EXIT DO hover event, which on exit does not affect the itr variable.
            y_restore = CSRLIN: x_restore = POS(0) ' Restore column and row upon exit.

            IF olda_y(itr) <> 0 AND olda_x(itr) <> 0 THEN ' If alien ship on screen then mask old image.
                LOCATE olda_y(itr), olda_x(itr): PRINT SPACE$(LEN(alien$));
            END IF

            IF inertia(itr) = 0 THEN ' Determine how many moves in one direction.
                inertia(itr) = INT(RND * (bottom - top) / 2) + 1 ' How many moves to go in any one direction.
                ran(itr) = INT(RND * 8) + 1 ' Choose 1 of 8 possible directions.

                IF ran(itr) = oldran(itr) OR olda_y(itr) = 0 AND olda_x(itr) = 0 AND ran = 1 OR olda_y(itr) = 0 AND olda_x(itr) = 0 AND ran = 5 THEN
                    EXIT DO ' Just hover if direction was not changed on existing alien space ship or if a new alien space ship is entering from the sides and up or down was generated.
                END IF

                SELECT CASE ran(itr) ' Get changes in column and row coordinates.
                    CASE 1: ran_y(itr) = -1: ran_x(itr) = 0 '  Up.
                    CASE 2: ran_y(itr) = -1: ran_x(itr) = 2 '  Up and right.
                    CASE 3: ran_y(itr) = 0: ran_x(itr) = 2 '  Right.
                    CASE 4: ran_y(itr) = 1: ran_x(itr) = 2 '  Down and right.
                    CASE 5: ran_y(itr) = 1: ran_x(itr) = 0 '  Down.
                    CASE 6: ran_y(itr) = 1: ran_x(itr) = -2 '  Down and left.
                    CASE 7: ran_y(itr) = 0: ran_x(itr) = -2 '  Left.
                    CASE 8: ran_y(itr) = -1: ran_x(itr) = -2 ' Up and left.
                END SELECT

                IF olda_y(itr) = 0 AND olda_x(itr) = 0 THEN ' New alien space ship enters the screen.
                    i = RND * (bottom - top) \ 4
                    a_y(itr) = (bottom - top) \ 4 + i
                    IF ran(itr) < 5 THEN ' Determine side of entry from initial direction.
                        IF SCREEN(a_y(itr), left + LEN(alien$)) = 32 THEN
                            a_x(itr) = left + 1 ' Enter from the left side and go right.
                        ELSE
                            GOSUB a_erase ' Cancel and wait because space is occupied.
                            EXIT DO
                        END IF
                    ELSE
                        IF SCREEN(a_y(itr), right - LEN(alien$) + 1) = 32 THEN
                            a_x(itr) = right - LEN(alien$) ' Enter from the right side and go left.
                        ELSE
                            GOSUB a_erase: ' Cancel and wait because space is occupied.
                            EXIT DO
                        END IF
                    END IF
                END IF
                oldran(itr) = ran(itr) ' Remember last direction. Another line uses this to disallow any RND that chooses the same direction twice.
            ELSE
                inertia(itr) = inertia(itr) - 1 ' Count down the number of moves in any one direction. When zero, switch direction.
            END IF

            FOR i = 1 TO alien_ship_max
                IF i <> itr AND a_y(i) <> 0 THEN
                    IF a_y(itr) + ran_y(itr) = a_y(i) THEN
                        IF a_x(itr) + ran_x(itr) + LEN(alien$) > a_x(i) AND a_x(itr) + ran_x(itr) < a_x(i) + LEN(alien$) THEN
                            collide = 1
                            EXIT FOR
                        END IF
                    END IF
                END IF
            NEXT
            IF collide = 1 THEN
                j = a_y(itr): k = a_x(itr)
                ran_y(itr) = 0: ran_x(itr) = 0: inertia(itr) = 0
                collide = 0 ' Collision detection off. Collision detected and avoided.
            ELSE
                j = a_y(itr) + ran_y(itr): k = a_x(itr) + ran_x(itr)
            END IF

            IF j <= top OR k <= left OR k + LEN(alien$) > right THEN ' Alien ship out of range.
                inertia(itr) = 0 ' These two lines keep the out of range ship(s) reasonably nearby.
                IF j > -3 AND k < right + 3 AND k > -3 THEN a_y(itr) = j: a_x(itr) = k
            ELSE
                ' Check for collisions and reverse course if detected.
                IF j >= bottom THEN collide = -1

                COLOR itr
                IF collide THEN
                    ran_y(itr) = -ran_y(itr): ran_x(itr) = -ran_x(itr)
                    collide = 0

                    LOCATE olda_y(itr), olda_x(itr): PRINT alien$;
                ELSE
                    a_y(itr) = j: a_x(itr) = k ' Next move coordinates.
                    LOCATE j, k: PRINT alien$; ' Move alien space ship.
                    olda_y(itr) = j: olda_x(itr) = k ' Remember these coordinates to erase alien space ship on next loop.
                END IF
                COLOR 7
            END IF

            IF itr = alien_ship_max THEN itr = 0: EXIT DO
            IF ABS(z6 - TIMER) > s_delay / 2 THEN skipz5 = -1: EXIT DO
        LOOP
        IF skipz5 = 0 THEN z5 = TIMER
        z6 = TIMER
        LOCATE y_restore, x_restore ' Restore entry column and row positions.
    END IF
    EXIT SUB

    a_erase:
    a_y(itr) = 0: a_x(itr) = 0: olda_y(itr) = 0: olda_x(itr) = 0: inertia(itr) = 0: ran(itr) = 0: ran_y(itr) = 0: ran_x(itr) = 0: oldran(itr) = 0
    RETURN
END SUB

SUB explosion
    STATIC sound_check, soundfile%, t1&, t6&, t7&, t8&
    IF sound_check = 0 THEN
        IF _FILEEXISTS("Thunder1.ogg") AND _FILEEXISTS("Thunder1.ogg") AND _FILEEXISTS("Thunder1.ogg") AND _FILEEXISTS("Thunder1.ogg") THEN soundfile% = -1
        IF soundfile% THEN
            t1& = _SNDOPEN("Thunder1.ogg", "SYNC")
            t6& = _SNDOPEN("Thunder6.ogg", "SYNC")
            t7& = _SNDOPEN("Thunder7.ogg", "SYNC")
            t8& = _SNDOPEN("Thunder8.ogg", "SYNC")
        END IF
        sound_check = -1
        EXIT SUB
    END IF

    VIEW PRINT top TO bottom ' Needed to set print error parameters.
    b_y1 = CSRLIN: b_x1 = POS(0)
    h = 0
    ON ERROR GOTO offscreen
    DO
        IF h = 1 THEN burst$ = " " ELSE burst$ = CHR$(249)
        h = h + 1
        GOSUB flash
        FOR i = 1 TO 5
            SELECT CASE i
                CASE 1
                    COLOR 15
                    LOCATE b_y1, b_x1: PRINT burst$;
                    _DELAY .1
                CASE 2
                    IF burst$ = CHR$(249) THEN burst$ = CHR$(250)
                    COLOR 14, 0
                    LOCATE b_y1 - 1, b_x1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1, b_x1 - 1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1, b_x1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1, b_x1 + 1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1 + 1, b_x1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    _DELAY .1
                CASE 3
                    LOCATE b_y1 - 1, b_x1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1, b_x1 - 1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1, b_x1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1, b_x1 + 1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1 + 1, b_x1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                CASE 4
                    COLOR 4
                    LOCATE b_y1 - 1, b_x1 - 1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1 - 1, b_x1 + 1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1, b_x1 - 2
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1, b_x1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1, b_x1 + 2
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1 + 1, b_x1 - 1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    LOCATE b_y1 + 1, b_x1 + 1
                    IF er = 0 THEN PRINT burst$; ELSE er = 0
                    _DELAY .3
                CASE 5
                    LOCATE b_y1 - 1, b_x1 - 1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1 - 1, b_x1 + 1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1, b_x1 - 2
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1, b_x1 - 1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1, b_x1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1, b_x1 + 1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1, b_x1 + 2
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1 + 1, b_x1 - 1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
                    LOCATE b_y1 + 1, b_x1 + 1
                    IF er = 0 THEN PRINT " "; ELSE er = 0
            END SELECT
        NEXT
        IF h = 1 THEN h = 0: EXIT DO
    LOOP
    VIEW PRINT
    ON ERROR GOTO 0
    COLOR 7
    LOCATE b_y1, b_x1
    EXIT SUB

    flash:
    IF eflag THEN
        IF ABS(z7 - TIMER) > .1 THEN
            eflag = 0
            PALETTE 0, 0
            z7 = TIMER
        ELSE
            j = -j * -1
            IF j = 0 THEN
                PALETTE 0, 63
                _DELAY .05
            ELSE
                PALETTE 0, 0
                _DELAY .05
            END IF
        END IF
    END IF
    IF eflag = 0 THEN
        PALETTE 0, 36
        IF soundfile% THEN
            _SNDPLAY t1&
            _DELAY .05
            PALETTE 0, 0
            _SNDPLAY t7&
        ELSE
            _DELAY .075
        END IF
        eflag = -1
        z7 = TIMER
    END IF
    PALETTE 0, 0
    RETURN
END SUB

So what's next? Well, at some point it becomes time to see what was needed to get this far, and consider if converting to TYPE variables would be adventitious to the project.

Pete
Reply


Messages In This Thread
RE: In the spirit of Terry's Tutorials - Alien Space Ship - by Pete - 10-05-2022, 10:11 PM



Users browsing this thread: 9 Guest(s)