130 Widgets

Semi-random thoughts and tales of tinkering

Lesson 12: The Complete Game!

You've learned every building block (pun intended! 😄). Now let's see how they all come together in the final game, plus a few bonus features: a day/night cycle, crafting, and a health system! 🎮🏆

Bonus Feature: Day/Night Cycle

The sky changes color over time, creating a day/night cycle! We use a simple timer that cycles through sunrise → day → sunset → night:

let gameTime = 30000;  // Start at noon

function getTimeOfDay() {
  const cycle = 120000;  // Full cycle = 2 minutes
  return (gameTime % cycle) / cycle;  // Returns 0.0 to 1.0
}

function getSkyColor(time) {
  if (time < 0.2)  return lerpColor('#0a0a2e', '#87ceeb', time / 0.2);   // Dawn
  if (time < 0.5)  return '#87ceeb';                                      // Day
  if (time < 0.7)  return lerpColor('#87ceeb', '#0a0a2e', (time-0.5)/0.2);// Dusk
  return '#0a0a2e';                                                        // Night
}

// Darken the screen at night
function getDarkness(time) {
  if (time < 0.2) return 1 - time / 0.2;   // Getting lighter (dawn)
  if (time < 0.5) return 0;                 // Full daylight
  if (time < 0.7) return (time - 0.5) / 0.2; // Getting darker (dusk)
  return 1;                                  // Full darkness
}

🌈 Lerping Colors

lerpColor smoothly blends between two colors. "Lerp" stands for Linear Interpolation — a fancy way of saying "gradually transition from A to B." At 0% you get color A, at 100% you get color B, and at 50% you get a perfect mix in between!

Bonus Feature: Crafting

Crafting turns raw materials into new items. Each recipe lists inputs and outputs:

const RECIPES = [
  // 1 wood → 4 planks
  { input: { WOOD: 1 }, output: { block: PLANKS, count: 4 } },

  // 4 planks → 1 crafting table
  { input: { PLANKS: 4 }, output: { block: CRAFTING_TABLE, count: 1 } },

  // 1 cobblestone + 1 coal → 4 torches
  { input: { COBBLESTONE: 1, COAL: 1 }, output: { block: TORCH, count: 4 } },
];

function canCraft(recipe) {
  // Check if player has all required inputs
  return Object.entries(recipe.input).every(([blockType, needed]) => {
    const total = inventory.reduce((sum, slot) =>
      sum + (slot && slot.block === blockType ? slot.count : 0), 0);
    return total >= needed;
  });
}

Bonus Feature: Health System

const player = {
  health: 20,       // 10 hearts (each heart = 2 HP)
  maxHealth: 20,
  // ...other properties
};

// Fall damage — if falling speed is too high when landing
if (player.vy > 10) {
  player.health -= Math.floor((player.vy - 10) * 2);
}

// Passive healing (small random chance each frame)
if (player.health < player.maxHealth && Math.random() < 0.003) {
  player.health++;
}

// Respawn when health reaches 0
if (player.health <= 0) {
  player.health = player.maxHealth;
  // Teleport back to spawn point
}

How Everything Fits Together

Here's the complete architecture of our game — every system you built!

LessonConceptWhat It Does in the Game
1Canvas & DrawingThe screen we draw everything on
2Variables & FunctionsPlayer position, drawBlock(), drawPlayer()
3Animation LoopThe gameLoop() that runs 60× per second
4Keyboard ControlsWASD movement, slot selection
5Gravity & JumpingFalling, jumping, velocity physics
62D ArraysThe world grid storing every block
7Collision DetectionWalking on blocks, hitting walls
8Scrolling CameraShowing a huge world through a small window
9Mouse InputBreaking and placing blocks
10InventoryCollecting and managing items
11World GenerationProcedural terrain, trees, ores, caves
12PolishDay/night, crafting, health, final game

🎉 Congratulations! 🎉

You've learned how to build a complete 2D game from scratch! You now understand variables, functions, arrays, loops, physics, collision detection, procedural generation, and so much more.

These are real programming skills that professional game developers use every day. You should be really proud! 🌟

⛏️ Play the Complete Game!

What You Can Add Next

The game is complete, but there's always more you can add! Here are some ideas:

🧟 Enemies

Add zombies or creepers that spawn at night and chase the player!

🎵 Sound Effects

Use the Web Audio API to add mining, placing, and walking sounds.

💾 Save/Load

Use localStorage to save the world and load it later.

🌊 Water Physics

Make water flow and fill in gaps, like real Minecraft water!

🏠 More Blocks

Add doors, windows, stairs, ladders — each with unique behavior.

🌱 Farming

Plant seeds, water them, and harvest crops!

🗺️ Biomes

Different regions: desert, snow, jungle — each with unique terrain.

👥 Multiplayer

Use WebSockets to let friends join your world!

Resources to Keep Learning

📚 Recommended Next Steps

  • MDN Web Docs — The best reference for HTML, CSS, and JavaScript
  • JavaScript.info — A free, comprehensive JavaScript tutorial
  • Game Programming Patterns — Learn how professional games are structured
  • Khan Academy Computer Programming — Free interactive coding courses
  • Scratch → JavaScript — If you know Scratch, you're already halfway there!
🚀 The most important thing: Keep building! The best way to learn programming is to make things you're excited about. You've already proven you can build a whole game. What will you create next? 🌟

🏆 Final Challenges — Your Journey Continues!

  • Add at least one new block type to the game (like sand, snow, or lava)
  • Implement saving the world using localStorage.setItem('world', JSON.stringify(world))
  • Make the player's walking animation smoother by adding more frames
  • Create a start screen with a title and "Play" button
  • Add background music using the <audio> tag
  • Challenge: Build the coolest house you can in your game and screenshot it!