Skip to content

Instantly share code, notes, and snippets.

@guiseek
Last active April 15, 2023 04:33
Show Gist options
  • Save guiseek/3ac007fa83aa215be525cd0649f1ee66 to your computer and use it in GitHub Desktop.
Save guiseek/3ac007fa83aa215be525cd0649f1ee66 to your computer and use it in GitHub Desktop.
Breakout
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