Last active
April 15, 2023 04:33
-
-
Save guiseek/3ac007fa83aa215be525cd0649f1ee66 to your computer and use it in GitHub Desktop.
Breakout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import './style.scss' | |
const canvas = document.createElement('canvas') | |
const contexto = canvas.getContext('2d') | |
const config = { | |
bola: { | |
raio: 10, | |
}, | |
raquete: { | |
altura: 10, | |
largura: 75, | |
}, | |
bloco: { | |
linhas: 6, | |
colunas: 3, | |
largura: 75, | |
altura: 20, | |
enchimento: 10, | |
margem: { | |
superior: 60, | |
esquerda: 10, | |
}, | |
}, | |
} | |
canvas.width = | |
(config.bloco.largura + config.bloco.enchimento) * config.bloco.linhas + | |
config.bloco.margem.esquerda | |
canvas.height = 800 | |
const estado = { | |
raquete: { | |
x: canvas.width - config.raquete.largura, | |
direcao: undefined, | |
}, | |
interacao: { | |
esquerda: false, | |
direita: false, | |
}, | |
posicao: { | |
x: canvas.width / 2, | |
y: canvas.height - 30, | |
}, | |
velocidade: { | |
x: 3, | |
y: -3, | |
}, | |
historico: { | |
ultimoLado: undefined, | |
}, | |
pontos: { | |
partida: 0, | |
acumulado: 0, | |
}, | |
vidas: 3, | |
} | |
const blocos: Bloco[][] = [] | |
redefineTodosOsBlocos() | |
document.onkeydown = (e) => { | |
if (e.code === 'ArrowRight') { | |
estado.interacao.direita = true | |
} else if (e.code === 'ArrowLeft') { | |
estado.interacao.esquerda = true | |
} | |
} | |
document.onkeyup = (e) => { | |
if (e.code === 'ArrowRight') { | |
estado.interacao.direita = false | |
} else if (e.code === 'ArrowLeft') { | |
estado.interacao.esquerda = false | |
} | |
} | |
document.onmousemove = (e) => { | |
const margem = config.raquete.largura / 2 | |
const relativoX = e.clientX - canvas.offsetLeft | |
if (relativoX > margem && relativoX < canvas.width - margem) { | |
estado.raquete.x = relativoX - margem | |
} | |
} | |
function detectaColisao() { | |
for (let c = 0; c < config.bloco.colunas; c++) { | |
for (let l = 0; l < config.bloco.linhas; l++) { | |
const bloco = blocos[c][l] | |
if (bloco.estado === 1) { | |
if ( | |
estado.posicao.x > bloco.x && | |
estado.posicao.x < bloco.x + config.bloco.largura && | |
estado.posicao.y > bloco.y && | |
estado.posicao.y < | |
bloco.y + config.bloco.altura + config.bloco.altura / 2 | |
) { | |
estado.velocidade.y = -estado.velocidade.y | |
bloco.estado = 0 | |
estado.pontos.partida++ | |
if ( | |
estado.pontos.partida == | |
config.bloco.linhas * config.bloco.colunas | |
) { | |
estado.pontos.acumulado += estado.pontos.partida | |
estado.pontos.partida = 0 | |
// redefinePosicaoRelativa(canvas, ['center', 'end']) | |
estado.posicao.x = alignRelative(canvas.width, 'center') | |
estado.posicao.y = alignRelative(canvas.height, 'end') | |
estado.velocidade.x *= 1.5 | |
estado.velocidade.y *= 1.5 | |
redefineTodosOsBlocos() | |
alert('Você ganhou, parabéns') | |
} | |
} | |
} | |
} | |
} | |
} | |
function redefineTodosOsBlocos() { | |
for (let c = 0; c < config.bloco.colunas; c++) { | |
blocos[c] = [] | |
for (let l = 0; l < config.bloco.linhas; l++) { | |
blocos[c][l] = {x: 0, y: 0, estado: 1} | |
} | |
} | |
} | |
function alignRelative(size: number, align: Align) { | |
switch (align) { | |
case 'center': { | |
return size / 2 | |
} | |
case 'end': { | |
return size - 30 | |
} | |
case 'start': | |
default: { | |
return 20 | |
} | |
} | |
} | |
function desenhaBola() { | |
contexto.beginPath() | |
contexto.arc( | |
estado.posicao.x, | |
estado.posicao.y, | |
config.bola.raio, | |
0, | |
Math.PI * 2 | |
) | |
contexto.fillStyle = 'yellow' | |
contexto.fill() | |
contexto.closePath() | |
} | |
function desenhaRaquete() { | |
contexto.beginPath() | |
contexto.rect( | |
estado.raquete.x, | |
canvas.height - config.raquete.altura, | |
config.raquete.largura, | |
config.raquete.altura | |
) | |
contexto.fillStyle = '#fff' | |
contexto.fill() | |
contexto.closePath() | |
} | |
function desenhaPontos() { | |
contexto.font = '24px Arial' | |
contexto.fillStyle = 'white' | |
const total = estado.pontos.acumulado + estado.pontos.partida | |
contexto.fillText(`Pontos: ${total}`, 8, 30) | |
} | |
function desenhaVidas() { | |
contexto.font = '24px Arial' | |
contexto.fillStyle = 'lime' | |
contexto.fillText(`Vidas: ${estado.vidas}`, canvas.width - 100, 30) | |
} | |
function desenhaBlocos() { | |
for (let c = 0; c < config.bloco.colunas; c++) { | |
for (let r = 0; r < config.bloco.linhas; r++) { | |
if (blocos[c][r].estado == 1) { | |
const blocoX = | |
r * (config.bloco.largura + config.bloco.enchimento) + | |
config.bloco.margem.esquerda | |
const blocoY = | |
c * (config.bloco.altura + config.bloco.enchimento) + | |
config.bloco.margem.superior | |
blocos[c][r].x = blocoX | |
blocos[c][r].y = blocoY | |
contexto.beginPath() | |
contexto.rect(blocoX, blocoY, config.bloco.largura, config.bloco.altura) | |
contexto.fillStyle = 'deeppink' | |
contexto.fill() | |
contexto.closePath() | |
} | |
} | |
} | |
} | |
const detector = { | |
get bolaBateuNaDireita() { | |
return ( | |
estado.posicao.x + estado.velocidade.x > canvas.width - config.bola.raio | |
) | |
}, | |
get raqueteVindoDaEsquerda() { | |
return 0 | |
}, | |
get bolaBateuNaEsquerda() { | |
return estado.posicao.x + estado.velocidade.x < config.bola.raio | |
}, | |
get bolaBateuNoTeto() { | |
return estado.posicao.y + estado.velocidade.y < config.bola.raio | |
}, | |
get bolaBateuNoChao() { | |
return ( | |
estado.posicao.y + estado.velocidade.y > | |
canvas.height - config.raquete.altura - config.bola.raio | |
) | |
}, | |
get bolaEstaSobreARaquete() { | |
return ( | |
estado.posicao.x > estado.raquete.x - config.bola.raio && | |
estado.posicao.x < | |
estado.raquete.x + config.raquete.largura + config.bola.raio | |
) | |
}, | |
} | |
function desenha(currentTime: number) { | |
contexto.clearRect(0, 0, canvas.width, canvas.height) | |
desenhaBlocos() | |
desenhaBola() | |
desenhaRaquete() | |
desenhaPontos() | |
desenhaVidas() | |
detectaColisao() | |
if (detector.bolaBateuNaDireita) { | |
estado.historico.ultimoLado = 'direita' | |
} | |
if (detector.bolaBateuNaDireita || detector.bolaBateuNaEsquerda) { | |
estado.velocidade.x = -estado.velocidade.x | |
} | |
if (detector.bolaBateuNoTeto) { | |
estado.velocidade.y = -estado.velocidade.y | |
} else if (detector.bolaBateuNoChao) { | |
if (detector.bolaEstaSobreARaquete) { | |
estado.velocidade.y = -estado.velocidade.y | |
} else { | |
estado.vidas-- | |
if (!estado.vidas) { | |
// alert('Fim de jogo') | |
document.location.reload() | |
} else { | |
estado.posicao.x = alignRelative(canvas.width, 'center') | |
estado.posicao.y = alignRelative(canvas.height, 'end') | |
// dx = 2 | |
// dy = -2 | |
// estado.raquete.x = (canvas.width - config.raquete.largura) / 2 | |
} | |
} | |
} | |
if ( | |
estado.interacao.direita && | |
estado.raquete.x < canvas.width - config.raquete.largura | |
) { | |
estado.raquete.x += 7 | |
estado.raquete.direcao = 'LTR' | |
} else if (estado.interacao.esquerda && estado.raquete.x > 0) { | |
estado.raquete.direcao = 'RTL' | |
estado.raquete.x -= 7 | |
} | |
// console.log(estado.raquete.direcao) | |
estado.posicao.x += estado.velocidade.x | |
estado.posicao.y += estado.velocidade.y | |
requestAnimationFrame(desenha) | |
} | |
document.body.appendChild(canvas) | |
desenha(+document.timeline.currentTime) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment