Añadidos juegos

This commit is contained in:
2025-08-21 23:42:55 +02:00
parent ec9c7d8d63
commit 90b2643d8d
46 changed files with 3936 additions and 0 deletions

17
ladrillos/index.html Normal file
View 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
View 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
View 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;
}
}