test / index.html
isatis's picture
Add 2 files
4f331af verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Medieval Pong: Siege of the Castle</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=MedievalSharp&display=swap');
body {
margin: 0;
padding: 0;
background-color: #111;
overflow: hidden;
font-family: 'MedievalSharp', cursive;
color: #d4af37;
text-align: center;
}
#game-container {
position: relative;
width: 800px;
height: 500px;
margin: 20px auto;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="800" height="500" viewBox="0 0 800 500"><rect width="800" height="500" fill="%23101010"/><rect x="50" y="100" width="700" height="300" fill="%23222" stroke="%23d4af37" stroke-width="2"/><rect x="300" y="150" width="200" height="200" fill="%23333" stroke="%23d4af37" stroke-width="2"/><rect x="350" y="200" width="100" height="150" fill="%23555" stroke="%23d4af37" stroke-width="2"/><rect x="375" y="200" width="50" height="30" fill="%23d4af37"/><polygon points="400,50 450,150 350,150" fill="%23777" stroke="%23d4af37" stroke-width="2"/><circle cx="400" cy="250" r="10" fill="%23d4af37"/><line x1="400" y1="260" x2="400" y2="350" stroke="%23d4af37" stroke-width="2"/><line x1="370" y1="290" x2="430" y2="290" stroke="%23d4af37" stroke-width="2"/></svg>');
border: 3px solid #d4af37;
box-shadow: 0 0 20px rgba(212, 175, 55, 0.5);
}
#scoreboard {
display: flex;
justify-content: space-between;
padding: 10px 50px;
font-size: 24px;
text-shadow: 2px 2px 4px #000;
}
.paddle {
position: absolute;
width: 20px;
height: 100px;
background: linear-gradient(to bottom, #8B0000, #B22222, #8B0000);
border: 2px solid #d4af37;
border-radius: 5px;
box-shadow: 0 0 15px #FF4500;
}
#left-paddle {
left: 30px;
top: 200px;
}
#right-paddle {
right: 30px;
top: 200px;
}
.flame {
position: absolute;
width: 10px;
height: 20px;
background: radial-gradient(ellipse at center, #FF8C00 0%, #FF4500 50%, transparent 70%);
border-radius: 50%;
animation: flicker 0.3s infinite alternate;
}
@keyframes flicker {
0% { opacity: 0.7; transform: scaleY(0.9); }
100% { opacity: 1; transform: scaleY(1.1); }
}
#ball {
position: absolute;
width: 20px;
height: 20px;
background: radial-gradient(circle at 30% 30%, #FFF, #FFD700, #B22222);
border-radius: 50%;
box-shadow: 0 0 10px #FF4500;
}
.explosion {
position: absolute;
width: 40px;
height: 40px;
border-radius: 50%;
background: radial-gradient(circle, rgba(255,69,0,0.8) 0%, rgba(255,140,0,0.6) 40%, rgba(255,215,0,0) 70%);
animation: explode 0.5s forwards;
pointer-events: none;
}
@keyframes explode {
0% { transform: scale(0.1); opacity: 1; }
100% { transform: scale(2); opacity: 0; }
}
.particle {
position: absolute;
width: 6px;
height: 6px;
background-color: #FF8C00;
border-radius: 50%;
animation: particle-fly 1s forwards;
pointer-events: none;
}
@keyframes particle-fly {
0% { transform: translate(0, 0); opacity: 1; }
100% { transform: translate(var(--tx), var(--ty)); opacity: 0; }
}
#start-screen, #game-over {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 10;
}
#game-over {
display: none;
}
h1 {
font-size: 48px;
margin-bottom: 20px;
text-shadow: 3px 3px 5px #000;
}
button {
padding: 15px 30px;
font-family: 'MedievalSharp', cursive;
font-size: 20px;
background: linear-gradient(to bottom, #8B0000, #B22222);
color: #d4af37;
border: 2px solid #d4af37;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s;
}
button:hover {
transform: scale(1.05);
box-shadow: 0 0 15px #FF4500;
}
#instructions {
margin-top: 20px;
font-size: 18px;
}
</style>
</head>
<body>
<div id="game-container">
<div id="scoreboard">
<div id="player-score">Player: 0</div>
<div id="ai-score">AI: 0</div>
</div>
<div id="left-paddle" class="paddle"></div>
<div id="right-paddle" class="paddle"></div>
<div id="ball"></div>
<div id="start-screen">
<h1>Medieval Pong: Siege of the Castle</h1>
<button id="start-button">Begin the Siege!</button>
<div id="instructions">
Defend your castle! Use W/S keys to move your flaming paddle.<br>
Each hit creates an explosive impact. First to 5 wins!
</div>
</div>
<div id="game-over">
<h1 id="result-message">Victory!</h1>
<button id="restart-button">Fight Again!</button>
</div>
</div>
<script>
// Game elements
const gameContainer = document.getElementById('game-container');
const leftPaddle = document.getElementById('left-paddle');
const rightPaddle = document.getElementById('right-paddle');
const ball = document.getElementById('ball');
const playerScoreDisplay = document.getElementById('player-score');
const aiScoreDisplay = document.getElementById('ai-score');
const startScreen = document.getElementById('start-screen');
const gameOverScreen = document.getElementById('game-over');
const resultMessage = document.getElementById('result-message');
const startButton = document.getElementById('start-button');
const restartButton = document.getElementById('restart-button');
// Game state
let gameRunning = false;
let playerScore = 0;
let aiScore = 0;
let ballX = 400;
let ballY = 250;
let ballSpeedX = 4;
let ballSpeedY = 4;
let leftPaddleY = 200;
let rightPaddleY = 200;
const paddleHeight = 100;
const paddleWidth = 20;
const ballSize = 20;
const gameWidth = 800;
const gameHeight = 500;
// Key states
const keys = {
w: false,
s: false
};
// Add flame effects to paddles
function addFlames() {
// Left paddle flames
for (let i = 0; i < 3; i++) {
const flame = document.createElement('div');
flame.className = 'flame';
flame.style.left = '-10px';
flame.style.top = `${20 + i * 30}px`;
leftPaddle.appendChild(flame);
}
// Right paddle flames
for (let i = 0; i < 3; i++) {
const flame = document.createElement('div');
flame.className = 'flame';
flame.style.right = '-10px';
flame.style.top = `${20 + i * 30}px`;
rightPaddle.appendChild(flame);
}
}
// Create explosion effect
function createExplosion(x, y) {
const explosion = document.createElement('div');
explosion.className = 'explosion';
explosion.style.left = `${x - 20}px`;
explosion.style.top = `${y - 20}px`;
gameContainer.appendChild(explosion);
// Create particles
for (let i = 0; i < 10; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
particle.style.left = `${x - 3}px`;
particle.style.top = `${y - 3}px`;
// Random direction for particles
const angle = Math.random() * Math.PI * 2;
const speed = 2 + Math.random() * 5;
const tx = Math.cos(angle) * speed * 30;
const ty = Math.sin(angle) * speed * 30;
particle.style.setProperty('--tx', `${tx}px`);
particle.style.setProperty('--ty', `${ty}px`);
gameContainer.appendChild(particle);
// Remove particles after animation
setTimeout(() => {
particle.remove();
}, 1000);
}
// Remove explosion after animation
setTimeout(() => {
explosion.remove();
}, 500);
}
// Update game state
function update() {
if (!gameRunning) return;
// Move player paddle
if (keys.w && leftPaddleY > 0) {
leftPaddleY -= 5;
}
if (keys.s && leftPaddleY < gameHeight - paddleHeight) {
leftPaddleY += 5;
}
// Simple AI for right paddle
const paddleCenter = rightPaddleY + paddleHeight / 2;
if (paddleCenter < ballY - 10) {
rightPaddleY += 4;
} else if (paddleCenter > ballY + 10) {
rightPaddleY -= 4;
}
// Keep AI paddle in bounds
if (rightPaddleY < 0) rightPaddleY = 0;
if (rightPaddleY > gameHeight - paddleHeight) rightPaddleY = gameHeight - paddleHeight;
// Update paddle positions
leftPaddle.style.top = `${leftPaddleY}px`;
rightPaddle.style.top = `${rightPaddleY}px`;
// Move ball
ballX += ballSpeedX;
ballY += ballSpeedY;
// Ball collision with top and bottom
if (ballY <= 0 || ballY >= gameHeight - ballSize) {
ballSpeedY = -ballSpeedY;
createExplosion(ballX, ballY <= 0 ? ballSize : gameHeight - ballSize);
}
// Ball collision with paddles
if (
ballX <= 30 + paddleWidth &&
ballY + ballSize >= leftPaddleY &&
ballY <= leftPaddleY + paddleHeight
) {
ballSpeedX = -ballSpeedX * 1.1; // Increase speed slightly
ballSpeedY += (ballY - (leftPaddleY + paddleHeight / 2)) * 0.05; // Add angle based on hit position
createExplosion(30 + paddleWidth, ballY);
}
if (
ballX >= gameWidth - 30 - paddleWidth - ballSize &&
ballY + ballSize >= rightPaddleY &&
ballY <= rightPaddleY + paddleHeight
) {
ballSpeedX = -ballSpeedX * 1.1; // Increase speed slightly
ballSpeedY += (ballY - (rightPaddleY + paddleHeight / 2)) * 0.05; // Add angle based on hit position
createExplosion(gameWidth - 30 - paddleWidth, ballY);
}
// Ball out of bounds (score)
if (ballX < 0) {
aiScore++;
aiScoreDisplay.textContent = `AI: ${aiScore}`;
resetBall();
if (aiScore >= 5) endGame(false);
}
if (ballX > gameWidth) {
playerScore++;
playerScoreDisplay.textContent = `Player: ${playerScore}`;
resetBall();
if (playerScore >= 5) endGame(true);
}
// Update ball position
ball.style.left = `${ballX}px`;
ball.style.top = `${ballY}px`;
// Continue animation
requestAnimationFrame(update);
}
// Reset ball to center
function resetBall() {
ballX = gameWidth / 2 - ballSize / 2;
ballY = gameHeight / 2 - ballSize / 2;
ballSpeedX = (Math.random() > 0.5 ? 1 : -1) * 4;
ballSpeedY = (Math.random() * 4 - 2);
// Show ball at center
ball.style.left = `${ballX}px`;
ball.style.top = `${ballY}px`;
// Pause for a moment
gameRunning = false;
setTimeout(() => {
gameRunning = true;
update();
}, 1000);
}
// End game
function endGame(playerWon) {
gameRunning = false;
resultMessage.textContent = playerWon ? "Victory! The Castle Stands!" : "Defeat! The Castle Burns!";
gameOverScreen.style.display = "flex";
}
// Start game
function startGame() {
playerScore = 0;
aiScore = 0;
playerScoreDisplay.textContent = "Player: 0";
aiScoreDisplay.textContent = "AI: 0";
startScreen.style.display = "none";
gameOverScreen.style.display = "none";
resetBall();
gameRunning = true;
update();
}
// Event listeners
document.addEventListener('keydown', (e) => {
if (e.key.toLowerCase() === 'w') keys.w = true;
if (e.key.toLowerCase() === 's') keys.s = true;
});
document.addEventListener('keyup', (e) => {
if (e.key.toLowerCase() === 'w') keys.w = false;
if (e.key.toLowerCase() === 's') keys.s = false;
});
startButton.addEventListener('click', startGame);
restartButton.addEventListener('click', startGame);
// Initialize
addFlames();
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
</html>