Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
You'd think this would be faster, but NO!!!!!! [Resolved]
#14
Steve is pretty good with graphics, but his text ability is pretty half-ASCII. Big Grin

Hey guys, banter aside, just don't miss the point of why I made this post in the first place, to call attention to a peculiar slow-down event, caused by assigning a variable to SCREEN(). Look at it this way, if assigning a variable to avoid repeated asc() checking should speed things up, assigning a variable to SCREEN() should also speed things up; ah, but it didn't. It markedly slowed the animation down. Steve's other suggestion of creating and assigning a new variable to ASC() is correct, but is imperceptible in regard to speed, the difference in speed change by assigning a variable to SCREEN(), in my routine, again, is markedly noteable.

BTW - The CASE 2 part is simply unfinished. I was in the process of adding another condition when this occurred, that's why it is empty with no EXIT FOR, so ignore it, it's not the problem, anyway.

@DSman195276

If it helps, I stripped 70% of the code out to make it easier.

Code example 1 demos the speed as it should be.

Code example 2 demos assigning h to SCREEN(), which slows it down 5x.

To find the code in question, search: Check area through width of ship

Code Example #1
Code: (Select All)
DEFINT H-K
$RESIZE:ON
_RESIZE OFF
RANDOMIZE TIMER
' Note: timer is not adjusted for stroke of midnight event, so don't stay up late playing this.
REM Main
f1 = 22 ' Sets font size to 22 and calculates the max screen height and width for your desktop.
h = (_DESKTOPHEIGHT - 60) \ f1
w = _DESKTOPWIDTH \ (f1 / 1.66)
WIDTH w, h
_SCREENMOVE 0, 0
fontpath$ = ENVIRON$("SYSTEMROOT") + "\fonts\lucon.ttf" 'Find Windows Folder Path.
font& = _LOADFONT(fontpath$, f1, "monospace")
_FONT font&
_DELAY .25
_RESIZE ON , _SMOOTH ' Allows resizing. Note: this is for slight adjustments. As of this version there is no compensitory function to change the font size during screen size changes.
TYPE gen_var
    intro AS INTEGER ' Runs a protion of the alien subroutine as part of the intro.
    nol AS INTEGER ' Number of game levels.
    level AS INTEGER ' Current game level.
    level_up AS INTEGER ' Routes code to next game level.
    top AS INTEGER ' Top boundary. (Changeable).
    bottom AS INTEGER ' Bottom boundary. (Changeable).
    left AS INTEGER ' Left boundary. (Changeable).
    right AS INTEGER ' Right boundary. (Changeable).
    kb_access AS INTEGER ' Routes code to either Guardian/Alien or general keyboard routine. -1 Guardian/Alien, 0 keyboard.
    mouse_or_key_move AS INTEGER
    play AS INTEGER
    snd1 AS LONG ' Explosion sound effect.
    snd2 AS LONG ' Explosion sound effect.
END TYPE

DIM SHARED v AS gen_var

TYPE guardian
    num AS INTEGER ' Number of Guardians aka lives.
    diry AS INTEGER ' Guardian row move. +1, 0, -1.
    dirx AS INTEGER ' Guardian column move. +2, 0, -2. Equals vertical pixel movement. 16x8.
    y AS INTEGER ' Guardian coordinates row.
    x AS INTEGER ' Guardian coordinates column.
    thrusters AS INTEGER ' Guardian speed. (User Determined).
    m_max AS INTEGER ' Restricts # of missiles fired in one direction.
    m_status AS INTEGER ' Missile status. -1 when fired, 1 while moving.
    m_fired AS INTEGER ' The number of missile deployed and still active.
    m_n AS INTEGER ' FOR/NEXT counter variable shared by other routines to index through the number of missiles fired in a specific direction.
    m_d AS INTEGER ' Missile direction. (1-8).
    m_y AS INTEGER ' Missile row advancement increment: +1, 0, -1 Note: Missile row and column coordinates are defined in arrays.
    m_x AS INTEGER ' Missile column advancement increment: +2, 0, -2. Equals vertical pixel movement. 16x8.
    m_asc AS INTEGER ' ASCII charater representing a fired missile.
    m_launcher AS STRING
    icon AS STRING ' Gardian comm icon. For this edition, it is the same as the flagship: "*"
    flagship AS STRING ' Guardian ascii character.
END TYPE

DIM SHARED g AS guardian

TYPE alien
    max AS INTEGER ' Maximum # of alien ships on screen.
    count AS INTEGER ' Number of alien ships. (Counter).
    itr AS INTEGER ' Iteration array number to cycle through the active alien ships. (Counter).
    cycle_delay AS SINGLE ' Timer cycle controls how fast alien ships move.
    ship AS STRING ' Alien ship ASCII design.
END TYPE

DIM SHARED a AS alien

DO
    GOSUB set_arrays

    SELECT CASE v.play
        CASE 1
            CALL set_up
            CALL comm
            v.level = -1: CALL game_level: v.level_up = 0
        CASE 0
            CALL set_up
            CALL comm
            CALL intro
            v.intro = 0: a.max = 0
            GOSUB set_arrays
            v.level = -1: CALL game_level: v.level_up = 0 ' This variable is canceled here so game will play instead of go another level up.
    END SELECT

    g.y = (v.bottom - v.top) \ 2 + v.top: g.x = (v.right - v.left + 1) \ 2 + v.left ' Set initial column and row for Guardian craft.

    CALL game

    GOSUB zero_variables
LOOP

set_arrays:
ii = 15 ' Default max setting for number of alien ships used here to intially dim arrays.
g.m_max = 8 ' * missiles max per direction.
REDIM SHARED a_y(ii), a_x(ii), a_mask_y(ii), a_mask_x(ii), a_inertia(ii) ' Alien movement.
REDIM SHARED a_ran(ii), a_olda_ran(ii), a_y_loc(ii), a_x_loc(ii) ' Alien motvement.
REDIM SHARED m_n(g.m_max), m_x(g.m_max, 8), m_y(g.m_max, 8) ' Guardian missiles.

' Array descriptions and actions.
' a_y() , a_x() Alien ship postions rows and columns.
' a_mask_y(), a_mask_x() Alien ship last position. Masked on next move.
' a_inertia(ii) Number of moves in one direction selected by random for an alien ship.
' a_ran(ii), a_olda_ran(ii) Determines the direction in which the inertia will travel and the prior direction is kept to disallow the same direction twice.
' a_y_loc(ii), a_x_loc(ii) The row and column cordinates of the aliens ships.
' m_n(g.m_max), m_x(g.m_max, 8), m_y(g.m_max, 8)  Missile number and Missile index 1 to g.m_max for position. 8 is the fixed number of 8 different directions.
RETURN

zero_variables:
' Zero variables.
g.diry = 0: g.dirx = 0: g.m_status = 0: g.m_fired = 0: g.m_d = 0: g.m_y = 0: g.m_x = 0
a.count = 0: a.itr = 0: a.cycle_delay = 0: v.level_up = 0: v.mouse_or_key_move = 0: g.m_launcher = ""
RETURN

skipintro:
RETURN

' Error handler.
offscreen: ' Prevents error if blast particles row and column are off-screen. Effect is a partial blast on side of screen.
IF ERR = 5 THEN er = -1: RESUME NEXT
PRINT "Opps, unexpected error"; ERR
END

SUB intro
    j = (v.bottom - v.top) \ 2 + v.top
    k = (v.right - v.left) \ 2 + v.left
    v.intro = -1: a.max = 10
    FOR i = 1 TO 90
        SOUND 900, .05
        CALL alien_move
        LOCATE j, k: COLOR 15: PRINT g.flagship;: COLOR 7
        _DELAY .07
    NEXT
END SUB

SUB set_up
    v.top = 3: v.bottom = _HEIGHT: v.left = 1: v.right = _WIDTH
    g.flagship = CHR$(15)
    a.ship = "-<>-"
    g.num = 3 ' 3 Guardian (lives) to start.
    g.thrusters = 10 ' Shows 1/2 thrust at start up on comm.
    g.icon = g.flagship
    g.m_asc = 250: g.diry = -1: ' Initiate missile ASCII character. g.diry = -1 initiates fire upwards if unmoved.
    IF _FILEEXISTS("Thunder1.ogg") AND _FILEEXISTS("Thunder1.ogg") AND _FILEEXISTS("Thunder1.ogg") AND _FILEEXISTS("Thunder1.ogg") THEN ' Sound effects provided by TheBOB, Bob Seguin, from The QBasic Forum.
        v.snd1 = _SNDOPEN("Thunder1.ogg", "SYNC")
        v.snd2 = _SNDOPEN("Thunder7.ogg", "SYNC")
    END IF
    v.play = -1 ' Skip into on replay.
    LOCATE 2, 1: PRINT STRING$(_WIDTH, CHR$(196));
    _KEYCLEAR ' Clear any previous key presses in buffer.
END SUB

SUB game
END SUB

SUB comm
END SUB

SUB Guardian_missiles
END SUB

SUB missile_check (k)
END SUB

SUB alien_move
    STATIC z5
    y_restore = CSRLIN: x_restore = POS(0) ' Restore column and row upon exit.
    IF ABS(z5 - TIMER) > a.cycle_delay OR v.intro THEN ' z5 is a time delay for alien space ship maneuvers. It can be altered in the "game" subroutine.
        IF v.intro = 0 THEN hh = INT(RND * a.max) + 1 ELSE hh = 15
        FOR h = 1 TO hh
            a.itr = a.itr + 1: IF a.itr > a.max THEN a.itr = 1 ' Needed to offset the EXIT DO hover event, which on exit does not affect the a.itr variable.
            IF a_ran(a.itr) <> -1 THEN ' This is how a destroyed ship is bypassed. -1 is a destroyed alien ship. Code moves to end of DO:LOOP.
                IF a_inertia(a.itr) = 0 THEN ' Determine how many moves in one direction.
                    a_inertia(a.itr) = INT(RND * (v.bottom - v.top) / 2) + 1 ' How many moves to go in any one direction.
                    a_ran(a.itr) = INT(RND * 8) + 1 ' Choose 1 of 8 possible directions.

                    IF a_ran(a.itr) = a_olda_ran(a.itr) OR a_mask_y(a.itr) = 0 AND a_mask_x(a.itr) = 0 AND ran = 1 OR a_mask_y(a.itr) = 0 AND a_mask_x(a.itr) = 0 AND ran = 5 THEN
                        EXIT FOR ' 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 a_ran(a.itr) ' Get changes in column and row coordinates.
                        CASE 1: a_y_loc(a.itr) = -1: a_x_loc(a.itr) = 0 '  Up.
                        CASE 2: a_y_loc(a.itr) = -1: a_x_loc(a.itr) = 2 '  Up and right.
                        CASE 3: a_y_loc(a.itr) = 0: a_x_loc(a.itr) = 2 '   Right.
                        CASE 4: a_y_loc(a.itr) = 1: a_x_loc(a.itr) = 2 '   Down and right.
                        CASE 5: a_y_loc(a.itr) = 1: a_x_loc(a.itr) = 0 '   Down.
                        CASE 6: a_y_loc(a.itr) = 1: a_x_loc(a.itr) = -2 '  Down and left.
                        CASE 7: a_y_loc(a.itr) = 0: a_x_loc(a.itr) = -2 '  Left.
                        CASE 8: a_y_loc(a.itr) = -1: a_x_loc(a.itr) = -2 ' Up and left.
                    END SELECT

                    IF a_y(a.itr) = 0 AND a_x(a.itr) = 0 AND a_ran(a.itr) <> -1 THEN ' New alien space ship enters the screen.
                        i = RND * (v.bottom - v.top) \ 4
                        a_y(a.itr) = (v.bottom - v.top) \ 4 + i + v.top
                        IF a_ran(a.itr) < 5 THEN ' Determine side of entry from initial direction.
                            IF SCREEN(a_y(a.itr), v.left + LEN(a.ship)) = 32 THEN
                                a_x(a.itr) = v.left + 1 ' Enter from the left side and go right.
                            ELSE
                                CALL a_erase
                                EXIT FOR
                            END IF
                        ELSE
                            IF SCREEN(a_y(a.itr), v.right - LEN(a.ship) + 1) = 32 THEN
                                a_x(a.itr) = v.right - LEN(a.ship) ' Enter from the right side and go left.
                            ELSE
                                CALL a_erase
                                EXIT FOR
                            END IF
                        END IF
                    END IF
                    a_olda_ran(a.itr) = a_ran(a.itr) ' Remember last direction. Another line uses this to disallow any RND that chooses the same direction twice.
                ELSE
                    a_inertia(a.itr) = a_inertia(a.itr) - 1 ' Count down the number of moves in any one direction. When zero, switch direction.
                END IF

                FOR i = 1 TO a.max
                    IF i <> a.itr AND a_y(i) <> 0 THEN
                        IF a_y(a.itr) + a_y_loc(a.itr) = a_y(i) THEN
                            IF a_x(a.itr) + a_x_loc(a.itr) + LEN(a.ship) > a_x(i) AND a_x(a.itr) + a_x_loc(a.itr) < a_x(i) + LEN(a.ship) THEN
                                collide = 1
                                EXIT FOR
                            END IF
                        END IF
                    END IF
                NEXT
                IF collide = 1 THEN
                    j = a_y(a.itr): k = a_x(a.itr)
                    a_y_loc(a.itr) = 0: a_x_loc(a.itr) = 0: a_inertia(a.itr) = 0
                    collide = 0 ' Collision detection off. Collision was detected and avoided.
                ELSE
                    j = a_y(a.itr) + a_y_loc(a.itr): k = a_x(a.itr) + a_x_loc(a.itr)
                END IF

                IF j <= v.top OR k <= v.left OR k + LEN(a.ship) > v.right THEN ' Alien ship out of range off screen.
                    a_inertia(a.itr) = 0 ' These two lines keep the out of range ship(s) reasonably nearby.
                    IF j > v.top - 4 AND k < v.right + 3 AND k > v.left - 4 THEN a_y(a.itr) = j: a_x(a.itr) = k
                    IF a_mask_y(a.itr) <> 0 AND a_mask_x(a.itr) <> 0 THEN
                        LOCATE a_mask_y(a.itr), a_mask_x(a.itr)
                        PRINT SPACE$(LEN(a.ship)); ' Mask old position here because the show part of the mask and show routine cannot be used when out of range.
                    END IF
                    a_mask_y(a.itr) = 0: a_mask_x(a.itr) = 0
                ELSE
                    ' Check for v.bottom collision and reverse course if detected.
                    COLOR a.itr
                    IF j >= v.bottom THEN
                        a_y_loc(a.itr) = -a_y_loc(a.itr): a_x_loc(a.itr) = -a_x_loc(a.itr)
                    ELSE
                        a_y(a.itr) = j: a_x(a.itr) = k ' Next move coordinates.
                        ii = 0
                        FOR i = 0 TO LEN(a.ship) - 1 ' Check area through width of ship. Remember all or parts of ship are still present on screen.
                            IF SCREEN(j, k + i) = ASC(g.flagship) OR SCREEN(j, k + i) = g.m_asc THEN ' Check for contact (collision) with Guardian or missile.
                                IF SCREEN(j, k + i) = ASC(g.flagship) THEN
                                    ii = 1 ' Indicates contact with flagship and evokes call abduction routine a few lines down.
                                    EXIT FOR
                                ELSE
                                    ii = 2 ' Indicates ship into missile collision.
                                    EXIT FOR
                                END IF
                            END IF
                        NEXT
                        IF ii <> 2 THEN
                            '--------------------------------------------Move alien ship-------------------------------------------------
                            IF a_mask_y(a.itr) <> 0 AND a_mask_x(a.itr) <> 0 THEN LOCATE a_mask_y(a.itr), a_mask_x(a.itr): PRINT SPACE$(LEN(a.ship));
                            LOCATE j, k: PRINT a.ship;
                            a_mask_y(a.itr) = j: a_mask_x(a.itr) = k ' Remember these coordinates to erase alien space ship on next loop.
                            '------------------------------------------------------------------------------------------------------------
                        END IF
                        SELECT CASE ii
                            CASE 1
                                CALL guardian_abduction: EXIT FOR ' Exit loop.
                            CASE 2
                                '''BEEP: BEEP: BEEP: DO: _LIMIT 10: LOOP UNTIL INKEY$ = CHR$(13)
                        END SELECT
                    END IF
                    COLOR 7
                END IF
            END IF ' a_ran(a.itr) > -1 exit point.
            IF a.itr = a.max THEN a.itr = 0: EXIT FOR ' Finished loop. Keep this outside the IF/THEN statement.
        NEXT h
        z5 = TIMER
        LOCATE y_restore, x_restore ' Restore entry column and row positions.
    END IF ' End time event.
END SUB

SUB explosion
END SUB

SUB remove_missile
END SUB

SUB mask_missiles
END SUB

SUB a_erase
    a_y(a.itr) = 0: a_x(a.itr) = 0: a_mask_y(a.itr) = 0: a_mask_x(a.itr) = 0: a_inertia(a.itr) = 0: a_ran(a.itr) = 0: a_y_loc(a.itr) = 0: a_x_loc(a.itr) = 0: a_olda_ran(a.itr) = 0
END SUB

SUB remove_ship
END SUB

SUB guardian_abduction
END SUB

SUB game_level ' Evaluates both alien defeated on a level and Guardian abduction.
END SUB

SUB mouse (mouse_event1, mouse_event2)
END SUB

Code Example #2, the slow-down problem.
Code: (Select All)
DEFINT H-K
$RESIZE:ON
_RESIZE OFF
RANDOMIZE TIMER
' Note: timer is not adjusted for stroke of midnight event, so don't stay up late playing this.
REM Main
f1 = 22 ' Sets font size to 22 and calculates the max screen height and width for your desktop.
h = (_DESKTOPHEIGHT - 60) \ f1
w = _DESKTOPWIDTH \ (f1 / 1.66)
WIDTH w, h
_SCREENMOVE 0, 0
fontpath$ = ENVIRON$("SYSTEMROOT") + "\fonts\lucon.ttf" 'Find Windows Folder Path.
font& = _LOADFONT(fontpath$, f1, "monospace")
_FONT font&
_DELAY .25
_RESIZE ON , _SMOOTH ' Allows resizing. Note: this is for slight adjustments. As of this version there is no compensitory function to change the font size during screen size changes.
TYPE gen_var
    intro AS INTEGER ' Runs a protion of the alien subroutine as part of the intro.
    nol AS INTEGER ' Number of game levels.
    level AS INTEGER ' Current game level.
    level_up AS INTEGER ' Routes code to next game level.
    top AS INTEGER ' Top boundary. (Changeable).
    bottom AS INTEGER ' Bottom boundary. (Changeable).
    left AS INTEGER ' Left boundary. (Changeable).
    right AS INTEGER ' Right boundary. (Changeable).
    kb_access AS INTEGER ' Routes code to either Guardian/Alien or general keyboard routine. -1 Guardian/Alien, 0 keyboard.
    mouse_or_key_move AS INTEGER
    play AS INTEGER
    snd1 AS LONG ' Explosion sound effect.
    snd2 AS LONG ' Explosion sound effect.
END TYPE

DIM SHARED v AS gen_var

TYPE guardian
    num AS INTEGER ' Number of Guardians aka lives.
    diry AS INTEGER ' Guardian row move. +1, 0, -1.
    dirx AS INTEGER ' Guardian column move. +2, 0, -2. Equals vertical pixel movement. 16x8.
    y AS INTEGER ' Guardian coordinates row.
    x AS INTEGER ' Guardian coordinates column.
    thrusters AS INTEGER ' Guardian speed. (User Determined).
    m_max AS INTEGER ' Restricts # of missiles fired in one direction.
    m_status AS INTEGER ' Missile status. -1 when fired, 1 while moving.
    m_fired AS INTEGER ' The number of missile deployed and still active.
    m_n AS INTEGER ' FOR/NEXT counter variable shared by other routines to index through the number of missiles fired in a specific direction.
    m_d AS INTEGER ' Missile direction. (1-8).
    m_y AS INTEGER ' Missile row advancement increment: +1, 0, -1 Note: Missile row and column coordinates are defined in arrays.
    m_x AS INTEGER ' Missile column advancement increment: +2, 0, -2. Equals vertical pixel movement. 16x8.
    m_asc AS INTEGER ' ASCII charater representing a fired missile.
    m_launcher AS STRING
    icon AS STRING ' Gardian comm icon. For this edition, it is the same as the flagship: "*"
    flagship AS STRING ' Guardian ascii character.
END TYPE

DIM SHARED g AS guardian

TYPE alien
    max AS INTEGER ' Maximum # of alien ships on screen.
    count AS INTEGER ' Number of alien ships. (Counter).
    itr AS INTEGER ' Iteration array number to cycle through the active alien ships. (Counter).
    cycle_delay AS SINGLE ' Timer cycle controls how fast alien ships move.
    ship AS STRING ' Alien ship ASCII design.
END TYPE

DIM SHARED a AS alien

DO
    GOSUB set_arrays

    SELECT CASE v.play
        CASE 1
            CALL set_up
            CALL comm
            v.level = -1: CALL game_level: v.level_up = 0
        CASE 0
            CALL set_up
            CALL comm
            CALL intro
            v.intro = 0: a.max = 0
            GOSUB set_arrays
            v.level = -1: CALL game_level: v.level_up = 0 ' This variable is canceled here so game will play instead of go another level up.
    END SELECT

    g.y = (v.bottom - v.top) \ 2 + v.top: g.x = (v.right - v.left + 1) \ 2 + v.left ' Set initial column and row for Guardian craft.

    CALL game

    GOSUB zero_variables
LOOP

set_arrays:
ii = 15 ' Default max setting for number of alien ships used here to intially dim arrays.
g.m_max = 8 ' * missiles max per direction.
REDIM SHARED a_y(ii), a_x(ii), a_mask_y(ii), a_mask_x(ii), a_inertia(ii) ' Alien movement.
REDIM SHARED a_ran(ii), a_olda_ran(ii), a_y_loc(ii), a_x_loc(ii) ' Alien motvement.
REDIM SHARED m_n(g.m_max), m_x(g.m_max, 8), m_y(g.m_max, 8) ' Guardian missiles.

' Array descriptions and actions.
' a_y() , a_x() Alien ship postions rows and columns.
' a_mask_y(), a_mask_x() Alien ship last position. Masked on next move.
' a_inertia(ii) Number of moves in one direction selected by random for an alien ship.
' a_ran(ii), a_olda_ran(ii) Determines the direction in which the inertia will travel and the prior direction is kept to disallow the same direction twice.
' a_y_loc(ii), a_x_loc(ii) The row and column cordinates of the aliens ships.
' m_n(g.m_max), m_x(g.m_max, 8), m_y(g.m_max, 8)  Missile number and Missile index 1 to g.m_max for position. 8 is the fixed number of 8 different directions.
RETURN

zero_variables:
' Zero variables.
g.diry = 0: g.dirx = 0: g.m_status = 0: g.m_fired = 0: g.m_d = 0: g.m_y = 0: g.m_x = 0
a.count = 0: a.itr = 0: a.cycle_delay = 0: v.level_up = 0: v.mouse_or_key_move = 0: g.m_launcher = ""
RETURN

skipintro:
RETURN

' Error handler.
offscreen: ' Prevents error if blast particles row and column are off-screen. Effect is a partial blast on side of screen.
IF ERR = 5 THEN er = -1: RESUME NEXT
PRINT "Opps, unexpected error"; ERR
END

SUB intro
    j = (v.bottom - v.top) \ 2 + v.top
    k = (v.right - v.left) \ 2 + v.left
    v.intro = -1: a.max = 10
    FOR i = 1 TO 90
        SOUND 900, .05
        CALL alien_move
        LOCATE j, k: COLOR 15: PRINT g.flagship;: COLOR 7
        _DELAY .07
    NEXT
END SUB

SUB set_up
    v.top = 3: v.bottom = _HEIGHT: v.left = 1: v.right = _WIDTH
    g.flagship = CHR$(15)
    a.ship = "-<>-"
    g.num = 3 ' 3 Guardian (lives) to start.
    g.thrusters = 10 ' Shows 1/2 thrust at start up on comm.
    g.icon = g.flagship
    g.m_asc = 250: g.diry = -1: ' Initiate missile ASCII character. g.diry = -1 initiates fire upwards if unmoved.
    IF _FILEEXISTS("Thunder1.ogg") AND _FILEEXISTS("Thunder1.ogg") AND _FILEEXISTS("Thunder1.ogg") AND _FILEEXISTS("Thunder1.ogg") THEN ' Sound effects provided by TheBOB, Bob Seguin, from The QBasic Forum.
        v.snd1 = _SNDOPEN("Thunder1.ogg", "SYNC")
        v.snd2 = _SNDOPEN("Thunder7.ogg", "SYNC")
    END IF
    v.play = -1 ' Skip into on replay.
    LOCATE 2, 1: PRINT STRING$(_WIDTH, CHR$(196));
    _KEYCLEAR ' Clear any previous key presses in buffer.
END SUB

SUB game
END SUB

SUB comm
END SUB

SUB Guardian_missiles
END SUB

SUB missile_check (k)
END SUB

SUB alien_move
    STATIC z5
    y_restore = CSRLIN: x_restore = POS(0) ' Restore column and row upon exit.
    IF ABS(z5 - TIMER) > a.cycle_delay OR v.intro THEN ' z5 is a time delay for alien space ship maneuvers. It can be altered in the "game" subroutine.
        IF v.intro = 0 THEN hh = INT(RND * a.max) + 1 ELSE hh = 15
        FOR h = 1 TO hh
            a.itr = a.itr + 1: IF a.itr > a.max THEN a.itr = 1 ' Needed to offset the EXIT DO hover event, which on exit does not affect the a.itr variable.
            IF a_ran(a.itr) <> -1 THEN ' This is how a destroyed ship is bypassed. -1 is a destroyed alien ship. Code moves to end of DO:LOOP.
                IF a_inertia(a.itr) = 0 THEN ' Determine how many moves in one direction.
                    a_inertia(a.itr) = INT(RND * (v.bottom - v.top) / 2) + 1 ' How many moves to go in any one direction.
                    a_ran(a.itr) = INT(RND * 8) + 1 ' Choose 1 of 8 possible directions.

                    IF a_ran(a.itr) = a_olda_ran(a.itr) OR a_mask_y(a.itr) = 0 AND a_mask_x(a.itr) = 0 AND ran = 1 OR a_mask_y(a.itr) = 0 AND a_mask_x(a.itr) = 0 AND ran = 5 THEN
                        EXIT FOR ' 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 a_ran(a.itr) ' Get changes in column and row coordinates.
                        CASE 1: a_y_loc(a.itr) = -1: a_x_loc(a.itr) = 0 '  Up.
                        CASE 2: a_y_loc(a.itr) = -1: a_x_loc(a.itr) = 2 '  Up and right.
                        CASE 3: a_y_loc(a.itr) = 0: a_x_loc(a.itr) = 2 '   Right.
                        CASE 4: a_y_loc(a.itr) = 1: a_x_loc(a.itr) = 2 '   Down and right.
                        CASE 5: a_y_loc(a.itr) = 1: a_x_loc(a.itr) = 0 '   Down.
                        CASE 6: a_y_loc(a.itr) = 1: a_x_loc(a.itr) = -2 '  Down and left.
                        CASE 7: a_y_loc(a.itr) = 0: a_x_loc(a.itr) = -2 '  Left.
                        CASE 8: a_y_loc(a.itr) = -1: a_x_loc(a.itr) = -2 ' Up and left.
                    END SELECT

                    IF a_y(a.itr) = 0 AND a_x(a.itr) = 0 AND a_ran(a.itr) <> -1 THEN ' New alien space ship enters the screen.
                        i = RND * (v.bottom - v.top) \ 4
                        a_y(a.itr) = (v.bottom - v.top) \ 4 + i + v.top
                        IF a_ran(a.itr) < 5 THEN ' Determine side of entry from initial direction.
                            IF SCREEN(a_y(a.itr), v.left + LEN(a.ship)) = 32 THEN
                                a_x(a.itr) = v.left + 1 ' Enter from the left side and go right.
                            ELSE
                                CALL a_erase
                                EXIT FOR
                            END IF
                        ELSE
                            IF SCREEN(a_y(a.itr), v.right - LEN(a.ship) + 1) = 32 THEN
                                a_x(a.itr) = v.right - LEN(a.ship) ' Enter from the right side and go left.
                            ELSE
                                CALL a_erase
                                EXIT FOR
                            END IF
                        END IF
                    END IF
                    a_olda_ran(a.itr) = a_ran(a.itr) ' Remember last direction. Another line uses this to disallow any RND that chooses the same direction twice.
                ELSE
                    a_inertia(a.itr) = a_inertia(a.itr) - 1 ' Count down the number of moves in any one direction. When zero, switch direction.
                END IF

                FOR i = 1 TO a.max
                    IF i <> a.itr AND a_y(i) <> 0 THEN
                        IF a_y(a.itr) + a_y_loc(a.itr) = a_y(i) THEN
                            IF a_x(a.itr) + a_x_loc(a.itr) + LEN(a.ship) > a_x(i) AND a_x(a.itr) + a_x_loc(a.itr) < a_x(i) + LEN(a.ship) THEN
                                collide = 1
                                EXIT FOR
                            END IF
                        END IF
                    END IF
                NEXT
                IF collide = 1 THEN
                    j = a_y(a.itr): k = a_x(a.itr)
                    a_y_loc(a.itr) = 0: a_x_loc(a.itr) = 0: a_inertia(a.itr) = 0
                    collide = 0 ' Collision detection off. Collision was detected and avoided.
                ELSE
                    j = a_y(a.itr) + a_y_loc(a.itr): k = a_x(a.itr) + a_x_loc(a.itr)
                END IF

                IF j <= v.top OR k <= v.left OR k + LEN(a.ship) > v.right THEN ' Alien ship out of range off screen.
                    a_inertia(a.itr) = 0 ' These two lines keep the out of range ship(s) reasonably nearby.
                    IF j > v.top - 4 AND k < v.right + 3 AND k > v.left - 4 THEN a_y(a.itr) = j: a_x(a.itr) = k
                    IF a_mask_y(a.itr) <> 0 AND a_mask_x(a.itr) <> 0 THEN
                        LOCATE a_mask_y(a.itr), a_mask_x(a.itr)
                        PRINT SPACE$(LEN(a.ship)); ' Mask old position here because the show part of the mask and show routine cannot be used when out of range.
                    END IF
                    a_mask_y(a.itr) = 0: a_mask_x(a.itr) = 0
                ELSE
                    ' Check for v.bottom collision and reverse course if detected.
                    COLOR a.itr
                    IF j >= v.bottom THEN
                        a_y_loc(a.itr) = -a_y_loc(a.itr): a_x_loc(a.itr) = -a_x_loc(a.itr)
                    ELSE
                        a_y(a.itr) = j: a_x(a.itr) = k ' Next move coordinates.
                        ii = 0
                        FOR i = 0 TO LEN(a.ship) - 1 ' Check area through width of ship. Remember all or parts of ship are still present on screen.
                            h = SCREEN(j, k + i)
                            IF h = ASC(g.flagship) OR h = g.m_asc THEN ' Check for contact (collision) with Guardian or missile.
                                IF h = ASC(g.flagship) THEN
                                    ii = 1 ' Indicates contact with flagship and evokes call abduction routine a few lines down.
                                    EXIT FOR
                                ELSE
                                    ii = 2 ' Indicates ship into missile collision.
                                    EXIT FOR
                                END IF
                            END IF
                        NEXT
                        IF ii <> 2 THEN
                            '--------------------------------------------Move alien ship-------------------------------------------------
                            IF a_mask_y(a.itr) <> 0 AND a_mask_x(a.itr) <> 0 THEN LOCATE a_mask_y(a.itr), a_mask_x(a.itr): PRINT SPACE$(LEN(a.ship));
                            LOCATE j, k: PRINT a.ship;
                            a_mask_y(a.itr) = j: a_mask_x(a.itr) = k ' Remember these coordinates to erase alien space ship on next loop.
                            '------------------------------------------------------------------------------------------------------------
                        END IF
                        SELECT CASE ii
                            CASE 1
                                CALL guardian_abduction: EXIT FOR ' Exit loop.
                            CASE 2
                                '''BEEP: BEEP: BEEP: DO: _LIMIT 10: LOOP UNTIL INKEY$ = CHR$(13)
                        END SELECT
                    END IF
                    COLOR 7
                END IF
            END IF ' a_ran(a.itr) > -1 exit point.
            IF a.itr = a.max THEN a.itr = 0: EXIT FOR ' Finished loop. Keep this outside the IF/THEN statement.
        NEXT h
        z5 = TIMER
        LOCATE y_restore, x_restore ' Restore entry column and row positions.
    END IF ' End time event.
END SUB

SUB explosion
END SUB

SUB remove_missile
END SUB

SUB mask_missiles
END SUB

SUB a_erase
    a_y(a.itr) = 0: a_x(a.itr) = 0: a_mask_y(a.itr) = 0: a_mask_x(a.itr) = 0: a_inertia(a.itr) = 0: a_ran(a.itr) = 0: a_y_loc(a.itr) = 0: a_x_loc(a.itr) = 0: a_olda_ran(a.itr) = 0
END SUB

SUB remove_ship
END SUB

SUB guardian_abduction
END SUB

SUB game_level ' Evaluates both alien defeated on a level and Guardian abduction.
END SUB

SUB mouse (mouse_event1, mouse_event2)
END SUB

Pete
Reply


Messages In This Thread
RE: You'd think this would be faster, but NO!!!!!! - by Pete - 10-14-2022, 05:55 PM



Users browsing this thread: 1 Guest(s)