Made some modifications to this one, since I love breakout games. Added support for multiple balls and the player can now shoot bullets to destroy bricks (better be a powerup later on).

`rem Breakout principles, part 2.`

rem

rem Original version by John, continued by Marcus.

rem 2016-06-04: Support for multiple balls (not used yet)

rem Bullets

rem

import "Speed.lib"

constant:

MAX_BALLS 16

MAX_BULLETS 8

visible:

rem Bricks.

bricks[20][15]

rem Paddle.

paddleX = 320

paddleY = 400

rem Balls.

balls?[MAX_BALLS]

ballCaptured

rem Bullets.

bullets?[MAX_BULLETS]

hidden:

rem Turn off automatic redraw.

set redraw off

rem Init bricks.

for y = 0 to 14; for x = 0 to 19

bricks[x][y] = 1

next; next

proc InitBalls

proc InitBullets

rem Game loop.

do

rem Update paddle and balls.

proc UpdatePaddle

proc UpdateBalls

proc UpdateBullets

if ballCaptured = false and mousebutton(0, true)

proc AddBullet paddleX - 32, paddleY - 16

proc AddBullet paddleX + 32, paddleY - 16

endif

rem Draw.

set color 0, 0, 0

cls

proc DrawBricks

proc DrawPaddle

proc DrawBullets

proc DrawBall

rem Instructions.

set color 255, 255, 255

set caret width(primary)/2, 440

center "Left mouse button: Launch ball, shoot bullets"

rem Copy graphics to window and wait.

redraw

_SPD_HoldFrame 60

loop

rem Update paddle.

procedure UpdatePaddle()

paddleX = mousex()

endproc

rem Init balls.

procedure InitBalls()

for i = 0 to MAX_BALLS - 1

balls[i].x# = 0.0

balls[i].y# = 0.0

balls[i].dx# = 0.0

balls[i].dy# = 0.0

balls[i].speed = 4

balls[i].alive = false

next

ballCaptured = true

balls[0].alive = true

endproc

rem Update ball.

procedure UpdateBalls()

rem Is ball captured?

if ballCaptured

rem Set above paddle.

balls[0].x# = float(paddleX - 8)

balls[0].y# = float(paddleY - 16)

rem Launch?

if mousebutton(0, true)

balls[0].dx# = 0.0

balls[0].dy# = -1.0

balls[0].speed = 4

balls[0].alive = true

ballCaptured = false

endif

else

anyAlive = false

for i = 0 to MAX_BALLS - 1

if balls[i].alive

proc UpdateBall balls[i]

anyAlive = true

endif

next

if not anyAlive

ballCaptured = true

balls[0].alive = true

endif

endif

endproc

procedure UpdateBall(&ball?)

rem Being lazy here, don't wanna modify John's code, so I'm just

rem copying the object's members to local variables, which I copy

rem back at the end of the function.

ballX# = ball.x#

ballY# = ball.y#

ballDX# = ball.dx#

ballDY# = ball.dy#

ballSpeed = ball.speed

rem Move ball ballSpeed times.

for i = 1 to ballSpeed

rem Move.

ballX = ballX + ballDX

ballY = ballY + ballDY

rem Collision with paddle?

dx# = ballX + 8.0 - float(paddleX)

if abs#(dx) < 48.0 and ballY + 16.0 > float(paddleY) and ballY < float(paddleY) + 16.0

rem Bounce.

ballDY = -1.0

ballDX = dx/24.0

k# = 1.0/sqr(ballDX*ballDX + ballDY*ballDY)

ballDX = ballDX*k

ballDY = ballDY*k

endif

rem Check vertical collisions with bricks.

brickX = int(ballX + 8.0)/32

if brickX >= 0 and brickX < sizeof(bricks, 0)

rem Check brick above ball.

brickY = int(ballY)/16

if brickY < sizeof(bricks, 1) and brickY >= 0 and bricks[brickX][brickY]

bricks[brickX][brickY] = 0

ballDY = abs#(ballDY)

endif

rem Check brick below ball.

brickY = int(ballY + 16.0)/16

if brickY < sizeof(bricks, 1) and brickY >= 0 and bricks[brickX][brickY]

bricks[brickX][brickY] = 0

ballDY = -abs#(ballDY)

endif

endif

rem Check horizontal collisions with bricks.

brickY = int(ballY + 8.0)/16

if brickY >= 0 and brickY < sizeof(bricks, 1)

rem Check brick left of ball.

brickX = int(ballX)/32

if brickX < sizeof(bricks, 0) and brickX >= 0 and bricks[brickX][brickY]

bricks[brickX][brickY] = 0

ballDX = abs#(ballDX)

endif

rem Check brick right of ball.

brickX = int(ballX + 16.0)/32

if brickX < sizeof(bricks, 0) and brickX >= 0 and bricks[brickX][brickY]

bricks[brickX][brickY] = 0

ballDX = -abs#(ballDX)

endif

endif

rem Bounce on walls and ceiling.

if ballX < 0.0

ballDX = abs#(ballDX)

elseif ballX > 624.0

ballDX = -abs#(ballDX)

endif

if ballY < 0.0

ballDY = abs#(ballDY)

rem Ball lost?

elseif ballY > 480.0

ball.alive = false

break

endif

next

rem Lazy finish up by copying locals to object.

ball.x# = ballX#

ball.y# = ballY#

ball.dx# = ballDX#

ball.dy# = ballDY#

ball.speed = ballSpeed

endproc

rem Init bullets.

procedure InitBullets()

for i = 0 to MAX_BULLETS - 1

bullets[i].alive = false

next

endproc

rem Add bullet if possible.

procedure AddBullet(x, y)

rem look for free spot.

for i = 0 to MAX_BULLETS - 1

if bullets[i].alive = false then break

next

if i = MAX_BULLETS then return

bullets[i].alive = true

bullets[i].x = x

bullets[i].y = y

endproc

rem Update bullets.

procedure UpdateBullets()

for i = 0 to MAX_BULLETS - 1

if bullets[i].alive then proc UpdateBullet bullets[i]

next

endproc

rem Update bullet.

procedure UpdateBullet(&bullet?)

bullet.y = bullet.y - 8

if bullet.y < -16

bullet.alive = false

endif

x = bullet.x/32

y = bullet.y/16

if x >= 0 and x < sizeof(bricks, 0) and y >= 0 and y < sizeof(bricks, 1)

if bricks[x][y]

bricks[x][y] = 0

bullet.alive = false

endif

endif

endproc

rem Draw bullets.

procedure DrawBullets()

set color 255, 255, 255

for i = 0 to MAX_BULLETS - 1

if bullets[i].alive

draw rect bullets[i].x - 4, bullets[i].y, 8, 16, true

endif

next

endproc

rem Draw bricks.

procedure DrawBricks()

set color 192, 192, 192

for y = 0 to 14; for x = 0 to 19

if bricks[x][y] then draw rect x*32 + 1, y*16 + 1, 30, 14, true

next; next

endproc

rem Draw paddle.

procedure DrawPaddle()

set color 128, 128, 128

draw rect paddleX - 48, paddleY, 96, 16, true

endproc

rem Draw ball.

procedure DrawBall()

set color 255, 255, 255

for i = 0 to MAX_BALLS - 1

if balls[i].alive

draw rect int(balls[i].x#), int(balls[i].y#), 16, 16, true

endif

next

endproc