10-05-2022, 10:11 PM
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)
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
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