Smile Jump
by SparkTurtle66341 lines8.2 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Smile Jump</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #111;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
font-family: Arial, sans-serif;
color: white;
overflow: hidden;
}
canvas {
background: linear-gradient(to bottom, #1a2a6c, #b21f1f);
border-radius: 12px;
box-shadow: 0 0 25px rgba(0,0,0,0.5);
max-width: 100%;
}
#ui {
margin-top: 12px;
text-align: center;
font-size: 18px;
}
#jumpBtn {
margin-top: 15px;
padding: 16px 60px;
font-size: 22px;
font-weight: bold;
background: #00c3ff;
color: white;
border: none;
border-radius: 50px;
cursor: pointer;
box-shadow: 0 6px 0 #0090c0;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
#jumpBtn:active {
transform: translateY(4px);
box-shadow: 0 2px 0 #0090c0;
}
#message {
font-size: 22px;
font-weight: bold;
margin-top: 8px;
height: 32px;
color: #fff;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="800" height="450"></canvas>
<div id="ui">
<div>Level: <span id="level">1</span> | Rods: <span id="rods">0</span> / <span id="needed">10</span></div>
<div id="message"></div>
</div>
<button id="jumpBtn">JUMP</button>
<script>
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
// Game settings
const GRAVITY = 0.7;
const JUMP_FORCE = -15;
const GROUND_Y = 380;
let player = {
x: 130,
y: GROUND_Y - 50,
width: 50,
height: 50,
velocityY: 0,
onGround: true,
scaleX: 1,
scaleY: 1,
rotation: 0
};
let rods = [];
let level = 1;
let rodsPassed = 0;
let rodsNeeded = 10;
let gameSpeed = 5.5;
let gameState = "playing";
let spawnTimer = 0;
// Jump function
function jump() {
if (gameState === "playing" && player.onGround) {
player.velocityY = JUMP_FORCE;
player.onGround = false;
player.scaleX = 0.75;
player.scaleY = 1.3;
player.rotation = -0.2;
}
else if (gameState === "levelComplete") {
nextLevel();
}
else if (gameState === "gameOver" || gameState === "finished") {
restartGame();
}
}
document.getElementById("jumpBtn").addEventListener("click", jump);
document.addEventListener("keydown", (e) => {
if (e.code === "Space" || e.code === "ArrowUp") {
e.preventDefault();
jump();
}
});
// Create blue rod
function createRod() {
const h = 55 + Math.random() * 55;
rods.push({
x: canvas.width + 30,
y: GROUND_Y - h,
width: 28,
height: h,
passed: false
});
}
// Collision check
function checkCollision(p, r) {
return (
p.x < r.x + r.width &&
p.x + p.width > r.x &&
p.y < r.y + r.height &&
p.y + p.height > r.y
);
}
// Update game
function update() {
if (gameState !== "playing") return;
// Physics
player.velocityY += GRAVITY;
player.y += player.velocityY;
if (player.y + player.height >= GROUND_Y) {
player.y = GROUND_Y - player.height;
player.velocityY = 0;
player.onGround = true;
player.scaleX = 1.3;
player.scaleY = 0.7;
player.rotation = 0;
}
// Smooth animation return
player.scaleX += (1 - player.scaleX) * 0.18;
player.scaleY += (1 - player.scaleY) * 0.18;
player.rotation += (0 - player.rotation) * 0.15;
if (!player.onGround) {
player.rotation = player.velocityY * 0.018;
}
// Spawn rods
spawnTimer++;
if (spawnTimer > Math.max(50, 95 - level * 2.2)) {
createRod();
spawnTimer = 0;
}
// Move rods
for (let i = rods.length - 1; i >= 0; i--) {
let rod = rods[i];
rod.x -= gameSpeed;
if (!rod.passed && rod.x + rod.width < player.x) {
rod.passed = true;
rodsPassed++;
document.getElementById("rods").textContent = rodsPassed;
if (rodsPassed >= rodsNeeded) {
levelComplete();
}
}
if (checkCollision(player, rod)) {
gameOver();
}
if (rod.x + rod.width < 0) {
rods.splice(i, 1);
}
}
}
// Level complete
function levelComplete() {
gameState = "levelComplete";
if (level >= 20) {
gameState = "finished";
document.getElementById("message").textContent = "YOU BEAT ALL 20 LEVELS!";
} else {
document.getElementById("message").textContent = `Level ${level} Complete! Tap JUMP`;
}
}
function nextLevel() {
level++;
rodsPassed = 0;
rodsNeeded = level * 10;
gameSpeed = 5.5 + level * 0.32;
rods = [];
spawnTimer = 0;
player.y = GROUND_Y - player.height;
player.velocityY = 0;
player.onGround = true;
player.scaleX = 1;
player.scaleY = 1;
player.rotation = 0;
gameState = "playing";
document.getElementById("level").textContent = level;
document.getElementById("rods").textContent = 0;
document.getElementById("needed").textContent = rodsNeeded;
document.getElementById("message").textContent = "";
}
function gameOver() {
gameState = "gameOver";
document.getElementById("message").textContent = "Game Over! Tap JUMP to retry";
}
function restartGame() {
level = 1;
rodsPassed = 0;
rodsNeeded = 10;
gameSpeed = 5.5;
rods = [];
spawnTimer = 0;
player.y = GROUND_Y - player.height;
player.velocityY = 0;
player.onGround = true;
player.scaleX = 1;
player.scaleY = 1;
player.rotation = 0;
gameState = "playing";
document.getElementById("level").textContent = 1;
document.getElementById("rods").textContent = 0;
document.getElementById("needed").textContent = 10;
document.getElementById("message").textContent = "";
}
// Draw smiling face player
function drawPlayer() {
ctx.save();
const cx = player.x + player.width / 2;
const cy = player.y + player.height / 2;
ctx.translate(cx, cy);
ctx.rotate(player.rotation);
ctx.scale(player.scaleX, player.scaleY);
// yellow face
ctx.beginPath();
ctx.arc(0, 0, 26, 0, Math.PI * 2);
ctx.fillStyle = "#FFD93D";
ctx.fill();
ctx.lineWidth = 3;
ctx.strokeStyle = "#E6B800";
ctx.stroke();
// Eyes
ctx.fillStyle = "#333";
ctx.beginPath();
ctx.arc(-9, -6, 4.5, 0, Math.PI * 2);
ctx.arc(9, -6, 4.5, 0, Math.PI * 2);
ctx.fill();
// Big smile
ctx.beginPath();
ctx.arc(0, 4, 14, 0.15 * Math.PI, 0.85 * Math.PI);
ctx.lineWidth = 3.5;
ctx.strokeStyle = "#333";
ctx.stroke();
ctx.restore();
}
// Main draw
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Ground line
ctx.strokeStyle = "rgba(255,255,255,0.4)";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(0, GROUND_Y);
ctx.lineTo(canvas.width, GROUND_Y);
ctx.stroke();
// Blue rods
rods.forEach(rod => {
// Main rod
ctx.fillStyle = "#00B7FF";
ctx.fillRect(rod.x, rod.y, rod.width, rod.height);
// Light edge
ctx.fillStyle = "#7DE2FF";
ctx.fillRect(rod.x, rod.y, 8, rod.height);
});
// Draw the player
drawPlayer();
// Dark overlay when paused
if (gameState !== "playing") {
ctx.fillStyle = "rgba(0, 0, 0, 0.55)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}
// Game loop
function gameLoop() {
update();
draw();
requestAnimationFrame(gameLoop);
}
gameLoop();
</script>
</body>
</html>Game Source: Smile Jump
Creator: SparkTurtle66
Libraries: none
Complexity: complex (341 lines, 8.2 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: smile-jump-sparkturtle66" to link back to the original. Then publish at arcadelab.ai/publish.