myawesomeface / index.html
Lookimi's picture
Add 2 files
83791a4 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Neon Mutation Breakout - AI Edition</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #0f172a;
font-family: 'Courier New', monospace;
}
canvas {
display: block;
}
.status-panel {
position: absolute;
top: 20px;
right: 20px;
width: 300px;
background: rgba(15, 23, 42, 0.8);
border: 2px solid #4f46e5;
border-radius: 8px;
padding: 15px;
color: #e2e8f0;
font-size: 14px;
box-shadow: 0 0 20px #4f46e5;
max-height: 80vh;
overflow-y: auto;
}
.mutation-event {
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #334155;
animation: pulse 0.5s;
}
@keyframes pulse {
0% { background-color: rgba(79, 70, 229, 0); }
50% { background-color: rgba(79, 70, 229, 0.3); }
100% { background-color rgba(79, 70, 229, 0); }
}
.mutation-positive {
color: #4ade80;
}
.mutation-negative {
color: #f87171;
}
.mutation-neutral {
color: #60a5fa;
}
.title {
position: absolute;
top: 20px;
left: 20px;
color: #e2e8f0;
font-size: 24px;
text-shadow: 0 0 10px #4f46e5;
}
.score {
position: absolute;
top: 60px;
left: 20px;
color: #e2e8f0;
font-size: 18px;
text-shadow: 0 0 5px #4f46e5;
}
.game-over {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(15, 23, 42, 0.9);
border: 2px solid #4f46e5;
border-radius: 8px;
padding: 30px;
color: #e2e8f0;
text-align: center;
box-shadow: 0 0 30px #4f46e5;
display: none;
}
.restart-btn {
background: #4f46e5;
color: white;
border: none;
padding: 10px 20px;
margin-top: 20px;
border-radius: 5px;
cursor: pointer;
font-family: 'Courier New', monospace;
font-size: 16px;
transition: all 0.3s;
}
.restart-btn:hover {
background: #6366f1;
transform: scale(1.05);
}
.speed-indicator {
position: absolute;
bottom: 20px;
left: 20px;
color: #e2e8f0;
font-size: 14px;
}
.speed-bar {
height: 5px;
background: linear-gradient(90deg, #4f46e5, #ec4899);
margin-top: 5px;
border-radius: 5px;
}
.ai-controls {
position: absolute;
bottom: 20px;
right: 20px;
display: flex;
gap: 10px;
}
.ai-btn {
background: rgba(79, 70, 229, 0.7);
color: white;
border: none;
width: 60px;
height: 60px;
border-radius: 50%;
font-size: 24px;
cursor: pointer;
transition: all 0.2s;
box-shadow: 0 0 10px #4f46e5;
}
.ai-btn:hover {
background: rgba(79, 70, 229, 1);
transform: scale(1.1);
}
.ai-btn:active {
transform: scale(0.95);
}
.ai-mode {
position: absolute;
top: 100px;
left: 20px;
color: #e2e8f0;
font-size: 14px;
}
.ai-learning {
position: absolute;
top: 120px;
left: 20px;
color: #e2e8f0;
font-size: 14px;
}
</style>
</head>
<body>
<div class="title">NEON MUTATION BREAKOUT - PERFECT AI</div>
<div class="score">SCORE: <span id="score">0</span></div>
<div class="ai-mode">AI MODE: <span id="ai-mode">PERFECT</span></div>
<div class="ai-learning">AI LEARNING RATE: <span id="ai-learning">100%</span></div>
<div class="speed-indicator">
GAME SPEED: <span id="speed">1.0x</span>
<div class="speed-bar" id="speed-bar"></div>
</div>
<div class="status-panel">
<h3 class="text-lg font-bold mb-4 text-center border-b border-indigo-500 pb-2">MUTATION EVENTS</h3>
<div id="mutation-log"></div>
</div>
<div class="game-over" id="game-over">
<h2 class="text-2xl font-bold mb-4">LEVEL COMPLETE</h2>
<p>Final Score: <span id="final-score">0</span></p>
<p>Mutations Achieved: <span id="mutation-count">0</span></p>
<p>AI Mastery: <span id="ai-mastery">100%</span></p>
<button class="restart-btn" id="restart-btn">NEXT LEVEL</button>
</div>
<div class="ai-controls">
<button class="ai-btn" id="ai-train-btn">🧠</button>
<button class="ai-btn" id="ai-play-btn">🤖</button>
</div>
<canvas id="gameCanvas"></canvas>
<script>
// Game canvas setup
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Game state
let gameRunning = true;
let score = 0;
let gameSpeed = 1.0;
let speedIncreaseTimer = 0;
let mutationCount = 0;
let lastMutationTime = 0;
// AI state
let aiMode = 'PERFECT'; // 'LEARNING' or 'PLAYING' or 'PERFECT'
let aiLearningRate = 1.0;
let aiMastery = 1.0;
let aiMemory = [];
let aiDecisionThreshold = 1.0;
// Paddle
const paddle = {
width: 100,
height: 15,
x: canvas.width / 2 - 50,
y: canvas.height - 30,
speed: 15,
color: '#4f46e5'
};
// Ball
const ball = {
radius: 10,
x: canvas.width / 2,
y: canvas.height / 2,
dx: 5 * gameSpeed,
dy: -5 * gameSpeed,
color: '#ec4899',
speed: 5
};
// Bricks
const brick = {
rowCount: 5,
columnCount: 10,
width: 75,
height: 20,
padding: 10,
offsetTop: 60,
offsetLeft: 30,
colors: ['#4f46e5', '#6366f1', '#818cf8', '#a5b4fc', '#c7d2fe']
};
let bricks = [];
function initBricks() {
bricks = [];
for (let c = 0; c < brick.columnCount; c++) {
bricks[c] = [];
for (let r = 0; r < brick.rowCount; r++) {
bricks[c][r] = { x: 0, y: 0, status: 1, color: brick.colors[r] };
}
}
}
// Mutation effects
const mutations = {
paddleWiden: { name: "Paddle Widened", effect: () => { paddle.width += 20; }, type: "positive" },
paddleNarrow: { name: "Paddle Narrowed", effect: () => { paddle.width = Math.max(60, paddle.width - 20); }, type: "negative" },
ballSpeedUp: { name: "Ball Speed Increased", effect: () => { ball.speed += 1; updateBallSpeed(); }, type: "neutral" },
ballSpeedDown: { name: "Ball Speed Decreased", effect: () => { ball.speed = Math.max(3, ball.speed - 1); updateBallSpeed(); }, type: "neutral" },
multiBall: { name: "Multi-Ball!", effect: () => { createExtraBall(); }, type: "positive" },
gameSpeedUp: { name: "Game Speed Increased", effect: () => { gameSpeed = Math.min(3.0, gameSpeed + 0.2); updateSpeedDisplay(); }, type: "neutral" },
gameSpeedDown: { name: "Game Speed Decreased", effect: () => { gameSpeed = Math.max(0.8, gameSpeed - 0.2); updateSpeedDisplay(); }, type: "neutral" },
paddleSpeedUp: { name: "Paddle Speed Increased", effect: () => { paddle.speed += 2; }, type: "positive" },
paddleSpeedDown: { name: "Paddle Speed Decreased", effect: () => { paddle.speed = Math.max(5, paddle.speed - 2; }, type: "negative" },
aiLearningBoost: { name: "AI Learning Boost", effect: () => { aiLearningRate = Math.min(1, aiLearningRate + 0.1); updateAIDisplay(); }, type: "positive" },
aiForget: { name: "AI Memory Reset", effect: () => { aiMemory = []; aiLearningRate = Math.max(0, aiLearningRate - 0.2); updateAIDisplay(); }, type: "negative" }
};
let extraBalls = [];
function createExtraBall() {
extraBalls.push({
radius: 10,
x: ball.x,
y: ball.y,
dx: (Math.random() > 0.5 ? 1 : -1) * ball.speed * gameSpeed,
dy: -ball.speed * gameSpeed,
color: `hsl(${Math.random() * 360}, 100%, 70%)`
});
}
// AI functions - PERFECT VERSION
function makeAIDecision() {
if (aiMode !== 'PERFECT' && aiMode !== 'PLAYING') return;
// Perfect prediction of ball's position
const prediction = perfectBallPrediction();
// Move paddle to intercept the ball perfectly
const paddleCenter = paddle.x + paddle.width / 2;
const targetX = prediction - paddle.width / 2;
// Smooth movement to target position
if (targetX > paddle.x + 5) {
paddle.x = Math.min(targetX, paddle.x + paddle.speed * gameSpeed);
} else if (targetX < paddle.x - 5) {
paddle.x = Math.max(targetX, paddle.x - paddle.speed * gameSpeed);
}
}
function perfectBallPrediction() {
// Simulate ball's path perfectly
let simX = ball.x;
let simY = ball.y;
let simDX = ball.dx;
let simDY = ball.dy;
while (simY < paddle.y) {
// Move ball
simX += simDX;
simY += simDY;
// Check wall collisions
if (simX < ball.radius || simX > canvas.width - ball.radius) {
simDX = -simDX;
}
// Check ceiling collision
if (simY < ball.radius) {
simDY = -simDY;
}
// Check brick collisions
for (let c = 0; c < brick.columnCount; c++) {
for (let r = 0; r < brick.rowCount; r++) {
const b = bricks[c][r];
if (b.status === 1) {
if (simX > b.x && simX < b.x + brick.width &&
simY > b.y && simY < b.y + brick.height) {
simDY = -simDY;
// Don't actually break the brick in simulation
}
}
}
}
}
// Return predicted X position at paddle level
return Math.max(ball.radius, Math.min(canvas.width - ball.radius, simX));
}
function updateAIDisplay() {
document.getElementById('ai-mode').textContent = aiMode;
document.getElementById('ai-learning').textContent = `${Math.floor(aiLearningRate * 100)}%`;
}
// Input handling
let rightPressed = false;
let leftPressed = false;
document.addEventListener('keydown', keyDownHandler);
document.addEventListener('keyup', keyUpHandler);
document.addEventListener('mousemove', mouseMoveHandler);
// AI control buttons
document.getElementById('ai-train-btn').addEventListener('click', () => {
aiMode = 'LEARNING';
updateAIDisplay();
});
document.getElementById('ai-play-btn').addEventListener('click', () => {
aiMode = 'PERFECT';
updateAIDisplay();
});
function keyDownHandler(e) {
if (e.key === 'Right' || e.key === 'ArrowRight') {
rightPressed = true;
} else if (e.key === 'Left' || e.key === 'ArrowLeft') {
leftPressed = true;
}
}
function keyUpHandler(e) {
if (e.key === 'Right' || e.key === 'ArrowRight') {
rightPressed = false;
} else if (e.key === 'Left' || e.key === 'ArrowLeft') {
leftPressed = false;
}
}
function mouseMoveHandler(e) {
if (aiMode === 'PERFECT') return;
const relativeX = e.clientX - canvas.offsetLeft;
if (relativeX > paddle.width / 2 && relativeX < canvas.width - paddle.width / 2) {
paddle.x = relativeX - paddle.width / 2;
}
}
// Collision detection
function collisionDetection() {
for (let c = 0; c < brick.columnCount; c++) {
for (let r = 0; r < brick.rowCount; r++) {
const b = bricks[c][r];
if (b.status === 1) {
if (
ball.x > b.x &&
ball.x < b.x + brick.width &&
ball.y > b.y &&
ball.y < b.y + brick.height
) {
ball.dy = -ball.dy;
b.status = 0;
score += 10 * gameSpeed;
document.getElementById('score').textContent = Math.floor(score);
// Chance to trigger mutation when hitting a brick
if (Math.random() < 0.1 && Date.now() - lastMutationTime > 5000) {
triggerRandomMutation();
}
}
}
}
}
}
function triggerRandomMutation() {
lastMutationTime = Date.now();
mutationCount++;
// Get random mutation
const mutationKeys = Object.keys(mutations);
const randomKey = mutationKeys[Math.floor(Math.random() * mutationKeys.length)];
const mutation = mutations[randomKey];
// Apply mutation effect
mutation.effect();
// Log mutation
logMutation(mutation.name, mutation.type);
}
function logMutation(name, type) {
const logElement = document.createElement('div');
logElement.className = `mutation-event mutation-${type}`;
const time = new Date().toLocaleTimeString();
logElement.innerHTML = `<strong>${time}</strong>: ${name}`;
const logContainer = document.getElementById('mutation-log');
logContainer.insertBefore(logElement, logContainer.firstChild);
// Keep log from growing too large
if (logContainer.children.length > 20) {
logContainer.removeChild(logContainer.lastChild);
}
// Highlight new event
logElement.style.animation = 'pulse 1s';
setTimeout(() => {
logElement.style.animation = '';
}, 1000);
}
// Game functions
function updateBallSpeed() {
const directionX = ball.dx > 0 ? 1 : -1;
const directionY = ball.dy > 0 ? 1 : -1;
ball.dx = directionX * ball.speed * gameSpeed;
ball.dy = directionY * ball.speed * gameSpeed;
}
function updateSpeedDisplay() {
document.getElementById('speed').textContent = gameSpeed.toFixed(1) + 'x';
document.getElementById('speed-bar').style.width = `${(gameSpeed / 3) * 100}%`;
}
function drawBall(ballObj) {
ctx.beginPath();
ctx.arc(ballObj.x, ballObj.y, ballObj.radius, 0, Math.PI * 2);
ctx.fillStyle = ballObj.color;
ctx.fill();
ctx.closePath();
// Glow effect
ctx.shadowBlur = 15;
ctx.shadowColor = ballObj.color;
ctx.fill();
ctx.shadowBlur = 0;
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddle.x, paddle.y, paddle.width, paddle.height);
ctx.fillStyle = paddle.color;
ctx.fill();
ctx.closePath();
// Glow effect
ctx.shadowBlur = 20;
ctx.shadowColor = paddle.color;
ctx.fill();
ctx.shadowBlur = 0;
}
function drawBricks() {
for (let c = 0; c < brick.columnCount; c++) {
for (let r = 0; r < brick.rowCount; r++) {
if (bricks[c][r].status === 1) {
const brickX = c * (brick.width + brick.padding) + brick.offsetLeft;
const brickY = r * (brick.height + brick.padding) + brick.offsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brick.width, brick.height);
ctx.fillStyle = bricks[c][r].color;
ctx.fill();
ctx.closePath();
// Glow effect
ctx.shadowBlur = 10;
ctx.shadowColor = bricks[c][r].color;
ctx.fill();
ctx.shadowBlur = 0;
}
}
}
}
function draw() {
if (!gameRunning) return;
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw game elements
drawBricks();
drawBall(ball);
for (const extraBall of extraBalls) {
drawBall(extraBall);
}
drawPaddle();
// AI functions
makeAIDecision();
// Collision detection
collisionDetection();
// Wall collision (left/right)
if (ball.x + ball.dx > canvas.width - ball.radius || ball.x + ball.dx < ball.radius) {
ball.dx = -ball.dx;
}
// Wall collision (top)
if (ball.y + ball.dy < ball.radius) {
ball.dy = -ball.dy;
}
// Paddle collision
if (
ball.y + ball.dy > canvas.height - ball.radius - paddle.height &&
ball.y + ball.dy < canvas.height - ball.radius &&
ball.x > paddle.x &&
ball.x < paddle.x + paddle.width
) {
// Calculate bounce angle based on where ball hits paddle
const hitPosition = (ball.x - (paddle.x + paddle.width / 2)) / (paddle.width / 2);
const angle = hitPosition * Math.PI / 3; // Max 60 degree angle
ball.dy = -Math.abs(ball.speed * gameSpeed * Math.cos(angle));
ball.dx = ball.speed * gameSpeed * Math.sin(angle);
}
// Extra balls paddle collision
for (let i = 0; i < extraBalls.length; i++) {
const eb = extraBalls[i];
if (
eb.y + eb.dy > canvas.height - eb.radius - paddle.height &&
eb.y + eb.dy < canvas.height - eb.radius &&
eb.x > paddle.x &&
eb.x < paddle.x + paddle.width
) {
const hitPosition = (eb.x - (paddle.x + paddle.width / 2)) / (paddle.width / 2);
const angle = hitPosition * Math.PI / 3;
eb.dy = -Math.abs(eb.dy * Math.cos(angle));
eb.dx = eb.dx * Math.sin(angle);
}
// Extra balls wall collision
if (eb.x + eb.dx > canvas.width - eb.radius || eb.x + eb.dx < eb.radius) {
eb.dx = -eb.dx;
}
if (eb.y + eb.dy < eb.radius) {
eb.dy = -eb.dy;
}
// Move extra balls
eb.x += eb.dx;
eb.y += eb.dy;
// Remove extra balls that go out of bounds
if (eb.y > canvas.height) {
extraBalls.splice(i, 1);
i--;
}
}
// Game over check (should never happen with perfect AI)
if (ball.y + ball.dy > canvas.height) {
// Check if this is the last ball
if (extraBalls.length === 0) {
gameOver();
return;
} else {
// Remove main ball but keep playing with extra balls
ball.y = -100;
}
}
// Move ball
ball.x += ball.dx;
ball.y += ball.dy;
// Move paddle (if not in AI PERFECT mode)
if (aiMode !== 'PERFECT') {
if (rightPressed && paddle.x < canvas.width - paddle.width) {
paddle.x += paddle.speed * gameSpeed;
} else if (leftPressed && paddle.x > 0) {
paddle.x -= paddle.speed * gameSpeed;
}
}
// Gradually increase game speed
speedIncreaseTimer++;
if (speedIncreaseTimer > 500 && gameSpeed < 3.0) {
gameSpeed += 0.05;
updateSpeedDisplay();
speedIncreaseTimer = 0;
}
// Check win condition
let allBricksDestroyed = true;
for (let c = 0; c < brick.columnCount; c++) {
for (let r = 0; r < brick.rowCount; r++) {
if (bricks[c][r].status === 1) {
allBricksDestroyed = false;
break;
}
}
if (!allBricksDestroyed) break;
}
if (allBricksDestroyed) {
// Level complete - reset with more bricks
brick.rowCount = Math.min(8, brick.rowCount + 1);
initBricks();
// Reset ball position
ball.x = canvas.width / 2;
ball.y = canvas.height / 2;
ball.dx = 5 * gameSpeed;
ball.dy = -5 * gameSpeed;
// Bonus points for completing level
score += 100 * gameSpeed;
document.getElementById('score').textContent = Math.floor(score);
// Higher chance for mutation after level complete
if (Math.random() < 0.3) {
triggerRandomMutation();
}
}
requestAnimationFrame(draw);
}
function gameOver() {
gameRunning = false;
document.getElementById('final-score').textContent = Math.floor(score);
document.getElementById('mutation-count').textContent = mutationCount;
document.getElementById('ai-mastery').textContent = `${Math.floor(aiLearningRate * 100)}%`;
document.getElementById('game-over').style.display = 'block';
}
function resetGame() {
gameRunning = true;
score = 0;
gameSpeed = 1.0;
speedIncreaseTimer = 0;
mutationCount = 0;
lastMutationTime = 0;
extraBalls = [];
// Reset AI
aiLearningRate = 1.0;
aiMemory = [];
aiMode = 'PERFECT';
document.getElementById('score').textContent = '0';
document.getElementById('speed').textContent = '1.0x';
document.getElementById('speed-bar').style.width = '33.3%';
document.getElementById('game-over').style.display = 'none';
document.getElementById('mutation-log').innerHTML = '';
updateAIDisplay();
// Reset paddle
paddle.width = 100;
paddle.speed = 15;
paddle.x = canvas.width / 2 - 50;
// Reset ball
ball.speed = 5;
ball.x = canvas.width / 2;
ball.y = canvas.height / 2;
ball.dx = 5 * gameSpeed;
ball.dy = -5 * gameSpeed;
updateBallSpeed();
// Reset bricks
brick.rowCount = 5;
initBricks();
draw();
}
// Initialize game
document.getElementById('restart-btn').addEventListener('click', resetGame);
// Handle window resize
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
paddle.y = canvas.height - 30;
});
initBricks();
updateSpeedDisplay();
updateAIDisplay();
draw();
</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 <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=Lookimi/myawesomeface" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
</html>