'Game controls: Arrows for Player 1. ' ' W ' A S D for Player 2. ' 'Enter to resume after a goal. Space to reinit ball. Esc to quit. 'Fiddle with Delay constant to change game speed. DECLARE SUB center (row, t$) DECLARE SUB init () DECLARE SUB initball () DECLARE SUB face (n, b, p) DECLARE SUB project (a, b, c, p) DECLARE SUB controller (n!, b, p) DECLARE FUNCTION yy! (a!, b!, c!) DECLARE FUNCTION xx! (a!, b!, c!) DECLARE SUB cube (n, a, b, c, p) DIM SHARED fx(8), fy(8), fz(8) 'box DIM SHARED cx(2), cy(2), cz(2) 'controller DIM SHARED mx(2), my(2), mz(2) 'controller memory DIM SHARED moved(2) DIM SHARED ffx(8), ffy(8), ffz(8) DIM SHARED bx, by, bz 'ball DIM SHARED k, ing, cs DIM SHARED mark, ball DIM SHARED speedx, speedy, speedz DIM SHARED s DIM SHARED score1, score2 CONST true = -1 CONST tolerance = .8 CONST intensity = 15 delay = 5000 debug = 0 s = false init ds = 160: dy = 100 pixelx = ds / 160: pixely = dy / 100 SCREEN 12: WINDOW (-ds, -dy)-(ds, dy) LOCATE 5, 10: PRINT "Press 1 for 1-player game." LOCATE 6, 10: PRINT "Press 2 for 2-players game." DO: a$ = INKEY$: LOOP UNTIL a$ <> "" CLS : IF a$ = "2" THEN GOTO twoplayers cube ing, 0, 0, 0, 2 face mark, ing, 14 face mark, -ing, 1 'note that y is reversed because it reads data 'from the LOWER face of a cube COLOR 2 initball CIRCLE (xx(bx, by, bz), yy(bx, by, bz)), xx(ball, 0, bz), 2 FOR i = 1 TO 2 controller i, cy(i), 2 'controller i, SGN(cy(i)) * ing, 8 NEXT controller 1, SGN(cy(1)) * ing, 8 LOCATE 1, 25: PRINT score1 LOCATE 1, 52: PRINT score2 ON TIMER(1) GOSUB change TIMER ON DEF SEG = &H40 mt = 0 DO time = (time + 1) MOD 24 IF time = 0 THEN lt = PEEK(&H6C): IF lt < 0 THEN lt = lt + 256 media = ABS(mt - lt) IF debug THEN LOCATE 1, 1: PRINT media mt = lt SELECT CASE media CASE IS < 5 delay = delay + 1000 CASE IS > 10 delay = delay - 1000 END SELECT END IF CIRCLE (xx(bx, by, bz), yy(bx, by, bz)), xx(ball, 0, bz), 0 project bx, by, bz, 0 bx = bx + speedx by = by + speedy bz = bz + speedz CIRCLE (xx(bx, by, bz), yy(bx, by, bz)), xx(ball, 0, bz), 2 project bx, by, bz, 8 FOR d = 1 TO delay: NEXT IF ABS(bx) > ing THEN speedx = -speedx: IF s THEN SOUND 500, .5 IF ABS(by) > ing THEN IF s THEN SOUND 500, .5 IF ABS(bx) < mark AND ABS(bz) < mark THEN SELECT CASE SGN(by) CASE 1 center 15, "Goal for player 1!" score1 = score1 + 1 CASE -1 center 15, "Player 2 scored!" score2 = score2 + 1 END SELECT LOCATE 1, 25: PRINT score1 LOCATE 1, 52: PRINT score2 DO: a$ = INKEY$: LOOP UNTIL a$ = CHR$(13) CLS center 1, myt$ LOCATE 1, 25: PRINT score1 LOCATE 1, 52: PRINT score2 initball END IF speedy = -speedy END IF IF ABS(bz) > ing THEN speedz = -speedz: IF s THEN SOUND 500, .5 cube ing, 0, 0, 0, 2 face mark, ing, 2 face mark, -ing, 2 a$ = INKEY$ IF a$ = CHR$(27) THEN IF score1 > score2 THEN s$ = "Player 1 has won!" IF score2 > score1 THEN s$ = "Player 2 has won!" IF score2 = score1 THEN s$ = "Round drawn!" center 16, s$ SLEEP END END IF IF a$ <> "" THEN a$ = RIGHT$(a$, 1) IF a$ = "H" THEN cspeedz = 1 'cspeedz + 1 force = force + intensity END IF IF a$ = "P" THEN cspeedz = -1 'cspeedz - 1 force = force + intensity END IF IF a$ = "M" THEN cspeedx = 1 'cspeedx + 1 force = force + intensity END IF IF a$ = "K" THEN cspeedx = -1 'cspeedx - 1 force = force + intensity END IF IF UCASE$(a$) = "S" THEN s = NOT s IF a$ = CHR$(32) THEN CLS : initball: center 1, myt$ LOCATE 1, 25: PRINT score1 LOCATE 1, 52: PRINT score2 END IF IF a$ = CHR$(8) THEN controller 1, cy(1), 0 controller 1, SGN(cy(1)) * ing, 0 cx(1) = 0 cz(1) = 0 END IF 'player controller IF cspeedx <> 0 OR cspeedz <> 0 THEN moved(1) = true IF moved(1) THEN controller 1, cy(1), 0 controller 1, SGN(cy(1)) * ing, 0 IF force > 0 THEN force = force - 1 cx(1) = cx(1) + cspeedx cz(1) = cz(1) + cspeedz ELSE cspeedx = 0 cspeedz = 0 END IF END IF 'player controller boundaries IF ABS(cx(1)) > ing - cs THEN cx(1) = SGN(cx(1)) * (ing - cs) IF ABS(cz(1)) > ing - cs THEN cz(1) = SGN(cz(1)) * (ing - cs) 'cpu controls IF time = 0 AND speedy > 0 THEN IF bx <> cx(2) THEN controller 2, cy(2), 0 'controller 2, SGN(cy(2)) * ing, 0 cx(2) = cx(2) + SGN(bx - cx(2)) * 5 END IF IF bz <> cz(2) THEN controller 2, cy(2), 0 'controller 2, SGN(cy(2)) * ing, 0 cz(2) = cz(2) + SGN(bz - cz(2)) * 5 END IF END IF 'ball checks done = 0 FOR i = 1 TO 2 ii = (i - 1) * 2 - 1 IF NOT done AND by * SGN(ii) > 0 THEN IF ABS(by - cy(i)) < tolerance THEN IF ABS(bx - cx(i)) < cs AND ABS(bz - cz(i)) < cs THEN speedy = -speedy: IF s THEN SOUND 500, .6 done = true END IF END IF END IF controller i, cy(i), 2 'controller i, SGN(cy(i)) * ing, 8 NEXT controller 1, SGN(cy(1)) * ing, 8 LOOP '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** '********************************************************************** twoplayers: cube ing, 0, 0, 0, 2 face mark, ing, 14 face mark, -ing, 1 'note that y is reversed because it reads data 'from the LOWER face of a cube COLOR 2 initball FOR i = 1 TO 2 controller i, cy(i), 2 controller i, SGN(cy(i)) * ing, 8 NEXT LOCATE 1, 25: PRINT score1 LOCATE 1, 52: PRINT score2 ON TIMER(1) GOSUB change TIMER ON DEF SEG = &H40 mt = 0 DO time = (time + 1) MOD 24 IF time = 0 THEN lt = PEEK(&H6C): IF lt < 0 THEN lt = lt + 256 media = ABS(mt - lt) IF debug THEN LOCATE 1, 1: PRINT media mt = lt SELECT CASE media CASE IS < 5 delay = delay + 1000 CASE IS > 10 delay = delay - 1000 END SELECT END IF CIRCLE (xx(bx, by, bz), yy(bx, by, bz)), xx(ball, 0, bz), 0 project bx, by, bz, 0 bx = bx + speedx by = by + speedy bz = bz + speedz CIRCLE (xx(bx, by, bz), yy(bx, by, bz)), xx(ball, 0, bz), 2 project bx, by, bz, 8 FOR d = 1 TO delay: NEXT IF ABS(bx) > ing THEN speedx = -speedx: IF s THEN SOUND 500, .5 IF ABS(by) > ing THEN IF s THEN SOUND 500, .5 IF ABS(bx) < mark AND ABS(bz) < mark THEN SELECT CASE SGN(by) CASE 1 center 15, "Goal for player 1!" score1 = score1 + 1 CASE -1 center 15, "Player 2 scored!" score2 = score2 + 1 END SELECT LOCATE 1, 25: PRINT score1 LOCATE 1, 52: PRINT score2 DO: a$ = INKEY$: LOOP UNTIL a$ = CHR$(13) CLS center 1, myt$ LOCATE 1, 25: PRINT score1 LOCATE 1, 52: PRINT score2 initball END IF speedy = -speedy END IF IF ABS(bz) > ing THEN speedz = -speedz: IF s THEN SOUND 500, .5 cube ing, 0, 0, 0, 2 face mark, ing, 2 face mark, -ing, 2 a$ = INKEY$ IF a$ = CHR$(27) THEN IF score1 > score2 THEN s$ = "Player 1 has won!" IF score2 > score1 THEN s$ = "Player 2 has won!" IF score2 = score1 THEN s$ = "Round drawn!" center 16, s$ SLEEP END END IF IF a$ <> "" THEN a$ = RIGHT$(a$, 1) IF a$ = "H" THEN cspeedz = cspeedz + 1 force = force + intensity END IF IF a$ = "P" THEN cspeedz = cspeedz - 1 force = force + intensity END IF IF a$ = "M" THEN cspeedx = cspeedx + 1 force = force + intensity END IF IF a$ = "K" THEN cspeedx = cspeedx - 1 force = force + intensity END IF '/********************************************************* ' Player Two Controls '/********************************************************* IF UCASE$(a$) = "W" THEN cspeedz2 = cspeedz2 - 1 force2 = force2 + intensity END IF IF UCASE$(a$) = "S" THEN cspeedz2 = cspeedz2 + 1 force2 = force2 + intensity END IF IF UCASE$(a$) = "D" THEN cspeedx2 = cspeedx2 + 1 force2 = force2 + intensity END IF IF UCASE$(a$) = "A" THEN cspeedx2 = cspeedx2 - 1 force2 = force2 + intensity END IF 'IF UCASE$(a$) = "S" THEN s = NOT s IF a$ = CHR$(32) THEN CLS : initball: center 1, myt$ LOCATE 1, 25: PRINT score1 LOCATE 1, 52: PRINT score2 END IF IF a$ = CHR$(8) THEN FOR i = 1 TO 2 controller i, cy(i), 0 controller i, SGN(cy(i)) * ing, 0 cx(i) = 0 cz(i) = 0 NEXT END IF 'player controller IF cspeedx <> 0 OR cspeedz <> 0 THEN moved(1) = true IF moved(1) THEN controller 1, cy(1), 0 controller 1, SGN(cy(1)) * ing, 0 IF force > 0 THEN force = force - 1 cx(1) = cx(1) + cspeedx cz(1) = cz(1) + cspeedz ELSE cspeedx = 0 cspeedz = 0 END IF END IF 'player two controls IF cspeedx2 <> 0 OR cspeedz2 <> 0 THEN moved(2) = true IF moved(2) THEN controller 2, cy(2), 0 controller 2, SGN(cy(2)) * ing, 0 IF force2 > 0 THEN force2 = force2 - 1 cx(2) = cx(2) + cspeedx2 cz(2) = cz(2) + cspeedz2 ELSE cspeedx2 = 0 cspeedz2 = 0 END IF END IF 'player controller boundaries IF ABS(cx(1)) > ing - cs THEN cx(1) = SGN(cx(1)) * (ing - cs) IF ABS(cz(1)) > ing - cs THEN cz(1) = SGN(cz(1)) * (ing - cs) IF ABS(cx(2)) > ing - cs THEN cx(2) = SGN(cx(2)) * (ing - cs) IF ABS(cz(2)) > ing - cs THEN cz(2) = SGN(cz(2)) * (ing - cs) 'ball checks done = 0 FOR i = 1 TO 2 ii = (i - 1) * 2 - 1 IF NOT done AND by * SGN(ii) > 0 THEN IF ABS(by - cy(i)) < tolerance THEN IF ABS(bx - cx(i)) < cs AND ABS(bz - cz(i)) < cs THEN speedy = -speedy: IF s THEN SOUND 500, .6 done = true END IF END IF END IF controller i, cy(i), 2 controller i, SGN(cy(i)) * ing, 8 NEXT LOOP END cube: DATA -1,-1,-1, 1,-1,-1, 1,-1,1, -1,-1,1 DATA -1,1,-1, 1,1,-1, 1,1,1, -1,1,1 change: kt = kt + 1 nkt = 120 - kt ktm = INT(nkt / 60) kts = nkt MOD 60 one$ = LTRIM$(STR$(ktm)) IF LEN(one$) = 1 THEN one$ = "0" + one$ two$ = LTRIM$(STR$(kts)) IF LEN(two$) = 1 THEN two$ = "0" + two$ myt$ = one$ + ":" + two$ center 1, myt$ IF nkt = 0 THEN center 14, "Time is up!" IF score1 > score2 THEN s$ = "Player 1 has won!" IF score2 > score1 THEN s$ = "Player 2 has won!" IF score2 = score1 THEN s$ = "Round drawn!" center 16, s$ SLEEP END END IF RETURN SUB center (row, t$) LOCATE row, 40 - (LEN(t$) * .5): PRINT t$ END SUB SUB controller (n, b, p) ' FOR i = 1 TO 4 ' x = fx(i) * cs + cx(n) ' 'y = cy(n) ' y = b ' z = fz(i) * cs + cz(n) ' sx = xx(x, y, z): sy = yy(x, y, z) ' IF i <> 1 THEN LINE (sx, sy)-(mx, my), p: ELSE x1 = sx: y1 = sy ' mx = sx: my = sy ' NEXT ' ' LINE (sx, sy)-(x1, y1), p 'makes the border cube FOR j = 0 TO 1 FOR i = 1 TO 4 x = ffx(i + j * 4) + cx(n) y = ffy(i + j * 4) + b z = ffz(i + j * 4) + cz(n) sx = xx(x, y, z): sy = yy(x, y, z) IF i <> 1 THEN LINE (sx, sy)-(mx, my), p: ELSE x1 = sx: y1 = sy mx = sx: my = sy IF j = 0 THEN x = ffx(i + 4) + cx(n) y = ffy(i + 4) + b z = ffz(i + 4) + cz(n) sxx = xx(x, y, z): syy = yy(x, y, z) LINE (sx, sy)-(sxx, syy), p END IF NEXT LINE (sx, sy)-(x1, y1), p NEXT END SUB SUB cube (n, a, b, c, p) 'makes the border cube FOR j = 0 TO 1 FOR i = 1 TO 4 x = fx(i + j * 4) * n + a y = fy(i + j * 4) * n + b z = fz(i + j * 4) * n + c sx = xx(x, y, z): sy = yy(x, y, z) IF i <> 1 THEN LINE (sx, sy)-(mx, my), p: ELSE x1 = sx: y1 = sy mx = sx: my = sy IF j = 0 THEN x = fx(i + 4) * n + a y = fy(i + 4) * n + b z = fz(i + 4) * n + c sxx = xx(x, y, z): syy = yy(x, y, z) LINE (sx, sy)-(sxx, syy), p END IF NEXT LINE (sx, sy)-(x1, y1), p NEXT END SUB SUB face (n, b, p) 'note that y is reversed because it reads data 'from the LOWER face of a cube FOR i = 1 TO 4 x = fx(i) * n y = fy(i) * b z = fz(i) * n sx = xx(x, y, z): sy = yy(x, y, z) IF i <> 1 THEN LINE (sx, sy)-(mx, my), p: ELSE x1 = sx: y1 = sy mx = sx: my = sy NEXT LINE (sx, sy)-(x1, y1), p END SUB SUB init ing = 70 cs = INT(ing / 4) 'controller size ball = 3 'ball size (ray) mark = ing * .6 RESTORE cube FOR i = 1 TO 8 READ fx(i): READ fy(i): READ fz(i) NEXT RESTORE cube FOR i = 1 TO 8 READ ffx(i): READ ffy(i): READ ffz(i) ffx(i) = CINT(ffx(i) * cs) ffy(i) = CINT(ffy(i) * .06 * cs) ffz(i) = CINT(ffz(i) * cs) NEXT k = 300 'distance from the screen cy(1) = -.8 * ing: cy(2) = -cy(1) 'controller's locations END SUB SUB initball pi = ATN(1) * 4 RANDOMIZE TIMER 'speedx = (RND * 2) - 1 'speedy = (RND * 2) - 1 'speedz = (RND * 2) - 1 m = 1.5 a1 = RND * 2 * pi a2 = RND * 2 * pi speedx = m * COS(a1) * COS(a2) speedz = m * SIN(a1) '* SIN(a2) speedy = m * SIN(a2) bx = 0 by = 0 bz = 0 END SUB SUB project (a, b, c, p) sx = xx(-ing, b, c) sy = yy(-ing, b, c) sx2 = xx(a, -ing, c) sy2 = yy(a, -ing, c) 'PSET (sx, sy), p 'PSET (-sx, sy), p 'PSET (sx2, sy2), p 'PSET (sx2, -sy2), p CIRCLE (sx2, sy2), xx(ball, 0, c), p CIRCLE (sx2, -sy2), xx(ball, 0, c), p END SUB FUNCTION xx (a, b, c) IF c + k <> 0 THEN t = a * k / (c + k) ELSE t = 0 xx = t END FUNCTION FUNCTION yy (a, b, c) IF c + k <> 0 THEN t = b * k / (c + k): ELSE t = 0 yy = t END FUNCTION