Files
Gists/breakout.coffee/breakout.coffee
2023-06-19 09:38:01 -04:00

155 lines
4.3 KiB
CoffeeScript

canvas = document.getElementById "myCanvas"
ctx = canvas.getContext "2d"
# Player
score = 0
lives = 3
drawScore = ->
ctx.font = "16px Arial"
ctx.fillStyle = "#0095DD"
ctx.fillText "Score: " + score, 8, 20
drawLives = ->
ctx.font = "16px Arial"
ctx.fillStyle = "#0095DD"
ctx.fillText "Lives: " + lives, canvas.width - 65, 20
# Ball
x = canvas.width / 2
y = canvas.height - 30
dx = 2
dy = -2
ballRadius = 10
drawBall = ->
do ctx.beginPath
ctx.arc x, y, ballRadius, 0, Math.PI * 2
ctx.fillStyle = "#0095DD"
do ctx.fill
do ctx.closePath
# Paddle
paddleHeight = 10
paddleWidth = 75
paddleX = (canvas.width - paddleWidth) / 2
rightPressed = false
leftPressed = false
drawPaddle = ->
do ctx.beginPath
ctx.rect paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight
ctx.fillStyle = "#0095DD"
do ctx.fill
do ctx.closePath
# Bricks
brickRowCount = 3
brickColumnCount = 5
brickWidth = 75
brickHeight = 20
brickPadding = 10
brickOffsetTop = 30
brickOffsetLeft = 30
bricks = []
for c in [0 ... brickColumnCount]
bricks[c] = []
for r in [0 ... brickRowCount]
bricks[c][r] =
x: (c * (brickWidth + brickPadding)) + brickOffsetLeft,
y: (r * (brickHeight + brickPadding)) + brickOffsetTop,
active: true
drawBricks = ->
drawSingleBrick = (brick) ->
do ctx.beginPath
ctx.rect brick.x, brick.y, brickWidth, brickHeight
ctx.fillStyle = "#0095DD"
do ctx.fill
do ctx.closePath
for col in bricks
for b in col
drawSingleBrick b if b.active
collisionDetection = ->
for col in bricks
for b in col
if b.active and x > b.x and x < b.x + brickWidth and y > b.y and y < b.y + brickHeight
dy = -dy
b.active = false
score++
if score == brickRowCount * brickColumnCount
alert "A winner is you!"
do document.location.reload
# Game loop
gameLoop = ->
ctx.clearRect 0, 0, canvas.width, canvas.height
do drawBricks
do drawBall
do drawPaddle
do drawScore
do drawLives
do collisionDetection
x += dx
y += dy
dx = -dx if (x + dx > canvas.width - ballRadius) or (x + dx < ballRadius)
dy = -dy if (y + dy < ballRadius)
if y + dy > canvas.height - ballRadius
if x > paddleX and x < paddleX + paddleWidth
dy = -dy - 0.25
if dx >= 0 then dx += 0.25 else dx -= 0.25
else
lives--
if not lives
alert "Game over, man!"
do document.location.reload
else
x = canvas.width / 2
y = canvas.height - 30
dx = 2
dy = -2
paddleX = (canvas.width - paddleWidth) / 2
paddleX += 7 if rightPressed and paddleX < canvas.width - paddleWidth
paddleX -= 7 if leftPressed and paddleX > 0
requestAnimationFrame gameLoop
# Input handlers
keyDownHandler = (e) ->
if e.keyCode == 39
rightPressed = true
else if e.keyCode == 37
leftPressed = true
keyUpHandler = (e) ->
if e.keyCode == 39
rightPressed = false
else if e.keyCode == 37
leftPressed = false
mouseMoveHandler = (e) ->
hw = (paddleWidth / 2)
relativeX = e.clientX - canvas.offsetLeft
paddleX = relativeX - hw if relativeX > hw and relativeX < canvas.width - hw
# Initialization
document.addEventListener "keydown", keyDownHandler, false
document.addEventListener "keyup", keyUpHandler, false
document.addEventListener "mousemove", mouseMoveHandler, false
do gameLoop