In the spirit of Terry's Tutorials - GUARDIAN Alien Space Ship Game
#4
Okay, how about we put 5 alien space ships in on the screen? It's actually easier than it sounds. All we need is a iteration counter (I'll use the variable name itr for that) and the variables already in use, all being changed into arrays. So if we had ship we would replace it with ship(itr). The QB64 IDE has a nice CHANGE routine so if you already coded ship in 20 places, the change feature would change it to ship(itr) in all 20 places at once. I did almost all of the edits from my last post to this post using that method.

With all the variables changed to arrays, we simply DIM or value of 5 space ships in the STATIC statement:

Code: (Select All)
    STATIC 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, itr, alien_ship_max

Sorry, but you have to hard code the number. The STATIC statement won't compile with a variable.

Now we need the space ship max variable added: IF alien$ = "" THEN alien$ = "-<>-": alien_ship_max = 5 ' Initiate.

Finally we just wrap what we already have in a DO:LOOP that moves each of the 5 space ships before exiting.

Stage 3)

Code: (Select All)
DIM SHARED top, bottom, left, right
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, "_");

DO
    _LIMIT 30
    alien_move
LOOP

SUB alien_move:
    STATIC 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, itr, alien_ship_max
    IF alien$ = "" THEN alien$ = "-<>-": alien_ship_max = 5 ' Initiate.
    IF ABS(z5 - TIMER) > .1 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.
                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
        LOOP
        z5 = TIMER
        LOCATE y_restore, x_restore ' Restore entry column and row positions.
    END IF
END SUB

The next adjustment will be a "flow through" modification. Flow through makes it possible to do other things rather than just be stuck in a task loop until the task is finished. This is a very important timing element for gaming.

Pete
Reply


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



Users browsing this thread: 6 Guest(s)