Añadidos juegos
This commit is contained in:
17
ladrillos/index.html
Normal file
17
ladrillos/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Breakout</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Rompe Ladrillos</h1>
|
||||
<p>Usa el ratón para mover el bloque. Rompe todos los ladrillos para ganar.</p>
|
||||
<canvas id="gameCanvas" width="540" height="480"></canvas>
|
||||
<div id="score">Puntuación: <span id="score-value">0</span></div>
|
||||
<button id="restart-btn">Reiniciar</button>
|
||||
<div id="game-over-message"></div>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
147
ladrillos/script.js
Normal file
147
ladrillos/script.js
Normal file
@@ -0,0 +1,147 @@
|
||||
const canvas = document.getElementById('gameCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const scoreSpan = document.getElementById('score-value');
|
||||
const restartBtn = document.getElementById('restart-btn');
|
||||
const gameOverDiv = document.getElementById('game-over-message');
|
||||
|
||||
const ballRadius = 8;
|
||||
let x, y, dx, dy;
|
||||
const paddleHeight = 12, paddleWidth = 75;
|
||||
let paddleX;
|
||||
const brickRowCount = 5, brickColumnCount = 7;
|
||||
const brickWidth = 60, brickHeight = 20, brickPadding = 10, brickOffsetTop = 30, brickOffsetLeft = 30;
|
||||
let bricks = [];
|
||||
let score, gameOver;
|
||||
|
||||
function setupBricks() {
|
||||
bricks = [];
|
||||
for(let c=0; c<brickColumnCount; c++) {
|
||||
bricks[c] = [];
|
||||
for(let r=0; r<brickRowCount; r++) {
|
||||
bricks[c][r] = { x:0, y:0, status:1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function startGame() {
|
||||
x = canvas.width/2;
|
||||
y = canvas.height-30;
|
||||
dx = 3;
|
||||
dy = -3;
|
||||
paddleX = (canvas.width-paddleWidth)/2;
|
||||
score = 0;
|
||||
scoreSpan.textContent = score;
|
||||
gameOver = false;
|
||||
gameOverDiv.textContent = '';
|
||||
setupBricks();
|
||||
document.addEventListener("mousemove", mouseMoveHandler);
|
||||
draw();
|
||||
}
|
||||
|
||||
function mouseMoveHandler(e) {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
let relativeX = e.clientX - rect.left;
|
||||
if(relativeX > 0 && relativeX < canvas.width) {
|
||||
paddleX = relativeX - paddleWidth/2;
|
||||
if(paddleX < 0) paddleX = 0;
|
||||
if(paddleX + paddleWidth > canvas.width) paddleX = canvas.width - paddleWidth;
|
||||
}
|
||||
}
|
||||
|
||||
function collisionDetection() {
|
||||
for(let c=0; c<brickColumnCount; c++) {
|
||||
for(let r=0; r<brickRowCount; r++) {
|
||||
const b = bricks[c][r];
|
||||
if(b.status == 1) {
|
||||
if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
|
||||
dy = -dy;
|
||||
b.status = 0;
|
||||
score++;
|
||||
scoreSpan.textContent = score;
|
||||
if(score == brickRowCount*brickColumnCount) {
|
||||
gameOver = true;
|
||||
gameOverDiv.textContent = "¡Ganaste! 🏆";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawBall() {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, ballRadius, 0, Math.PI*2);
|
||||
ctx.fillStyle = "#f9d923";
|
||||
ctx.fill();
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
function drawPaddle() {
|
||||
ctx.beginPath();
|
||||
ctx.rect(paddleX, canvas.height-paddleHeight-5, paddleWidth, paddleHeight);
|
||||
ctx.fillStyle = "#e94560";
|
||||
ctx.fill();
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
function drawBricks() {
|
||||
for(let c=0; c<brickColumnCount; c++) {
|
||||
for(let r=0; r<brickRowCount; r++) {
|
||||
if(bricks[c][r].status == 1) {
|
||||
const brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft;
|
||||
const brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;
|
||||
bricks[c][r].x = brickX;
|
||||
bricks[c][r].y = brickY;
|
||||
ctx.beginPath();
|
||||
ctx.rect(brickX, brickY, brickWidth, brickHeight);
|
||||
ctx.fillStyle = "#393e46";
|
||||
ctx.strokeStyle = "#f9d923";
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
drawBricks();
|
||||
drawBall();
|
||||
drawPaddle();
|
||||
collisionDetection();
|
||||
|
||||
// Rebote en las paredes
|
||||
if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
|
||||
dx = -dx;
|
||||
}
|
||||
if(y + dy < ballRadius) {
|
||||
dy = -dy;
|
||||
} else if(y + dy > canvas.height-ballRadius-paddleHeight-5) {
|
||||
// Rebote en la paleta
|
||||
if(x > paddleX && x < paddleX + paddleWidth) {
|
||||
dy = -dy;
|
||||
} else if (y + dy > canvas.height-ballRadius) {
|
||||
// GAME OVER
|
||||
gameOver = true;
|
||||
gameOverDiv.textContent = "¡Game Over! 😢";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
x += dx;
|
||||
y += dy;
|
||||
|
||||
if(!gameOver) {
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
}
|
||||
|
||||
restartBtn.onclick = function() {
|
||||
document.removeEventListener("mousemove", mouseMoveHandler);
|
||||
startGame();
|
||||
};
|
||||
|
||||
// Inicio
|
||||
startGame();
|
115
ladrillos/styles.css
Normal file
115
ladrillos/styles.css
Normal file
@@ -0,0 +1,115 @@
|
||||
/* Reset y box-sizing global */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Variables de colores y métricas */
|
||||
:root {
|
||||
/* Colores */
|
||||
--color-bg: #1a1a2e;
|
||||
--color-text: #e7e7de;
|
||||
--color-accent: #e94560;
|
||||
--color-highlight: #f9d923;
|
||||
--color-canvas-bg: #0f3460;
|
||||
--color-shadow: rgba(37, 34, 43, 0.8);
|
||||
|
||||
/* Sombras y radios */
|
||||
--radius: 8px;
|
||||
--shadow: 0 0 16px var(--color-shadow);
|
||||
|
||||
/* Tipografía */
|
||||
--font: 'Arial', sans-serif;
|
||||
}
|
||||
|
||||
/* BODY: centrar y padding responsive */
|
||||
body {
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
font-family: var(--font);
|
||||
font-size: 100%; /* 1rem = 16px base */
|
||||
line-height: 1.4;
|
||||
text-align: center;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
padding: clamp(1rem, 4vw, 2rem);
|
||||
}
|
||||
|
||||
/* TITULAR */
|
||||
h1 {
|
||||
margin-top: clamp(1.5rem, 6vw, 3rem);
|
||||
color: var(--color-accent);
|
||||
font-size: clamp(1.75rem, 8vw, 2.75rem);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* PÁRRAFOS */
|
||||
p {
|
||||
color: #fff;
|
||||
font-size: clamp(0.9rem, 2.5vw, 1.2rem);
|
||||
margin: clamp(0.5rem, 2vw, 1rem) 0;
|
||||
}
|
||||
|
||||
/* CANVAS: ancho fluido, altura automática para mantener proporción */
|
||||
canvas {
|
||||
width: 100%;
|
||||
max-width: 640px;
|
||||
aspect-ratio: 640 / 480;
|
||||
height: auto;
|
||||
background: var(--color-canvas-bg);
|
||||
display: block;
|
||||
margin: clamp(1rem, 4vw, 2rem) auto;
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
/* PUNTUACIÓN */
|
||||
#score {
|
||||
color: var(--color-highlight);
|
||||
font-size: clamp(1rem, 2.5vw, 1.5rem);
|
||||
margin-top: clamp(0.5rem, 2vw, 1rem);
|
||||
}
|
||||
|
||||
/* MENSAJE DE GAME OVER */
|
||||
#game-over-message {
|
||||
color: var(--color-accent);
|
||||
font-size: clamp(1.2rem, 4vw, 1.8rem);
|
||||
margin-top: clamp(0.75rem, 3vw, 1.5rem);
|
||||
min-height: 2em;
|
||||
}
|
||||
|
||||
/* BOTÓN REINICIAR */
|
||||
#restart-btn {
|
||||
margin-top: clamp(0.75rem, 3vw, 1.5rem);
|
||||
font-size: clamp(0.9rem, 2.5vw, 1.2rem);
|
||||
padding: clamp(0.5rem, 2vw, 1rem) clamp(1rem, 4vw, 2rem);
|
||||
border: none;
|
||||
border-radius: var(--radius);
|
||||
background: var(--color-accent);
|
||||
color: #fafafa;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
#restart-btn:hover {
|
||||
background: #f0134d;
|
||||
}
|
||||
|
||||
/* MEDIA QUERY (opcional) para pantallas muy pequeñas */
|
||||
@media (max-width: 320px) {
|
||||
body {
|
||||
padding: 1rem;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
#restart-btn {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user