svelte-easy-rockpaperscissors Svelte Themes

Svelte Easy Rockpaperscissors

šŸŖØšŸ“„āœ‚ļø Rock Paper Scissors Game

A fun and interactive Rock Paper Scissors game built with SvelteKit, TypeScript, and Bun! Perfect for learning Svelte basics.

šŸŽ® Game Modes

  • šŸ‘„ Player vs Player (PvP): Play against a friend on the same device
  • šŸ¤– Player vs CPU: Play against the computer

šŸš€ Quick Start

Prerequisites

Make sure you have Bun installed on your computer.

Installation & Running

# Install dependencies
bun install

# Start the development server
bun run dev

# Open in browser (usually http://localhost:5173)

šŸ“š Learning Svelte - Step-by-Step Guide for Beginners

This guide explains how the game works, perfect for junior high students learning Svelte!


šŸ“– Table of Contents

  1. What is SvelteKit?
  2. Project Structure
  3. Understanding Svelte Files
  4. The Home Page
  5. Player vs Player Mode
  6. Player vs CPU Mode
  7. Key Concepts Explained

1. What is SvelteKit?

Svelte is a modern way to build websites. Unlike other frameworks, Svelte turns your code into tiny, fast JavaScript when you build your app.

SvelteKit is a tool that helps you build complete web applications with Svelte. It handles:

  • Routing: Going from page to page (like / to /pvp)
  • File organization: Where to put your code
  • Building: Making your app ready for the internet

2. Project Structure

src/
ā”œā”€ā”€ routes/              # Your pages go here!
│   ā”œā”€ā”€ +page.svelte     # Home page (/)
│   ā”œā”€ā”€ pvp/
│   │   └── +page.svelte # PvP mode page (/pvp)
│   └── cpu/
│       └── +page.svelte # vs CPU page (/cpu)
ā”œā”€ā”€ app.html            # Main HTML template
└── lib/                # Reusable code (empty for now)

Important: In SvelteKit, files named +page.svelte automatically become pages!

  • routes/+page.svelte → becomes the / page
  • routes/pvp/+page.svelte → becomes the /pvp page

3. Understanding Svelte Files

A Svelte file (.svelte) has 3 sections:

<script>
  // JavaScript code goes here
  // Variables, functions, game logic
</script>

<!-- HTML goes here -->
<!-- What the user sees -->

<style>
  /* CSS styling goes here */
  /* How things look */
</style>

Let's break down each section!


4. The Home Page

File: src/routes/+page.svelte

Part 1: The Script Section

<script lang="ts">
  import { goto } from '$app/navigation';

  function startPvP() {
    goto('/pvp');
  }

  function startVsCPU() {
    goto('/cpu');
  }
</script>

What's happening?

  • lang="ts" means we're using TypeScript (JavaScript with extra type checking)
  • import { goto } brings in a function to navigate between pages
  • startPvP() and startVsCPU() are functions that take us to different pages

Part 2: The HTML Section

<div class="container">
  <h1>šŸŖØšŸ“„āœ‚ļø</h1>
  <h2>Rock Paper Scissors</h2>
  
  <div class="button-group">
    <button class="mode-button" on:click={startPvP}>
      šŸ‘„ Player vs Player
    </button>
    <button class="mode-button" on:click={startVsCPU}>
      šŸ¤– Player vs CPU
    </button>
  </div>
</div>

New Svelte concept: on:click={startPvP}

  • This connects a button click to a function
  • When you click the button, it runs the startPvP function
  • Similar to HTML's onclick but more powerful!

Part 3: The Style Section

<style>
  .container {
    text-align: center;
    background: white;
    padding: 3rem 2rem;
    border-radius: 20px;
    /* More styles... */
  }
</style>

Special: Styles in Svelte are scoped by default!

  • They only apply to THIS component
  • Won't affect other pages
  • No naming conflicts!

5. Player vs Player Mode

File: src/routes/pvp/+page.svelte

Key Concepts

1. Reactive Variables
let player1Choice: Choice = null;
let player2Choice: Choice = null;
let scores = { player1: 0, player2: 0 };

In Svelte, regular let variables are reactive:

  • When you change them, the page updates automatically
  • No need to manually update the display!
2. Type Definitions
type Choice = 'rock' | 'paper' | 'scissors' | null;

This TypeScript code says: "A Choice can ONLY be one of these values"

  • Helps catch mistakes
  • Makes your code safer
3. Conditional Rendering
{#if !player1Choice}
  <div>Player 1's Turn</div>
{:else if showPlayer2 && !player2Choice}
  <div>Player 2's Turn</div>
{:else if result}
  <div>Show Results</div>
{/if}

Svelte's special syntax:

  • {#if condition} - Show this if true
  • {:else if condition} - Otherwise, check this
  • {:else} - Otherwise, show this
  • {/if} - End of if block
4. Looping Through Data
{#each choices as choice}
  <button on:click={() => selectPlayer1(choice)}>
    <span>{emojis[choice]}</span>
    <span>{choice}</span>
  </button>
{/each}

What's happening?

  • {#each array as item} loops through an array
  • Creates a button for each choice (rock, paper, scissors)
  • Less code, more power!
5. Game Logic
function determineWinner() {
  if (player1Choice === player2Choice) {
    result = "It's a Tie! šŸ¤";
  } else if (
    (player1Choice === 'rock' && player2Choice === 'scissors') ||
    (player1Choice === 'scissors' && player2Choice === 'paper') ||
    (player1Choice === 'paper' && player2Choice === 'rock')
  ) {
    result = 'Player 1 Wins! šŸŽ‰';
    scores.player1++;  // Automatically updates the display!
  } else {
    result = 'Player 2 Wins! šŸŽ‰';
    scores.player2++;
  }
}

How Rock Paper Scissors works:

  • Rock beats Scissors
  • Scissors beats Paper
  • Paper beats Rock

When we update scores.player1++, Svelte automatically updates the scoreboard on the page!


6. Player vs CPU Mode

File: src/routes/cpu/+page.svelte

The CPU "Brain"

function selectChoice(choice: Choice) {
  playerChoice = choice;
  isThinking = true;
  
  setTimeout(() => {
    const randomIndex = Math.floor(Math.random() * choices.length);
    cpuChoice = choices[randomIndex];
    isThinking = false;
    determineWinner();
  }, 1000);
}

What's happening?

  1. Player makes a choice
  2. Set isThinking = true (shows loading spinner)
  3. Wait 1 second (setTimeout)
  4. Pick a random choice for CPU
  5. Set isThinking = false
  6. Determine winner

Random Number Explained:

Math.random()              // 0.0 to 0.999...
Math.random() * 3          // 0.0 to 2.999...
Math.floor(Math.random() * 3)  // 0, 1, or 2
choices[randomIndex]       // rock, paper, or scissors

7. Key Concepts Explained

A. Reactivity (The Magic of Svelte)

let count = 0;  // When this changes...
<p>{count}</p>  <!-- This updates automatically! -->

In other frameworks, you'd need to tell the page to update. Svelte does it automatically!

B. Event Handling

<button on:click={playAgain}>Play Again</button>
<button on:click={() => goto('/')}>Go Home</button>
  • on:click={function} - Call a function
  • on:click={() => doSomething()} - Call with arrow function (useful for parameters)

C. Component State

"State" means "the current condition of your app":

  • What choices were made?
  • What's the score?
  • Is the CPU thinking?

In Svelte, state is just regular variables with let!

D. Navigation

import { goto } from '$app/navigation';

goto('/pvp');  // Go to the /pvp page

SvelteKit makes page navigation easy with the goto function.

E. Styling with Animations

@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}

h1 {
  animation: bounce 2s ease-in-out infinite;
}

This makes the emoji bounce up and down!


šŸŽÆ Challenges for Learning

Try these modifications to learn more:

Beginner:

  1. Change the colors in the CSS
  2. Add more emoji to the game
  3. Change the "thinking" time for CPU

Intermediate:

  1. Add a "Best of 5" mode
  2. Add sound effects when someone wins
  3. Create a leaderboard that saves to localStorage

Advanced:

  1. Add a "Best of 5" rounds system
  2. Create animated transitions between screens
  3. Add difficulty levels for CPU (easy/medium/hard)

šŸ› ļø Useful Commands

# Development
bun run dev          # Start development server
bun run build        # Build for production
bun run preview      # Preview production build

# Type checking
bun run check        # Check for TypeScript errors

šŸ“– Additional Resources


šŸ¤” Questions to Think About

  1. Why is Svelte different? It compiles your code into tiny JavaScript instead of including a big framework.

  2. What makes Svelte reactive? Variables with let automatically update the page when changed.

  3. How does routing work? Files named +page.svelte in the routes folder automatically become pages.

  4. Why use TypeScript? It catches errors before you run your code and makes it easier to understand.


šŸŽ‰ You Did It!

You now understand:

  • āœ… How SvelteKit structures projects
  • āœ… How Svelte files work (script, HTML, style)
  • āœ… Reactivity and state management
  • āœ… Conditional rendering and loops
  • āœ… Event handling and navigation
  • āœ… Building a complete game!

Next steps: Try modifying the game and see what happens. The best way to learn is by doing!


Built with ā¤ļø using SvelteKit + TypeScript + Bun

Top categories

Loading Svelte Themes