<!--- PAGE INVADER 1.0 -->
<style>
#gameContainer {
margin: 0;
padding: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #000;
font-family: 'PixelFont', sans-serif;
position: relative;
border: 2px solid #fff;
}
#gameCanvas {
background-color: #000;
display: block;
}
#score {
color: #fff;
font-size: 24px;
position: absolute;
top: 20px;
font-family: 'PixelFont', sans-serif;
}
#startButton {
color: #fff;
font-size: 24px;
font-family: 'PixelFont', sans-serif;
animation: blink 1s infinite;
position: absolute;
}
#message {
color: #fff;
font-size: 24px;
font-family: 'PixelFont', sans-serif;
position: absolute;
display: none;
}
@keyframes blink {
50% { opacity: 0; }
}
#colorForm {
position: relative;
background: black;
padding: 10px;
border-radius: 0px;
}
#mobileControls {
position: absolute;
bottom: 10px;
display: flex;
gap: 10px;
}
#mobileControls button {
padding: 10px;
font-size: 18px;
font-family: 'PixelFont', sans-serif;
}
</style>
<div id="gameContainer">
<div id="score">Score: 0 | Lives: 3</div>
<div id="message"></div>
<canvas id="gameCanvas"></canvas>
<button id="startButton">START</button>
<div id="mobileControls" style="display: none;">
<button id="moveLeftButton">←</button>
<button id="moveRightButton">→</button>
<button id="shootButton">Shoot</button>
</div>
</div>
<script>
let canvasColor = '#000';
let playerColor = '#fff';
let enemyColor = '#ff0000';
let bulletColor = '#00ff00';
let borderColor = '#fff';
let watermarkColor = '#fff';
const watermarkBase64 = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iYiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3My4yNzIiIGhlaWdodD0iMjEuMjQ4IiB2aWV3Qm94PSIwIDAgNzMuMjcyIDIxLjI0OCI+CiAgPGcgaWQ9ImMiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+CiAgICA8ZyBvcGFjaXR5PSIuNiI+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMTcuMzIzIDAgMTcuMjM4IDEuMTU1IDE4LjUzNiAxLjE1NSAxOC4yOTIgNC42ODQgMTYuOTc2IDQuNjg0IDE3LjA2NCAzLjQ5NiAxNC40NDQgMy40OTYgMTQuNTQzIDIuMzIgMTAuNjI4IDIuMzIgMTAuNTEyIDMuNDk2IDEzLjEzMiAzLjQ5NiAxMy4wMjYgNC42ODQgMTQuMzQ1IDQuNjg0IDE0LjI0NCA1Ljg4MSAxMS41OTggNS44ODEgMTEuNDg0IDcuMDg5IDE1LjQ3IDcuMDg5IDE1LjU2NiA1Ljg4MSAxOC4yMDkgNS44ODEgMTguMDQxIDguMzEgMTYuNzA3IDguMzEgMTYuNjE2IDkuNTQgOC41NzIgOS41NCA4LjY5OSA4LjMxIDcuMzY2IDguMzEgNy42MyA1Ljg4MSA4Ljk1MiA1Ljg4MSA5LjA3NiA0LjY4NCA3Ljc2IDQuNjg0IDguMTQ0IDEuMTU1IDkuNDQyIDEuMTU1IDkuNTYyIDAgMTcuMzIzIDAiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNjQuNDk1LDUuODgxaC0xLjMyMmwuMTE5LDEuMjA4aDEuMzI4bC4xMjcsMS4yMjFoMS4zMzdsLjEzNCwxLjIzaC00LjAyMmwtLjExNi0xLjIzaC0xLjMzN2wtLjEwOS0xLjIyMWgtMS4zMjhsLjIwNiwyLjQ1MWgtNC4wMjJsLS4xNy0yLjQ1MWgxLjMzMWwtLjM1NC00Ljc2OWgtMS4zMDdMNTQuODMsMGg3Ljc2MWwuMTE0LDEuMTU1aDEuMjk4bC4xMjEsMS4xNjVoMS4zMDdsLjI1NywyLjM2NGgtMS4zMTlsLjEyNCwxLjE5N1pNNjEuNjI3LDMuNDk2aDEuMzFsLS4xMTYtMS4xNzZoLTMuOTE1bC4xOTksMi4zNjRoMi42MzRsLS4xMTItMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNDAuNjkxLDUuODgxaC0xLjMyMmwuMDEyLDEuMjA4aDEuMzI4bC4wMTgsMS4yMjFoMS4zMzRsLjAyNCwxLjIzaC00LjAxOWwtLjAwNi0xLjIzaC0xLjMzN3YtMS4yMjFoLTEuMzI4bC0uMDEyLDIuNDUxaC00LjAyMmwuMDQ4LTIuNDUxaDEuMzNsLjA3MS00Ljc2OWgtMS4zMDdMMzEuNTUsMGg3Ljc2MWwuMDExLDEuMTU1aDEuMjk4bC4wMTcsMS4xNjVoMS4zMDRsLjA0NywyLjM2NGgtMS4zMTZsLjAxOCwxLjE5N1pNMzguMDM2LDMuNDk2aDEuMzFsLS4wMTItMS4xNzZoLTMuOTE1bC0uMDEyLDIuMzY0aDIuNjM0bC0uMDA2LTEuMTg5IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTI4Ljc5LDUuODgxaC0xLjMyNWwtLjA0MiwxLjIwOGgxLjMzMWwtLjAzNiwxLjIyMWgxLjMzNGwtLjAzLDEuMjNoLTQuMDIybC4wNDktMS4yM2gtMS4zMzRsLjA1NC0xLjIyMWgtMS4zMjhsLS4xMjEsMi40NTFoLTQuMDIybC4xNTgtMi40NTFoMS4zMjhsLjI4My00Ljc2OWgtMS4zMDRMMTkuOTExLDBoNy43NThsLS4wNCwxLjE1NWgxLjMwMWwtLjAzNSwxLjE2NWgxLjMwNGwtLjA1OCwyLjM2NGgtMS4zMTZsLS4wMzUsMS4xOTdaTTI2LjIzOSwzLjQ5NmgxLjMxbC4wNDEtMS4xNzZoLTMuOTEybC0uMTE3LDIuMzY0aDIuNjMxbC4wNDctMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTIuMzgzLDIuMzJoMS4zMDRsLjM4NSw1Ljk5aC0xLjMzNGwuMDczLDEuMjNoLTYuNzA0bC0uMDQzLTEuMjNoLTEuMzM0bC0uMDM2LTEuMjIxaC0xLjMyOGwtLjE0Ny01LjkzNGgxLjI5OEw0NC40ODQsMGg2LjQ2NmwuMDYzLDEuMTU1aDEuMzAxbC4wNjksMS4xNjVaTTUxLjI3LDUuODgxbC0uMDY1LTEuMTk3aC0xLjMxNmwtLjA1OS0xLjE4OWgtMS4zMWwtLjA1Mi0xLjE3NmgtMS4zMDRsLjA0NywxLjE3NmgtMS4zMTNsLjA0MSwxLjE4OWgxLjMxOWwuMDQ3LDEuMTk3aDEuMzIybC4wNTQsMS4yMDhoMS4zMjhsLS4wNi0xLjIwOGgxLjMyMiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iNzAuNzU0IDEwLjg4MyA3MC45MSAxMi4xMzYgNzIuMjYzIDEyLjEzNiA3Mi43NiAxNS45NjkgNzEuMzg5IDE1Ljk2OSA3MS4yMjggMTQuNjggNjguNDk1IDE0LjY4IDY4LjM0OCAxMy40MDEgNjQuMjcxIDEzLjQwMSA2NC40IDE0LjY4IDY3LjEzIDE0LjY4IDY3LjI3MiAxNS45NjkgNjguNjQzIDE1Ljk2OSA2OC43OTMgMTcuMjY5IDY2LjAzNyAxNy4yNjkgNjYuMTc1IDE4LjU4NSA3MC4zMzEgMTguNTg1IDcwLjE3NCAxNy4yNjkgNzIuOTI5IDE3LjI2OSA3My4yNzIgMTkuOTExIDcxLjg4MSAxOS45MTEgNzIuMDQ5IDIxLjI0OCA2My42NTcgMjEuMjQ4IDYzLjUzIDE5LjkxMSA2Mi4xMzkgMTkuOTExIDYxLjkgMTcuMjY5IDYzLjI3OCAxNy4yNjkgNjMuMTU0IDE1Ljk2OSA2MS43ODMgMTUuOTY5IDYxLjQzNyAxMi4xMzYgNjIuNzg5IDEyLjEzNiA2Mi42NyAxMC44ODMgNzAuNzU0IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMzUuMDI1IDEwLjg4MyAzNS4wMTcgMTIuMTM2IDM2LjM3MyAxMi4xMzYgMzYuMzY4IDE1Ljk2OSAzNC45OTQgMTUuOTY5IDM1LjAwMiAxNC42OCAzMy42MzcgMTQuNjggMzMuNjUxIDEzLjQwMSAyOS41NzEgMTMuNDAxIDI5LjUzOCAxNC42OCAyOC4xNzMgMTQuNjggMjguMDkzIDE3LjI2OSAyOS40NzEgMTcuMjY5IDI5LjQzNyAxOC41ODUgMzMuNTkzIDE4LjU4NSAzMy42MDggMTcuMjY5IDM2LjM2NiAxNy4yNjkgMzYuMzY1IDE4LjU4NSAzNC45NzcgMTguNTg1IDM0Ljk2OSAxOS45MTEgMzMuNTc4IDE5LjkxMSAzMy41NjMgMjEuMjQ4IDI3Ljk3IDIxLjI0OCAyOC4wMTEgMTkuOTExIDI2LjYyIDE5LjkxMSAyNi42NjggMTguNTg1IDI1LjI4IDE4LjU4NSAyNS40OTIgMTMuNDAxIDI2Ljg1NCAxMy40MDEgMjYuODk5IDEyLjEzNiAyOC4yNTIgMTIuMTM2IDI4LjI5MSAxMC44ODMgMzUuMDI1IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik0yMi41NzgsMTcuMjY5aC0xLjM3OGwtLjA3MywxLjMxNmgxLjM4NGwtLjA2NywxLjMyNWgxLjM5MWwtLjA2MSwxLjMzOGgtNC4xOTZsLjA4MS0xLjMzOGgtMS4zOTFsLjA4Ny0xLjMyNWgtMS4zODRsLS4xODgsMi42NjNoLTQuMTk2bC4yMjctMi42NjNoMS4zODRsLjQxNy01LjE4NGgtMS4zNTlsLjIxNS0yLjUxOGg4LjA4NGwtLjA3LDEuMjUzaDEuMzUzbC0uMDY0LDEuMjY1aDEuMzU5bC0uMTE4LDIuNTY4aC0xLjM3MWwtLjA2NiwxLjMwMVpNMTkuOTc2LDE0LjY4aDEuMzY4bC4wNzEtMS4yNzloLTQuMDc5bC0uMTgxLDIuNTY4aDIuNzQzbC4wNzgtMS4yODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTguODMzLDEzLjQwMWgxLjM1OWwuNTU2LDYuNTFoLTEuMzkxbC4xMDgsMS4zMzhoLTkuNzg5bC0uMTgyLTMuOTc5aDEuMzc4bC0uMTk2LTMuODY5aC0xLjM1OWwtLjExNS0yLjUxOGg4LjA4MWwuMDk1LDEuMjUzaDEuMzU1bC4xMDIsMS4yNjVaTTU3Ljc2MywxNy4yNjlsLS4wOTgtMS4zMDFoLTEuMzcybC0uMDkxLTEuMjg5aC0xLjM2NWwtLjA4NC0xLjI3OWgtMS4zNjJsLjIzNSwzLjg2OWgxLjM4MWwuMDg2LDEuMzE2aDEuMzg0bC0uMDkzLTEuMzE2aDEuMzc4IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTEwLjY1NywxMi4xMzZoMS4zNTZsLS44MjMsOS4xMTNoLTQuMTk2bC4xNDEtMS4zMzhIMi45NTlsLS4xNjEsMS4zMzhIMGwuMzQ2LTIuNjYzaDEuMzg3bC4zMjctMi42MTZoMS4zNzJsLjE1NS0xLjI4OWgxLjM2NWwuMjkzLTIuNTQ0aC0xLjM1MmwuMTUtMS4yNTNoNi43MzVsLS4xMTksMS4yNTNaTTguNzksMTcuMjY5bC4yNTktMi41ODloLTEuMzY1bC0uMTM1LDEuMjg5aC0xLjM3MWwtLjE0MywxLjMwMWgyLjc1NiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik00Ni41NSwxMi4xMzZoMS4zNTJsLjM3Miw5LjExM2gtNC4xOTZsLS4wMzUtMS4zMzhoLTQuMTczbC4wMTUsMS4zMzhoLTIuNzk4bC0uMDAzLTIuNjYzaDEuMzg0bC0uMDE2LTIuNjE2aDEuMzc0bC0uMDE0LTEuMjg5aDEuMzY1bC0uMDQxLTIuNTQ0aC0xLjM1M2wtLjAxNC0xLjI1M2g2LjczNWwuMDQ1LDEuMjUzWk00NS4zNTYsMTcuMjY5bC0uMDgtMi41ODloLTEuMzY4bC4wMzQsMS4yODloLTEuMzcxbC4wMjcsMS4zMDFoMi43NTkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+';
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const playerWidth = 50;
const playerHeight = 30;
const bulletWidth = 5;
const bulletHeight = 10;
const enemyWidth = 40;
const enemyHeight = 30;
let playerX = (canvas.width - playerWidth) / 2;
let bullets = [];
let enemies = [];
let enemyBullets = [];
let leftPressed = false;
let rightPressed = false;
let shootPressed = false;
let score = 0;
let lives = 3;
let gameStarted = false;
let enemyDirection = 1; // 1 for right, -1 for left
let messageElement = document.getElementById('message');
function initEnemies() {
enemies = [];
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 8; col++) {
let x = col * (enemyWidth + 10) + 30;
let y = row * (enemyHeight + 10) + 30;
enemies.push({ x: x, y: y, status: 1 });
}
}
}
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') leftPressed = true;
if (e.key === 'ArrowRight') rightPressed = true;
if (e.key === ' ') {
shootPressed = true;
e.preventDefault(); // Prevent space bar from scrolling the page
}
});
document.addEventListener('keyup', (e) => {
if (e.key === 'ArrowLeft') leftPressed = false;
if (e.key === 'ArrowRight') rightPressed = false;
if (e.key === ' ') shootPressed = false;
});
document.getElementById('moveLeftButton').addEventListener('mousedown', () => leftPressed = true);
document.getElementById('moveLeftButton').addEventListener('mouseup', () => leftPressed = false);
document.getElementById('moveRightButton').addEventListener('mousedown', () => rightPressed = true);
document.getElementById('moveRightButton').addEventListener('mouseup', () => rightPressed = false);
document.getElementById('shootButton').addEventListener('mousedown', () => shootPressed = true);
document.getElementById('shootButton').addEventListener('mouseup', () => shootPressed = false);
function updateColor(element, color) {
switch (element) {
case 'canvasColor':
canvasColor = color;
document.getElementById('gameContainer').style.backgroundColor = color;
break;
case 'playerColor':
playerColor = color;
break;
case 'enemyColor':
enemyColor = color;
break;
case 'bulletColor':
bulletColor = color;
break;
case 'borderColor':
borderColor = color;
document.getElementById('gameContainer').style.borderColor = color;
break;
case 'watermarkColor':
watermarkColor = color;
break;
}
draw();
saveColors();
}
function saveColors() {
const canvasWidth = document.getElementById('canvasWidth').value || canvas.style.width;
const canvasHeight = document.getElementById('canvasHeight').value || canvas.style.height;
const css = `
<style>
#gameContainer {
background-color: ${canvasColor} !important;
border-color: ${borderColor} !important;
}
#score {
color: ${playerColor} !important;
}
#startButton {
background-color: ${playerColor} !important;
}
.player {
background-color: ${playerColor} !important;
}
.enemy {
background-color: ${enemyColor} !important;
}
.bullet {
background-color: ${bulletColor} !important;
}
#gameCanvas {
background-color: ${canvasColor} !important;
width: ${canvasWidth} !important;
height: ${canvasHeight} !important;
}
canvas {
background-color: ${canvasColor} !important;
}
</style>
`;
const trimmedCss = css.trim();
document.getElementById('add-css').value = trimmedCss;
document.getElementById('add-css-export-2').innerHTML = trimmedCss;
document.getElementById('add-css-export-3').innerHTML = trimmedCss;
}
function updateCanvasSize() {
const canvasWidth = document.getElementById('canvasWidth').value;
const canvasHeight = document.getElementById('canvasHeight').value;
if (canvasWidth) canvas.style.width = canvasWidth;
if (canvasHeight) canvas.style.height = canvasHeight;
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
playerX = (canvas.width - playerWidth) / 2;
draw();
}
function drawPlayer() {
ctx.fillStyle = playerColor;
ctx.beginPath();
ctx.moveTo(playerX, canvas.height - playerHeight);
ctx.lineTo(playerX + playerWidth / 2, canvas.height - playerHeight - 20);
ctx.lineTo(playerX + playerWidth, canvas.height - playerHeight);
ctx.closePath();
ctx.fill();
}
function drawBullet(bullet) {
ctx.fillStyle = bulletColor;
ctx.fillRect(bullet.x, bullet.y, bulletWidth, bulletHeight);
}
function drawEnemies() {
enemies.forEach(enemy => {
if (enemy.status === 1) {
ctx.fillStyle = enemyColor;
ctx.beginPath();
ctx.arc(enemy.x + enemyWidth / 2, enemy.y + enemyHeight / 2, enemyWidth / 2, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
});
}
function drawWatermark() {
const img = new Image();
img.src = watermarkBase64;
img.onload = () => {
ctx.drawImage(img, (canvas.width - img.width) / 2, (canvas.height - img.height) / 2);
ctx.fillStyle = watermarkColor;
ctx.globalAlpha = 0.6;
ctx.fill();
ctx.globalAlpha = 1.0;
};
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = canvasColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawPlayer();
bullets.forEach(drawBullet);
enemyBullets.forEach(drawBullet);
drawEnemies();
drawWatermark();
document.getElementById('score').innerText = `Score: ${score} | Lives: ${lives}`;
}
function movePlayer() {
if (leftPressed && playerX > 0) playerX -= 5;
if (rightPressed && playerX < canvas.width - playerWidth) playerX += 5;
}
function moveBullets() {
bullets.forEach(bullet => bullet.y -= 5);
bullets = bullets.filter(bullet => bullet.y > 0);
enemyBullets.forEach(bullet => bullet.y += 5);
enemyBullets = enemyBullets.filter(bullet => bullet.y < canvas.height);
}
function shootBullet() {
if (shootPressed) {
bullets.push({ x: playerX + playerWidth / 2 - bulletWidth / 2, y: canvas.height - playerHeight - 20 });
shootPressed = false;
}
}
function enemyShoot() {
enemies.forEach(enemy => {
if (enemy.status === 1 && Math.random() < 0.01) {
enemyBullets.push({ x: enemy.x + enemyWidth / 2 - bulletWidth / 2, y: enemy.y + enemyHeight });
}
});
}
function moveEnemies() {
let moveDown = false;
enemies.forEach(enemy => {
if (enemy.status === 1) {
enemy.x += enemyDirection * 2;
if (enemy.x + enemyWidth > canvas.width || enemy.x < 0) {
moveDown = true;
}
}
});
if (moveDown) {
enemies.forEach(enemy => {
enemy.y += 10;
});
enemyDirection *= -1;
}
}
function detectCollisions() {
bullets.forEach(bullet => {
enemies.forEach(enemy => {
if (enemy.status === 1 && bullet.x > enemy.x && bullet.x < enemy.x + enemyWidth && bullet.y > enemy.y && bullet.y < enemy.y + enemyHeight) {
enemy.status = 0;
bullet.y = -10;
score++;
}
});
});
enemyBullets.forEach(bullet => {
if (bullet.x > playerX && bullet.x < playerX + playerWidth && bullet.y > canvas.height - playerHeight - 20) {
bullet.y = canvas.height + 10;
lives--;
if (lives <= 0) {
gameOver();
}
}
});
enemies.forEach(enemy => {
if (enemy.status === 1 && enemy.y + enemyHeight > canvas.height - playerHeight - 10 && enemy.x + enemyWidth > playerX && enemy.x < playerX + playerWidth) {
lives--;
enemy.status = 0;
if (lives <= 0) {
gameOver();
}
}
});
}
function gameOver() {
messageElement.innerText = 'Game Over!';
messageElement.style.display = 'block';
gameStarted = false;
setTimeout(() => {
document.location.reload();
}, 3000);
}
function winGame() {
messageElement.innerText = 'You Win!';
messageElement.style.display = 'block';
gameStarted = false;
setTimeout(() => {
document.location.reload();
}, 3000);
}
function update() {
if (!gameStarted) return;
if (enemies.every(enemy => enemy.status === 0)) {
winGame();
}
movePlayer();
moveBullets();
shootBullet();
enemyShoot();
moveEnemies();
detectCollisions();
draw();
}
const startButton = document.getElementById('startButton');
startButton.addEventListener('click', () => {
gameStarted = true;
startButton.style.display = 'none';
setInterval(update, 1000 / 60);
initEnemies();
});
if (/Mobi|Android/i.test(navigator.userAgent)) {
document.getElementById('mobileControls').style.display = 'flex';
canvas.style.width = '100%';
canvas.style.height = '500px';
} else {
canvas.style.width = '100%';
canvas.style.height = '500px';
}
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
playerX = (canvas.width - playerWidth) / 2;
draw();
</script>
<!--- PAGE INVADER 1.0 -->
<style>
#gameContainer {
margin: 0;
padding: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #000;
font-family: 'PixelFont', sans-serif;
position: relative;
border: 2px solid #fff;
}
#gameCanvas {
background-color: #000;
display: block;
}
#score {
color: #fff;
font-size: 24px;
position: absolute;
top: 20px;
font-family: 'PixelFont', sans-serif;
}
#startButton {
color: #fff;
font-size: 24px;
font-family: 'PixelFont', sans-serif;
animation: blink 1s infinite;
position: absolute;
}
#message {
color: #fff;
font-size: 24px;
font-family: 'PixelFont', sans-serif;
position: absolute;
display: none;
}
@keyframes blink {
50% { opacity: 0; }
}
#colorForm {
position: relative;
background: black;
padding: 10px;
border-radius: 0px;
}
#mobileControls {
position: absolute;
bottom: 10px;
display: flex;
gap: 10px;
}
#mobileControls button {
padding: 10px;
font-size: 18px;
font-family: 'PixelFont', sans-serif;
}
</style>
<div id="gameContainer">
<div id="score">Score: 0 | Lives: 3</div>
<div id="message"></div>
<canvas id="gameCanvas"></canvas>
<button id="startButton">START</button>
<div id="mobileControls" style="display: none;">
<button id="moveLeftButton">←</button>
<button id="moveRightButton">→</button>
<button id="shootButton">Shoot</button>
</div>
</div>
<script>
let canvasColor = '#000';
let playerColor = '#fff';
let enemyColor = '#ff0000';
let bulletColor = '#00ff00';
let borderColor = '#fff';
let watermarkColor = '#fff';
const watermarkBase64 = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iYiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3My4yNzIiIGhlaWdodD0iMjEuMjQ4IiB2aWV3Qm94PSIwIDAgNzMuMjcyIDIxLjI0OCI+CiAgPGcgaWQ9ImMiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+CiAgICA8ZyBvcGFjaXR5PSIuNiI+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMTcuMzIzIDAgMTcuMjM4IDEuMTU1IDE4LjUzNiAxLjE1NSAxOC4yOTIgNC42ODQgMTYuOTc2IDQuNjg0IDE3LjA2NCAzLjQ5NiAxNC40NDQgMy40OTYgMTQuNTQzIDIuMzIgMTAuNjI4IDIuMzIgMTAuNTEyIDMuNDk2IDEzLjEzMiAzLjQ5NiAxMy4wMjYgNC42ODQgMTQuMzQ1IDQuNjg0IDE0LjI0NCA1Ljg4MSAxMS41OTggNS44ODEgMTEuNDg0IDcuMDg5IDE1LjQ3IDcuMDg5IDE1LjU2NiA1Ljg4MSAxOC4yMDkgNS44ODEgMTguMDQxIDguMzEgMTYuNzA3IDguMzEgMTYuNjE2IDkuNTQgOC41NzIgOS41NCA4LjY5OSA4LjMxIDcuMzY2IDguMzEgNy42MyA1Ljg4MSA4Ljk1MiA1Ljg4MSA5LjA3NiA0LjY4NCA3Ljc2IDQuNjg0IDguMTQ0IDEuMTU1IDkuNDQyIDEuMTU1IDkuNTYyIDAgMTcuMzIzIDAiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNjQuNDk1LDUuODgxaC0xLjMyMmwuMTE5LDEuMjA4aDEuMzI4bC4xMjcsMS4yMjFoMS4zMzdsLjEzNCwxLjIzaC00LjAyMmwtLjExNi0xLjIzaC0xLjMzN2wtLjEwOS0xLjIyMWgtMS4zMjhsLjIwNiwyLjQ1MWgtNC4wMjJsLS4xNy0yLjQ1MWgxLjMzMWwtLjM1NC00Ljc2OWgtMS4zMDdMNTQuODMsMGg3Ljc2MWwuMTE0LDEuMTU1aDEuMjk4bC4xMjEsMS4xNjVoMS4zMDdsLjI1NywyLjM2NGgtMS4zMTlsLjEyNCwxLjE5N1pNNjEuNjI3LDMuNDk2aDEuMzFsLS4xMTYtMS4xNzZoLTMuOTE1bC4xOTksMi4zNjRoMi42MzRsLS4xMTItMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNDAuNjkxLDUuODgxaC0xLjMyMmwuMDEyLDEuMjA4aDEuMzI4bC4wMTgsMS4yMjFoMS4zMzRsLjAyNCwxLjIzaC00LjAxOWwtLjAwNi0xLjIzaC0xLjMzN3YtMS4yMjFoLTEuMzI4bC0uMDEyLDIuNDUxaC00LjAyMmwuMDQ4LTIuNDUxaDEuMzNsLjA3MS00Ljc2OWgtMS4zMDdMMzEuNTUsMGg3Ljc2MWwuMDExLDEuMTU1aDEuMjk4bC4wMTcsMS4xNjVoMS4zMDRsLjA0NywyLjM2NGgtMS4zMTZsLjAxOCwxLjE5N1pNMzguMDM2LDMuNDk2aDEuMzFsLS4wMTItMS4xNzZoLTMuOTE1bC0uMDEyLDIuMzY0aDIuNjM0bC0uMDA2LTEuMTg5IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTI4Ljc5LDUuODgxaC0xLjMyNWwtLjA0MiwxLjIwOGgxLjMzMWwtLjAzNiwxLjIyMWgxLjMzNGwtLjAzLDEuMjNoLTQuMDIybC4wNDktMS4yM2gtMS4zMzRsLjA1NC0xLjIyMWgtMS4zMjhsLS4xMjEsMi40NTFoLTQuMDIybC4xNTgtMi40NTFoMS4zMjhsLjI4My00Ljc2OWgtMS4zMDRMMTkuOTExLDBoNy43NThsLS4wNCwxLjE1NWgxLjMwMWwtLjAzNSwxLjE2NWgxLjMwNGwtLjA1OCwyLjM2NGgtMS4zMTZsLS4wMzUsMS4xOTdaTTI2LjIzOSwzLjQ5NmgxLjMxbC4wNDEtMS4xNzZoLTMuOTEybC0uMTE3LDIuMzY0aDIuNjMxbC4wNDctMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTIuMzgzLDIuMzJoMS4zMDRsLjM4NSw1Ljk5aC0xLjMzNGwuMDczLDEuMjNoLTYuNzA0bC0uMDQzLTEuMjNoLTEuMzM0bC0uMDM2LTEuMjIxaC0xLjMyOGwtLjE0Ny01LjkzNGgxLjI5OEw0NC40ODQsMGg2LjQ2NmwuMDYzLDEuMTU1aDEuMzAxbC4wNjksMS4xNjVaTTUxLjI3LDUuODgxbC0uMDY1LTEuMTk3aC0xLjMxNmwtLjA1OS0xLjE4OWgtMS4zMWwtLjA1Mi0xLjE3NmgtMS4zMDRsLjA0NywxLjE3NmgtMS4zMTNsLjA0MSwxLjE4OWgxLjMxOWwuMDQ3LDEuMTk3aDEuMzIybC4wNTQsMS4yMDhoMS4zMjhsLS4wNi0xLjIwOGgxLjMyMiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iNzAuNzU0IDEwLjg4MyA3MC45MSAxMi4xMzYgNzIuMjYzIDEyLjEzNiA3Mi43NiAxNS45NjkgNzEuMzg5IDE1Ljk2OSA3MS4yMjggMTQuNjggNjguNDk1IDE0LjY4IDY4LjM0OCAxMy40MDEgNjQuMjcxIDEzLjQwMSA2NC40IDE0LjY4IDY3LjEzIDE0LjY4IDY3LjI3MiAxNS45NjkgNjguNjQzIDE1Ljk2OSA2OC43OTMgMTcuMjY5IDY2LjAzNyAxNy4yNjkgNjYuMTc1IDE4LjU4NSA3MC4zMzEgMTguNTg1IDcwLjE3NCAxNy4yNjkgNzIuOTI5IDE3LjI2OSA3My4yNzIgMTkuOTExIDcxLjg4MSAxOS45MTEgNzIuMDQ5IDIxLjI0OCA2My42NTcgMjEuMjQ4IDYzLjUzIDE5LjkxMSA2Mi4xMzkgMTkuOTExIDYxLjkgMTcuMjY5IDYzLjI3OCAxNy4yNjkgNjMuMTU0IDE1Ljk2OSA2MS43ODMgMTUuOTY5IDYxLjQzNyAxMi4xMzYgNjIuNzg5IDEyLjEzNiA2Mi42NyAxMC44ODMgNzAuNzU0IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMzUuMDI1IDEwLjg4MyAzNS4wMTcgMTIuMTM2IDM2LjM3MyAxMi4xMzYgMzYuMzY4IDE1Ljk2OSAzNC45OTQgMTUuOTY5IDM1LjAwMiAxNC42OCAzMy42MzcgMTQuNjggMzMuNjUxIDEzLjQwMSAyOS41NzEgMTMuNDAxIDI5LjUzOCAxNC42OCAyOC4xNzMgMTQuNjggMjguMDkzIDE3LjI2OSAyOS40NzEgMTcuMjY5IDI5LjQzNyAxOC41ODUgMzMuNTkzIDE4LjU4NSAzMy42MDggMTcuMjY5IDM2LjM2NiAxNy4yNjkgMzYuMzY1IDE4LjU4NSAzNC45NzcgMTguNTg1IDM0Ljk2OSAxOS45MTEgMzMuNTc4IDE5LjkxMSAzMy41NjMgMjEuMjQ4IDI3Ljk3IDIxLjI0OCAyOC4wMTEgMTkuOTExIDI2LjYyIDE5LjkxMSAyNi42NjggMTguNTg1IDI1LjI4IDE4LjU4NSAyNS40OTIgMTMuNDAxIDI2Ljg1NCAxMy40MDEgMjYuODk5IDEyLjEzNiAyOC4yNTIgMTIuMTM2IDI4LjI5MSAxMC44ODMgMzUuMDI1IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik0yMi41NzgsMTcuMjY5aC0xLjM3OGwtLjA3MywxLjMxNmgxLjM4NGwtLjA2NywxLjMyNWgxLjM5MWwtLjA2MSwxLjMzOGgtNC4xOTZsLjA4MS0xLjMzOGgtMS4zOTFsLjA4Ny0xLjMyNWgtMS4zODRsLS4xODgsMi42NjNoLTQuMTk2bC4yMjctMi42NjNoMS4zODRsLjQxNy01LjE4NGgtMS4zNTlsLjIxNS0yLjUxOGg4LjA4NGwtLjA3LDEuMjUzaDEuMzUzbC0uMDY0LDEuMjY1aDEuMzU5bC0uMTE4LDIuNTY4aC0xLjM3MWwtLjA2NiwxLjMwMVpNMTkuOTc2LDE0LjY4aDEuMzY4bC4wNzEtMS4yNzloLTQuMDc5bC0uMTgxLDIuNTY4aDIuNzQzbC4wNzgtMS4yODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTguODMzLDEzLjQwMWgxLjM1OWwuNTU2LDYuNTFoLTEuMzkxbC4xMDgsMS4zMzhoLTkuNzg5bC0uMTgyLTMuOTc5aDEuMzc4bC0uMTk2LTMuODY5aC0xLjM1OWwtLjExNS0yLjUxOGg4LjA4MWwuMDk1LDEuMjUzaDEuMzU1bC4xMDIsMS4yNjVaTTU3Ljc2MywxNy4yNjlsLS4wOTgtMS4zMDFoLTEuMzcybC0uMDkxLTEuMjg5aC0xLjM2NWwtLjA4NC0xLjI3OWgtMS4zNjJsLjIzNSwzLjg2OWgxLjM4MWwuMDg2LDEuMzE2aDEuMzg0bC0uMDkzLTEuMzE2aDEuMzc4IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTEwLjY1NywxMi4xMzZoMS4zNTZsLS44MjMsOS4xMTNoLTQuMTk2bC4xNDEtMS4zMzhIMi45NTlsLS4xNjEsMS4zMzhIMGwuMzQ2LTIuNjYzaDEuMzg3bC4zMjctMi42MTZoMS4zNzJsLjE1NS0xLjI4OWgxLjM2NWwuMjkzLTIuNTQ0aC0xLjM1MmwuMTUtMS4yNTNoNi43MzVsLS4xMTksMS4yNTNaTTguNzksMTcuMjY5bC4yNTktMi41ODloLTEuMzY1bC0uMTM1LDEuMjg5aC0xLjM3MWwtLjE0MywxLjMwMWgyLjc1NiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik00Ni41NSwxMi4xMzZoMS4zNTJsLjM3Miw5LjExM2gtNC4xOTZsLS4wMzUtMS4zMzhoLTQuMTczbC4wMTUsMS4zMzhoLTIuNzk4bC0uMDAzLTIuNjYzaDEuMzg0bC0uMDE2LTIuNjE2aDEuMzc0bC0uMDE0LTEuMjg5aDEuMzY1bC0uMDQxLTIuNTQ0aC0xLjM1M2wtLjAxNC0xLjI1M2g2LjczNWwuMDQ1LDEuMjUzWk00NS4zNTYsMTcuMjY5bC0uMDgtMi41ODloLTEuMzY4bC4wMzQsMS4yODloLTEuMzcxbC4wMjcsMS4zMDFoMi43NTkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+';
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const playerWidth = 50;
const playerHeight = 30;
const bulletWidth = 5;
const bulletHeight = 10;
const enemyWidth = 40;
const enemyHeight = 30;
let playerX = (canvas.width - playerWidth) / 2;
let bullets = [];
let enemies = [];
let enemyBullets = [];
let leftPressed = false;
let rightPressed = false;
let shootPressed = false;
let score = 0;
let lives = 3;
let gameStarted = false;
let enemyDirection = 1; // 1 for right, -1 for left
let messageElement = document.getElementById('message');
function initEnemies() {
enemies = [];
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 8; col++) {
let x = col * (enemyWidth + 10) + 30;
let y = row * (enemyHeight + 10) + 30;
enemies.push({ x: x, y: y, status: 1 });
}
}
}
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') leftPressed = true;
if (e.key === 'ArrowRight') rightPressed = true;
if (e.key === ' ') {
shootPressed = true;
e.preventDefault(); // Prevent space bar from scrolling the page
}
});
document.addEventListener('keyup', (e) => {
if (e.key === 'ArrowLeft') leftPressed = false;
if (e.key === 'ArrowRight') rightPressed = false;
if (e.key === ' ') shootPressed = false;
});
document.getElementById('moveLeftButton').addEventListener('mousedown', () => leftPressed = true);
document.getElementById('moveLeftButton').addEventListener('mouseup', () => leftPressed = false);
document.getElementById('moveRightButton').addEventListener('mousedown', () => rightPressed = true);
document.getElementById('moveRightButton').addEventListener('mouseup', () => rightPressed = false);
document.getElementById('shootButton').addEventListener('mousedown', () => shootPressed = true);
document.getElementById('shootButton').addEventListener('mouseup', () => shootPressed = false);
function updateColor(element, color) {
switch (element) {
case 'canvasColor':
canvasColor = color;
document.getElementById('gameContainer').style.backgroundColor = color;
break;
case 'playerColor':
playerColor = color;
break;
case 'enemyColor':
enemyColor = color;
break;
case 'bulletColor':
bulletColor = color;
break;
case 'borderColor':
borderColor = color;
document.getElementById('gameContainer').style.borderColor = color;
break;
case 'watermarkColor':
watermarkColor = color;
break;
}
draw();
saveColors();
}
function saveColors() {
const canvasWidth = document.getElementById('canvasWidth').value || canvas.style.width;
const canvasHeight = document.getElementById('canvasHeight').value || canvas.style.height;
const css = `
<style>
#gameContainer {
background-color: ${canvasColor} !important;
border-color: ${borderColor} !important;
}
#score {
color: ${playerColor} !important;
}
#startButton {
background-color: ${playerColor} !important;
}
.player {
background-color: ${playerColor} !important;
}
.enemy {
background-color: ${enemyColor} !important;
}
.bullet {
background-color: ${bulletColor} !important;
}
#gameCanvas {
background-color: ${canvasColor} !important;
width: ${canvasWidth} !important;
height: ${canvasHeight} !important;
}
canvas {
background-color: ${canvasColor} !important;
}
</style>
`;
const trimmedCss = css.trim();
document.getElementById('add-css').value = trimmedCss;
document.getElementById('add-css-export-2').innerHTML = trimmedCss;
document.getElementById('add-css-export-3').innerHTML = trimmedCss;
}
function updateCanvasSize() {
const canvasWidth = document.getElementById('canvasWidth').value;
const canvasHeight = document.getElementById('canvasHeight').value;
if (canvasWidth) canvas.style.width = canvasWidth;
if (canvasHeight) canvas.style.height = canvasHeight;
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
playerX = (canvas.width - playerWidth) / 2;
draw();
}
function drawPlayer() {
ctx.fillStyle = playerColor;
ctx.beginPath();
ctx.moveTo(playerX, canvas.height - playerHeight);
ctx.lineTo(playerX + playerWidth / 2, canvas.height - playerHeight - 20);
ctx.lineTo(playerX + playerWidth, canvas.height - playerHeight);
ctx.closePath();
ctx.fill();
}
function drawBullet(bullet) {
ctx.fillStyle = bulletColor;
ctx.fillRect(bullet.x, bullet.y, bulletWidth, bulletHeight);
}
function drawEnemies() {
enemies.forEach(enemy => {
if (enemy.status === 1) {
ctx.fillStyle = enemyColor;
ctx.beginPath();
ctx.arc(enemy.x + enemyWidth / 2, enemy.y + enemyHeight / 2, enemyWidth / 2, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
});
}
function drawWatermark() {
const img = new Image();
img.src = watermarkBase64;
img.onload = () => {
ctx.drawImage(img, (canvas.width - img.width) / 2, (canvas.height - img.height) / 2);
ctx.fillStyle = watermarkColor;
ctx.globalAlpha = 0.6;
ctx.fill();
ctx.globalAlpha = 1.0;
};
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = canvasColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawPlayer();
bullets.forEach(drawBullet);
enemyBullets.forEach(drawBullet);
drawEnemies();
drawWatermark();
document.getElementById('score').innerText = `Score: ${score} | Lives: ${lives}`;
}
function movePlayer() {
if (leftPressed && playerX > 0) playerX -= 5;
if (rightPressed && playerX < canvas.width - playerWidth) playerX += 5;
}
function moveBullets() {
bullets.forEach(bullet => bullet.y -= 5);
bullets = bullets.filter(bullet => bullet.y > 0);
enemyBullets.forEach(bullet => bullet.y += 5);
enemyBullets = enemyBullets.filter(bullet => bullet.y < canvas.height);
}
function shootBullet() {
if (shootPressed) {
bullets.push({ x: playerX + playerWidth / 2 - bulletWidth / 2, y: canvas.height - playerHeight - 20 });
shootPressed = false;
}
}
function enemyShoot() {
enemies.forEach(enemy => {
if (enemy.status === 1 && Math.random() < 0.01) {
enemyBullets.push({ x: enemy.x + enemyWidth / 2 - bulletWidth / 2, y: enemy.y + enemyHeight });
}
});
}
function moveEnemies() {
let moveDown = false;
enemies.forEach(enemy => {
if (enemy.status === 1) {
enemy.x += enemyDirection * 2;
if (enemy.x + enemyWidth > canvas.width || enemy.x < 0) {
moveDown = true;
}
}
});
if (moveDown) {
enemies.forEach(enemy => {
enemy.y += 10;
});
enemyDirection *= -1;
}
}
function detectCollisions() {
bullets.forEach(bullet => {
enemies.forEach(enemy => {
if (enemy.status === 1 && bullet.x > enemy.x && bullet.x < enemy.x + enemyWidth && bullet.y > enemy.y && bullet.y < enemy.y + enemyHeight) {
enemy.status = 0;
bullet.y = -10;
score++;
}
});
});
enemyBullets.forEach(bullet => {
if (bullet.x > playerX && bullet.x < playerX + playerWidth && bullet.y > canvas.height - playerHeight - 20) {
bullet.y = canvas.height + 10;
lives--;
if (lives <= 0) {
gameOver();
}
}
});
enemies.forEach(enemy => {
if (enemy.status === 1 && enemy.y + enemyHeight > canvas.height - playerHeight - 10 && enemy.x + enemyWidth > playerX && enemy.x < playerX + playerWidth) {
lives--;
enemy.status = 0;
if (lives <= 0) {
gameOver();
}
}
});
}
function gameOver() {
messageElement.innerText = 'Game Over!';
messageElement.style.display = 'block';
gameStarted = false;
setTimeout(() => {
document.location.reload();
}, 3000);
}
function winGame() {
messageElement.innerText = 'You Win!';
messageElement.style.display = 'block';
gameStarted = false;
setTimeout(() => {
document.location.reload();
}, 3000);
}
function update() {
if (!gameStarted) return;
if (enemies.every(enemy => enemy.status === 0)) {
winGame();
}
movePlayer();
moveBullets();
shootBullet();
enemyShoot();
moveEnemies();
detectCollisions();
draw();
}
const startButton = document.getElementById('startButton');
startButton.addEventListener('click', () => {
gameStarted = true;
startButton.style.display = 'none';
setInterval(update, 1000 / 60);
initEnemies();
});
if (/Mobi|Android/i.test(navigator.userAgent)) {
document.getElementById('mobileControls').style.display = 'flex';
canvas.style.width = '100%';
canvas.style.height = '500px';
} else {
canvas.style.width = '100%';
canvas.style.height = '500px';
}
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
playerX = (canvas.width - playerWidth) / 2;
draw();
</script>
<!--- PAGE INVADER 1.0 -->
<style>
#gameContainer {
margin: 0;
padding: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #000;
font-family: 'PixelFont', sans-serif;
position: relative;
border: 2px solid #fff;
}
#gameCanvas {
background-color: #000;
display: block;
}
#score {
color: #fff;
font-size: 24px;
position: absolute;
top: 20px;
font-family: 'PixelFont', sans-serif;
}
#startButton {
color: #fff;
font-size: 24px;
font-family: 'PixelFont', sans-serif;
animation: blink 1s infinite;
position: absolute;
}
#message {
color: #fff;
font-size: 24px;
font-family: 'PixelFont', sans-serif;
position: absolute;
display: none;
}
@keyframes blink {
50% { opacity: 0; }
}
#colorForm {
position: relative;
background: black;
padding: 10px;
border-radius: 0px;
}
#mobileControls {
position: absolute;
bottom: 10px;
display: flex;
gap: 10px;
}
#mobileControls button {
padding: 10px;
font-size: 18px;
font-family: 'PixelFont', sans-serif;
}
</style>
<div id="gameContainer">
<div id="score">Score: 0 | Lives: 3</div>
<div id="message"></div>
<canvas id="gameCanvas"></canvas>
<button id="startButton">START</button>
<div id="mobileControls" style="display: none;">
<button id="moveLeftButton">←</button>
<button id="moveRightButton">→</button>
<button id="shootButton">Shoot</button>
</div>
</div>
<script>
let canvasColor = '#000';
let playerColor = '#fff';
let enemyColor = '#ff0000';
let bulletColor = '#00ff00';
let borderColor = '#fff';
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const playerWidth = 50;
const playerHeight = 30;
const bulletWidth = 5;
const bulletHeight = 10;
const enemyWidth = 40;
const enemyHeight = 30;
let playerX = (canvas.width - playerWidth) / 2;
let bullets = [];
let enemies = [];
let enemyBullets = [];
let leftPressed = false;
let rightPressed = false;
let shootPressed = false;
let score = 0;
let lives = 3;
let gameStarted = false;
let enemyDirection = 1; // 1 for right, -1 for left
let messageElement = document.getElementById('message');
function initEnemies() {
enemies = [];
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 8; col++) {
let x = col * (enemyWidth + 10) + 30;
let y = row * (enemyHeight + 10) + 30;
enemies.push({ x: x, y: y, status: 1 });
}
}
}
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') leftPressed = true;
if (e.key === 'ArrowRight') rightPressed = true;
if (e.key === ' ') {
shootPressed = true;
e.preventDefault(); // Prevent space bar from scrolling the page
}
});
document.addEventListener('keyup', (e) => {
if (e.key === 'ArrowLeft') leftPressed = false;
if (e.key === 'ArrowRight') rightPressed = false;
if (e.key === ' ') shootPressed = false;
});
document.getElementById('moveLeftButton').addEventListener('mousedown', () => leftPressed = true);
document.getElementById('moveLeftButton').addEventListener('mouseup', () => leftPressed = false);
document.getElementById('moveRightButton').addEventListener('mousedown', () => rightPressed = true);
document.getElementById('moveRightButton').addEventListener('mouseup', () => rightPressed = false);
document.getElementById('shootButton').addEventListener('mousedown', () => shootPressed = true);
document.getElementById('shootButton').addEventListener('mouseup', () => shootPressed = false);
function updateColor(element, color) {
switch (element) {
case 'canvasColor':
canvasColor = color;
document.getElementById('gameContainer').style.backgroundColor = color;
break;
case 'playerColor':
playerColor = color;
break;
case 'enemyColor':
enemyColor = color;
break;
case 'bulletColor':
bulletColor = color;
break;
case 'borderColor':
borderColor = color;
document.getElementById('gameContainer').style.borderColor = color;
break;
}
draw();
saveColors();
}
function saveColors() {
const canvasWidth = document.getElementById('canvasWidth').value || canvas.style.width;
const canvasHeight = document.getElementById('canvasHeight').value || canvas.style.height;
const css = `
<style>
#gameContainer {
background-color: ${canvasColor} !important;
border-color: ${borderColor} !important;
}
#score {
color: ${playerColor} !important;
}
#startButton {
background-color: ${playerColor} !important;
}
.player {
background-color: ${playerColor} !important;
}
.enemy {
background-color: ${enemyColor} !important;
}
.bullet {
background-color: ${bulletColor} !important;
}
#gameCanvas {
background-color: ${canvasColor} !important;
width: ${canvasWidth} !important;
height: ${canvasHeight} !important;
}
canvas {
background-color: ${canvasColor} !important;
}
</style>
`;
const trimmedCss = css.trim();
document.getElementById('add-css').value = trimmedCss;
document.getElementById('add-css-export-2').innerHTML = trimmedCss;
document.getElementById('add-css-export-3').innerHTML = trimmedCss;
}
function updateCanvasSize() {
const canvasWidth = document.getElementById('canvasWidth').value;
const canvasHeight = document.getElementById('canvasHeight').value;
if (canvasWidth) canvas.style.width = canvasWidth;
if (canvasHeight) canvas.style.height = canvasHeight;
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
playerX = (canvas.width - playerWidth) / 2;
draw();
}
function drawPlayer() {
ctx.fillStyle = playerColor;
ctx.beginPath();
ctx.moveTo(playerX, canvas.height - playerHeight);
ctx.lineTo(playerX + playerWidth / 2, canvas.height - playerHeight - 20);
ctx.lineTo(playerX + playerWidth, canvas.height - playerHeight);
ctx.closePath();
ctx.fill();
}
function drawBullet(bullet) {
ctx.fillStyle = bulletColor;
ctx.fillRect(bullet.x, bullet.y, bulletWidth, bulletHeight);
}
function drawEnemies() {
enemies.forEach(enemy => {
if (enemy.status === 1) {
ctx.fillStyle = enemyColor;
ctx.beginPath();
ctx.arc(enemy.x + enemyWidth / 2, enemy.y + enemyHeight / 2, enemyWidth / 2, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
});
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = canvasColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawPlayer();
bullets.forEach(drawBullet);
enemyBullets.forEach(drawBullet);
drawEnemies();
document.getElementById('score').innerText = `Score: ${score} | Lives: ${lives}`;
}
function movePlayer() {
if (leftPressed && playerX > 0) playerX -= 5;
if (rightPressed && playerX < canvas.width - playerWidth) playerX += 5;
}
function moveBullets() {
bullets.forEach(bullet => bullet.y -= 5);
bullets = bullets.filter(bullet => bullet.y > 0);
enemyBullets.forEach(bullet => bullet.y += 5);
enemyBullets = enemyBullets.filter(bullet => bullet.y < canvas.height);
}
function shootBullet() {
if (shootPressed) {
bullets.push({ x: playerX + playerWidth / 2 - bulletWidth / 2, y: canvas.height - playerHeight - 20 });
shootPressed = false;
}
}
function enemyShoot() {
enemies.forEach(enemy => {
if (enemy.status === 1 && Math.random() < 0.01) {
enemyBullets.push({ x: enemy.x + enemyWidth / 2 - bulletWidth / 2, y: enemy.y + enemyHeight });
}
});
}
function moveEnemies() {
let moveDown = false;
enemies.forEach(enemy => {
if (enemy.status === 1) {
enemy.x += enemyDirection * 2;
if (enemy.x + enemyWidth > canvas.width || enemy.x < 0) {
moveDown = true;
}
}
});
if (moveDown) {
enemies.forEach(enemy => {
enemy.y += 10;
});
enemyDirection *= -1;
}
}
function detectCollisions() {
bullets.forEach(bullet => {
enemies.forEach(enemy => {
if (enemy.status === 1 && bullet.x > enemy.x && bullet.x < enemy.x + enemyWidth && bullet.y > enemy.y && bullet.y < enemy.y + enemyHeight) {
enemy.status = 0;
bullet.y = -10;
score++;
}
});
});
enemyBullets.forEach(bullet => {
if (bullet.x > playerX && bullet.x < playerX + playerWidth && bullet.y > canvas.height - playerHeight - 20) {
bullet.y = canvas.height + 10;
lives--;
if (lives <= 0) {
gameOver();
}
}
});
enemies.forEach(enemy => {
if (enemy.status === 1 && enemy.y + enemyHeight > canvas.height - playerHeight - 10 && enemy.x + enemyWidth > playerX && enemy.x < playerX + playerWidth) {
lives--;
enemy.status = 0;
if (lives <= 0) {
gameOver();
}
}
});
}
function gameOver() {
messageElement.innerText = 'Game Over!';
messageElement.style.display = 'block';
gameStarted = false;
setTimeout(() => {
document.location.reload();
}, 3000);
}
function winGame() {
messageElement.innerText = 'You Win!';
messageElement.style.display = 'block';
gameStarted = false;
setTimeout(() => {
document.location.reload();
}, 3000);
}
function update() {
if (!gameStarted) return;
if (enemies.every(enemy => enemy.status === 0)) {
winGame();
}
movePlayer();
moveBullets();
shootBullet();
enemyShoot();
moveEnemies();
detectCollisions();
draw();
}
const startButton = document.getElementById('startButton');
startButton.addEventListener('click', () => {
gameStarted = true;
startButton.style.display = 'none';
setInterval(update, 1000 / 60);
initEnemies();
});
if (/Mobi|Android/i.test(navigator.userAgent)) {
document.getElementById('mobileControls').style.display = 'flex';
canvas.style.width = '100%';
canvas.style.height = '500px';
} else {
canvas.style.width = '100%';
canvas.style.height = '500px';
}
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
playerX = (canvas.width - playerWidth) / 2;
draw();
</script>
You can keep your changes by saving your game to the dashboard, and copy them again later.