Steve is pretty good with graphics, but his text ability is pretty half-ASCII.
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 Example #2, the slow-down problem.
Pete
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