In the spirit of Terry's Tutorials - GUARDIAN Alien Space Ship Game
#8
To make an explosion with a collision, a simple FOR/NEXT loop is created to check the coordinates of each space ship. If they intersect, the program call the sub "explosion." The explosion sub consists of a particle burst, flashing screen, produced with a palette loop, and thunder sounds, which require downloading and unzipping the attached zip containing the .ogg sound file.

Stage 5)

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, "_");
VIEW PRINT top TO bottom ' Needed to set print error parameters.
s_delay = 100
DO
    _LIMIT 30
    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(INKEY$) THEN SOUND 1000, .1
    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(5), a_x(5), olda_y(5), olda_x(5), inertia(5), ran(5), ran_y(5), ran_x(5), oldran(5), z5, z6, itr, alien_ship_max
    IF alien$ = "" THEN
        alien$ = "-<>-": alien_ship_max = 5 ' Initiate.
        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 LOCATE olda_y(itr), olda_x(itr): PRINT SPACE$(LEN(alien$));

            IF inertia(itr) = 0 THEN
                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) = 1 '  Up and right.
                    CASE 3: ran_y(itr) = 0: ran_x(itr) = 1 '   Right.
                    CASE 4: ran_y(itr) = 1: ran_x(itr) = 1 '   Down and right.
                    CASE 5: ran_y(itr) = 1: ran_x(itr) = 0 '   Down.
                    CASE 6: ran_y(itr) = 1: ran_x(itr) = -1 '  Down and left.
                    CASE 7: ran_y(itr) = 0: ran_x(itr) = -1 '  Left.
                    CASE 8: ran_y(itr) = -1: ran_x(itr) = -1 ' Up and left.
                END SELECT

                IF olda_y(itr) = 0 AND olda_x(itr) = 0 THEN ' New alien space ship enters the screen.
                    a_y(itr) = (bottom - top) \ 2: a_x(itr) = (right - left) \ 2 ' Center sreen.
                    a_y(itr) = (bottom - top) \ 4 + RND * (bottom - top) \ 4
                    IF ran(itr) < 5 THEN ' Determine side of entry from initial direction.
                        a_x(itr) = left + 1 ' Enter from the left side and go right.
                    ELSE
                        a_x(itr) = right - LEN(alien$) ' Enter from the right side and go left.
                    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
            a_y(itr) = a_y(itr) + ran_y(itr): a_x(itr) = a_x(itr) + ran_x(itr) * 2 ' Next move coordinates. I use * 2 for horizontal movement to match the 16x8 pixel height over width factor.
            IF a_y(itr) < top OR a_y(itr) > bottom OR a_x(itr) <= left OR a_x(itr) + LEN(alien$) > right THEN
                olda_x(itr) = 0: olda_y(itr) = 0: inertia(itr) = 0: oldran(itr) = 0 ' Out of bounds and off the screen.
            ELSE
                LOCATE a_y(itr), a_x(itr): PRINT alien$; ' Move alien space ship.
                ' Check for collisions.
                FOR i = 1 TO alien_ship_max
                    IF i <> itr AND a_y(i) <> 0 THEN
                        IF a_y(itr) = a_y(i) AND a_x(itr) >= a_x(i) AND a_x(itr) < a_x(i) + LEN(alien$) THEN
                            LOCATE a_y(i), a_x(i): PRINT SPACE$(LEN(alien$));: LOCATE a_y(itr), a_x(itr): PRINT SPACE$(LEN(alien$));
                            CALL explosion
                            a_y(irt) = 0: a_x(i) = 0 ' Remove exploded alien space ships.
                        END IF
                    END IF
                NEXT
                olda_y(itr) = a_y(itr): olda_x(itr) = a_x(itr) ' Remember these coordinates to erase alien space ship on next loop.
            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
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

    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
    ON ERROR GOTO 0
    COLOR 7
    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


In the next update the aliens will be given a bit more A.I. to avoid colliding with one another.

Pete


Attached Files
.7z   ASCII Invaders Sound.7z (Size: 1.45 MB / Downloads: 74)
Reply


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



Users browsing this thread: 7 Guest(s)