Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
12-22-2022, 12:08 AM
The idea of this rather simple game comes from "Astrostorm", which I beheld first on an Apple IIe nearly 40 years back!
Lazy game program. Just press spacebar to start or stop your spaceship. Beware: the response could be a bit late. Work your way toward the top of the screen. The game ends if your spaceship is bashed by an asteroid.
Code: (Select All) 'by mnrvovrfc 2022-dec-21
OPTION _EXPLICIT
DIM AS INTEGER px, py, ph, cm, cb, uc, j, ay, ax, fc
DIM AS LONG kk
DIM AS _BYTE dead, done, holdspace
DIM AS STRING sp40
_TITLE "Astroshower LC"
WIDTH 40, 25: CLS
px = 1: py = 20: ph = 0: cm = 10: cb = 0: kk = 0
sp40 = SPACE$(40)
dead = 0
done = 0
holdspace = 0
uc = 20
fc = 8
LOCATE 24, 1: COLOR 7: PRINT 0;
LOCATE py, px: COLOR fc: PRINT ">";
DO UNTIL dead OR done
IF uc > 0 THEN
uc = uc - 1
IF uc < 1 THEN fc = 15
END IF
FOR j = 1 TO 5
_DELAY 0.015
IF uc < 1 THEN
IF _KEYDOWN(27) THEN done = 1: EXIT FOR
IF _KEYDOWN(32) AND holdspace = 0 THEN
IF cm > 0 THEN cm = cm - 1
holdspace = 1
IF ph = 0 THEN ph = 1 ELSE ph = 0
END IF
IF _KEYDOWN(32) = 0 AND holdspace THEN holdspace = 0
END IF
NEXT ''j
IF done THEN EXIT DO
_DISPLAY
IF ph = 1 THEN
kk = kk + cm + 1
LOCATE 24, 1: COLOR 7: PRINT kk;
COLOR 15
LOCATE py, px: PRINT " ";
px = px + ph
IF px > 40 THEN
px = 1
ph = 0
IF py > 10 THEN
py = py - 1
cb = cb + 1
END IF
cm = cm + cb
END IF
IF SCREEN(py, px) = 42 THEN dead = 1: EXIT DO
LOCATE py, px: PRINT ">";
END IF
j = random1(7) - 4
IF j > 0 THEN
COLOR 7
DO WHILE j > 0
DO
ax = random1(38) + 1
LOOP UNTIL SCREEN(1, ax) = 32
LOCATE 1, ax: PRINT "*";
j = j - 1
LOOP
END IF
LOCATE py, px: COLOR fc: PRINT " ";
COLOR 7
ay = 23
DO WHILE ay > 1
ax = 40
DO WHILE ax > 1
LOCATE ay, ax: PRINT CHR$(SCREEN(ay - 1, ax));
ax = ax - 1
LOOP
ay = ay - 1
LOOP
LOCATE 1, 1: PRINT sp40;
IF SCREEN(py, px) = 42 THEN dead = 1: EXIT DO
LOCATE py, px: COLOR fc: PRINT ">";
LOOP
_AUTODISPLAY
IF dead THEN
LOCATE 1, 1: COLOR 4
PRINT "You have died!";
END
END IF
SYSTEM
FUNCTION random1& (maxval)
random1 = INT(RND * maxval + 1)
END FUNCTION
Posts: 2,171
Threads: 222
Joined: Apr 2022
Reputation:
103
Ah, the good old days. I'd be the richest man in the world if my two great life plans ever come together.
Plan #1: Build a time machine with a range to 1970.
Plan #2: Code a pong game.
Now the good news is, I'm half way there. That's right, I built the time machine. Now all I have to do if figure out how to code a pong game???
Pete
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
I read a book which was a half-opinionated story of the history of Atari up to and including the creation of their awesomesauce 2600 machine. It seems a lot of energy was needed just to create that "Pong" game which wasn't a big deal.
I have to dig deep into my archives but I created four different programs of silly pong games in text mode in QuickBASIC. Then in QB64 I cobbled them up into one program with a menu to choose one of the games to play. One of the variations has the ball "explode" after it hits the target, and the fragments could also hit targets for additional points. It wasn't very interesting, I was very bored the day I created it.
In addition I was motivated by that famous book of games by David Heiserman I think was his name, for IBM PC. I believe there was an edition for TRS-80 computers but not necessarily for the Color Computer. One called "Arrow Shoot" which was very funny. I created a fancy version in Freebasic with four levels. It would be easy to convert it to QB64.
"A large tree fell on your head, and you're dead! Dead, dead, dead! You took 1 step. You collected zero treasures."
Nobody wanted to play an "adventure" game in which that was always the message!
Also the "Hacker's Aid" was one of my favorite programs. Not so good: the "translators". There's one that teaches somebody to talk like Bugs Bunny LOL.
Under 50 bucks! 50 bucks? The fun is back, oh yes sirree! It's the twenty-six hundred from Ah-tah-ree!
Posts: 2,171
Threads: 222
Joined: Apr 2022
Reputation:
103
The guy who invented Pong Ralph Baer did so in the 1950's but shelved it. Unfortunately he sold out to Magnavox who turned Ralph's 'Brown Box' into the Magnavox Odyssey. Nolan Bushnell saw the pong game at a sales convention, where Bushnell impersonated a Magnavox salesman. So, as the saying goes, "Good artists borrow, great artists steal."
Pete
Posts: 476
Threads: 25
Joined: Nov 2022
Reputation:
45
(12-22-2022, 12:29 AM)Pete Wrote: Plan #2: Code a pong game.
Same page Pete.
I have the same ambition. I found this excellent tutorial on Pong with Vectors in YouTube, and also have been learning Vectors from Sprezzo. I also wanted to share this thing I made that does not use vectors, but it's pretty fun! I used the approach of a matrix of 3x3 cells to determine collisions. Turn your speakers on and at a low volume (it uses PLAY MB for sound effects, and the feedback is necessary). I almost had it perfect, and I think I could add one more permutation in my 3x3 matrix collision handler to get it so that the single brick in certain conditions isn't erased. Anyway, sharing is caring
YouTube Playlist: Godot Pong with Vectors Tutorial Series
Here is a video of the thing running: BOUNCER demo
Steve: I MergeFile'd this thing FYI useful for sharing inline in forum pastes!
I made this thing:
Code: (Select All) ''
' BOUNCER
'
' A little sandbox prototype to help me master the logic and physics for
' ball and paddle stuff. Mostly figuring out collisions and reflections.
'
' Press F5 to start the debugger. This is something that will also wind up
' going into my QB64_GJ_LIB for sure. Also a bunch of the _MISC.BM funcs
' and subs will be added too.
'
' @author Rick Christy <grymmjack@gmail.com>
'
$CONSOLE
OPTION _EXPLICIT
OPTION _EXPLICITARRAY
$IF FALSE = UNDEFINED AND TRUE = UNDEFINED THEN
CONST FALSE = 0 : CONST TRUE = NOT FALSE
$END IF
$EXEICON:'./BOUNCER.ico'
_TITLE "BOUNCER"
_CONSOLETITLE "BOUNCER"
TYPE CONFIG
FULLSCREEN AS INTEGER
FULLSCREEN_SMOOTH AS INTEGER
RANDOM_BG AS INTEGER
RANDOM_FG AS INTEGER
SOUND_ENABLED AS INTEGER
BALL_CHAOS_TIMER AS INTEGER
RAND_NUM_BLOCKS AS INTEGER
CHAOS_SECS AS INTEGER
NUM_BLOCKS AS INTEGER
ORIG_NUM_BLOCKS AS INTEGER
PREV_NUM_BLOCKS AS INTEGER
BLOCK_MAX_W AS INTEGER
BLOCK_MAX_H AS INTEGER
LIM AS INTEGER
AUTO_BLOCKS_SECS AS INTEGER
END TYPE
DIM SHARED CFG AS CONFIG
TYPE SCREEN_OBJECT
BG_KOLOR AS LONG
FG_KOLOR AS LONG
W AS INTEGER
H AS INTEGER
BPP AS INTEGER
VISIBLE_PAGE AS INTEGER
ACTIVE_PAGE AS INTEGER
END TYPE
DIM SHARED __SCREEN AS SCREEN_OBJECT
CONST GAME_SCREEN = 0%
CONST DEBUGGER_CONSOLE = 1%
TYPE BALL_OBJECT
X AS INTEGER
Y AS INTEGER
X_DIR AS INTEGER
Y_DIR AS INTEGER
SPEED AS INTEGER
KOLOR AS LONG
TRACE_PATH AS INTEGER
HIT_90_NUM AS INTEGER
DISPLAY AS STRING * 1
END TYPE
DIM SHARED BALL AS BALL_OBJECT
DIM SHARED BALL_9GRID(1 TO 3, 1 TO 3) AS INTEGER
DIM SHARED BALL_25GRID(1 TO 5, 1 TO 5) AS INTEGER
DIM SHARED BALL_ROUND AS STRING
DIM SHARED BALL_SOLID AS STRING
BALL_ROUND$ = CHR$(9)
BALL_SOLID$ = CHR$(10)
TYPE BLOCK_OBJECT
X AS INTEGER
Y AS INTEGER
W AS INTEGER
H AS INTEGER
INDEX AS INTEGER
KOLOR AS LONG
LIVES AS INTEGER
DISPLAY AS STRING * 1
END TYPE
DIM SHARED BLOCK AS BLOCK_OBJECT
DIM SHARED BLOCKS(1 TO CFG.NUM_BLOCKS%) AS BLOCK_OBJECT
TYPE LEVEL_OBJECT
START_X AS INTEGER
END_X AS INTEGER
START_Y AS INTEGER
END_Y AS INTEGER
END TYPE
DIM SHARED LEVEL AS LEVEL_OBJECT
TYPE STATS_OBJECT
TOP_BOUNCES AS INTEGER
RIGHT_BOUNCES AS INTEGER
BOT_BOUNCES AS INTEGER
LEFT_BOUNCES AS INTEGER
BLOCK_BOUNCES AS INTEGER
BALL_INVERTS AS INTEGER
BALL_RANDOMS AS INTEGER
END TYPE
DIM SHARED STATS AS STATS_OBJECT
TYPE TIMER_OBJECT
STARTED AS DOUBLE
STOPPED AS DOUBLE
TICKS AS LONG
SECONDS AS LONG
HOLD AS INTEGER
LAP_COUNT AS INTEGER
END TYPE
TYPE TIMER_LAP
STARTED AS DOUBLE
STOPPED AS DOUBLE
TICKS AS LONG
END TYPE
DIM SHARED MAIN_TIMER AS INTEGER
DIM SHARED TICKS_TIMER AS TIMER_OBJECT
DIM SHARED TIMER_LAPS(10) AS TIMER_LAP
TYPE DEBUG_OBJECT
ENABLED AS INTEGER
DO_BREAKPOINTS AS INTEGER
IN_CONSOLE AS INTEGER
VERBOSE AS INTEGER
VERBOSITY AS INTEGER
NEXT_STEP AS INTEGER
CUR_STEP AS INTEGER
PREV_STEP AS INTEGER
MARK_TIME AS STRING
MARK_TIMER AS DOUBLE
PREV_MARK_TIME AS STRING
PREV_MARK_TIMER AS DOUBLE
END TYPE
DIM SHARED DEBUG AS DEBUG_OBJECT
DIM SHARED AS INTEGER DEBUG_MIN, DEBUG_AVG, DEBUG_MAX, DEBUG_WTF
DEBUG_MIN% = 1
DEBUG_AVG% = 2
DEBUG_MAX% = 3
DEBUG_WTF% = 4
configure
ball_init
level_init
block_init
blocks_init
timers_init
debug_init
screen_init
DIM AS STRING k, dmsg
DO:
IF CFG.LIM% > 0 THEN _LIMIT CFG.LIM%
k$ = INKEY$
IF k$ <> "" THEN DPRINT "INKEY$", DEBUG_MIN
SELECT CASE k$
CASE LCASE$("s"): 'S = Toggle sound
DPRINT "INKEY$: 'S' TOGGLE SOUND", DEBUG_AVG
ball_toggle_sound : stats_update
CASE LCASE$("b"): 'B = Toggle breakpoints
DPRINT "INKEY$: 'B' TOGGLE BREAKPOINTS", DEBUG_AVG
debug_toggle_do_breakpoints : stats_update
CASE "=": '+/ = Increase speed by increasing limit
DPRINT "INKEY$: '=' INCREASE LIMIT", DEBUG_AVG
CFG.LIM% = CFG.LIM% + 1 : stats_update
CASE "-": '- = Decrease speed by decreasing limit
DPRINT "INKEY$: '-' DECREASE LIMIT", DEBUG_AVG
CFG.LIM% = CFG.LIM% - 1 : stats_update
CASE " ": 'SPACE = randomize blocks
DPRINT "INKEY$: ' ' RANDOMIZE BLOCKS", DEBUG_AVG
blocks_init : game_step
CASE ",": ', = increment total blocks
DPRINT "INKEY$: ',' INCREMENT BLOCKS", DEBUG_AVG
blocks_dec : game_step
CASE ".": '. = decrement total blocks
DPRINT "INKEY$: '.' DECREMENT BLOCKS", DEBUG_AVG
blocks_inc : game_step
CASE CHR$(0) + "G": 'HOME = Show console explicit
DPRINT "INKEY$: 'HOME' SHOW DEBUG CONSOLE EXPLICIT", DEBUG_AVG
debug_console_show
CASE CHR$(0) + "O": 'END = Hide console explicit
DPRINT "INKEY$: 'END' HIDE DEBUG CONSOLE EXPLICIT", DEBUG_AVG
debug_console_hide
CASE CHR$(0) + ";": 'F1 = toggle ball trace path
DPRINT "INKEY$: 'F1' TOGGLE BALL TRACE PATH", DEBUG_AVG
ball_toggle_trace_path
CASE CHR$(0) + "<": 'F2 = clear debug console
DPRINT "INKEY$: 'F2' CLEAR CONSOLE", DEBUG_AVG
console_clear
CASE CHR$(0) + "=": 'F3 = mark console
DPRINT "INKEY$: 'F3' MARK CONSOLE", DEBUG_AVG
console_mark
CASE CHR$(0) + ">": 'F4 = toggle ball char
DPRINT "INKEY$: 'F4' toggle ball char", DEBUG_AVG
ball_toggle_char
CASE CHR$(0) + "?": 'F5 = start debugging
DPRINT "INKEY$: 'F5' START DEBUGGING", DEBUG_AVG
debug_start : stats_update
CASE CHR$(0) + "A": 'F7 = go to next debug step
DPRINT "INKEY$: 'F7' NEXT STEP", DEBUG_AVG
debug_next : stats_update
CASE CHR$(0) + "B": 'F8 = stop debugging
DPRINT "INKEY$: 'F8' STOP DEBUGGING", DEBUG_AVG
debug_stop : game_step
CASE CHR$(0) + "C": 'F9 = debug level min
DPRINT "INKEY$: 'F9' DEBUG LEVEL MIN", DEBUG_AVG
DEBUG.VERBOSITY% = DEBUG_MIN : stats_update
CASE CHR$(0) + "D": 'F10 = debug level avg
DPRINT "INKEY$: 'F10' DEBUG LEVEL AVG", DEBUG_AVG
DEBUG.VERBOSITY% = DEBUG_AVG : stats_update
CASE CHR$(0) + CHR$(133): 'F11 = debug level max
DPRINT "INKEY$: 'F11' DEBUG LEVEL MAX", DEBUG_AVG
DEBUG.VERBOSITY% = DEBUG_MAX : stats_update
'FUTURE - add F12 - toggle cross hair to show x, y of screen and ball
CASE CHR$(27): ' ESC = Quit
DPRINT "INKEY$: 'ESC' QUIT", DEBUG_AVG
timers_main_shutdown
SYSTEM
END SELECT
IF DEBUG.ENABLED% = TRUE THEN
IF DEBUG.NEXT_STEP% = TRUE THEN game_step
ELSE
game_step
END IF
_DISPLAY
LOOP UNTIL _KEYHIT = 27 'ESC = Quit
COLOR 0, 7 : CLS
SYSTEM
SUB game_step
DPRINT "game_step", DEBUG_MIN
IF DEBUG.ENABLED% = TRUE THEN DEBUG.NEXT_STEP% = FALSE
ball_move
ball_stay_in_bounds
stats_update
END SUB
SUB configure
DPRINT "configure", DEBUG_AVG
CFG.FULLSCREEN% = TRUE
CFG.FULLSCREEN_SMOOTH% = TRUE
CFG.RANDOM_BG% = TRUE
CFG.RANDOM_FG% = TRUE
CFG.SOUND_ENABLED% = TRUE
CFG.BALL_CHAOS_TIMER% = TRUE
CFG.RAND_NUM_BLOCKS% = TRUE
CFG.CHAOS_SECS% = 5
CFG.NUM_BLOCKS% = 16
CFG.ORIG_NUM_BLOCKS% = CFG.NUM_BLOCKS%
CFG.PREV_NUM_BLOCKS% = CFG.NUM_BLOCKS%
CFG.BLOCK_MAX_W% = 10
CFG.BLOCK_MAX_H% = 10
CFG.LIM% = 30
CFG.AUTO_BLOCKS_SECS% = 30
END SUB
SUB screen_init
DPRINT "screen_init", DEBUG_AVG
screen_reset
__SCREEN.W% = _WIDTH
__SCREEN.H% = _HEIGHT
__SCREEN.BPP% = _PIXELSIZE
__SCREEN.VISIBLE_PAGE% = 0
__SCREEN.ACTIVE_PAGE% = 0
IF CFG.FULLSCREEN% = FALSE THEN
_SCREENMOVE _MIDDLE
END IF
END SUB
SUB screen_reset
DPRINT "screen_reset", DEBUG_AVG
screen_set_active_page GAME_SCREEN : screen_fullscreen
screen_set_active_page DEBUGGER_CONSOLE : screen_fullscreen
END SUB
SUB screen_fullscreen
DPRINT "screen_fullscreen", DEBUG_WTF
_BLINK OFF
_CONTROLCHR OFF
IF CFG.FULLSCREEN% = TRUE THEN
IF CFG.FULLSCREEN_SMOOTH% = TRUE THEN
_FULLSCREEN _SQUAREPIXELS, _SMOOTH
ELSE
_FULLSCREEN _SQUAREPIXELS
END IF
END IF
END SUB
SUB screen_clear
DPRINT "screen_clear", DEBUG_AVG
IF CFG.RANDOM_BG% = TRUE THEN __SCREEN.BG_KOLOR& = rand_in_range(0, 7)
screen_set_active_page GAME_SCREEN
COLOR BALL.KOLOR&,__SCREEN.BG_KOLOR&
CLS
END SUB
SUB screen_set_active_page (page%)
DPRINT "screen_set_active_page(page%=" + n$(page%) + ")", DEBUG_WTF
SCREEN ,,page%
screen_fullscreen
__SCREEN.ACTIVE_PAGE% = page%
END SUB
SUB screen_set_visible_page (page%)
DPRINT "screen_set_visible_page(page%=" + n$(page%) + ")", DEBUG_WTF
SCREEN ,,,page%
screen_fullscreen
__SCREEN.VISIBLE_PAGE% = page%
END SUB
SUB screen_set_both_pages (page%)
DPRINT "screen_set_both_pages(page%=" + n$(page%) + ")", DEBUG_WTF
SCREEN ,,page%,page%
screen_fullscreen
__SCREEN.ACTIVE_PAGE% = page%
__SCREEN.VISIBLE_PAGE% = page%
END SUB
SUB ball_init
DPRINT "ball_init", DEBUG_AVG
BALL.X% = rand_in_range(LEVEL.START_X%, LEVEL.END_X%)
BALL.Y% = rand_in_range(LEVEL.START_Y%, LEVEL.END_Y%)
BALL.X_DIR% = 1
BALL.Y_DIR% = -1
BALL.SPEED% = 1
BALL.KOLOR& = 15
BALL.HIT_90_NUM% = 0
BALL.TRACE_PATH% = TRUE
BALL.DISPLAY$ = CHR$(9)
END SUB
SUB ball_toggle_char
DPRINT "ball_toggle_char", DEBUG_MAX
IF BALL.DISPLAY$ = BALL_ROUND$ THEN
BALL.DISPLAY$ = BALL_SOLID$
ELSE
BALL.DISPLAY$ = BALL_ROUND$
ENDIF
screen_set_active_page GAME_SCREEN
LOCATE BALL.Y%, BALL.X% : PRINT BALL.DISPLAY$;
END SUB
SUB ball_toggle_trace_path
DPRINT "ball_toggle_trace_path", DEBUG_MAX
IF BALL.TRACE_PATH% = TRUE THEN
BALL.TRACE_PATH% = FALSE
ball_clear_traces
ELSE
BALL.TRACE_PATH% = TRUE
END IF
END SUB
SUB ball_clear_traces
DPRINT "ball_clear_traces", DEBUG_MAX
DIM AS INTEGER y, x, c
FOR y% = LEVEL.START_Y% TO LEVEL.END_Y%
FOR x% = LEVEL.START_X TO LEVEL.END_X%
c% = SCREEN(y%, x%)
IF c% = 249 THEN
screen_set_both_pages GAME_SCREEN
LOCATE y%, x% : PRINT " ";
END IF
NEXT x%
NEXT y%
END SUB
SUB ball_get_25grid
DPRINT "ball_get_25grid", DEBUG_AVG
DIM AS INTEGER x, y, grid_x, grid_y, char
FOR y%=1 TO 5
grid_y% = clamp(BALL.Y%-5 + y%, LEVEL.START_Y%, LEVEL.END_Y%)
FOR x% = 1 TO 5
grid_x% = clamp(BALL.X%-5 + x%, LEVEL.START_X%, LEVEL.END_X%)
screen_set_active_page GAME_SCREEN
char% = SCREEN(grid_y%, grid_x%)
IF char% <> ASC(BALL.DISPLAY$) THEN
SELECT CASE char%
CASE ASC(BLOCK.DISPLAY$):
BALL_25GRID(y%, x%) = 1
CASE ELSE:
BALL_25GRID(y%, x%) = 0
END SELECT
END IF
NEXT x%
NEXT y%
END SUB
SUB ball_get_9grid
DPRINT "ball_get_9grid", DEBUG_AVG
DIM AS INTEGER x, y, grid_x, grid_y, char
FOR y%=1 TO 3
grid_y% = clamp(BALL.Y%-2 + y%, LEVEL.START_Y%, LEVEL.END_Y%)
FOR x% = 1 TO 3
grid_x% = clamp(BALL.X%-2 + x%, LEVEL.START_X%, LEVEL.END_X%)
screen_set_active_page GAME_SCREEN
char% = SCREEN(grid_y%, grid_x%)
IF char% <> ASC(BALL.DISPLAY$) THEN
SELECT CASE char%
CASE ASC(BLOCK.DISPLAY$):
BALL_9GRID(y%, x%) = 1
CASE ELSE:
BALL_9GRID(y%, x%) = 0
END SELECT
END IF
NEXT x%
NEXT y%
IF DEBUG.ENABLED% = TRUE AND DEBUG.VERBOSITY% >= DEBUG_AVG THEN ball_dump_9grid
END SUB
SUB ball_dump_9grid
DPRINT "ball_dump_9grid", DEBUG_AVG
DIM AS INTEGER y, x
DIM s AS STRING
DPRINT "", DEBUG_AVG
DPRINT "BALL_9GRID(" + n$(y%) + ", " + n$(x%) + ") {", DEBUG_AVG
FOR y% = 1 TO 3
s$ = " "
FOR x% = 1 TO 3
s$ = s$ + n$(BALL_9GRID(y%, x%)) + " "
NEXT x%
DPRINT s$, DEBUG_AVG
NEXT y%
DPRINT "}", DEBUG_AVG
END SUB
FUNCTION ball_will_bounce_9grid% (y%, x%)
DPRINT "ball_will_bounce_9grid (" + _
"y%=" + n$(y%) + ", x%=" + n$(x%) + ")", DEBUG_MAX
DIM AS INTEGER check_y, check_x, checks_sum
checks_sum% = 0
FOR check_y% = 1 TO 3
FOR check_x% = 1 TO 3
checks_sum% = checks_sum% + BALL_9GRID(check_y%, check_x%)
NEXT check_x%
NEXT check_y%
IF checks_sum% > 0 THEN
ball_chaos_hold
ball_will_bounce_9grid% = TRUE
ELSE
ball_will_bounce_9grid% = FALSE
END IF
END FUNCTION
FUNCTION ball_will_bounce_25grid% (y%, x%)
DPRINT "ball_will_bounce_25grid (" + _
"y%=" + n$(y%) + ", x%=" + n$(x%) + ")", DEBUG_MAX
DIM AS INTEGER check_y, check_x, checks_sum
checks_sum% = 0
FOR check_y% = 1 TO 5
FOR check_x% = 1 TO 5
checks_sum% = checks_sum% + BALL_25GRID(check_y%, check_x%)
NEXT check_x%
NEXT check_y%
IF checks_sum% > 0 THEN
ball_chaos_hold
ball_will_bounce_25grid% = TRUE
ELSE
ball_will_bounce_25grid% = FALSE
END IF
END FUNCTION
FUNCTION ball_will_invert_path% ()
DPRINT "ball_will_invert_path()", DEBUG_AVG
DIM AS INTEGER top_left, top_right, bot_left, bot_right, sum
'_3L = 3 L shape neighbors _2L = partial L shape neighbors (2 but not 3)
DIM AS INTEGER top_left_2L, top_right_2L, bot_left_2L, bot_right_2L
DIM AS INTEGER top_left_3L, top_right_3L, bot_left_3L, bot_right_3L
DIM AS INTEGER top_left_4L, top_right_4L, bot_left_4L, bot_right_4L
DIM AS INTEGER top_left_5L, top_right_5L, bot_left_5L, bot_right_5L
'x..
'.*.
'...\ = x-1 y-1
top_left% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 0) _
)
'..x
'.*.
'.../ = x+1 y-1
top_right% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 0) _
)
'...
'.*.
'x../ = x-1 y+1
bot_left% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 0) _
)
'...
'.*.
'..x\ = x+1 y+1
bot_right% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 1) _
)
'xx.
'x*.
'...\ = x-1 y-1
top_left_2L% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 1) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 1) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 0) _
)
'.xx
'.*x
'.../ = x+1 y-1
top_right_2L% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 1) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 1) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 0) _
)
'...
'x*.
'xx./ = x-1 y+1
bot_left_2L% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 1) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 1) _
AND (BALL_9GRID(3,3) = 0) _
)
'...
'.*x
'.xx\ = x+1 y+1
bot_right_2L% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 1) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 1) _
AND (BALL_9GRID(3,3) = 1) _
)
'xxx
'x*.
'x..\ = x-1 y-1
top_left_3L% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 1) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 1) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 0) _
)
'xxx
'.*x
'..x/ = x+1 y-1
top_right_3L% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 1) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 1) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 1) _
)
'x..
'x*.
'xxx/ = x-1 y+1
bot_left_3L% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 1) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 1) _
AND (BALL_9GRID(3,3) = 1) _
)
'..x
'.*x
'xxx\ = x+1 y+1
bot_right_3L% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 1) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 1) _
AND (BALL_9GRID(3,3) = 1) _
)
'xx.
'x*.
'x..\ = x-1 y-1
top_left_4L% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 1) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 1) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 0) _
)
'.xx
'.*x
'..x/ = x+1 y-1
top_right_4L% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 1) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 1) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 1) _
)
'x..
'x*.
'xx./ = x-1 y+1
bot_left_4L% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 1) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 1) _
AND (BALL_9GRID(3,3) = 0) _
)
'..x
'.*x
'.xx\ = x+1 y+1
bot_right_4L% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 1) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 1) _
AND (BALL_9GRID(3,3) = 1) _
)
'x.x
'x*.
'x..\ = x-1 y-1
top_left_5L% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 1) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 0) _
)
'x.x
'.*x
'..x/ = x+1 y-1
top_right_5L% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 1) _
AND (BALL_9GRID(3,1) = 0) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 1) _
)
'x..
'x*.
'x.x/ = x-1 y+1
bot_left_5L% = ( _
(BALL_9GRID(1,1) = 1) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 0) _
AND (BALL_9GRID(2,1) = 1) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 0) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 1) _
)
'..x
'.*x
'x.x\ = x+1 y+1
bot_right_5L% = ( _
(BALL_9GRID(1,1) = 0) _
AND (BALL_9GRID(1,2) = 0) _
AND (BALL_9GRID(1,3) = 1) _
AND (BALL_9GRID(2,1) = 0) _
AND (BALL_9GRID(2,2) = 0) _
AND (BALL_9GRID(2,3) = 1) _
AND (BALL_9GRID(3,1) = 1) _
AND (BALL_9GRID(3,2) = 0) _
AND (BALL_9GRID(3,3) = 1) _
)
sum% = 0
DIM AS INTEGER will_corner, will_2L, will_3L, will_4L, will_5L, will_invert
will_corner% = FALSE
will_2L% = FALSE : will_3L% = FALSE : will_4L% = FALSE : will_5L% = FALSE
will_invert% = FALSE
IF top_left% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_corner% = TRUE
END IF
IF top_right% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_corner% = TRUE
END IF
IF bot_left% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_corner% = TRUE
END IF
IF bot_right% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_corner% = TRUE
END IF
IF top_left_2L% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_2L% = TRUE
END IF
IF top_right_2L% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_2L% = TRUE
END IF
IF bot_left_2L% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_2L% = TRUE
END IF
IF bot_right_2L% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_2L% = TRUE
END IF
IF top_left_3L% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_3L% = TRUE
END IF
IF top_right_3L% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_3L% = TRUE
END IF
IF bot_left_3L% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_3L% = TRUE
END IF
IF bot_right_3L% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_3L% = TRUE
END IF
IF top_left_4L% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_4L% = TRUE
END IF
IF top_right_4L% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_4L% = TRUE
END IF
IF bot_left_4L% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_4L% = TRUE
END IF
IF bot_right_4L% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_4L% = TRUE
END IF
IF top_left_5L% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_5L% = TRUE
END IF
IF top_right_5L% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = -1 THEN
sum% = sum% + 1 : will_5L% = TRUE
END IF
IF bot_left_5L% = TRUE AND BALL.X_DIR% = -1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_5L% = TRUE
END IF
IF bot_right_5L% = TRUE AND BALL.X_DIR% = 1 AND BALL.Y_DIR% = 1 THEN
sum% = sum% + 1 : will_5L% = TRUE
END IF
IF sum% > 0 THEN will_invert% = TRUE
DPRINT " top_left%=" + b$(top_left%), DEBUG_WTF
DPRINT " top_right%=" + b$(top_right%), DEBUG_WTF
DPRINT " bot_left%=" + b$(bot_left%), DEBUG_WTF
DPRINT " bot_right%=" + b$(bot_right%), DEBUG_WTF
DPRINT " top_left_2L%=" + b$(top_left_2L%), DEBUG_WTF
DPRINT "top_right_2L%=" + b$(top_right_2L%), DEBUG_WTF
DPRINT " bot_left_2L%=" + b$(bot_left_2L%), DEBUG_WTF
DPRINT "bot_right_2L%=" + b$(bot_right_2L%), DEBUG_WTF
DPRINT " top_left_3L%=" + b$(top_left_3L%), DEBUG_WTF
DPRINT "top_right_3L%=" + b$(top_right_3L%), DEBUG_WTF
DPRINT " bot_left_3L%=" + b$(bot_left_3L%), DEBUG_WTF
DPRINT "bot_right_3L%=" + b$(bot_right_3L%), DEBUG_WTF
DPRINT " top_left_4L%=" + b$(top_left_4L%), DEBUG_WTF
DPRINT "top_right_4L%=" + b$(top_right_4L%), DEBUG_WTF
DPRINT " bot_left_4L%=" + b$(bot_left_4L%), DEBUG_WTF
DPRINT "bot_right_4L%=" + b$(bot_right_4L%), DEBUG_WTF
DPRINT " top_left_5L%=" + b$(top_left_5L%), DEBUG_WTF
DPRINT "top_right_5L%=" + b$(top_right_5L%), DEBUG_WTF
DPRINT " bot_left_5L%=" + b$(bot_left_5L%), DEBUG_WTF
DPRINT "bot_right_5L%=" + b$(bot_right_5L%), DEBUG_WTF
DPRINT "-------------", DEBUG_WTF
DPRINT " sum: " + n$(sum%), DEBUG_WTF
DPRINT "-------------", DEBUG_WTF
DPRINT " will invert%=" + b$(will_invert%), DEBUG_WTF
DPRINT " will_corner%=" + b$(will_corner%), DEBUG_WTF
DPRINT " will_2L%=" + b$(will_2L%), DEBUG_WTF
DPRINT " will_3L%=" + b$(will_3L%), DEBUG_WTF
DPRINT " will_4L%=" + b$(will_4L%), DEBUG_WTF
DPRINT " will_5L%=" + b$(will_5L%), DEBUG_WTF
IF sum% > 0 THEN
DPRINT "ball_will_invert_path = TRUE", DEBUG_WTF
ball_sound_invert
ball_will_invert_path% = TRUE
ELSE
DPRINT "ball_will_invert_path = FALSE", DEBUG_WTF
ball_will_invert_path% = FALSE
END IF
END FUNCTION
FUNCTION ball_will_bounce_left% ()
DPRINT "ball_will_bounce_left()", DEBUG_AVG
'..x
'.*x
'..x
IF BALL_9GRID(1,3) _
+ BALL_9GRID(2,3) _
+ BALL_9GRID(3,3) >= 2 _
THEN
DPRINT "ball_will_bounce_left = TRUE", DEBUG_AVG
BALL.HIT_90_NUM% = 0
ball_will_bounce_left% = TRUE
ELSE
DPRINT "ball_will_bounce_left = FALSE", DEBUG_AVG
ball_will_bounce_left% = FALSE
END IF
END FUNCTION
FUNCTION ball_will_bounce_right% ()
DPRINT "ball_will_bounce_right()", DEBUG_AVG
'x..
'x*.
'x..
IF BALL_9GRID(1,1) _
+ BALL_9GRID(2,1) _
+ BALL_9GRID(3,1) >= 2 _
THEN
DPRINT "ball_will_bounce_right = TRUE", DEBUG_AVG
BALL.HIT_90_NUM% = 0
ball_will_bounce_right% = TRUE
ELSE
DPRINT "ball_will_bounce_right = FALSE", DEBUG_AVG
ball_will_bounce_right% = FALSE
END IF
END FUNCTION
FUNCTION ball_will_bounce_down% ()
DPRINT "ball_will_bounce_down()", DEBUG_AVG
'xxx
'.*.
'...
IF BALL_9GRID(1,1) _
+ BALL_9GRID(1,2) _
+ BALL_9GRID(1,3) >= 2 _
THEN
DPRINT "ball_will_bounce_down = TRUE", DEBUG_AVG
BALL.HIT_90_NUM% = 0
ball_will_bounce_down% = TRUE
ELSE
DPRINT "ball_will_bounce_down = FALSE", DEBUG_AVG
ball_will_bounce_down% = FALSE
END IF
END FUNCTION
FUNCTION ball_will_bounce_up% ()
DPRINT "ball_will_bounce_up()", DEBUG_AVG
'...
'.*.
'xxx
IF BALL_9GRID(3,1) _
+ BALL_9GRID(3,2) _
+ BALL_9GRID(3,3) >= 2 _
THEN
DPRINT "ball_will_bounce_up = TRUE", DEBUG_AVG
BALL.HIT_90_NUM% = 0
ball_will_bounce_up% = TRUE
ELSE
DPRINT "ball_will_bounce_up = FALSE", DEBUG_AVG
ball_will_bounce_up% = FALSE
END IF
END FUNCTION
SUB ball_hit_block
DPRINT "ball_hit_block", DEBUG_AVG
DIM AS INTEGER _
bouncing_up, bouncing_down, _
bouncing_left, bouncing_right, _
inverting_path, bouncing
bouncing% = FALSE
bouncing_up% = ball_will_bounce_up%
bouncing_down% = ball_will_bounce_down%
bouncing_left% = ball_will_bounce_left%
bouncing_right% = ball_will_bounce_right%
inverting_path% = ball_will_invert_path%
IF inverting_path% = TRUE THEN
BALL.Y_DIR% = BALL.Y_DIR% * -1
BALL.X_DIR% = BALL.X_DIR% * -1
BALL.HIT_90_NUM% = BALL.HIT_90_NUM% + 1
ball_sound_invert
ELSEIF bouncing_up% = TRUE THEN
BALL.Y_DIR% = -1
bouncing% = TRUE
ELSEIF bouncing_down% = TRUE THEN
BALL.Y_DIR% = 1
bouncing% = TRUE
ELSEIF bouncing_left% = TRUE THEN
BALL.X_DIR% = -1
bouncing% = TRUE
ELSEIF bouncing_right% = TRUE THEN
BALL.X_DIR% = 1
bouncing% = TRUE
END IF
IF bouncing% = TRUE THEN ball_sound_hit_block
END SUB
SUB ball_erase (y%, x%)
DPRINT "ball_erase", DEBUG_AVG
DIM AS INTEGER c
y% = clamp(y%, LEVEL.START_Y%, LEVEL.END_Y%)
x% = clamp(x%, LEVEL.START_X%, LEVEL.END_X%)
c% = SCREEN(y%, x%)
IF c% = ASC(BLOCK.DISPLAY$) THEN EXIT SUB
screen_set_active_page GAME_SCREEN
COLOR BALL.KOLOR&, __SCREEN.BG_KOLOR&
IF BALL.TRACE_PATH% = FALSE THEN
LOCATE y%, x% : PRINT SPACE$(LEN(BALL.DISPLAY$))
ELSE
LOCATE y%, x% : PRINT CHR$(249);
END IF
END SUB
SUB ball_move
DPRINT "ball_move", DEBUG_AVG
ball_erase BALL.Y%, BALL.X%
ball_get_9grid
IF (ball_will_bounce_9grid(BALL.Y%, BALL.X%)) THEN
ball_hit_block
END IF
BALL.X% = clamp(BALL.X% + BALL.X_DIR%, LEVEL.START_X%, LEVEL.END_X%)
BALL.Y% = clamp(BALL.Y% + BALL.Y_DIR%, LEVEL.START_Y%, LEVEL.END_Y%)
screen_set_active_page GAME_SCREEN
COLOR BALL.KOLOR&, __SCREEN.BG_KOLOR&
LOCATE BALL.Y%, BALL.X% : PRINT BALL.DISPLAY$;
ball_chaos_unhold
END SUB
SUB ball_chaos_hold
DPRINT "ball_chaos_hold", DEBUG_MAX
TICKS_TIMER.HOLD% = TRUE
END SUB
SUB ball_chaos_unhold
DPRINT "ball_chaos_unhold", DEBUG_MAX
TICKS_TIMER.HOLD% = FALSE
END SUB
SUB ball_chaos
DIM AS INTEGER old_x, old_y, x, y, sum
ball_get_25grid
FOR y% = 1 TO 5
FOR x% = 1 TO 5
sum% = sum% + BALL_25GRID(y%, x%)
NEXT x%
NEXT y%
IF sum% = 0 THEN
old_x% = BALL.X% : old_y% = BALL.Y%
ball_erase old_y%, old_x%
BALL.X% = BALL.X% + (rand_in_range(0,1) * rand_sign)
BALL.Y% = BALL.Y% + (rand_in_range(0,1) * rand_sign)
DIM s AS STRING
s$ = "***** BALL_CHAOS_TIMER ***** "
s$ = s$ + "OLD BALL.Y%=" + n$(old_y%)
s$ = s$ + ", BALL.X%=" + n$(old_x%)
s$ = s$ + " -> NEW BALL.Y%=" + n$(BALL.Y%)
s$ = s$ + ", BALL.X%=" + n$(BALL.X%)
DPRINT s$, DEBUG_MIN
ball_sound_chaos
ELSE
ball_chaos_hold
END IF
END SUB
SUB ball_stay_in_bounds
DPRINT "ball_stay_in_bounds", DEBUG_AVG
DIM AS INTEGER new_x, pad
IF BALL.Y% <= LEVEL.START_Y% THEN
ball_bounce_top
ELSEIF BALL.X% >= LEVEL.END_X% THEN
ball_bounce_right
ELSEIF BALL.Y% >= LEVEL.END_Y% THEN
ball_bounce_bot
ELSEIF BALL.X% <= LEVEL.START_X% THEN
ball_bounce_left
END IF
pad% = 3
'top left corner of level
IF BALL.Y% = (LEVEL.START_Y% + pad%) AND BALL.X% = (LEVEL.START_X% + pad%) THEN
DPRINT "* IN TOP LEFT CORNER OF LEVEL", DEBUG_AVG
new_x% = BALL.X% + rand_in_range(1,pad%)
IF new_x% <> BALL.X% THEN
BALL.HIT_90_NUM% = 0
ball_erase BALL.Y%, BALL.X%
BALL.X% = new_x%
ball_sound_random
STATS.BALL_RANDOMS% = STATS.BALL_RANDOMS% + 1
END IF
END IF
'bottom left corner of level
IF BALL.Y% = (LEVEL.END_Y% - pad%) AND BALL.X% = (LEVEL.START_X% + pad%) THEN
DPRINT "* IN BOTTOM LEFT CORNER OF LEVEL", DEBUG_AVG
new_x% = BALL.X% + rand_in_range(1,pad%)
IF new_x% <> BALL.X% THEN
BALL.HIT_90_NUM% = 0
ball_erase BALL.Y%, BALL.X%
BALL.X% = new_x%
ball_sound_random
STATS.BALL_RANDOMS% = STATS.BALL_RANDOMS% + 1
END IF
END IF
'top right corner of level
IF BALL.Y% = (LEVEL.START_Y% + pad%) AND BALL.X% = (LEVEL.END_X% - pad%) THEN
DPRINT "* IN TOP RIGHT CORNER OF LEVEL", DEBUG_AVG
new_x% = BALL.X% - rand_in_range(1,pad%)
IF new_x% <> BALL.X% THEN
BALL.HIT_90_NUM% = 0
ball_erase BALL.Y%, BALL.X%
BALL.X% = new_x%
ball_sound_random
STATS.BALL_RANDOMS% = STATS.BALL_RANDOMS% + 1
END IF
END IF
'bottom right corner of level
IF BALL.Y% = (LEVEL.END_Y% - pad%) AND BALL.X% = (LEVEL.END_X% - pad%) THEN
DPRINT "* IN BOTTOM RIGHT CORNER OF LEVEL", DEBUG_AVG
new_x% = BALL.X% - rand_in_range(1,pad%)
IF new_x% <> BALL.X% THEN
BALL.HIT_90_NUM% = 0
ball_erase BALL.Y%, BALL.X%
BALL.X% = new_x%
ball_sound_random
STATS.BALL_RANDOMS% = STATS.BALL_RANDOMS% + 1
END IF
END IF
END SUB
SUB ball_bounce_top
DPRINT "ball_bounce_top", DEBUG_AVG
BALL.Y_DIR% = BALL.Y_DIR% * -1
DIM AS INTEGER new_x
ball_sound_bounce_top
END SUB
SUB ball_bounce_right
DPRINT "ball_bounce_right", DEBUG_AVG
BALL.X_DIR% = BALL.X_DIR% * -1
ball_sound_bounce_right
END SUB
SUB ball_bounce_bot
DPRINT "ball_bounce_bot", DEBUG_AVG
BALL.Y_DIR% = BALL.Y_DIR% * -1
ball_sound_bounce_bot
END SUB
SUB ball_bounce_left
DPRINT "ball_bounce_left", DEBUG_AVG
BALL.X_DIR% = BALL.X_DIR% * -1
ball_sound_bounce_left
END SUB
SUB ball_toggle_sound
DPRINT "ball_toggle_sound", DEBUG_MAX
IF CFG.SOUND_ENABLED% = TRUE THEN
CFG.SOUND_ENABLED% = FALSE
ELSE
CFG.SOUND_ENABLED% = TRUE
END IF
END SUB
SUB ball_sound_random
DPRINT "ball_sound_random", DEBUG_MAX
STATS.BALL_RANDOMS% = STATS.BALL_RANDOMS% + 1
IF CFG.SOUND_ENABLED% = FALSE THEN EXIT SUB
ball_soundfx_random
END SUB
SUB ball_soundfx_random
PLAY "V25 O5 T255 MS L64 C,D#,E#,G MF"
END SUB
SUB ball_sound_chaos
DPRINT "ball_sound_chaos", DEBUG_MAX
STATS.BALL_RANDOMS% = STATS.BALL_RANDOMS% + 1
IF CFG.SOUND_ENABLED% = FALSE THEN EXIT SUB
PLAY "V25 O6 T180 MS L64 DD#DD#DD#DD# MF"
END SUB
SUB ball_sound_bounce_top
DPRINT "ball_sound_bounce_top", DEBUG_MAX
STATS.TOP_BOUNCES% = STATS.TOP_BOUNCES% + 1
IF CFG.SOUND_ENABLED% = FALSE THEN EXIT SUB
PLAY "V50 O4 T180 MS L32 C MF"
END SUB
SUB ball_sound_bounce_bot
DPRINT "ball_sound_bounce_bot", DEBUG_MAX
STATS.BOT_BOUNCES% = STATS.BOT_BOUNCES% + 1
IF CFG.SOUND_ENABLED% = FALSE THEN EXIT SUB
PLAY "V50 O3 T180 MS L32 C MF"
END SUB
SUB ball_sound_bounce_left
DPRINT "ball_sound_bounce_left", DEBUG_MAX
STATS.LEFT_BOUNCES% = STATS.LEFT_BOUNCES% + 1
IF CFG.SOUND_ENABLED% = FALSE THEN EXIT SUB
PLAY "V50 O3 T180 MS L32 F MF"
END SUB
SUB ball_sound_bounce_right
DPRINT "ball_sound_bounce_right", DEBUG_MAX
STATS.RIGHT_BOUNCES% = STATS.RIGHT_BOUNCES% + 1
IF CFG.SOUND_ENABLED% = FALSE THEN EXIT SUB
PLAY "V50 O3 T180 MS L32 G MF"
END SUB
SUB ball_sound_hit_block
DPRINT "ball_sound_hit_block", DEBUG_MAX
STATS.BLOCK_BOUNCES% = STATS.BLOCK_BOUNCES% + 1
IF CFG.SOUND_ENABLED% = FALSE THEN EXIT SUB
DIM r AS INTEGER
r% = rand_in_range(1,6)
SELECT CASE r%
CASE 1:
PLAY "V70 O1 T180 MS L32 C MF"
CASE 2:
PLAY "V70 O1 T180 MS L32 G MF"
CASE 3:
PLAY "V70 O1 T180 MS L32 D MF"
CASE 4:
PLAY "V70 O1 T180 MS L32 F MF"
CASE 5:
PLAY "V70 O1 T180 MS L32 G MF"
CASE 5:
PLAY "V70 O3 T255 MS L64 A MF"
END SELECT
END SUB
SUB ball_sound_invert
DPRINT "ball_sound_invert", DEBUG_MAX
STATS.BALL_INVERTS% = STATS.BALL_INVERTS% + 1
IF CFG.SOUND_ENABLED% = FALSE THEN EXIT SUB
ball_soundfx_random
END SUB
SUB block_init
DPRINT "block_init", DEBUG_AVG
BLOCK.X% = 1
BLOCK.Y% = 1
BLOCK.W% = CFG.BLOCK_MAX_W%
BLOCK.H% = CFG.BLOCK_MAX_H%
BLOCK.INDEX% = 0
BLOCK.KOLOR& = 10
BLOCK.LIVES% = 3
BLOCK.DISPLAY$ = CHR$(219) 'CHR$(177)
END SUB
SUB blocks_init
DPRINT "blocks_init", DEBUG_AVG
blocks_sound_init
DIM AS INTEGER i, j, w, h, x, y, in_range_x, in_range_y
DIM c AS LONG
screen_clear
IF CFG.RAND_NUM_BLOCKS% = TRUE THEN
CFG.PREV_NUM_BLOCKS% = CFG.NUM_BLOCKS%
CFG.NUM_BLOCKS% = rand_in_range(1, CFG.ORIG_NUM_BLOCKS%)
END IF
REDIM BLOCKS(1 TO CFG.NUM_BLOCKS%) AS BLOCK_OBJECT
ball_get_9grid
FOR i% = 1 TO CFG.NUM_BLOCKS%
w% = rand_in_range(1, CFG.BLOCK_MAX_W%)
h% = rand_in_range(1, CFG.BLOCK_MAX_H%)
DO: 'prevent creation of block where ball currently is
x% = clamp(rand_in_range(LEVEL.START_X%, LEVEL.END_X%-w%), 1, LEVEL.END_X%)
y% = clamp(rand_in_range(LEVEL.START_Y%, LEVEL.END_Y%-h%), 1, LEVEL.END_Y%)
in_range_x% = in_range(BALL.X%, x%, x%+w%)
in_range_y% = in_range(BALL.Y%, y%, y%+h%)
LOOP UNTIL in_range_x% = FALSE AND in_range_y% = FALSE AND ball_will_bounce_9grid(y%, x%) = FALSE
IF CFG.RANDOM_BG% = TRUE THEN
DO:
c& = rand_in_range(8,15)
LOOP UNTIL c& <> _BACKGROUNDCOLOR
ELSE
DO:
c& = rand_in_range(1,15)
LOOP UNTIL c& <> _BACKGROUNDCOLOR
END IF
IF CFG.RANDOM_FG% = TRUE THEN
DO:
BALL.KOLOR& = rand_in_range(8,15)
LOOP UNTIL BALL.KOLOR& <> _BACKGROUNDCOLOR
END IF
' kludge to fix contrast for low contrast color combinations
IF BALL.KOLOR& = 3 AND _BACKGROUNDCOLOR = 2 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 2 AND _BACKGROUNDCOLOR = 3 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 4 AND _BACKGROUNDCOLOR = 5 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 5 AND _BACKGROUNDCOLOR = 4 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 1 AND _BACKGROUNDCOLOR = 4 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 4 AND _BACKGROUNDCOLOR = 1 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 6 AND _BACKGROUNDCOLOR = 5 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 5 AND _BACKGROUNDCOLOR = 6 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 6 AND _BACKGROUNDCOLOR = 4 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 4 AND _BACKGROUNDCOLOR = 6 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 6 AND _BACKGROUNDCOLOR = 3 THEN BALL.KOLOR& = 15
IF BALL.KOLOR& = 3 AND _BACKGROUNDCOLOR = 6 THEN BALL.KOLOR& = 15
IF _BACKGROUNDCOLOR = 7 THEN BALL.KOLOR& = 0
BLOCKS(i%).X% = x%
BLOCKS(i%).Y% = y%
BLOCKS(i%).W% = rand_in_range(1, CFG.BLOCK_MAX_W%)
BLOCKS(i%).H% = rand_in_range(1, CFG.BLOCK_MAX_H%)
BLOCKS(i%).KOLOR& = c&
FOR j% = y% TO y%+h%
screen_set_active_page GAME_SCREEN
LOCATE j%, x%
COLOR c&, __SCREEN.BG_KOLOR&
PRINT STRING$(w%, BLOCK.DISPLAY$);
NEXT j%
NEXT i%
END SUB
SUB blocks_inc
DPRINT "blocks_inc", DEBUG_AVG
CFG.PREV_NUM_BLOCKS% = CFG.NUM_BLOCKS%
CFG.NUM_BLOCKS% = min(CFG.NUM_BLOCKS%+1, 1)
IF CFG.PREV_NUM_BLOCKS% <> CFG.NUM_BLOCKS% THEN blocks_init
END SUB
SUB blocks_dec
DPRINT "blocks_dev", DEBUG_AVG
CFG.PREV_NUM_BLOCKS% = CFG.NUM_BLOCKS%
CFG.NUM_BLOCKS% = min(CFG.NUM_BLOCKS%-1, 1)
IF CFG.PREV_NUM_BLOCKS% <> CFG.NUM_BLOCKS% THEN blocks_init
END SUB
SUB blocks_sound_init
DPRINT "blocks_sound_init", DEBUG_AVG
IF CFG.SOUND_ENABLED% = FALSE THEN EXIT SUB
DIM r AS INTEGER
r% = rand_in_range(1,6)
SELECT CASE r%
CASE 1:
PLAY "V70 O3 T180 MS L32 C,C#,D,D# O4 C,C#,D,D# O5 C,C#,D,D# MB"
CASE 2:
PLAY "V70 O3 T180 MS L32 G,G#,A,A# O4 G,G#,A,A# O5 G,G#,A,A# MB"
CASE 3:
PLAY "V70 O3 T180 MS L32 D,D#,E,E# O4 D,D#,E,E# O5 D,D#,E,E# MB"
CASE 4:
PLAY "V70 O3 T180 MS L32 F,F#,G,G# O4 F,F#,G,G# O5 F,F#,G,G# MB"
CASE 5:
PLAY "V70 O3 T180 MS L32 B,B#,C,C# O4 B,B#,C,C# O5 B,B#,C,C# MB"
CASE 5:
PLAY "V70 O3 T255 MS L32 A,A#,C,C# O4 A,A#,C,C# O5 A,A#,C,C# MB"
END SELECT
END SUB
SUB level_init
DPRINT "level_init", DEBUG_AVG
LEVEL.START_X% = 1
LEVEL.START_Y% = 1
LEVEL.END_X% = _WIDTH
LEVEL.END_Y% = _HEIGHT - 3
END SUB
SUB stats_init
DPRINT "stats_init", DEBUG_AVG
STATS.TOP_BOUNCES% = 0
STATS.RIGHT_BOUNCES% = 0
STATS.BOT_BOUNCES% = 0
STATS.LEFT_BOUNCES% = 0
STATS.BLOCK_BOUNCES% = 0
STATS.BALL_INVERTS% = 0
STATS.BALL_RANDOMS% = 0
END Sub
SUB stats_update
DPRINT "stats_update", DEBUG_MAX
DIM t AS INTEGER
DIM AS LONG old_fg, old_bg
old_fg& = _DEFAULTCOLOR
old_bg& = _BACKGROUNDCOLOR
t% = STATS.TOP_BOUNCES%
DIM AS STRING s, s2, s3
s$ = "ESC:END,SPACE:RND,+/-:SPD,F1:TRACE,F4:BALL,F5:DEBUG->HOME/END:SHOW/HIDE CONSOLE"
s2$ = "BOUNCE"
IF BALL.TRACE_PATH% = TRUE THEN s2$ = s2$ + " TR"
s2$ = s2$ + " T" + n$(STATS.TOP_BOUNCES%)
s2$ = s2$ + " R" + n$(STATS.RIGHT_BOUNCES%)
s2$ = s2$ + " B" + n$(STATS.BOT_BOUNCES%)
s2$ = s2$ + " L" + n$(STATS.LEFT_BOUNCES%)
s2$ = s2$ + " BL" + n$(STATS.BLOCK_BOUNCES%)
' s2$ = s2$ + " BI" + n$(STATS.BALL_INVERTS%)
' s2$ = s2$ + " BR" + n$(STATS.BALL_RANDOMS%)
' s2$ = s2$ + " B9" + n$(BALL.HIT_90_NUM%)
' s2$ = s2$ + " TI:" + ln$(TICKS_TIMER.SECONDS&)
s2$ = s2$ + " FPS:" + n$(CFG.LIM%)
s2$ = s2$ + " #B" + n$(CFG.NUM_BLOCKS%)
IF DEBUG.DO_BREAKPOINTS% = TRUE THEN
s2$ = s2$ + " B:RKP ON"
ELSE
s2$ = s2$ + " B:RKP OFF"
END IF
IF CFG.SOUND_ENABLED% = TRUE THEN
s2$ = s2$ + " S:ND ON"
ELSE
s2$ = s2$ + " S:ND OFF"
END IF
screen_set_both_pages GAME_SCREEN
LOCATE _HEIGHT-2, 1 : PRINT SPACE$(_WIDTH)
IF DEBUG.ENABLED% = TRUE THEN
SELECT CASE DEBUG.VERBOSITY%
CASE DEBUG_MIN:
s3$ = "[MIN]"
CASE DEBUG_AVG:
s3$ = "[AVG]"
CASE DEBUG_MAX:
s3$ = "[MAX]"
END SELECT
s3$ = s3$ + " S:" + n$(DEBUG.CUR_STEP%)
s3$ = s3$ + " F2:CLR F3:MARK F7:NEXT F8:STOP"
s3$ = s3$ + " F9:MIN F10:AVG F11:MAX"
COLOR 0,15
LOCATE _HEIGHT-2, 1 : PRINT SPACE$(_WIDTH)
LOCATE _HEIGHT-2, 1 : PRINT s3$;
END IF
COLOR 15, 0
LOCATE _HEIGHT-1, 1 : PRINT SPACE$(_WIDTH);
LOCATE _HEIGHT-1, 1 : PRINT s$;
LOCATE _HEIGHT, 1 : PRINT SPACE$(_WIDTH);
LOCATE _HEIGHT, 1 : PRINT s2$;
COLOR old_fg&, old_bg&
END SUB
SUB timers_init
DPRINT "timers_init", DEBUG_AVG
TICKS_TIMER.STARTED# = TIMER
TICKS_TIMER.TICKS& = 0
TICKS_TIMER.SECONDS& = 0
TIMER_LAPS(0).STARTED# = TICKS_TIMER.STARTED#
TICKS_TIMER.LAP_COUNT% = 1
TICKS_TIMER.HOLD% = FALSE
timers_main_startup
END SUB
SUB timers_tick
DPRINT "timers_tick", DEBUG_MAX
IF CFG.AUTO_BLOCKS_SECS% > 0 THEN
IF TICKS_TIMER.TICKS& > 0 AND TICKS_TIMER.TICKS& MOD CFG.AUTO_BLOCKS_SECS% = 0 THEN
blocks_init
END IF
END IF
IF CFG.BALL_CHAOS_TIMER% = TRUE AND TICKS_TIMER.HOLD% = FALSE THEN
IF TICKS_TIMER.TICKS& MOD CFG.CHAOS_SECS% = 0 THEN
ball_chaos
END IF
END IF
TICKS_TIMER.TICKS& = TICKS_TIMER.TICKS& + 1
TICKS_TIMER.SECONDS& = TICKS_TIMER.SECONDS& + 1
END SUB
SUB timers_ticks_reset
DPRINT "timers_ticks_reset", DEBUG_AVG
TICKS_TIMER.TICKS& = 0
TICKS_TIMER.SECONDS& = 0
END SUB
SUB timers_main_startup
DPRINT "timers_main_startup", DEBUG_AVG
MAIN_TIMER% = _FREETIMER
ON TIMER(MAIN_TIMER%, 1) timers_tick
TIMER(MAIN_TIMER%) ON
END SUB
SUB timers_main_shutdown
DPRINT "timers_main_shutdown", DEBUG_AVG
TIMER(MAIN_TIMER%) OFF
TIMER(MAIN_TIMER%) FREE
END SUB
SUB timers_start_lap
DPRINT "timers_start_lap", DEBUG_MAX
END SUB
SUB timers_end_lap
DPRINT "timers_end_lap", DEBUG_MAX
END SUB
FUNCTION n$ (integ%)
DPRINT "n$(integ%=" + _TRIM$(STR$(integ%)) + ")", DEBUG_WTF
n$ = _TRIM$(STR$(integ%))
END FUNCTION
FUNCTION b$ (integ%)
DPRINT "b$(integ%=" + _TRIM$(STR$(integ%)) + ")", DEBUG_MAX
IF integ% = -1 THEN
b$ = "TRUE"
ELSEIF integ% = 0 THEN
b$ = "FALSE"
ENDIF
END FUNCTION
FUNCTION ln$ (longval!)
DPRINT "ln$(longval!=" + _TRIM$(STR$(longval!)) + ")", DEBUG_MAX
ln$ = _TRIM$(STR$(longval!))
END FUNCTION
FUNCTION inc% (value%)
DPRINT "inc(value%=" + n$(value%) + ")", DEBUG_MAX
inc% = value% + 1
END FUNCTION
FUNCTION dec% (value%)
DPRINT "dec(value%=" + n$(value%) + ")", DEBUG_MAX
dec% = value% - 1
END FUNCTION
FUNCTION inv% (value%)
DPRINT "inv(value%=" + n$(value%) + ")", DEBUG_MAX
inv% = value% * -1
END FUNCTION
FUNCTION min% (value%, minimum%)
DPRINT _
"min(value%=" + n$(value%) + _
", minimum%=" + n$(minimum%) + ")", DEBUG_MAX
IF value% < minimum% THEN value% = minimum%
min% = value%
END FUNCTION
FUNCTION max% (value%, maximum%)
DPRINT _
"max(value%=" + n$(value%) + _
", maximum%=" + n$(maximum%) + ")", DEBUG_MAX
IF value% > maximum% THEN value% = maximum%
max% = value%
END FUNCTION
FUNCTION clamp% (value%, minimum%, maximum%)
DPRINT _
"clamp(value%=" + n$(value%) + _
", minimum%=" + n$(minimum%) + _
", maximum%=" + n$(maximum%) + ")", DEBUG_MAX
IF value% > maximum% THEN
clamp% = maximum%
ELSEIF value% < minimum% THEN
clamp% = minimum%
ELSE
clamp% = value%
END IF
END FUNCTION
FUNCTION in_range% (value%, minimum%, maximum%)
DPRINT _
"in_range(value%=" + n$(value%) + _
", minimum%=" + n$(minimum%) + _
", maximum%=" + n$(maximum%) + ")", DEBUG_MAX
IF value% >= minimum% AND value% <= maximum% THEN
in_range% = TRUE
ELSE
in_range% = FALSE
END IF
END FUNCTION
FUNCTION rand_sign% ()
DIM r AS INTEGER
r% = -1 + INT(RND*2)
IF r% = 0 THEN r% = 1
rand_sign% = r%
END FUNCTION
FUNCTION rand_in_range% (minimum%, maximum%)
DPRINT _
"rand_in_range(minimum%=" + n$(minimum%) + _
", maximum%=" + n$(maximum%) + ")", DEBUG_MAX
rand_in_range% = INT(RND * (maximum% - minimum% + 1)) + 1
END FUNCTION
FUNCTION rand_int_choice% (arr_choices%())
DPRINT "rand_int_choice(arr_choices%())", DEBUG_MAX
DIM AS INTEGER minimum, maximum
minimum% = LBOUND(arr_choices%) : maximum% = UBOUND(arr_choices%)
rand_int_choice% = arr_choices%(rand_in_range(minimum%, maximum%))
END FUNCTION
FUNCTION rand_str_choice$ (arr_choices$())
DPRINT "rand_str_choice(arr_choices%())", DEBUG_MAX
DIM AS INTEGER minimum, maximum
minimum% = LBOUND(arr_choices$) : maximum% = UBOUND(arr_choices$)
rand_str_choice$ = arr_choices$(rand_in_range(minimum%, maximum%))
END FUNCTION
SUB debug_init
DPRINT "debug_init", DEBUG_MAX
DEBUG.ENABLED% = FALSE
DEBUG.DO_BREAKPOINTS% = TRUE
DEBUG.IN_CONSOLE% = FALSE
DEBUG.VERBOSE% = TRUE
DEBUG.VERBOSITY% = DEBUG_MIN
DEBUG.NEXT_STEP% = TRUE
DEBUG.CUR_STEP% = 0
DEBUG.PREV_STEP% = 0
DEBUG.PREV_MARK_TIME$ = ""
DEBUG.PREV_MARK_TIMER# = 0
DEBUG.MARK_TIME$ = ""
DEBUG.MARK_TIMER# = 0
IF DEBUG.ENABLED% = TRUE THEN debug_start
END SUB
SUB debug_start
DPRINT "debug_start", DEBUG_MAX
DEBUG.ENABLED% = TRUE
TIMER(MAIN_TIMER%) OFF
END SUB
SUB debug_next
DPRINT "debug_next", DEBUG_MAX
IF DEBUG.ENABLED% = TRUE THEN
DEBUG.PREV_STEP% = DEBUG.CUR_STEP%
DEBUG.CUR_STEP% = DEBUG.CUR_STEP% + 1
DEBUG.NEXT_STEP% = TRUE
END IF
END SUB
SUB debug_breakpoint (msg$)
DPRINT "debug_breakpoint", DEBUG_MIN
IF DEBUG.DO_BREAKPOINTS% = TRUE THEN
DEBUG.ENABLED% = TRUE
DEBUG.NEXT_STEP% = FALSE
TIMER(MAIN_TIMER%) OFF
DPRINT "[BREAKPOINT REACHED]: " + msg$, DEBUG_MIN
console_mark
debug_console
END IF
END SUB
SUB debug_toggle_do_breakpoints
DPRINT "debug_toggle_do_breakpoints", DEBUG_MAX
IF DEBUG.DO_BREAKPOINTS% = TRUE THEN
DEBUG.DO_BREAKPOINTS% = FALSE
ELSE
DEBUG.DO_BREAKPOINTS% = TRUE
ENDIF
END SUB
SUB debug_stop
DPRINT "debug_stop", DEBUG_MAX
IF DEBUG.ENABLED% = TRUE THEN
IF DEBUG.IN_CONSOLE% = TRUE THEN
debug_console_hide
END IF
DEBUG.ENABLED% = FALSE
DEBUG.NEXT_STEP% = FALSE
TIMER(MAIN_TIMER%) ON
END IF
END SUB
SUB debug_console
DPRINT "debug_console", DEBUG_MAX
IF DEBUG.IN_CONSOLE% = FALSE THEN
debug_console_show
ELSE
debug_console_hide
END IF
END SUB
SUB debug_console_show
DPRINT "debug_console_show", DEBUG_MAX
screen_set_both_pages DEBUGGER_CONSOLE
DEBUG.IN_CONSOLE% = TRUE
END SUB
SUB debug_console_hide
DPRINT "debug_console_hide", DEBUG_MAX
IF DEBUG.ENABLED% = TRUE THEN
screen_set_both_pages GAME_SCREEN
DEBUG.IN_CONSOLE% = FALSE
END IF
END SUB
SUB console_clear
DPRINT "console_clear", DEBUG_MAX
IF DEBUG.ENABLED% = TRUE THEN
screen_set_active_page DEBUGGER_CONSOLE
CLS
DIM i AS INTEGER
FOR i% = 0 TO 200
_ECHO ""
NEXT i%
END IF
END SUB
SUB console_mark
DPRINT "console_mark", DEBUG_MAX
DIM time_diff AS DOUBLE
IF DEBUG.ENABLED% = TRUE THEN
DEBUG.MARK_TIME$ = TIME$
DEBUG.MARK_TIMER# = TIMER
DPRINT "", DEBUG_MIN
IF DEBUG.PREV_MARK_TIMER# > 0 THEN
time_diff# = DEBUG.MARK_TIMER# - DEBUG.PREV_MARK_TIMER#
DPRINT DEBUG.PREV_MARK_TIME$ + " TO " + DEBUG.MARK_TIME$ + _
" (" + _TRIM$(STR$(time_diff#)) + ")" + _
STRING$(40, "="), DEBUG_MIN
ELSE
DPRINT DEBUG.MARK_TIME$ + " " + STRING$(40, "="), DEBUG_MIN
END IF
DPRINT "", DEBUG_MIN
DEBUG.PREV_MARK_TIME$ = DEBUG.MARK_TIME$
DEBUG.PREV_MARK_TIMER# = DEBUG.MARK_TIMER#
END IF
END SUB
SUB console_log (s$)
IF DEBUG.ENABLED% = TRUE THEN
screen_set_active_page DEBUGGER_CONSOLE
LOCATE ,1 : PRINT s$
END IF
END SUB
SUB DPRINT (s$, verbosity%)
IF DEBUG.ENABLED% = TRUE THEN
IF DEBUG.VERBOSITY% >= verbosity% THEN console_log(s$)
END IF
IF DEBUG.VERBOSE% = TRUE THEN
IF DEBUG.VERBOSITY% >= verbosity% THEN _ECHO s$
END IF
END SUB
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
LOL I wanted to make it this small using a joystick or a trackpad:
https://en.wikipedia.org/wiki/File:ARROW...26999).png
Posts: 296
Threads: 10
Joined: Apr 2022
Reputation:
6
@mnrvovrfc
Nice tiny game...i don't know how i miss it before
Posts: 296
Threads: 10
Joined: Apr 2022
Reputation:
6
I have question about this line of code :
Code: (Select All) IF _KEYDOWN(32) = 0 AND holdspace THEN holdspace = 0
what exactly mean holdspace then ?
Is that mean holdspace > 0 or holdspace <> 0 ?
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
(03-16-2023, 04:11 PM)aurel Wrote: what exactly mean holdspace then ?
This was part of failed logic so the program reacts when the user expects. That is,
do not move the spaceship!
if the spacebar is never pressed. But do move the spaceship as soon as the user presses the spacebar.
No need to hold the key, thought. Press it again so the spaceship stops moving.
Otherwise people could become irritated with key-repeat intruding or something else. Holding the spacebar to move the spaceship would have made better sense otherwise. Also it would have been harder to reward a player who touches as less as possible LOL.
The response is actually late. I was trying to demonstrate something discussed sometime before. In a game that is payware the response has to be immediate or it won't catch on. I should try to convert the "Wormer" program (in "other BASICs" forum) to QB64 so people could try it and I could demonstrate my point better. Even in a little arcade game like this one, people won't play if the program is late responding to keypresses. This works in music also, need to respond right when the musician touches a key on the music keyboard, or the drum sounds when it's hit with the stick. If it's late it's no good and rejected.
Posts: 296
Threads: 10
Joined: Apr 2022
Reputation:
6
i am asking you what mean just holdspace without expression
is :
1 .holdspace > 0
or
2 .holdspace <> 0
or something like
holdspace = 1
|