Sign up

Pong 404

   
0 - 0
           

Custom options

















Login to edit GAME

Copy Default Code

          

<style>
   #gameContainer {
       background-color: #ff0000 !important;
       border-color: #fff !important;
   }

   #score {
       color: #fff !important;
   }

   #startButton {
       background-color: #000 !important;
color: #fff !important;

   }

   .paddle {
       background-color: #fff !important;
   }

   .ball {
       background-color: #fff !important;
   }

   .centerLine {
       border-color: #fff !important;
   }

   #gameCanvas {
       background-color: #ff0000 !important;
       width: 100% !important;
       height: 500px !important;
   }

   canvas {
       background-color: #ff0000 !important;
   }

   #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;
   }

   @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">0 - 0</div>
   <canvas id="gameCanvas"></canvas>
   <button id="startButton" style="background:black !important; color: #fff !important;">START</button>
   <div id="mobileControls" style="display: none;">
       <button id="moveUpButton">Up</button>
       <button id="moveDownButton">Down</button>
   </div>
</div>

<!--- GAME JS --->
<script>
let canvasColor = '#000';
let paddleColor = '#fff';
let textColor = '#fff';
let ballColor = '#fff';
let borderColor = '#fff';
let centerLineColor = '#fff';

const watermarkBase64 = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iYiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3My4yNzIiIGhlaWdodD0iMjEuMjQ4IiB2aWV3Qm94PSIwIDAgNzMuMjcyIDIxLjI0OCI+CiAgPGcgaWQ9ImMiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+CiAgICA8ZyBvcGFjaXR5PSIuNiI+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMTcuMzIzIDAgMTcuMjM4IDEuMTU1IDE4LjUzNiAxLjE1NSAxOC4yOTIgNC42ODQgMTYuOTc2IDQuNjg0IDE3LjA2NCAzLjQ5NiAxNC40NDQgMy40OTYgMTQuNTQzIDIuMzIgMTAuNjI4IDIuMzIgMTAuNTEyIDMuNDk2IDEzLjEzMiAzLjQ5NiAxMy4wMjYgNC42ODQgMTQuMzQ1IDQuNjg0IDE0LjI0NCA1Ljg4MSAxMS41OTggNS44ODEgMTEuNDg0IDcuMDg5IDE1LjQ3IDcuMDg5IDE1LjU2NiA1Ljg4MSAxOC4yMDkgNS44ODEgMTguMDQxIDguMzEgMTYuNzA3IDguMzEgMTYuNjE2IDkuNTQgOC41NzIgOS41NCA4LjY5OSA4LjMxIDcuMzY2IDguMzEgNy42MyA1Ljg4MSA4Ljk1MiA1Ljg4MSA5LjA3NiA0LjY4NCA3Ljc2IDQuNjg0IDguMTQ0IDEuMTU1IDkuNDQyIDEuMTU1IDkuNTYyIDAgMTcuMzIzIDAiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNjQuNDk1LDUuODgxaC0xLjMyMmwuMTE5LDEuMjA4aDEuMzI4bC4xMjcsMS4yMjFoMS4zMzdsLjEzNCwxLjIzaC00LjAyMmwtLjExNi0xLjIzaC0xLjMzN2wtLjEwOS0xLjIyMWgtMS4zMjhsLjIwNiwyLjQ1MWgtNC4wMjJsLS4xNy0yLjQ1MWgxLjMzMWwtLjM1NC00Ljc2OWgtMS4zMDdMNTQuODMsMGg3Ljc2MWwuMTE0LDEuMTU1aDEuMjk4bC4xMjEsMS4xNjVoMS4zMDdsLjI1NywyLjM2NGgtMS4zMTlsLjEyNCwxLjE5N1pNNjEuNjI3LDMuNDk2aDEuMzFsLS4xMTYtMS4xNzZoLTMuOTE1bC4xOTksMi4zNjRoMi42MzRsLS4xMTItMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNDAuNjkxLDUuODgxaC0xLjMyMmwuMDEyLDEuMjA4aDEuMzI4bC4wMTgsMS4yMjFoMS4zMzRsLjAyNCwxLjIzaC00LjAxOWwtLjAwNi0xLjIzaC0xLjMzN3YtMS4yMjFoLTEuMzI4bC0uMDEyLDIuNDUxaC00LjAyMmwuMDQ4LTIuNDUxaDEuMzNsLjA3MS00Ljc2OWgtMS4zMDdMMzEuNTUsMGg3Ljc2MWwuMDExLDEuMTU1aDEuMjk4bC4wMTcsMS4xNjVoMS4zMDRsLjA0NywyLjM2NGgtMS4zMTZsLjAxOCwxLjE5N1pNMzguMDM2LDMuNDk2aDEuMzFsLS4wMTItMS4xNzZoLTMuOTE1bC0uMDEyLDIuMzY0aDIuNjM0bC0uMDA2LTEuMTg5IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTI4Ljc5LDUuODgxaC0xLjMyNWwtLjA0MiwxLjIwOGgxLjMzMWwtLjAzNiwxLjIyMWgxLjMzNGwtLjAzLDEuMjNoLTQuMDIybC4wNDktMS4yM2gtMS4zMzRsLjA1NC0xLjIyMWgtMS4zMjhsLS4xMjEsMi40NTFoLTQuMDIybC4xNTgtMi40NTFoMS4zMjhsLjI4My00Ljc2OWgtMS4zMDRMMTkuOTExLDBoNy43NThsLS4wNCwxLjE1NWgxLjMwMWwtLjAzNSwxLjE2NWgxLjMwNGwtLjA1OCwyLjM2NGgtMS4zMTZsLS4wMzUsMS4xOTdaTTI2LjIzOSwzLjQ5NmgxLjMxbC4wNDEtMS4xNzZoLTMuOTEybC0uMTE3LDIuMzY0aDIuNjMxbC4wNDctMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTIuMzgzLDIuMzJoMS4zMDRsLjM4NSw1Ljk5aC0xLjMzNGwuMDczLDEuMjNoLTYuNzA0bC0uMDQzLTEuMjNoLTEuMzM0bC0uMDM2LTEuMjIxaC0xLjMyOGwtLjE0Ny01LjkzNGgxLjI5OEw0NC40ODQsMGg2LjQ2NmwuMDYzLDEuMTU1aDEuMzAxbC4wNjksMS4xNjVaTTUxLjI3LDUuODgxbC0uMDY1LTEuMTk3aC0xLjMxNmwtLjA1OS0xLjE4OWgtMS4zMWwtLjA1Mi0xLjE3NmgtMS4zMDRsLjA0NywxLjE3NmgtMS4zMTNsLjA0MSwxLjE4OWgxLjMxOWwuMDQ3LDEuMTk3aDEuMzIybC4wNTQsMS4yMDhoMS4zMjhsLS4wNi0xLjIwOGgxLjMyMiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iNzAuNzU0IDEwLjg4MyA3MC45MSAxMi4xMzYgNzIuMjYzIDEyLjEzNiA3Mi43NiAxNS45NjkgNzEuMzg5IDE1Ljk2OSA3MS4yMjggMTQuNjggNjguNDk1IDE0LjY4IDY4LjM0OCAxMy40MDEgNjQuMjcxIDEzLjQwMSA2NC40IDE0LjY4IDY3LjEzIDE0LjY4IDY3LjI3MiAxNS45NjkgNjguNjQzIDE1Ljk2OSA2OC43OTMgMTcuMjY5IDY2LjAzNyAxNy4yNjkgNjYuMTc1IDE4LjU4NSA3MC4zMzEgMTguNTg1IDcwLjE3NCAxNy4yNjkgNzIuOTI5IDE3LjI2OSA3My4yNzIgMTkuOTExIDcxLjg4MSAxOS45MTEgNzIuMDQ5IDIxLjI0OCA2My42NTcgMjEuMjQ4IDYzLjUzIDE5LjkxMSA2Mi4xMzkgMTkuOTExIDYxLjkgMTcuMjY5IDYzLjI3OCAxNy4yNjkgNjMuMTU0IDE1Ljk2OSA2MS43ODMgMTUuOTY5IDYxLjQzNyAxMi4xMzYgNjIuNzg5IDEyLjEzNiA2Mi42NyAxMC44ODMgNzAuNzU0IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMzUuMDI1IDEwLjg4MyAzNS4wMTcgMTIuMTM2IDM2LjM3MyAxMi4xMzYgMzYuMzY4IDE1Ljk2OSAzNC45OTQgMTUuOTY5IDM1LjAwMiAxNC42OCAzMy42MzcgMTQuNjggMzMuNjUxIDEzLjQwMSAyOS41NzEgMTMuNDAxIDI5LjUzOCAxNC42OCAyOC4xNzMgMTQuNjggMjguMDkzIDE3LjI2OSAyOS40NzEgMTcuMjY5IDI5LjQzNyAxOC41ODUgMzMuNTkzIDE4LjU4NSAzMy42MDggMTcuMjY5IDM2LjM2NiAxNy4yNjkgMzYuMzY1IDE4LjU4NSAzNC45NzcgMTguNTg1IDM0Ljk2OSAxOS45MTEgMzMuNTc4IDE5LjkxMSAzMy41NjMgMjEuMjQ4IDI3Ljk3IDIxLjI0OCAyOC4wMTEgMTkuOTExIDI2LjYyIDE5LjkxMSAyNi42NjggMTguNTg1IDI1LjI4IDE4LjU4NSAyNS40OTIgMTMuNDAxIDI2Ljg1NCAxMy40MDEgMjYuODk5IDEyLjEzNiAyOC4yNTIgMTIuMTM2IDI4LjI5MSAxMC44ODMgMzUuMDI1IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik0yMi41NzgsMTcuMjY5aC0xLjM3OGwtLjA3MywxLjMxNmgxLjM4NGwtLjA2NywxLjMyNWgxLjM5MWwtLjA2MSwxLjMzOGgtNC4xOTZsLjA4MS0xLjMzOGgtMS4zOTFsLjA4Ny0xLjMyNWgtMS4zODRsLS4xODgsMi42NjNoLTQuMTk2bC4yMjctMi42NjNoMS4zODRsLjQxNy01LjE4NGgtMS4zNTlsLjIxNS0yLjUxOGg4LjA4NGwtLjA3LDEuMjUzaDEuMzUzbC0uMDY0LDEuMjY1aDEuMzU5bC0uMTE4LDIuNTY4aC0xLjM3MWwtLjA2NiwxLjMwMVpNMTkuOTc2LDE0LjY4aDEuMzY4bC4wNzEtMS4yNzloLTQuMDc5bC0uMTgxLDIuNTY4aDIuNzQzbC4wNzgtMS4yODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTguODMzLDEzLjQwMWgxLjM1OWwuNTU2LDYuNTFoLTEuMzkxbC4xMDgsMS4zMzhoLTkuNzg5bC0uMTgyLTMuOTc5aDEuMzc4bC0uMTk2LTMuODY5aC0xLjM1OWwtLjExNS0yLjUxOGg4LjA4MWwuMDk1LDEuMjUzaDEuMzU1bC4xMDIsMS4yNjVaTTU3Ljc2MywxNy4yNjlsLS4wOTgtMS4zMDFoLTEuMzcybC0uMDkxLTEuMjg5aC0xLjM2NWwtLjA4NC0xLjI3OWgtMS4zNjJsLjIzNSwzLjg2OWgxLjM4MWwuMDg2LDEuMzE2aDEuMzg0bC0uMDkzLTEuMzE2aDEuMzc4IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTEwLjY1NywxMi4xMzZoMS4zNTZsLS44MjMsOS4xMTNoLTQuMTk2bC4xNDEtMS4zMzhIMi45NTlsLS4xNjEsMS4zMzhIMGwuMzQ2LTIuNjYzaDEuMzg3bC4zMjctMi42MTZoMS4zNzJsLjE1NS0xLjI4OWgxLjM2NWwuMjkzLTIuNTQ0aC0xLjM1MmwuMTUtMS4yNTNoNi43MzVsLS4xMTksMS4yNTNaTTguNzksMTcuMjY5bC4yNTktMi41ODloLTEuMzY1bC0uMTM1LDEuMjg5aC0xLjM3MWwtLjE0MywxLjMwMWgyLjc1NiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik00Ni41NSwxMi4xMzZoMS4zNTJsLjM3Miw5LjExM2gtNC4xOTZsLS4wMzUtMS4zMzhoLTQuMTczbC4wMTUsMS4zMzhoLTIuNzk4bC0uMDAzLTIuNjYzaDEuMzg0bC0uMDE2LTIuNjE2aDEuMzc0bC0uMDE0LTEuMjg5aDEuMzY1bC0uMDQxLTIuNTQ0aC0xLjM1M2wtLjAxNC0xLjI1M2g2LjczNWwuMDQ1LDEuMjUzWk00NS4zNTYsMTcuMjY5bC0uMDgtMi41ODloLTEuMzY4bC4wMzQsMS4yODloLTEuMzcxbC4wMjcsMS4zMDFoMi43NTkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+'; // Example Base64 string


function updateColor(element, color) {
   switch (element) {
       case 'canvasColor':
           canvasColor = color;
           document.getElementById('gameContainer').style.backgroundColor = color;
           break;
       case 'paddleColor':
           paddleColor = color;
           break;
       case 'textColor':
           textColor = color;
           break;
       case 'ballColor':
           ballColor = color;
           break;
       case 'borderColor':
           borderColor = color;
           document.getElementById('gameContainer').style.borderColor = color;
           break;
       case 'centerLineColor':
           centerLineColor = color;
           break;
   }
   draw();
   saveColors(); // Call saveColors after updating colors
}

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: ${textColor} !important;
           }
           #startButton {
                background-color: ${textColor} !important;
           }
           .paddle {
               background-color: ${paddleColor} !important;
           }
           .ball {
               background-color: ${ballColor} !important;
           }
           .centerLine {
               border-color: ${centerLineColor} !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').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;
   draw(); // Redraw the canvas with the new size
}

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const paddleHeight = 100;
const paddleWidth = 10;
const ballRadius = 7;
let upPressed = false;
let downPressed = false;
let playerY = (canvas.height - paddleHeight) / 2;
let aiY = (canvas.height - paddleHeight) / 2;
let ballX = canvas.width / 2;
let ballY = canvas.height / 2;
let ballSpeedX = 3;
let ballSpeedY = 2;
let playerScore = 0;
let aiScore = 0;
let gameStarted = false;

document.addEventListener('keydown', (e) => {
   if (e.key === 'ArrowUp') {
       upPressed = true;
       e.preventDefault();
   }
   if (e.key === 'ArrowDown') {
       downPressed = true;
       e.preventDefault();
   }
});
document.addEventListener('keyup', (e) => {
   if (e.key === 'ArrowUp') {
       upPressed = false;
       e.preventDefault();
   }
   if (e.key === 'ArrowDown') {
       downPressed = false;
       e.preventDefault();
   }
});

document.getElementById('moveUpButton').addEventListener('mousedown', () => {
   upPressed = true;
});
document.getElementById('moveUpButton').addEventListener('mouseup', () => {
   upPressed = false;
});
document.getElementById('moveDownButton').addEventListener('mousedown', () => {
   downPressed = true;
});
document.getElementById('moveDownButton').addEventListener('mouseup', () => {
   downPressed = false;
});

function drawPaddle(x, y) {
   ctx.fillStyle = paddleColor;
   ctx.fillRect(x, y, paddleWidth, paddleHeight);
}

function drawBall() {
   ctx.beginPath();
   ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
   ctx.fillStyle = ballColor;
   ctx.fill();
   ctx.closePath();
}

function drawWatermark() {
   const img = new Image();
   img.src = watermarkBase64;
   img.onload = () => {
       const imgWidth = img.width * 2; // Increase size
       const imgHeight = img.height * 2; // Increase size
       const x = (canvas.width - imgWidth) / 2;
       const y = canvas.height - imgHeight - 10; // 10px from the bottom
       ctx.drawImage(img, x, y, imgWidth, imgHeight);
       canvas.addEventListener('click', (e) => {
           const rect = canvas.getBoundingClientRect();
           const mouseX = e.clientX - rect.left;
           const mouseY = e.clientY - rect.top;
           if (mouseX >= x && mouseX <= x + imgWidth && mouseY >= y && mouseY <= y + imgHeight) {
               window.open('https://errorarcade.webflow.io/', '_blank');
           }
       });
   };
}

function draw() {
   ctx.clearRect(0, 0, canvas.width, canvas.height);
   ctx.fillStyle = canvasColor;
   ctx.fillRect(0, 0, canvas.width, canvas.height);
   drawPaddle(0, playerY);
   drawPaddle(canvas.width - paddleWidth, aiY);
   drawBall();
   drawWatermark();

   // Draw center line
   ctx.beginPath();
   ctx.setLineDash([10, 8]);
   ctx.moveTo(canvas.width / 2, 0);
   ctx.lineTo(canvas.width / 2, canvas.height);
   ctx.strokeStyle = centerLineColor;
   ctx.stroke();
   ctx.closePath();

   document.getElementById('score').innerText = `${playerScore} - ${aiScore}`;
}

function movePaddle() {
   if (upPressed && playerY > 0) playerY -= 5;
   if (downPressed && playerY < canvas.height - paddleHeight) playerY += 5;
}

function moveBall() {
   ballX += ballSpeedX;
   ballY += ballSpeedY;

   if (ballY + ballSpeedY > canvas.height - ballRadius || ballY + ballSpeedY < ballRadius) {
       ballSpeedY = -ballSpeedY;
   }

   if (ballX + ballSpeedX > canvas.width - paddleWidth - ballRadius) {
       if (ballY > aiY && ballY < aiY + paddleHeight) {
           ballSpeedX = -ballSpeedX;
           // Add some randomness to the ball speed
           ballSpeedY += (Math.random() - 0.5) * 2;
       } else {
           playerScore++;
           resetBall();
       }
   } else if (ballX + ballSpeedX < paddleWidth + ballRadius) {
       if (ballY > playerY && ballY < playerY + paddleHeight) {
           ballSpeedX = -ballSpeedX;
           // Add some randomness to the ball speed
           ballSpeedY += (Math.random() - 0.5) * 2;
       } else {
           aiScore++;
           resetBall();
       }
   }

   // AI Movement with a chance to miss
   if (ballX > canvas.width / 2 && Math.random() > 0.1) {
       aiY = ballY - paddleHeight / 2;
   }
}

function resetBall() {
   ballX = canvas.width / 2;
   ballY = canvas.height / 2;
   ballSpeedX = -ballSpeedX;
   ballSpeedY = (Math.random() - 0.5) * 4;
}

function update() {
   if (!gameStarted) return;

   if (playerScore >= 3 || aiScore >= 3) {
       alert(`Game Over! ${playerScore >= 3 ? 'Player' : 'AI'} Wins!`);
       playerScore = 0;
       aiScore = 0;
       resetBall();
       gameStarted = false;
       document.getElementById('startButton').style.display = 'block';
   }

   movePaddle();
   moveBall();
   draw();
}

const startButton = document.getElementById('startButton');
startButton.addEventListener('click', () => {
   gameStarted = true;
   startButton.style.display = 'none';
   setInterval(update, 1000 / 60);
});

// Show mobile controls if on a mobile device and set default canvas size
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;
draw(); // Initial draw to reflect default size
</script>

Copy CUSTOM Code

          

<style>
   #gameContainer {
       background-color: #ff0000 !important;
       border-color: #fff !important;
   }

   #score {
       color: #fff !important;
   }

   #startButton {
       background-color: #000 !important;
color: #fff !important;

   }

   .paddle {
       background-color: #fff !important;
   }

   .ball {
       background-color: #fff !important;
   }

   .centerLine {
       border-color: #fff !important;
   }

   #gameCanvas {
       background-color: #ff0000 !important;
       width: 100% !important;
       height: 500px !important;
   }

   canvas {
       background-color: #ff0000 !important;
   }

   #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;
   }

   @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">0 - 0</div>
   <canvas id="gameCanvas"></canvas>
   <button id="startButton" style="background:black !important; color: #fff !important;">START</button>
   <div id="mobileControls" style="display: none;">
       <button id="moveUpButton">Up</button>
       <button id="moveDownButton">Down</button>
   </div>
</div>

<!--- GAME JS --->
<script>
let canvasColor = '#000';
let paddleColor = '#fff';
let textColor = '#fff';
let ballColor = '#fff';
let borderColor = '#fff';
let centerLineColor = '#fff';

const watermarkBase64 = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iYiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3My4yNzIiIGhlaWdodD0iMjEuMjQ4IiB2aWV3Qm94PSIwIDAgNzMuMjcyIDIxLjI0OCI+CiAgPGcgaWQ9ImMiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+CiAgICA8ZyBvcGFjaXR5PSIuNiI+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMTcuMzIzIDAgMTcuMjM4IDEuMTU1IDE4LjUzNiAxLjE1NSAxOC4yOTIgNC42ODQgMTYuOTc2IDQuNjg0IDE3LjA2NCAzLjQ5NiAxNC40NDQgMy40OTYgMTQuNTQzIDIuMzIgMTAuNjI4IDIuMzIgMTAuNTEyIDMuNDk2IDEzLjEzMiAzLjQ5NiAxMy4wMjYgNC42ODQgMTQuMzQ1IDQuNjg0IDE0LjI0NCA1Ljg4MSAxMS41OTggNS44ODEgMTEuNDg0IDcuMDg5IDE1LjQ3IDcuMDg5IDE1LjU2NiA1Ljg4MSAxOC4yMDkgNS44ODEgMTguMDQxIDguMzEgMTYuNzA3IDguMzEgMTYuNjE2IDkuNTQgOC41NzIgOS41NCA4LjY5OSA4LjMxIDcuMzY2IDguMzEgNy42MyA1Ljg4MSA4Ljk1MiA1Ljg4MSA5LjA3NiA0LjY4NCA3Ljc2IDQuNjg0IDguMTQ0IDEuMTU1IDkuNDQyIDEuMTU1IDkuNTYyIDAgMTcuMzIzIDAiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNjQuNDk1LDUuODgxaC0xLjMyMmwuMTE5LDEuMjA4aDEuMzI4bC4xMjcsMS4yMjFoMS4zMzdsLjEzNCwxLjIzaC00LjAyMmwtLjExNi0xLjIzaC0xLjMzN2wtLjEwOS0xLjIyMWgtMS4zMjhsLjIwNiwyLjQ1MWgtNC4wMjJsLS4xNy0yLjQ1MWgxLjMzMWwtLjM1NC00Ljc2OWgtMS4zMDdMNTQuODMsMGg3Ljc2MWwuMTE0LDEuMTU1aDEuMjk4bC4xMjEsMS4xNjVoMS4zMDdsLjI1NywyLjM2NGgtMS4zMTlsLjEyNCwxLjE5N1pNNjEuNjI3LDMuNDk2aDEuMzFsLS4xMTYtMS4xNzZoLTMuOTE1bC4xOTksMi4zNjRoMi42MzRsLS4xMTItMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNDAuNjkxLDUuODgxaC0xLjMyMmwuMDEyLDEuMjA4aDEuMzI4bC4wMTgsMS4yMjFoMS4zMzRsLjAyNCwxLjIzaC00LjAxOWwtLjAwNi0xLjIzaC0xLjMzN3YtMS4yMjFoLTEuMzI4bC0uMDEyLDIuNDUxaC00LjAyMmwuMDQ4LTIuNDUxaDEuMzNsLjA3MS00Ljc2OWgtMS4zMDdMMzEuNTUsMGg3Ljc2MWwuMDExLDEuMTU1aDEuMjk4bC4wMTcsMS4xNjVoMS4zMDRsLjA0NywyLjM2NGgtMS4zMTZsLjAxOCwxLjE5N1pNMzguMDM2LDMuNDk2aDEuMzFsLS4wMTItMS4xNzZoLTMuOTE1bC0uMDEyLDIuMzY0aDIuNjM0bC0uMDA2LTEuMTg5IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTI4Ljc5LDUuODgxaC0xLjMyNWwtLjA0MiwxLjIwOGgxLjMzMWwtLjAzNiwxLjIyMWgxLjMzNGwtLjAzLDEuMjNoLTQuMDIybC4wNDktMS4yM2gtMS4zMzRsLjA1NC0xLjIyMWgtMS4zMjhsLS4xMjEsMi40NTFoLTQuMDIybC4xNTgtMi40NTFoMS4zMjhsLjI4My00Ljc2OWgtMS4zMDRMMTkuOTExLDBoNy43NThsLS4wNCwxLjE1NWgxLjMwMWwtLjAzNSwxLjE2NWgxLjMwNGwtLjA1OCwyLjM2NGgtMS4zMTZsLS4wMzUsMS4xOTdaTTI2LjIzOSwzLjQ5NmgxLjMxbC4wNDEtMS4xNzZoLTMuOTEybC0uMTE3LDIuMzY0aDIuNjMxbC4wNDctMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTIuMzgzLDIuMzJoMS4zMDRsLjM4NSw1Ljk5aC0xLjMzNGwuMDczLDEuMjNoLTYuNzA0bC0uMDQzLTEuMjNoLTEuMzM0bC0uMDM2LTEuMjIxaC0xLjMyOGwtLjE0Ny01LjkzNGgxLjI5OEw0NC40ODQsMGg2LjQ2NmwuMDYzLDEuMTU1aDEuMzAxbC4wNjksMS4xNjVaTTUxLjI3LDUuODgxbC0uMDY1LTEuMTk3aC0xLjMxNmwtLjA1OS0xLjE4OWgtMS4zMWwtLjA1Mi0xLjE3NmgtMS4zMDRsLjA0NywxLjE3NmgtMS4zMTNsLjA0MSwxLjE4OWgxLjMxOWwuMDQ3LDEuMTk3aDEuMzIybC4wNTQsMS4yMDhoMS4zMjhsLS4wNi0xLjIwOGgxLjMyMiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iNzAuNzU0IDEwLjg4MyA3MC45MSAxMi4xMzYgNzIuMjYzIDEyLjEzNiA3Mi43NiAxNS45NjkgNzEuMzg5IDE1Ljk2OSA3MS4yMjggMTQuNjggNjguNDk1IDE0LjY4IDY4LjM0OCAxMy40MDEgNjQuMjcxIDEzLjQwMSA2NC40IDE0LjY4IDY3LjEzIDE0LjY4IDY3LjI3MiAxNS45NjkgNjguNjQzIDE1Ljk2OSA2OC43OTMgMTcuMjY5IDY2LjAzNyAxNy4yNjkgNjYuMTc1IDE4LjU4NSA3MC4zMzEgMTguNTg1IDcwLjE3NCAxNy4yNjkgNzIuOTI5IDE3LjI2OSA3My4yNzIgMTkuOTExIDcxLjg4MSAxOS45MTEgNzIuMDQ5IDIxLjI0OCA2My42NTcgMjEuMjQ4IDYzLjUzIDE5LjkxMSA2Mi4xMzkgMTkuOTExIDYxLjkgMTcuMjY5IDYzLjI3OCAxNy4yNjkgNjMuMTU0IDE1Ljk2OSA2MS43ODMgMTUuOTY5IDYxLjQzNyAxMi4xMzYgNjIuNzg5IDEyLjEzNiA2Mi42NyAxMC44ODMgNzAuNzU0IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMzUuMDI1IDEwLjg4MyAzNS4wMTcgMTIuMTM2IDM2LjM3MyAxMi4xMzYgMzYuMzY4IDE1Ljk2OSAzNC45OTQgMTUuOTY5IDM1LjAwMiAxNC42OCAzMy42MzcgMTQuNjggMzMuNjUxIDEzLjQwMSAyOS41NzEgMTMuNDAxIDI5LjUzOCAxNC42OCAyOC4xNzMgMTQuNjggMjguMDkzIDE3LjI2OSAyOS40NzEgMTcuMjY5IDI5LjQzNyAxOC41ODUgMzMuNTkzIDE4LjU4NSAzMy42MDggMTcuMjY5IDM2LjM2NiAxNy4yNjkgMzYuMzY1IDE4LjU4NSAzNC45NzcgMTguNTg1IDM0Ljk2OSAxOS45MTEgMzMuNTc4IDE5LjkxMSAzMy41NjMgMjEuMjQ4IDI3Ljk3IDIxLjI0OCAyOC4wMTEgMTkuOTExIDI2LjYyIDE5LjkxMSAyNi42NjggMTguNTg1IDI1LjI4IDE4LjU4NSAyNS40OTIgMTMuNDAxIDI2Ljg1NCAxMy40MDEgMjYuODk5IDEyLjEzNiAyOC4yNTIgMTIuMTM2IDI4LjI5MSAxMC44ODMgMzUuMDI1IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik0yMi41NzgsMTcuMjY5aC0xLjM3OGwtLjA3MywxLjMxNmgxLjM4NGwtLjA2NywxLjMyNWgxLjM5MWwtLjA2MSwxLjMzOGgtNC4xOTZsLjA4MS0xLjMzOGgtMS4zOTFsLjA4Ny0xLjMyNWgtMS4zODRsLS4xODgsMi42NjNoLTQuMTk2bC4yMjctMi42NjNoMS4zODRsLjQxNy01LjE4NGgtMS4zNTlsLjIxNS0yLjUxOGg4LjA4NGwtLjA3LDEuMjUzaDEuMzUzbC0uMDY0LDEuMjY1aDEuMzU5bC0uMTE4LDIuNTY4aC0xLjM3MWwtLjA2NiwxLjMwMVpNMTkuOTc2LDE0LjY4aDEuMzY4bC4wNzEtMS4yNzloLTQuMDc5bC0uMTgxLDIuNTY4aDIuNzQzbC4wNzgtMS4yODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTguODMzLDEzLjQwMWgxLjM1OWwuNTU2LDYuNTFoLTEuMzkxbC4xMDgsMS4zMzhoLTkuNzg5bC0uMTgyLTMuOTc5aDEuMzc4bC0uMTk2LTMuODY5aC0xLjM1OWwtLjExNS0yLjUxOGg4LjA4MWwuMDk1LDEuMjUzaDEuMzU1bC4xMDIsMS4yNjVaTTU3Ljc2MywxNy4yNjlsLS4wOTgtMS4zMDFoLTEuMzcybC0uMDkxLTEuMjg5aC0xLjM2NWwtLjA4NC0xLjI3OWgtMS4zNjJsLjIzNSwzLjg2OWgxLjM4MWwuMDg2LDEuMzE2aDEuMzg0bC0uMDkzLTEuMzE2aDEuMzc4IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTEwLjY1NywxMi4xMzZoMS4zNTZsLS44MjMsOS4xMTNoLTQuMTk2bC4xNDEtMS4zMzhIMi45NTlsLS4xNjEsMS4zMzhIMGwuMzQ2LTIuNjYzaDEuMzg3bC4zMjctMi42MTZoMS4zNzJsLjE1NS0xLjI4OWgxLjM2NWwuMjkzLTIuNTQ0aC0xLjM1MmwuMTUtMS4yNTNoNi43MzVsLS4xMTksMS4yNTNaTTguNzksMTcuMjY5bC4yNTktMi41ODloLTEuMzY1bC0uMTM1LDEuMjg5aC0xLjM3MWwtLjE0MywxLjMwMWgyLjc1NiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik00Ni41NSwxMi4xMzZoMS4zNTJsLjM3Miw5LjExM2gtNC4xOTZsLS4wMzUtMS4zMzhoLTQuMTczbC4wMTUsMS4zMzhoLTIuNzk4bC0uMDAzLTIuNjYzaDEuMzg0bC0uMDE2LTIuNjE2aDEuMzc0bC0uMDE0LTEuMjg5aDEuMzY1bC0uMDQxLTIuNTQ0aC0xLjM1M2wtLjAxNC0xLjI1M2g2LjczNWwuMDQ1LDEuMjUzWk00NS4zNTYsMTcuMjY5bC0uMDgtMi41ODloLTEuMzY4bC4wMzQsMS4yODloLTEuMzcxbC4wMjcsMS4zMDFoMi43NTkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+'; // Example Base64 string


function updateColor(element, color) {
   switch (element) {
       case 'canvasColor':
           canvasColor = color;
           document.getElementById('gameContainer').style.backgroundColor = color;
           break;
       case 'paddleColor':
           paddleColor = color;
           break;
       case 'textColor':
           textColor = color;
           break;
       case 'ballColor':
           ballColor = color;
           break;
       case 'borderColor':
           borderColor = color;
           document.getElementById('gameContainer').style.borderColor = color;
           break;
       case 'centerLineColor':
           centerLineColor = color;
           break;
   }
   draw();
   saveColors(); // Call saveColors after updating colors
}

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: ${textColor} !important;
           }
           #startButton {
                background-color: ${textColor} !important;
           }
           .paddle {
               background-color: ${paddleColor} !important;
           }
           .ball {
               background-color: ${ballColor} !important;
           }
           .centerLine {
               border-color: ${centerLineColor} !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').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;
   draw(); // Redraw the canvas with the new size
}

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const paddleHeight = 100;
const paddleWidth = 10;
const ballRadius = 7;
let upPressed = false;
let downPressed = false;
let playerY = (canvas.height - paddleHeight) / 2;
let aiY = (canvas.height - paddleHeight) / 2;
let ballX = canvas.width / 2;
let ballY = canvas.height / 2;
let ballSpeedX = 3;
let ballSpeedY = 2;
let playerScore = 0;
let aiScore = 0;
let gameStarted = false;

document.addEventListener('keydown', (e) => {
   if (e.key === 'ArrowUp') {
       upPressed = true;
       e.preventDefault();
   }
   if (e.key === 'ArrowDown') {
       downPressed = true;
       e.preventDefault();
   }
});
document.addEventListener('keyup', (e) => {
   if (e.key === 'ArrowUp') {
       upPressed = false;
       e.preventDefault();
   }
   if (e.key === 'ArrowDown') {
       downPressed = false;
       e.preventDefault();
   }
});

document.getElementById('moveUpButton').addEventListener('mousedown', () => {
   upPressed = true;
});
document.getElementById('moveUpButton').addEventListener('mouseup', () => {
   upPressed = false;
});
document.getElementById('moveDownButton').addEventListener('mousedown', () => {
   downPressed = true;
});
document.getElementById('moveDownButton').addEventListener('mouseup', () => {
   downPressed = false;
});

function drawPaddle(x, y) {
   ctx.fillStyle = paddleColor;
   ctx.fillRect(x, y, paddleWidth, paddleHeight);
}

function drawBall() {
   ctx.beginPath();
   ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
   ctx.fillStyle = ballColor;
   ctx.fill();
   ctx.closePath();
}

function drawWatermark() {
   const img = new Image();
   img.src = watermarkBase64;
   img.onload = () => {
       const imgWidth = img.width * 2; // Increase size
       const imgHeight = img.height * 2; // Increase size
       const x = (canvas.width - imgWidth) / 2;
       const y = canvas.height - imgHeight - 10; // 10px from the bottom
       ctx.drawImage(img, x, y, imgWidth, imgHeight);
       canvas.addEventListener('click', (e) => {
           const rect = canvas.getBoundingClientRect();
           const mouseX = e.clientX - rect.left;
           const mouseY = e.clientY - rect.top;
           if (mouseX >= x && mouseX <= x + imgWidth && mouseY >= y && mouseY <= y + imgHeight) {
               window.open('https://errorarcade.webflow.io/', '_blank');
           }
       });
   };
}

function draw() {
   ctx.clearRect(0, 0, canvas.width, canvas.height);
   ctx.fillStyle = canvasColor;
   ctx.fillRect(0, 0, canvas.width, canvas.height);
   drawPaddle(0, playerY);
   drawPaddle(canvas.width - paddleWidth, aiY);
   drawBall();
   drawWatermark();

   // Draw center line
   ctx.beginPath();
   ctx.setLineDash([10, 8]);
   ctx.moveTo(canvas.width / 2, 0);
   ctx.lineTo(canvas.width / 2, canvas.height);
   ctx.strokeStyle = centerLineColor;
   ctx.stroke();
   ctx.closePath();

   document.getElementById('score').innerText = `${playerScore} - ${aiScore}`;
}

function movePaddle() {
   if (upPressed && playerY > 0) playerY -= 5;
   if (downPressed && playerY < canvas.height - paddleHeight) playerY += 5;
}

function moveBall() {
   ballX += ballSpeedX;
   ballY += ballSpeedY;

   if (ballY + ballSpeedY > canvas.height - ballRadius || ballY + ballSpeedY < ballRadius) {
       ballSpeedY = -ballSpeedY;
   }

   if (ballX + ballSpeedX > canvas.width - paddleWidth - ballRadius) {
       if (ballY > aiY && ballY < aiY + paddleHeight) {
           ballSpeedX = -ballSpeedX;
           // Add some randomness to the ball speed
           ballSpeedY += (Math.random() - 0.5) * 2;
       } else {
           playerScore++;
           resetBall();
       }
   } else if (ballX + ballSpeedX < paddleWidth + ballRadius) {
       if (ballY > playerY && ballY < playerY + paddleHeight) {
           ballSpeedX = -ballSpeedX;
           // Add some randomness to the ball speed
           ballSpeedY += (Math.random() - 0.5) * 2;
       } else {
           aiScore++;
           resetBall();
       }
   }

   // AI Movement with a chance to miss
   if (ballX > canvas.width / 2 && Math.random() > 0.1) {
       aiY = ballY - paddleHeight / 2;
   }
}

function resetBall() {
   ballX = canvas.width / 2;
   ballY = canvas.height / 2;
   ballSpeedX = -ballSpeedX;
   ballSpeedY = (Math.random() - 0.5) * 4;
}

function update() {
   if (!gameStarted) return;

   if (playerScore >= 3 || aiScore >= 3) {
       alert(`Game Over! ${playerScore >= 3 ? 'Player' : 'AI'} Wins!`);
       playerScore = 0;
       aiScore = 0;
       resetBall();
       gameStarted = false;
       document.getElementById('startButton').style.display = 'block';
   }

   movePaddle();
   moveBall();
   draw();
}

const startButton = document.getElementById('startButton');
startButton.addEventListener('click', () => {
   gameStarted = true;
   startButton.style.display = 'none';
   setInterval(update, 1000 / 60);
});

// Show mobile controls if on a mobile device and set default canvas size
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;
draw(); // Initial draw to reflect default size
</script>

PRO GAMER

Copy CUSTOM Code

        

<style>
   #gameContainer {
       background-color: #ff0000 !important;
       border-color: #fff !important;
   }

   #score {
       color: #fff !important;
   }

   #startButton {
       background-color: #000 !important;
color: #fff !important;

   }

   .paddle {
       background-color: #fff !important;
   }

   .ball {
       background-color: #fff !important;
   }

   .centerLine {
       border-color: #fff !important;
   }

   #gameCanvas {
       background-color: #ff0000 !important;
       width: 100% !important;
       height: 500px !important;
   }

   canvas {
       background-color: #ff0000 !important;
   }

   #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;
   }

   @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">0 - 0</div>
   <canvas id="gameCanvas"></canvas>
   <button id="startButton" style="background:black !important; color: #fff !important;">START</button>
   <div id="mobileControls" style="display: none;">
       <button id="moveUpButton">Up</button>
       <button id="moveDownButton">Down</button>
   </div>
</div>

<!--- GAME JS --->
<script>
let canvasColor = '#000';
let paddleColor = '#fff';
let textColor = '#fff';
let ballColor = '#fff';
let borderColor = '#fff';
let centerLineColor = '#fff';

const watermarkBase64 = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iYiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3My4yNzIiIGhlaWdodD0iMjEuMjQ4IiB2aWV3Qm94PSIwIDAgNzMuMjcyIDIxLjI0OCI+CiAgPGcgaWQ9ImMiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+CiAgICA8ZyBvcGFjaXR5PSIuNiI+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMTcuMzIzIDAgMTcuMjM4IDEuMTU1IDE4LjUzNiAxLjE1NSAxOC4yOTIgNC42ODQgMTYuOTc2IDQuNjg0IDE3LjA2NCAzLjQ5NiAxNC40NDQgMy40OTYgMTQuNTQzIDIuMzIgMTAuNjI4IDIuMzIgMTAuNTEyIDMuNDk2IDEzLjEzMiAzLjQ5NiAxMy4wMjYgNC42ODQgMTQuMzQ1IDQuNjg0IDE0LjI0NCA1Ljg4MSAxMS41OTggNS44ODEgMTEuNDg0IDcuMDg5IDE1LjQ3IDcuMDg5IDE1LjU2NiA1Ljg4MSAxOC4yMDkgNS44ODEgMTguMDQxIDguMzEgMTYuNzA3IDguMzEgMTYuNjE2IDkuNTQgOC41NzIgOS41NCA4LjY5OSA4LjMxIDcuMzY2IDguMzEgNy42MyA1Ljg4MSA4Ljk1MiA1Ljg4MSA5LjA3NiA0LjY4NCA3Ljc2IDQuNjg0IDguMTQ0IDEuMTU1IDkuNDQyIDEuMTU1IDkuNTYyIDAgMTcuMzIzIDAiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNjQuNDk1LDUuODgxaC0xLjMyMmwuMTE5LDEuMjA4aDEuMzI4bC4xMjcsMS4yMjFoMS4zMzdsLjEzNCwxLjIzaC00LjAyMmwtLjExNi0xLjIzaC0xLjMzN2wtLjEwOS0xLjIyMWgtMS4zMjhsLjIwNiwyLjQ1MWgtNC4wMjJsLS4xNy0yLjQ1MWgxLjMzMWwtLjM1NC00Ljc2OWgtMS4zMDdMNTQuODMsMGg3Ljc2MWwuMTE0LDEuMTU1aDEuMjk4bC4xMjEsMS4xNjVoMS4zMDdsLjI1NywyLjM2NGgtMS4zMTlsLjEyNCwxLjE5N1pNNjEuNjI3LDMuNDk2aDEuMzFsLS4xMTYtMS4xNzZoLTMuOTE1bC4xOTksMi4zNjRoMi42MzRsLS4xMTItMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNDAuNjkxLDUuODgxaC0xLjMyMmwuMDEyLDEuMjA4aDEuMzI4bC4wMTgsMS4yMjFoMS4zMzRsLjAyNCwxLjIzaC00LjAxOWwtLjAwNi0xLjIzaC0xLjMzN3YtMS4yMjFoLTEuMzI4bC0uMDEyLDIuNDUxaC00LjAyMmwuMDQ4LTIuNDUxaDEuMzNsLjA3MS00Ljc2OWgtMS4zMDdMMzEuNTUsMGg3Ljc2MWwuMDExLDEuMTU1aDEuMjk4bC4wMTcsMS4xNjVoMS4zMDRsLjA0NywyLjM2NGgtMS4zMTZsLjAxOCwxLjE5N1pNMzguMDM2LDMuNDk2aDEuMzFsLS4wMTItMS4xNzZoLTMuOTE1bC0uMDEyLDIuMzY0aDIuNjM0bC0uMDA2LTEuMTg5IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTI4Ljc5LDUuODgxaC0xLjMyNWwtLjA0MiwxLjIwOGgxLjMzMWwtLjAzNiwxLjIyMWgxLjMzNGwtLjAzLDEuMjNoLTQuMDIybC4wNDktMS4yM2gtMS4zMzRsLjA1NC0xLjIyMWgtMS4zMjhsLS4xMjEsMi40NTFoLTQuMDIybC4xNTgtMi40NTFoMS4zMjhsLjI4My00Ljc2OWgtMS4zMDRMMTkuOTExLDBoNy43NThsLS4wNCwxLjE1NWgxLjMwMWwtLjAzNSwxLjE2NWgxLjMwNGwtLjA1OCwyLjM2NGgtMS4zMTZsLS4wMzUsMS4xOTdaTTI2LjIzOSwzLjQ5NmgxLjMxbC4wNDEtMS4xNzZoLTMuOTEybC0uMTE3LDIuMzY0aDIuNjMxbC4wNDctMS4xODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTIuMzgzLDIuMzJoMS4zMDRsLjM4NSw1Ljk5aC0xLjMzNGwuMDczLDEuMjNoLTYuNzA0bC0uMDQzLTEuMjNoLTEuMzM0bC0uMDM2LTEuMjIxaC0xLjMyOGwtLjE0Ny01LjkzNGgxLjI5OEw0NC40ODQsMGg2LjQ2NmwuMDYzLDEuMTU1aDEuMzAxbC4wNjksMS4xNjVaTTUxLjI3LDUuODgxbC0uMDY1LTEuMTk3aC0xLjMxNmwtLjA1OS0xLjE4OWgtMS4zMWwtLjA1Mi0xLjE3NmgtMS4zMDRsLjA0NywxLjE3NmgtMS4zMTNsLjA0MSwxLjE4OWgxLjMxOWwuMDQ3LDEuMTk3aDEuMzIybC4wNTQsMS4yMDhoMS4zMjhsLS4wNi0xLjIwOGgxLjMyMiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iNzAuNzU0IDEwLjg4MyA3MC45MSAxMi4xMzYgNzIuMjYzIDEyLjEzNiA3Mi43NiAxNS45NjkgNzEuMzg5IDE1Ljk2OSA3MS4yMjggMTQuNjggNjguNDk1IDE0LjY4IDY4LjM0OCAxMy40MDEgNjQuMjcxIDEzLjQwMSA2NC40IDE0LjY4IDY3LjEzIDE0LjY4IDY3LjI3MiAxNS45NjkgNjguNjQzIDE1Ljk2OSA2OC43OTMgMTcuMjY5IDY2LjAzNyAxNy4yNjkgNjYuMTc1IDE4LjU4NSA3MC4zMzEgMTguNTg1IDcwLjE3NCAxNy4yNjkgNzIuOTI5IDE3LjI2OSA3My4yNzIgMTkuOTExIDcxLjg4MSAxOS45MTEgNzIuMDQ5IDIxLjI0OCA2My42NTcgMjEuMjQ4IDYzLjUzIDE5LjkxMSA2Mi4xMzkgMTkuOTExIDYxLjkgMTcuMjY5IDYzLjI3OCAxNy4yNjkgNjMuMTU0IDE1Ljk2OSA2MS43ODMgMTUuOTY5IDYxLjQzNyAxMi4xMzYgNjIuNzg5IDEyLjEzNiA2Mi42NyAxMC44ODMgNzAuNzU0IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwb2x5Z29uIHBvaW50cz0iMzUuMDI1IDEwLjg4MyAzNS4wMTcgMTIuMTM2IDM2LjM3MyAxMi4xMzYgMzYuMzY4IDE1Ljk2OSAzNC45OTQgMTUuOTY5IDM1LjAwMiAxNC42OCAzMy42MzcgMTQuNjggMzMuNjUxIDEzLjQwMSAyOS41NzEgMTMuNDAxIDI5LjUzOCAxNC42OCAyOC4xNzMgMTQuNjggMjguMDkzIDE3LjI2OSAyOS40NzEgMTcuMjY5IDI5LjQzNyAxOC41ODUgMzMuNTkzIDE4LjU4NSAzMy42MDggMTcuMjY5IDM2LjM2NiAxNy4yNjkgMzYuMzY1IDE4LjU4NSAzNC45NzcgMTguNTg1IDM0Ljk2OSAxOS45MTEgMzMuNTc4IDE5LjkxMSAzMy41NjMgMjEuMjQ4IDI3Ljk3IDIxLjI0OCAyOC4wMTEgMTkuOTExIDI2LjYyIDE5LjkxMSAyNi42NjggMTguNTg1IDI1LjI4IDE4LjU4NSAyNS40OTIgMTMuNDAxIDI2Ljg1NCAxMy40MDEgMjYuODk5IDEyLjEzNiAyOC4yNTIgMTIuMTM2IDI4LjI5MSAxMC44ODMgMzUuMDI1IDEwLjg4MyIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik0yMi41NzgsMTcuMjY5aC0xLjM3OGwtLjA3MywxLjMxNmgxLjM4NGwtLjA2NywxLjMyNWgxLjM5MWwtLjA2MSwxLjMzOGgtNC4xOTZsLjA4MS0xLjMzOGgtMS4zOTFsLjA4Ny0xLjMyNWgtMS4zODRsLS4xODgsMi42NjNoLTQuMTk2bC4yMjctMi42NjNoMS4zODRsLjQxNy01LjE4NGgtMS4zNTlsLjIxNS0yLjUxOGg4LjA4NGwtLjA3LDEuMjUzaDEuMzUzbC0uMDY0LDEuMjY1aDEuMzU5bC0uMTE4LDIuNTY4aC0xLjM3MWwtLjA2NiwxLjMwMVpNMTkuOTc2LDE0LjY4aDEuMzY4bC4wNzEtMS4yNzloLTQuMDc5bC0uMTgxLDIuNTY4aDIuNzQzbC4wNzgtMS4yODkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8cGF0aCBkPSJNNTguODMzLDEzLjQwMWgxLjM1OWwuNTU2LDYuNTFoLTEuMzkxbC4xMDgsMS4zMzhoLTkuNzg5bC0uMTgyLTMuOTc5aDEuMzc4bC0uMTk2LTMuODY5aC0xLjM1OWwtLjExNS0yLjUxOGg4LjA4MWwuMDk1LDEuMjUzaDEuMzU1bC4xMDIsMS4yNjVaTTU3Ljc2MywxNy4yNjlsLS4wOTgtMS4zMDFoLTEuMzcybC0uMDkxLTEuMjg5aC0xLjM2NWwtLjA4NC0xLjI3OWgtMS4zNjJsLjIzNSwzLjg2OWgxLjM4MWwuMDg2LDEuMzE2aDEuMzg0bC0uMDkzLTEuMzE2aDEuMzc4IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz4KICAgICAgPHBhdGggZD0iTTEwLjY1NywxMi4xMzZoMS4zNTZsLS44MjMsOS4xMTNoLTQuMTk2bC4xNDEtMS4zMzhIMi45NTlsLS4xNjEsMS4zMzhIMGwuMzQ2LTIuNjYzaDEuMzg3bC4zMjctMi42MTZoMS4zNzJsLjE1NS0xLjI4OWgxLjM2NWwuMjkzLTIuNTQ0aC0xLjM1MmwuMTUtMS4yNTNoNi43MzVsLS4xMTksMS4yNTNaTTguNzksMTcuMjY5bC4yNTktMi41ODloLTEuMzY1bC0uMTM1LDEuMjg5aC0xLjM3MWwtLjE0MywxLjMwMWgyLjc1NiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+CiAgICAgIDxwYXRoIGQ9Ik00Ni41NSwxMi4xMzZoMS4zNTJsLjM3Miw5LjExM2gtNC4xOTZsLS4wMzUtMS4zMzhoLTQuMTczbC4wMTUsMS4zMzhoLTIuNzk4bC0uMDAzLTIuNjYzaDEuMzg0bC0uMDE2LTIuNjE2aDEuMzc0bC0uMDE0LTEuMjg5aDEuMzY1bC0uMDQxLTIuNTQ0aC0xLjM1M2wtLjAxNC0xLjI1M2g2LjczNWwuMDQ1LDEuMjUzWk00NS4zNTYsMTcuMjY5bC0uMDgtMi41ODloLTEuMzY4bC4wMzQsMS4yODloLTEuMzcxbC4wMjcsMS4zMDFoMi43NTkiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+'; // Example Base64 string


function updateColor(element, color) {
   switch (element) {
       case 'canvasColor':
           canvasColor = color;
           document.getElementById('gameContainer').style.backgroundColor = color;
           break;
       case 'paddleColor':
           paddleColor = color;
           break;
       case 'textColor':
           textColor = color;
           break;
       case 'ballColor':
           ballColor = color;
           break;
       case 'borderColor':
           borderColor = color;
           document.getElementById('gameContainer').style.borderColor = color;
           break;
       case 'centerLineColor':
           centerLineColor = color;
           break;
   }
   draw();
   saveColors(); // Call saveColors after updating colors
}

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: ${textColor} !important;
           }
           #startButton {
                background-color: ${textColor} !important;
           }
           .paddle {
               background-color: ${paddleColor} !important;
           }
           .ball {
               background-color: ${ballColor} !important;
           }
           .centerLine {
               border-color: ${centerLineColor} !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').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;
   draw(); // Redraw the canvas with the new size
}

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const paddleHeight = 100;
const paddleWidth = 10;
const ballRadius = 7;
let upPressed = false;
let downPressed = false;
let playerY = (canvas.height - paddleHeight) / 2;
let aiY = (canvas.height - paddleHeight) / 2;
let ballX = canvas.width / 2;
let ballY = canvas.height / 2;
let ballSpeedX = 3;
let ballSpeedY = 2;
let playerScore = 0;
let aiScore = 0;
let gameStarted = false;

document.addEventListener('keydown', (e) => {
   if (e.key === 'ArrowUp') {
       upPressed = true;
       e.preventDefault();
   }
   if (e.key === 'ArrowDown') {
       downPressed = true;
       e.preventDefault();
   }
});
document.addEventListener('keyup', (e) => {
   if (e.key === 'ArrowUp') {
       upPressed = false;
       e.preventDefault();
   }
   if (e.key === 'ArrowDown') {
       downPressed = false;
       e.preventDefault();
   }
});

document.getElementById('moveUpButton').addEventListener('mousedown', () => {
   upPressed = true;
});
document.getElementById('moveUpButton').addEventListener('mouseup', () => {
   upPressed = false;
});
document.getElementById('moveDownButton').addEventListener('mousedown', () => {
   downPressed = true;
});
document.getElementById('moveDownButton').addEventListener('mouseup', () => {
   downPressed = false;
});

function drawPaddle(x, y) {
   ctx.fillStyle = paddleColor;
   ctx.fillRect(x, y, paddleWidth, paddleHeight);
}

function drawBall() {
   ctx.beginPath();
   ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
   ctx.fillStyle = ballColor;
   ctx.fill();
   ctx.closePath();
}

function drawWatermark() {
   const img = new Image();
   img.src = watermarkBase64;
   img.onload = () => {
       const imgWidth = img.width * 2; // Increase size
       const imgHeight = img.height * 2; // Increase size
       const x = (canvas.width - imgWidth) / 2;
       const y = canvas.height - imgHeight - 10; // 10px from the bottom
       ctx.drawImage(img, x, y, imgWidth, imgHeight);
       canvas.addEventListener('click', (e) => {
           const rect = canvas.getBoundingClientRect();
           const mouseX = e.clientX - rect.left;
           const mouseY = e.clientY - rect.top;
           if (mouseX >= x && mouseX <= x + imgWidth && mouseY >= y && mouseY <= y + imgHeight) {
               window.open('https://errorarcade.webflow.io/', '_blank');
           }
       });
   };
}

function draw() {
   ctx.clearRect(0, 0, canvas.width, canvas.height);
   ctx.fillStyle = canvasColor;
   ctx.fillRect(0, 0, canvas.width, canvas.height);
   drawPaddle(0, playerY);
   drawPaddle(canvas.width - paddleWidth, aiY);
   drawBall();
   drawWatermark();

   // Draw center line
   ctx.beginPath();
   ctx.setLineDash([10, 8]);
   ctx.moveTo(canvas.width / 2, 0);
   ctx.lineTo(canvas.width / 2, canvas.height);
   ctx.strokeStyle = centerLineColor;
   ctx.stroke();
   ctx.closePath();

   document.getElementById('score').innerText = `${playerScore} - ${aiScore}`;
}

function movePaddle() {
   if (upPressed && playerY > 0) playerY -= 5;
   if (downPressed && playerY < canvas.height - paddleHeight) playerY += 5;
}

function moveBall() {
   ballX += ballSpeedX;
   ballY += ballSpeedY;

   if (ballY + ballSpeedY > canvas.height - ballRadius || ballY + ballSpeedY < ballRadius) {
       ballSpeedY = -ballSpeedY;
   }

   if (ballX + ballSpeedX > canvas.width - paddleWidth - ballRadius) {
       if (ballY > aiY && ballY < aiY + paddleHeight) {
           ballSpeedX = -ballSpeedX;
           // Add some randomness to the ball speed
           ballSpeedY += (Math.random() - 0.5) * 2;
       } else {
           playerScore++;
           resetBall();
       }
   } else if (ballX + ballSpeedX < paddleWidth + ballRadius) {
       if (ballY > playerY && ballY < playerY + paddleHeight) {
           ballSpeedX = -ballSpeedX;
           // Add some randomness to the ball speed
           ballSpeedY += (Math.random() - 0.5) * 2;
       } else {
           aiScore++;
           resetBall();
       }
   }

   // AI Movement with a chance to miss
   if (ballX > canvas.width / 2 && Math.random() > 0.1) {
       aiY = ballY - paddleHeight / 2;
   }
}

function resetBall() {
   ballX = canvas.width / 2;
   ballY = canvas.height / 2;
   ballSpeedX = -ballSpeedX;
   ballSpeedY = (Math.random() - 0.5) * 4;
}

function update() {
   if (!gameStarted) return;

   if (playerScore >= 3 || aiScore >= 3) {
       alert(`Game Over! ${playerScore >= 3 ? 'Player' : 'AI'} Wins!`);
       playerScore = 0;
       aiScore = 0;
       resetBall();
       gameStarted = false;
       document.getElementById('startButton').style.display = 'block';
   }

   movePaddle();
   moveBall();
   draw();
}

const startButton = document.getElementById('startButton');
startButton.addEventListener('click', () => {
   gameStarted = true;
   startButton.style.display = 'none';
   setInterval(update, 1000 / 60);
});

// Show mobile controls if on a mobile device and set default canvas size
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;
draw(); // Initial draw to reflect default size
</script>

Add this game (Admin only)

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Save Your edits

You can keep your changes by saving your game to the dashboard, and copy them again later.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.