Bounce 3: On the Town Source Code

This is Version 1.0, July 31, 2006.



'\ITECH\GAMES\BOUNCE3\BOUCE3
' Bounce3! On the Town (Version 1.0)
' (C) 2006 i-TECH and Kristopher Windsor

DECLARE SUB addscore (points AS INTEGER)
DECLARE SUB makelevel ()
DECLARE SUB makexplode (x AS INTEGER, y AS INTEGER, c AS INTEGER)
DECLARE SUB weather (code AS INTEGER) '0-Erase, 1-Rain, 2-Snow
DECLARE SUB shake ()

CONST bcount = 6, ecount = 2, hcount = 8, lcount = 2
CONST pcount = 8, qcount = 6, rcount = 4, scount = 16, wcount = 128

CONST delay = 30000, minbouncepower = 14, minsize = 18, true = -1
CONST pi = 3.14159, qspeed = 8, rdist = 500, speed = 8

TYPE building: x AS INTEGER: y AS INTEGER: w AS INTEGER: c AS INTEGER: END TYPE
TYPE extra: x AS INTEGER: y AS INTEGER: c AS INTEGER: END TYPE
TYPE helecopter: x AS INTEGER: y AS INTEGER: xv AS INTEGER: yv AS INTEGER: a AS SINGLE: minx AS INTEGER: maxx AS INTEGER: miny AS INTEGER: maxy AS INTEGER: c AS INTEGER: END TYPE
TYPE lightning: x AS INTEGER: d AS INTEGER: c AS INTEGER: b AS INTEGER: v AS INTEGER: END TYPE
TYPE rescuelight: x AS INTEGER: y AS INTEGER: a AS SINGLE: v AS SINGLE: c AS INTEGER: END TYPE
TYPE score: s AS INTEGER: n AS STRING * 16: END TYPE
TYPE weather: x AS INTEGER: y AS INTEGER: s AS INTEGER: v AS INTEGER: END TYPE
TYPE xplode: x AS INTEGER: y AS INTEGER: d AS INTEGER: c AS INTEGER: END TYPE

COMMON SHARED across AS INTEGER, pacross AS INTEGER, minacross AS INTEGER
COMMON SHARED shaked AS SINGLE, shakex AS INTEGER, shakey AS INTEGER, pshakex AS INTEGER, pshakey AS INTEGER
COMMON SHARED cheat AS INTEGER, shakeon AS INTEGER, slow AS LONG, windowon AS INTEGER, qon AS INTEGER
COMMON SHARED progress AS INTEGER, wind AS INTEGER
COMMON SHARED newgame AS INTEGER, whichb AS INTEGER, whichh AS INTEGER, whichq AS INTEGER

DIM SHARED b(1 TO bcount) AS building
DIM e(1 TO ecount)  AS extra
DIM SHARED h(1 TO hcount) AS helecopter
DIM l(1 TO lcount)  AS lightning
DIM p(1 TO pcount) AS extra
DIM SHARED q(1 TO qcount)  AS xplode
DIM SHARED r(1 TO rcount) AS rescuelight
DIM SHARED s(1 TO scount) AS score
DIM SHARED w(1 TO wcount) AS weather

DIM quit AS INTEGER, choice AS INTEGER, going AS INTEGER, ended AS INTEGER
DIM a AS INTEGER, d AS LONG, f AS INTEGER, g AS INTEGER, i AS INTEGER, j AS INTEGER, k AS STRING, lx AS INTEGER, o AS INTEGER, v AS SINGLE
DIM cheatsize AS INTEGER, lives AS INTEGER, points AS INTEGER
DIM x AS INTEGER, y AS INTEGER, px AS INTEGER, py AS INTEGER, xv AS INTEGER, yv AS INTEGER, size AS INTEGER, psize AS INTEGER

ON KEY(31) GOSUB quickexit: KEY(31) ON: RANDOMIZE TIMER
SCREEN 12: WIDTH 80, 30: CLS : GOSUB loaddata

choice = 1: quit = 0
DO
 LOCATE 9, 29: PRINT "Bounce 3: On the Town"
 weather 1

 SELECT CASE k
 CASE ""
  LOCATE 11, 29: PRINT "-> ";
  SELECT CASE choice
  CASE 1: PRINT "Play Game  "
  CASE 2: PRINT "High Scores"
  CASE 3: PRINT "Options    "
  CASE 4: PRINT "Help       "
  CASE 5: PRINT "Quit       "
  END SELECT
 CASE CHR$(0) + CHR$(72), CHR$(0) + CHR$(75)
  choice = choice - 1: IF choice = 0 THEN choice = 5
 CASE CHR$(0) + CHR$(77), CHR$(0) + CHR$(80)
  choice = choice + 1: IF choice = 6 THEN choice = 1
 CASE CHR$(13), " "
  CLS
  SELECT CASE choice
  CASE 1: GOSUB game: quit = 0
  CASE 2: GOSUB highscores
  CASE 3: GOSUB options
  CASE 4: GOSUB help
  CASE 5: quit = true
  END SELECT
  CLS
 CASE CHR$(27)
  IF choice = 5 THEN quit = true ELSE choice = 5
 END SELECT

 FOR a = 1 TO delay: NEXT a: k = INKEY$
LOOP UNTIL quit
weather 1
GOSUB quickexit

game:
across = 0
angle = 3 * pi / 2
bouncepower = minbouncepower - cheat * (22 - minbouncepower)
cheatsize = 60
ended = 0
going = 0
lives = 8
minacross = -256
newgame = true
points = 0
progress = 500
quit = 0
shaked = 0
size = minsize - cheat * (cheatsize - minsize)
whichq = 0
wind = 1 - cheat * 6
x = size
xv = 0
y = size
yv = 0
k = ""

FOR a = 1 TO bcount: b(a).c = 0: NEXT a
FOR a = 1 TO hcount: h(a).c = 0: NEXT a
FOR a = 1 TO ecount: e(a).x = 500: e(a).y = INT(RND * 480): e(a).c = a: NEXT a
FOR a = 1 TO lcount: l(a).d = 0: NEXT a
FOR a = 1 TO pcount: p(a).x = a * 50: p(a).y = INT(RND * 480): p(a).c = 10: NEXT a
FOR a = 1 TO qcount: q(a).c = 0: NEXT a
FOR a = 1 TO rcount: r(a).c = 0: NEXT a
b(bcount).x = 1: b(bcount).w = 500: b(bcount).y = 300: b(bcount).c = 9

DO
 IF minacross MOD 64 = 0 OR (NOT going) OR quit THEN GOSUB displaytext

 SELECT CASE k
 CASE CHR$(0) + CHR$(72): IF slow > 0 THEN slow = slow - 2000
 CASE CHR$(0) + CHR$(75): xv = -speed
 CASE CHR$(0) + CHR$(77): xv = speed
 CASE CHR$(0) + CHR$(80): IF slow < 500000 THEN slow = slow + 2000
 CASE CHR$(13): IF quit THEN going = true ELSE going = NOT going
  IF going THEN LOCATE 10, 26: PRINT SPACE$(30)
 CASE CHR$(27): IF going THEN going = 0 ELSE IF quit = 0 THEN quit = true: LOCATE 10, 26: PRINT SPACE$(30) ELSE going = true
 CASE " ": IF quit THEN going = true ELSE IF going THEN xv = -wind ELSE going = true: LOCATE 10, 26: PRINT SPACE$(30)
 CASE "k", "K": cheatsize = 2 ^ (RND * 8)
 END SELECT

 makelevel
 GOSUB calcanddisplay
 IF (lives = 0 OR across > 30000) AND NOT ended THEN ended = true: going = 0: quit = true

 FOR d = 1 TO slow: NEXT d: k = INKEY$
LOOP UNTIL quit AND going

GOSUB displaytext
d = TIMER: DO: k = INKEY$: LOOP UNTIL TIMER > d + 1
CLS : IF NOT cheat THEN addscore points
RETURN

calcanddisplay:
weather 2 + (across < 15000)
shake

'across
pacross = across
IF going THEN
 minacross = minacross + 1
 IF x + size - across > 420 THEN across = x + size - 420
 IF across < minacross THEN across = minacross
END IF

'bouncer
px = x: py = y
IF going THEN
 IF INT(RND * 64) = 0 AND size > minsize THEN size = size - 1
 IF INT(RND * 64) = 0 AND bouncepower > minbouncepower THEN bouncepower = bouncepower - 1
 IF INT(RND * 32) = 0 THEN i = 0
 IF cheat THEN size = cheatsize: bouncepower = 22
 x = x + xv + wind: IF x - size < across THEN x = across + size ELSE IF x + size > across + 640 THEN x = across - size + 640
 y = y + yv: yv = yv + 1
END IF

contact = 0
IF y + size > 479 THEN
 lives = lives - 1 - i: i = 0: shaked = 100: going = 0: yv = 0
 IF lives = 0 THEN
  y = -200: xv = -wind
 ELSE
  y = size: xv = speed: whichh = whichh + 1: IF whichh > hcount THEN whichh = 1
  h(whichh).minx = x - 1: h(whichh).x = x: h(whichh).maxx = x + 160
  h(whichh).miny = 99: h(whichh).y = 100: h(whichh).maxy = 101
  h(whichh).xv = xv + wind: h(whichh).yv = 0: h(whichh).c = INT(RND * 5) + 9
 END IF
END IF
IF going THEN
 FOR a = 1 TO bcount
  IF x + size > b(a).x AND x - size < b(a).x + b(a).w AND y + size > b(a).y AND b(a).c THEN contact = true
 NEXT a
 FOR a = 1 TO hcount
  IF SQR((x - h(a).x + 0&) * (x - h(a).x) + (y - h(a).y + 0&) * (y - h(a).y)) < size + 15 AND h(a).c THEN contact = true
 NEXT a
 IF contact THEN yv = -bouncepower: shaked = 10
END IF

IF NOT going THEN angle = angle + .5 ELSE angle = 3 * pi / 2 + (xv + wind) / 20
CIRCLE (px - pacross + pshakex, py + pshakey), psize, 0
CIRCLE (px + COS(pangle - 1) * psize / 2.5 - pacross + pshakex, py + SIN(pangle - 1) * psize / 2.5 + pshakey), psize / 5, 0
CIRCLE (px + COS(pangle + 1) * psize / 2.5 - pacross + pshakex, py + SIN(pangle + 1) * psize / 2.5 + pshakey), psize / 5, 0
PSET (px + COS(pangle - 1) * psize / 2.5 - pacross + pshakex, py + SIN(pangle - 1) * psize / 2.5 + pshakey), 0
PSET (px + COS(pangle + 1) * psize / 2.5 - pacross + pshakex, py + SIN(pangle + 1) * psize / 2.5 + pshakey), 0
CIRCLE (px - pacross + pshakex, py + psize / 6 + pshakey), psize / 10, 0 'nose
CIRCLE (px - pacross + pshakex, py + psize / 1.8 + pshakey), psize / 2, 0, pi, 0, 1 / 3

CIRCLE (x - across + shakex, y + shakey), size, 15
CIRCLE (x + COS(angle - 1) * size / 2.5 - across + shakex, y + SIN(angle - 1) * size / 2.5 + shakey), size / 5, 15 + i
CIRCLE (x + COS(angle + 1) * size / 2.5 - across + shakex, y + SIN(angle + 1) * size / 2.5 + shakey), size / 5, 15 + i
PSET (x + COS(angle - 1) * size / 2.5 - across + shakex, y + SIN(angle - 1) * size / 2.5 + shakey), 15
PSET (x + COS(angle + 1) * size / 2.5 - across + shakex, y + SIN(angle + 1) * size / 2.5 + shakey), 15
CIRCLE (x - across + shakex, y + size / 6 + shakey), size / 10, 15'nose
CIRCLE (x - across + shakex, y + size / 1.8 + shakey), size / 2, 15, pi, 0, 1 / 3
pangle = angle: psize = size

'buildings
FOR a = 1 TO bcount
 IF b(a).c > 0 THEN
  j = INT((b(a).w MOD 86) / 2 + 3)
  LINE (b(a).x - pacross + pshakex, b(a).y + pshakey)-(b(a).x + b(a).w - pacross + pshakex, 480), 0, B
  LINE (b(a).x - across + shakex, b(a).y + shakey)-(b(a).x + b(a).w - across + shakex, 480), b(a).c, B
 
  IF windowon THEN
   FOR f = b(a).x + j TO b(a).x + b(a).w + j - 86 STEP 86
   FOR g = b(a).y + j TO 479 STEP 86
    IF (f / 4 + g / 8) MOD 4 <= 1 THEN LINE (f - pacross + pshakex, g + pshakey)-(f - pacross + pshakex + 80, g + pshakey + 80), 0, B
    IF (f / 4 + g / 8) MOD 4 <= 1 THEN LINE (f - across + shakex, g + shakey)-(f - across + shakex + 80, g + shakey + 80), b(a).c, B
   NEXT g, f
  END IF
 END IF
NEXT a

'extras
a = INT(RND * ecount) + 1: IF e(a).c = 0 OR e(a).x + 80 < across THEN e(a).x = across + 650 + INT(RND * 150): e(a).y = INT(RND * 480): e(a).c = INT(RND * 3) + 1
FOR a = 1 TO ecount
 SELECT CASE e(a).c
 CASE 1
  CIRCLE (e(a).x - pacross + pshakex, e(a).y + pshakey), 4, 0
  CIRCLE (e(a).x - pacross + pshakex, e(a).y + pshakey), 8, 0

  IF SQR((x - e(a).x + 0&) * (x - e(a).x) + (y - e(a).y + 0&) * (y - e(a).y)) < size + 8 THEN
   e(a).c = 0
   size = size + 3: IF size > 40 THEN size = 40
   makexplode e(a).x, e(a).y, 13
  ELSE
   CIRCLE (e(a).x - across + shakex, e(a).y + shakey), 4, 13
   CIRCLE (e(a).x - across + shakex, e(a).y + shakey), 8, 13
  END IF
 CASE 2
  CIRCLE (e(a).x - pacross + pshakex, e(a).y + pshakey - 4), 8, 0, pi / 2 - 1, pi / 2 + 1
  CIRCLE (e(a).x - pacross + pshakex, e(a).y + pshakey), 8, 0, pi / 2 - 1, pi / 2 + 1
  CIRCLE (e(a).x - pacross + pshakex, e(a).y + pshakey + 4), 8, 0, pi / 2 - 1, pi / 2 + 1
 
  IF SQR((x - e(a).x + 0&) * (x - e(a).x) + (y - e(a).y + 0&) * (y - e(a).y)) < size + 8 THEN
   e(a).c = 0
   bouncepower = bouncepower + 3: IF bouncepower > 20 AND NOT cheat THEN bouncepower = 20
   makexplode e(a).x, e(a).y, 11
  ELSE
   CIRCLE (e(a).x - across + shakex, e(a).y + shakey - 4), 8, 11, pi / 2 - 1, pi / 2 + 1
   CIRCLE (e(a).x - across + shakex, e(a).y + shakey), 8, 11, pi / 2 - 1, pi / 2 + 1
   CIRCLE (e(a).x - across + shakex, e(a).y + shakey + 4), 8, 11, pi / 2 - 1, pi / 2 + 1
  END IF
 CASE 3
  LINE (e(a).x - pacross + pshakex - 2, e(a).y + pshakey - 2)-(e(a).x - pacross + pshakex + 2, e(a).y + pshakey + 2), 0, B
  LINE (e(a).x - pacross + pshakex - 5, e(a).y + pshakey - 5)-(e(a).x - pacross + pshakex + 5, e(a).y + pshakey + 5), 0, B
  LINE (e(a).x - pacross + pshakex - 8, e(a).y + pshakey - 8)-(e(a).x - pacross + pshakex + 8, e(a).y + pshakey + 8), 0, B

  IF SQR((x - e(a).x + 0&) * (x - e(a).x) + (y - e(a).y + 0&) * (y - e(a).y)) < size + 8 THEN
   e(a).c = 0
   i = true
   makexplode e(a).x, e(a).y, 12
  ELSE
   LINE (e(a).x - across + shakex - 2, e(a).y + shakey - 2)-(e(a).x - across + shakex + 2, e(a).y + shakey + 2), 12, B
   LINE (e(a).x - across + shakex - 5, e(a).y + shakey - 5)-(e(a).x - across + shakex + 5, e(a).y + shakey + 5), 12, B
   LINE (e(a).x - across + shakex - 8, e(a).y + shakey - 8)-(e(a).x - across + shakex + 8, e(a).y + shakey + 8), 12, B
  END IF
 END SELECT
NEXT a

'helecopters
FOR a = 1 TO hcount
 IF h(a).c > 0 THEN
  LINE (h(a).x - pacross + pshakex - 9, h(a).y + pshakey - 6)-(h(a).x - pacross + pshakex + 9, h(a).y + pshakey + 6), 0, B
  IF h(a).xv < 0 THEN
   CIRCLE (h(a).x - pacross + pshakex - 10, h(a).y + pshakey), 6, 0, pi / 2, 3 * pi / 2
   LINE (h(a).x - pacross + pshakex + 9, h(a).y + pshakey - 6)-STEP(16, 3), 0
   LINE STEP(0, 0)-STEP(-16, 9), 0
   LINE STEP(-15, 0)-STEP(0, 3), 0: LINE STEP(-4, 0)-STEP(8, 0), 0
   LINE STEP(5, -3)-STEP(0, 5), 0: LINE STEP(-4, 0)-STEP(8, 0), 0
   FOR v = 0 TO pi * 2 STEP pi / 4
    c = h(a).a + v: IF c > pi * 2 THEN c = c - pi * 2
    IF c > pi THEN LINE (h(a).x - pacross + pshakex, h(a).y + pshakey - 6)-STEP(COS(c) * 14, SIN(c) * 8), 0
    c = h(a).a * 2 + v: LINE (h(a).x - pacross + pshakex + 25, h(a).y + pshakey - 3)-STEP(COS(c) * 5, SIN(c) * 5), 0
   NEXT v
  ELSE
   CIRCLE (h(a).x - pacross + pshakex + 10, h(a).y + pshakey), 6, 0, 3 * pi / 2, pi / 2
   LINE (h(a).x - pacross + pshakex - 9, h(a).y + pshakey - 6)-STEP(-16, 3), 0
   LINE STEP(0, 0)-STEP(16, 9), 0
   LINE STEP(15, 0)-STEP(0, 3), 0: LINE STEP(4, 0)-STEP(-8, 0), 0
   LINE STEP(-5, -3)-STEP(0, 5), 0: LINE STEP(4, 0)-STEP(-8, 0), 0
   FOR v = 0 TO pi * 2 STEP pi / 4
    c = h(a).a + v: IF c > pi * 2 THEN c = c - pi * 2
    IF c > pi THEN LINE (h(a).x - pacross + pshakex, h(a).y + pshakey - 6)-STEP(COS(c) * 14, SIN(c) * 8), 0
    c = h(a).a * 2 + v: LINE (h(a).x - pacross + pshakex - 25, h(a).y + pshakey - 3)-STEP(COS(c) * 5, SIN(c) * 5), 0
   NEXT v
  END IF

  IF going THEN
   h(a).x = h(a).x + h(a).xv
   IF h(a).x < h(a).minx THEN h(a).x = h(a).minx: h(a).xv = ABS(h(a).xv)
   IF h(a).x > h(a).maxx THEN h(a).x = h(a).maxx: h(a).xv = -ABS(h(a).xv)
   h(a).y = h(a).y + h(a).yv
   IF h(a).y < h(a).miny THEN h(a).y = h(a).miny: h(a).yv = ABS(h(a).yv)
   IF h(a).y > h(a).maxy THEN h(a).y = h(a).maxy: h(a).yv = -ABS(h(a).yv)
  END IF
  h(a).a = h(a).a + .1: IF h(a).a > pi * 2 THEN h(a).a = h(a).a - pi * 2

  LINE (h(a).x - across + shakex - 9, h(a).y + shakey - 6)-(h(a).x - across + shakex + 9, h(a).y + shakey + 6), h(a).c, B
  IF h(a).xv < 0 THEN
   CIRCLE (h(a).x - across + shakex - 10, h(a).y + shakey), 6, h(a).c, pi / 2, 3 * pi / 2
   LINE (h(a).x - across + shakex + 9, h(a).y + shakey - 6)-STEP(16, 3), h(a).c
   LINE STEP(0, 0)-STEP(-16, 9), h(a).c
   LINE STEP(-15, 0)-STEP(0, 3), h(a).c: LINE STEP(-4, 0)-STEP(8, 0), h(a).c
   LINE STEP(5, -3)-STEP(0, 5), h(a).c: LINE STEP(-4, 0)-STEP(8, 0), h(a).c
   FOR v = 0 TO pi * 2 STEP pi / 4
    c = h(a).a + v: IF c > pi * 2 THEN c = c - pi * 2
    IF c > pi THEN LINE (h(a).x - across + shakex, h(a).y + shakey - 6)-STEP(COS(c) * 14, SIN(c) * 8), h(a).c
    c = h(a).a * 2 + v: LINE (h(a).x - across + shakex + 25, h(a).y + shakey - 3)-STEP(COS(c) * 5, SIN(c) * 5), h(a).c
   NEXT v
  ELSE
   CIRCLE (h(a).x - across + shakex + 10, h(a).y + shakey), 6, h(a).c, 3 * pi / 2, pi / 2
   LINE (h(a).x - across + shakex - 9, h(a).y + shakey - 6)-STEP(-16, 3), h(a).c
   LINE STEP(0, 0)-STEP(16, 9), h(a).c
   LINE STEP(15, 0)-STEP(0, 3), h(a).c: LINE STEP(4, 0)-STEP(-8, 0), h(a).c
   LINE STEP(-5, -3)-STEP(0, 5), h(a).c: LINE STEP(4, 0)-STEP(-8, 0), h(a).c
   FOR v = 0 TO pi * 2 STEP pi / 4
    c = h(a).a + v: IF c > pi * 2 THEN c = c - pi * 2
    IF c > pi THEN LINE (h(a).x - across + shakex, h(a).y + shakey - 6)-STEP(COS(c) * 14, SIN(c) * 8), h(a).c
    c = h(a).a * 2 + v: LINE (h(a).x - across + shakex - 25, h(a).y + shakey - 3)-STEP(COS(c) * 5, SIN(c) * 5), h(a).c
   NEXT v
  END IF
 END IF
NEXT a

'lightning
IF INT(RND * 64) = 0 THEN
 a = INT(RND * lcount) + 1
 IF l(a).d = 0 THEN
  l(a).b = INT(RND * bcount) + 1
  l(a).c = 14
  l(a).v = INT(RND * 60) + 60
  l(a).x = b(l(a).b).x + INT(RND * (b(l(a).b).w - l(a).v))
  IF b(l(a).b).c THEN l(a).d = INT(RND * 50) + 50
 ELSE
  IF b(l(a).b).x + b(l(a).b).w + 100 < across THEN l(a).d = 0
 END IF
END IF

FOR a = 1 TO lcount
 IF l(a).d > 0 THEN
  lx = l(a).x: f = l(a).d: g = l(a).v
  FOR d = 0 TO 2 * b(l(a).b).y / 3 STEP INT(b(l(a).b).y / 3) - (INT(b(l(a).b).y / 3) = 0)
   LINE (lx - pacross + pshakex, d + pshakey)-(lx + g - pacross + pshakex, d + INT(b(l(a).b).y / 3) + pshakey), 0
   LINE (lx - pacross + f + pshakex, d + pshakey)-(lx + g - pacross + INT(f / 4) + pshakex, d + INT(b(l(a).b).y / 3) + pshakey), 0
   lx = lx + g: f = INT(f / 4): g = -INT(ABS(g) / 1.5) * SGN(g)
  NEXT d
 
  IF l(a).c = 15 AND INT(RND * 6) = 0 THEN
   l(a).d = 0
  ELSE
   lx = l(a).x: f = l(a).d: g = l(a).v
   FOR d = 0 TO 2 * b(l(a).b).y / 3 STEP INT(b(l(a).b).y / 3) - (INT(b(l(a).b).y / 3) = 0)
    LINE (lx - across + shakex, d + shakey)-(lx + g - across + shakex, d + INT(b(l(a).b).y / 3) + shakey), l(a).c
    LINE (lx - across + f + shakex, d + shakey)-(lx + g - across + INT(f / 4) + shakex, d + INT(b(l(a).b).y / 3) + shakey), l(a).c
    lx = lx + g: f = INT(f / 4): g = -INT(ABS(g) / 1.5) * SGN(g)
   NEXT d
   IF INT(RND * 4) = 0 AND l(a).c < 15 THEN l(a).c = 15: makexplode lx, b(l(a).b).y, 14
  END IF
 END IF
NEXT a

'points
a = INT(RND * pcount) + 1: IF p(a).c = 0 OR p(a).x + 80 < across THEN p(a).x = across + 650 + INT(RND * 150): p(a).y = INT(RND * 480): p(a).c = 10
FOR a = 1 TO pcount
 IF p(a).c > 0 THEN
  CIRCLE (p(a).x - pacross + pshakex, p(a).y + pshakey), 8, 0, , , 1 / 2
  CIRCLE (p(a).x - pacross + pshakex, p(a).y + pshakey), 8, 0
  CIRCLE (p(a).x - pacross + pshakex, p(a).y + pshakey), 8, 0, , , 2

  IF SQR((x - p(a).x + 0&) * (x - p(a).x) + (y - p(a).y + 0&) * (y - p(a).y)) < size + 8 THEN
   p(a).c = 0
   points = points + 1
   GOSUB displaytext
   makexplode p(a).x, p(a).y, 10
  ELSE
   CIRCLE (p(a).x - across + shakex, p(a).y + shakey), 8, p(a).c, , , 1 / 2
   CIRCLE (p(a).x - across + shakex, p(a).y + shakey), 8, p(a).c
   CIRCLE (p(a).x - across + shakex, p(a).y + shakey), 8, p(a).c, , , 2
  END IF
 END IF
NEXT a

'rescue lights
FOR a = 1 TO rcount
 IF r(a).c > 0 THEN
  LINE (r(a).x - 16 - pacross + pshakex, r(a).y + 16 + pshakey)-(r(a).x + 16 - pacross + pshakex, r(a).y + 24 + pshakey), 0, B
  LINE (r(a).x - 16 - across + shakex, r(a).y + 16 + shakey)-(r(a).x + 16 - across + shakex, r(a).y + 24 + shakey), r(a).c, B
 
  CIRCLE (r(a).x - pacross + pshakex, r(a).y + pshakey), 16, 0, , , ABS(3 * pi / 2 - r(a).a) / pi * 2 + 1
  LINE (r(a).x - pacross + pshakex, r(a).y + pshakey)-STEP(COS(r(a).a + pi / 2) * 5, SIN(r(a).a + pi / 2) * 5), 0
  LINE STEP(0, 0)-STEP(COS(r(a).a) * rdist, SIN(r(a).a) * rdist), 0
  LINE STEP(0, 0)-STEP(COS(r(a).a - pi / 2) * 10, SIN(r(a).a - pi / 2) * 10), 0
  LINE STEP(0, 0)-STEP(COS(r(a).a + pi) * rdist, SIN(r(a).a + pi) * rdist), 0
  LINE STEP(0, 0)-STEP(COS(r(a).a + pi / 2) * 5, SIN(r(a).a + pi / 2) * 5), 0
 
  r(a).a = r(a).a + r(a).v
  IF r(a).a < pi THEN r(a).v = ABS(r(a).v)
  IF r(a).a > pi * 2 THEN r(a).v = -ABS(r(a).v)
 
  CIRCLE (r(a).x - across + shakex, r(a).y + shakey), 16, r(a).c, , , ABS(3 * pi / 2 - r(a).a) / pi * 2 + 1
  LINE (r(a).x - across + shakex, r(a).y + shakey)-STEP(COS(r(a).a + pi / 2) * 5, SIN(r(a).a + pi / 2) * 5), 14
  LINE STEP(0, 0)-STEP(COS(r(a).a) * rdist, SIN(r(a).a) * rdist), 14
  LINE STEP(0, 0)-STEP(COS(r(a).a - pi / 2) * 10, SIN(r(a).a - pi / 2) * 10), 14
  LINE STEP(0, 0)-STEP(COS(r(a).a + pi) * rdist, SIN(r(a).a + pi) * rdist), 14
  LINE STEP(0, 0)-STEP(COS(r(a).a + pi / 2) * 5, SIN(r(a).a + pi / 2) * 5), 14
 END IF
NEXT a

'xplodes
IF qon THEN
 FOR a = 1 TO qcount
  IF q(a).c > 0 THEN
   FOR v = 0 TO pi * 2 STEP pi / 8
    CIRCLE (q(a).x + COS(v) * (q(a).d - qspeed) - pacross - pshakex, q(a).y + SIN(v) * (q(a).d - qspeed) - pshakey), 2, 0
    CIRCLE (q(a).x + COS(v) * q(a).d - across - shakex, q(a).y + SIN(v) * q(a).d - shakey), 2, q(a).c
   NEXT v
   q(a).d = q(a).d + qspeed
  END IF
 NEXT a
END IF
RETURN

displaytext:
LOCATE 1, 1: PRINT "Progress:" + RTRIM$(STR$(INT(x / 300))) + "%  Points:"; points; " Energy:"; bouncepower; " Lives:"; lives
IF shaked < 1 AND NOT going THEN
 IF quit THEN LOCATE 10, 35: PRINT "< Game " + " Over >"
 IF minacross = -256 AND NOT quit THEN LOCATE 10, 28: PRINT "< Press [Space] to Start >"
 IF minacross > -256 AND NOT quit THEN LOCATE 10, 26: PRINT "< Press [Space] " + " to Continue >"
END IF
RETURN

help:
DO
 LOCATE 9, 29: PRINT "Bounce 3: Help"
 weather 1

 LOCATE 11, 29: PRINT "Bounce off the buildings and helecopters"
 LOCATE 12, 29: PRINT "while collecting points and bonuses."
 LOCATE 13, 29: PRINT "Get as many points as you can before"
 LOCATE 14, 29: PRINT "the progress gets to 100%."
 LOCATE 15, 29: PRINT "You will die if you land on the ground."

 FOR a = 1 TO delay: NEXT a
LOOP WHILE INKEY$ = ""
RETURN

highscores:
DO
 LOCATE 9, 29: PRINT "Bounce 3: High Scores"
 weather 1

 FOR a = 1 TO scount
  LOCATE a + 10, 29: PRINT s(a).n + " " + RIGHT$("00" + LTRIM$(STR$(s(a).s)), 4)
 NEXT a

 FOR a = 1 TO delay: NEXT a
LOOP WHILE INKEY$ = ""
RETURN

loaddata:
ON ERROR GOTO missingdata: OPEN "bounce3.txt" FOR INPUT AS #1: ON ERROR GOTO 0
FOR a = 1 TO scount
 LINE INPUT #1, s(a).n
 INPUT #1, s(a).s
NEXT a
ON ERROR GOTO resumenext: INPUT #1, cheat, qon, shakeon, slow, windowon: ON ERROR GOTO 0
CLOSE #1
RETURN

missingdata:
OPEN "bounce3.txt" FOR OUTPUT AS #1
FOR a = 1 TO scount
 PRINT #1, "'TzmNe!!!"
 WRITE #1, scount * 2 - a
NEXT a
WRITE #1, 0, -1, -1, 2000, -1
CLOSE #1
RESUME

options:
o = 1
DO
 LOCATE 9, 29: PRINT "Bounce 3: Options"
 weather 1

 SELECT CASE k
 CASE CHR$(0) + CHR$(72): o = o - 1: IF o = 0 THEN o = 5
 CASE CHR$(0) + CHR$(75)
  SELECT CASE o
  CASE 1: IF slow > 0 THEN slow = slow - 2000
  CASE 2: shakeon = NOT shakeon
  CASE 3: qon = NOT qon
  CASE 4: windowon = NOT windowon
  CASE 5: cheat = NOT cheat
  END SELECT
 CASE CHR$(0) + CHR$(77)
  SELECT CASE o
  CASE 1: IF slow < 500000 THEN slow = slow + 2000
  CASE 2: shakeon = NOT shakeon
  CASE 3: qon = NOT qon
  CASE 4: windowon = NOT windowon
  CASE 5: cheat = NOT cheat
  END SELECT
 CASE CHR$(0) + CHR$(80): o = o + 1: IF o > 5 THEN o = 1
 END SELECT

 FOR a = 1 TO 5
  IF a = o THEN COLOR 15 ELSE IF ABS(a - o) = 1 THEN COLOR 7 ELSE COLOR 8
  LOCATE a + 10, 29
  SELECT CASE a
  CASE 1: PRINT "Speed: "; : IF slow = 0 THEN PRINT "Full Speed" ELSE PRINT -slow; SPACE$(4)
  CASE 2: PRINT "Camera Shake: "; : IF shakeon THEN PRINT "On " ELSE PRINT "Off"
  CASE 3: PRINT "Particles: "; : IF qon THEN PRINT "On " ELSE PRINT "Off"
  CASE 4: PRINT "Windows: "; : IF windowon THEN PRINT "On " ELSE PRINT "Off"
  CASE 5: PRINT "Cheat Mode: "; : IF cheat THEN PRINT "On " ELSE PRINT "Off"
  END SELECT
 NEXT a: COLOR 15

 FOR a = 1 TO delay: NEXT a: k = INKEY$
LOOP UNTIL k = CHR$(13) OR k = CHR$(27) OR k = " "
RETURN

quickexit:
GOSUB savedata
SYSTEM

resumenext:
RESUME NEXT

savedata:
OPEN "bounce3.txt" FOR OUTPUT AS #1
FOR a = 1 TO scount
 PRINT #1, s(a).n
 WRITE #1, s(a).s
NEXT a
WRITE #1, cheat, qon, shakeon, slow, windowon
CLOSE #1
RETURN

SUB addscore (points AS INTEGER)
IF points <= s(scount).s THEN EXIT SUB
DIM a AS INTEGER, c AS INTEGER, k AS STRING, n AS STRING

FOR a = 1 TO scount
 IF s(a).s > points - 1 THEN c = a
NEXT a

FOR a = scount - 1 TO c + 1 STEP -1: SWAP s(a), s(a + 1): NEXT a

DO
 LOCATE 9, 29: PRINT "Bounce 3: High Score!"
 weather 1

 IF LEN(k) = 1 AND LEN(n) < 16 AND k <> CHR$(8) AND k <> CHR$(9) AND k <> CHR$(13) THEN n = n + k
 IF k = CHR$(8) AND LEN(n) > 0 THEN n = LEFT$(n, LEN(n) - 1)
 LOCATE 11, 29: PRINT "-> " + n + " "

 FOR a = 1 TO delay: NEXT a
 k = INKEY$
LOOP UNTIL (k = CHR$(13) OR k = CHR$(27)) AND LEN(n) > 0

s(c + 1).s = points
s(c + 1).n = n

DO
 LOCATE 9, 29: PRINT "Bounce 3: High Score!"
 weather 1

 LOCATE 11, 29: PRINT "#" + LTRIM$(STR$(c + 1)) + ": " + n + " " + RIGHT$("00" + LTRIM$(STR$(points)), 4)
 FOR a = 1 TO delay: NEXT a
LOOP WHILE INKEY$ = ""
END SUB

SUB makelevel
IF progress > across + 800 THEN EXIT SUB
STATIC po AS STRING * 1, py AS INTEGER

IF newgame THEN newgame = 0: po = " ": py = 300: whichb = 0: whichh = 0
DIM a AS INTEGER, x AS INTEGER, y AS INTEGER
x = progress + INT(RND * 80) + 100
y = INT(RND * 360) + 80: IF y < py - 100 THEN y = py - 100
py = y

IF INT(RND * 3) = 0 AND po <> "H" AND progress > 0 THEN 'helecopter or building
 whichh = whichh + 1: IF whichh > hcount THEN whichh = 1
 IF INT(RND * 3) = 0 THEN 'vertical or horizontal
  h(whichh).x = x + 1
  h(whichh).xv = 0
  h(whichh).minx = x
  h(whichh).maxx = x + 2
  h(whichh).y = y
  h(whichh).yv = INT(RND * 3) + 1
  h(whichh).miny = y
  h(whichh).maxy = INT(RND * 50) + 410
 ELSE
  h(whichh).x = x + 1
  h(whichh).xv = INT(RND * 3) + 2
  h(whichh).minx = x
  h(whichh).maxx = x + INT(RND * 400) + 50
  h(whichh).y = y
  h(whichh).yv = 0
  h(whichh).miny = y - 1
  h(whichh).maxy = y + 1
 END IF
 progress = h(whichh).maxx
 h(whichh).c = INT(RND * 5) + 9: po = "H"
ELSE
 whichb = whichb + 1: IF whichb > bcount THEN whichb = 1
 b(whichb).x = x
 b(whichb).y = y
 b(whichb).w = INT(RND * 220) + 60
 b(whichb).c = INT(RND * 5) + 9
 a = INT(RND * rcount) + 1
 IF r(a).x + rdist < across THEN
  r(a).x = x + INT(RND * (b(whichb).w - 40)) + 20
  r(a).y = y - 24
  r(a).a = 3 * pi / 2
  r(a).v = RND / 20 + 1 / 50
  r(a).c = b(whichb).c
 END IF
 progress = x + b(whichb).w: po = "B"
END IF
END SUB

SUB makexplode (x AS INTEGER, y AS INTEGER, c AS INTEGER)
IF NOT qon THEN EXIT SUB

whichq = whichq + 1: IF whichq > qcount THEN whichq = 1
IF q(whichq).c > 0 THEN
 FOR v = 0 TO pi * 2 STEP pi / 8
  CIRCLE (q(whichq).x + COS(v) * (q(whichq).d - qspeed) - pacross - pshakex, q(whichq).y + SIN(v) * (q(whichq).d - qspeed) - pshakey), 2, 0
 NEXT v
END IF

q(whichq).x = x: q(whichq).y = y: q(whichq).d = 0: q(whichq).c = c
END SUB

SUB shake
STATIC ccount: ccount = ccount + 1
IF shaked < 1 OR NOT shakeon THEN shaked = 0: shakex = 0: pshakex = 0: shakey = 0: pshakey = 0: EXIT SUB ELSE shaked = shaked / 1.2
CONST ss = 2
pshakex = FIX(shakex): pshakey = FIX(shakey)
shakex = FIX(COS(ccount * ss) * shaked): shakey = FIX(SIN(ccount * ss) * shaked)
END SUB

SUB weather (code AS INTEGER)
DIM a AS INTEGER
STATIC pcode AS INTEGER

SELECT CASE code
CASE 1
 IF pcode <> 1 THEN GOSUB eraseall
 GOSUB makedrop: GOSUB moverain
CASE 2
 IF pcode <> 2 THEN GOSUB eraseall
 GOSUB makedrop: GOSUB movesnow
CASE ELSE: GOSUB eraseall
END SELECT

pcode = code
EXIT SUB

eraseall:
SELECT CASE pcode
CASE 1
 FOR a = 1 TO wcount
  IF w(a).v THEN LINE (w(a).x, w(a).y)-(w(a).x, w(a).y + w(a).s), 0
 NEXT a
CASE 2
 FOR a = 1 TO wcount
  IF w(a).v THEN LINE (w(a).x - 1, w(a).y - 1)-(w(a).x + 1, w(a).y + 1), 0: LINE (w(a).x - 1, w(a).y + 1)-(w(a).x + 1, w(a).y - 1), 0
 NEXT a
END SELECT

FOR a = 1 TO wcount: w(a).v = 0: NEXT a
RETURN

makedrop:
a = INT(RND * wcount) + 1
IF w(a).v = 0 THEN w(a).x = INT(RND * 640): w(a).y = -8: w(a).s = INT(RND * 4) + 4: w(a).v = INT(RND * 6) + 6
RETURN

moverain:
FOR a = 1 TO wcount
 IF w(a).v THEN
  LINE (w(a).x, w(a).y)-(w(a).x, w(a).y + w(a).s), 0
  w(a).x = w(a).x + wind: w(a).y = w(a).y + w(a).v
  IF w(a).y > 479 THEN w(a).v = 0 ELSE LINE (w(a).x, w(a).y)-(w(a).x, w(a).y + w(a).s), 8
 END IF
NEXT a
RETURN

movesnow:
FOR a = 1 TO wcount
 IF w(a).v THEN
  LINE (w(a).x - 1, w(a).y - 1)-(w(a).x + 1, w(a).y + 1), 0
  LINE (w(a).x - 1, w(a).y + 1)-(w(a).x + 1, w(a).y - 1), 0
  w(a).x = w(a).x + wind: w(a).y = w(a).y + w(a).v
  IF w(a).y > 479 THEN w(a).v = 0 ELSE LINE (w(a).x - 1, w(a).y - 1)-(w(a).x + 1, w(a).y + 1), 7: LINE (w(a).x - 1, w(a).y + 1)-(w(a).x + 1, w(a).y - 1), 7
 END IF
NEXT a
RETURN
END SUB


(C) 2006 i-TECH