Terms & Conditions
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Climate Defender: Mission Earth</title>
<style>
body {
margin: 0;
font-family: "Arial", sans-serif;
background: linear-gradient(to top, #87ceeb, #f0f8ff);
overflow: hidden;
text-align: center;
color: #023047;
}
h1 {
margin-top: 10px;
}
canvas {
background: #c2f0c2;
display: block;
margin: 10px auto;
border: 4px solid #023047;
border-radius: 10px;
}
#startBtn {
padding: 12px 24px;
font-size: 18px;
background: #2d6a4f;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
}
#startBtn:hover {
background: #1b4332;
}
#info {
font-size: 18px;
margin: 10px;
}
</style>
</head>
<body>
<h1>🌎 Climate Defender: Mission Earth</h1>
<p id="info">Level 1: Catch renewable energy and keep the planet cool! (SDG 13)</p>
<canvas id="game" width="800" height="500"></canvas>
<button id="startBtn">Start Game</button>
<script>
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
const startBtn = document.getElementById("startBtn");
const info = document.getElementById("info");
let level = 1;
let player = { x: 400, y: 420, w: 50, h: 50, speed: 12 };
let objects = [];
let score = 0;
let temp = 25;
let speed = 2;
let gameRunning = false;
let levelGoal = 100;
// Visual defaults for text
ctx.textBaseline = "top";
ctx.textAlign = "left";
// 🎮 Player controls
document.addEventListener("keydown", (e) => {
if (!gameRunning) return;
if (e.key === "ArrowLeft" && player.x > 0) player.x = Math.max(0, player.x - player.speed);
if (e.key === "ArrowRight" && player.x < canvas.width - player.w)
player.x = Math.min(canvas.width - player.w, player.x + player.speed);
});
// 🧍♂ Draw player
function drawPlayer() {
// Draw player box
ctx.fillStyle = "#1b4332";
ctx.fillRect(player.x, player.y, player.w, player.h);
// Draw emoji inside the box
ctx.font = "28px Arial";
ctx.fillStyle = "white";
// center the emoji roughly
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("🧍♂", player.x + player.w / 2, player.y + player.h / 2);
// restore text alignment for HUD
ctx.textAlign = "left";
ctx.textBaseline = "top";
}
// 🌞 Spawn objects (renewable vs pollution)
function spawnObject() {
const renewableSet = ["☀", "💧", "💨"];
const pollutionSet = ["💀", "☁", "🔥", "🌪"];
const deforestSet = ["🌳", "🪓"];
let emoji;
let renewable = true;
if (level === 1) {
renewable = Math.random() < 0.6;
emoji = renewable
? renewableSet[Math.floor(Math.random() * renewableSet.length)]
: pollutionSet[Math.floor(Math.random() * pollutionSet.length)];
} else if (level === 2) {
renewable = Math.random() < 0.5;
// for level 2, deforestSet are negative (axes) and trees might be positive or negative.
emoji = renewable
? renewableSet[Math.floor(Math.random() * renewableSet.length)]
: deforestSet[Math.floor(Math.random() * deforestSet.length)];
} else {
renewable = Math.random() < 0.45;
const allBad = pollutionSet.concat(deforestSet);
emoji = renewable
? renewableSet[Math.floor(Math.random() * renewableSet.length)]
: allBad[Math.floor(Math.random() * allBad.length)];
}
objects.push({
x: Math.random() * (canvas.width - 40),
y: -48,
size: 40,
emoji,
renewable,
});
}
// 🎨 Draw falling objects
function drawObjects() {
ctx.font = "36px Arial";
ctx.textBaseline = "top";
objects.forEach((obj) => {
// draw emoji; offset a bit so it looks inside its bounding box
ctx.fillText(obj.emoji, obj.x, obj.y);
obj.y += speed;
});
}
// 💥 Collision detection
function checkCollision() {
objects = objects.filter((obj) => {
const hit =
player.x < obj.x + obj.size &&
player.x + player.w > obj.x &&
player.y < obj.y + obj.size &&
player.y + player.h > obj.y;
if (hit) {
if (obj.renewable) {
score += 10;
temp -= 0.2;
} else {
score -= 5;
temp += 0.5;
}
return false; // remove on hit
}
// remove if fallen out of canvas
return obj.y < canvas.height;
});
}
// 🌡 Draw HUD
function drawHUD() {
ctx.fillStyle = "black";
ctx.font = "20px Arial";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText(Level: ${level}, 20, 10);
ctx.fillText(Score: ${score}, 120, 10);
ctx.fillText(🌡 Temp: ${temp.toFixed(1)}°C, 650, 10);
if (temp >= 30) {
ctx.fillStyle = "red";
ctx.font = "18px Arial";
ctx.fillText("🔥 Global warming increasing!", 270, 40);
}
}
// 🎯 Check for level progress
function checkLevelProgress() {
if (score >= levelGoal) {
gameRunning = false;
level++;
if (level > 3) {
endGame("🌍 You saved the planet! SDG 13 achieved!");
return;
}
nextLevel();
}
}
// 🕹 Main game loop
function gameLoop() {
if (!gameRunning) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Different background per level
if (level === 1) ctx.fillStyle = "#c2f0c2";
else if (level === 2) ctx.fillStyle = "#b7e4c7";
else ctx.fillStyle = "#90e0ef";
ctx.fillRect(0, 0, canvas.width, canvas.height);
drawPlayer();
drawObjects();
checkCollision();
drawHUD();
checkLevelProgress();
// Spawn & speed
if (Math.random() < 0.03 + level * 0.01) spawnObject();
speed = 2 + level * 0.5;
// Temperature check
if (temp >= 35 || temp <= 10) {
endGame("🌡 Climate crisis! The planet overheated!");
return;
}
requestAnimationFrame(gameLoop);
}
// 🚀 Level transitions
function nextLevel() {
info.textContent =
level === 2
? "Level 2: Protect forests and keep the air clean 🌳"
: "Level 3: Stop global warming and save the planet 🌎";
// simple transition screen
ctx.fillStyle = "rgba(255,255,255,0.95)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "black";
ctx.font = "32px Arial";
ctx.textAlign = "center";
ctx.fillText(Level ${level} Starting..., canvas.width / 2, canvas.height / 2 - 20);
setTimeout(() => {
temp = 25;
objects = [];
score = 0;
gameRunning = true;
ctx.textAlign = "left";
gameLoop();
}, 1500);
}
// 💀 Game over or finish
function endGame(message) {
ctx.fillStyle = "rgba(0,0,0,0.6)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "white";
ctx.font = "30px Arial";
ctx.textAlign = "center";
ctx.fillText(message, canvas.width / 2, canvas.height / 2 - 30);
ctx.font = "22px Arial";
ctx.fillText(Final Score: ${score}, canvas.width / 2, canvas.height / 2 + 10);
gameRunning = false;
startBtn.style.display = "block";
startBtn.textContent = "Play Again";
level = 1;
info.textContent = "Level 1: Catch renewable energy and keep the planet cool! 🌞";
}
// ▶ Start game
startBtn.addEventListener("click", () => {
score = 0;
temp = 25;
level = 1;
objects = [];
gameRunning = true;
startBtn.style.display = "none";
info.textContent = "Level 1: Catch renewable energy and keep the planet cool!";
gameLoop();
});
</script>
</body>
</html>