save progress

This commit is contained in:
2026-05-06 10:01:40 +09:00
parent 155e25099d
commit 1535ed975a
27 changed files with 879 additions and 96 deletions

View File

@@ -1,7 +1,25 @@
<h1 style="color:black; padding:20px">
ColorQuest - Game (this is a placeholder)
</h1>
<script>
import { querystring } from 'svelte-spa-router';
import GameCanvas from '../components/GameCanvas.svelte';
import HUD from '../components/HUD.svelte';
<a href='#/gameover'>
<button>Game over</button>
</a>
// querystring is the part after ? in the URL e.g. "level=2"
// we parse it safely — if missing, default to level 1
$: levelNum = $querystring
? parseInt(new URLSearchParams($querystring).get('level')) || 1
: 1;
</script>
<div class="game-wrapper">
<GameCanvas levelNumber={levelNum}/>
<HUD levelNumber={levelNum}/>
</div>
<style>
.game-wrapper{
position: relative;
width: 800px;
height: 450px;
margin: 0 auto;
}
</style>

View File

@@ -1,7 +1,67 @@
<h1 style="color:black; padding:20px">
ColorQuest - Game Over (this is a placeholder)
</h1>
<script>
import {push} from 'svelte-spa-router';
import {querystring} from 'svelte-spa-router';
import {resetLevel} from '../stores/colorStore.js';
import {getLevel} from '../game/levelData.js';
<a href='#/levelselect'>
<button>Play Again</button>
</a>
$: levelNum = parseInt(new URLSearchParams($querystring).get('level')) || 1;
function retry(){
const level = getLevel(levelNum);
resetLevel(levelNum, level.color);
push(`/game/${levelNum}`);
}
</script>
<div class="screen">
<h1>the light faded...</h1>
<p>the world stays gray a little longer</p>
<div class="buttons">
<button on:click={retry}>try again</button>
<button on:click={() => push('/levelselect')}>level select</button>
</div>
</div>
<style>
.screen{
width: 800px;
height: 450px;
margin: 0 auto;
background: #0a0a0a;
color: #ccc;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 16px;
}
h1{
font-family:'Courier New', Courier, monospace;
font-size: 48px;
font-weight: 400;
color: white;
}
p{
font-family:'Courier New', Courier, monospace;
font-size: 20px;
opacity: .9;
}
.buttons{
display: flex;
gap: 16px;
margin-top: 8px
}
button{
padding: 10px 32px;
border-radius: 24px;
cursor: pointer;
font-family:'Courier New', Courier, monospace;
font-size: 20px;
background: rgba(255,255,255,0.08);
border: 1px solid rgba(255,255,255,0.2);
color: white;
}
button:hover{
background: rgba(255,255,255,0.18);
}
</style>

View File

@@ -1,7 +1,72 @@
<h1 style="color:black; padding:20px">
ColorQuest - Home (this is a placeholder)
</h1>
<script>
import {push} from 'svelte-spa-router';
import {unlockedColors} from '../stores/colorStore.js';
<a href='#/game'>
<button>Start Game</button>
</a>
function startGame() {
push('/levelselect');
}
</script>
<div class="title-screen">
<!--<img src="/backgrounds/title_bg.png" class="bg" alt="title background"/>-->
<div class="content">
<h1>ColorQuest</h1>
<p>Bring color back to your world</p>
<button on:click={startGame}>begin</button>
</div>
</div>
<style>
.title-screen{
width: 800px;
height: 450;
margin: 0 auto;
position: relative;
overflow: hidden;
background: #111;
height: 450px;
}
.bg{
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0.85;
}
.content{
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
color: white;
}
h1{
font-family:'Courier New', Courier, monospace;
font-size: 64px;
font-weight: 400;
text-shadow: 0 2px 12px rgba(0,0,0,0.7);
margin: 0;
}
p{
font-family:'Courier New', Courier, monospace;
font-size: 22px;
opacity: 0.8;
margin: 0;
}
button{
margin-top: 20px;
padding: 12px 40px;
font-family:'Courier New', Courier, monospace;
font-size: 22px;
background: rgba(255,255,255,0.15);
color: white;
border: 1px solid rgba(255,255,255,0.4);
border-radius: 30px;
cursor: pointer;
transition: background 0.2s;
}
button:hover{background: rgba(255,255,255,0.3);}
</style>

View File

@@ -1,7 +1,100 @@
<h1 style="color:black; padding:20px">
ColorQuest - Level Select (this is a placeholder)
</h1>
<script>
import {push} from 'svelte-spa-router';
import {unlockedColors} from '../stores/colorStore.js';
import {LEVELS} from '../game/levelData.js';
<a href='#/game'>
<button>Start Game</button>
</a>
function playLevel(id) {
push(`/game?level=${id}`);
}
// level 1 is always unlocked, other based on prev level completion
function isUnlocked(level){
if (level.id === 1) return true;
const prevLevel = LEVELS.find(l => l.id === level.id -1);
return $unlockedColors.includes(prevLevel.color);
}
</script>
<div class="screen">
<h1>Choose a level</h1>
<div class="level-grid">
{#each LEVELS as level}
<button
class="level-card"
class:locked={!isUnlocked(level)}
style="--c: {level.color}"
on:click={() => isUnlocked(level) && playLevel(level.id)}
>
<div class="swatch"></div>
<span class="name">{isUnlocked(level) ? level.name: '?'}</span>
</button>
{/each}
</div>
<button class="back" on:click={() => push('/')}>back</button>
</div>
<style>
.screen{
width: 800px;
height: 450px;
margin: 0 auto;
background: #111;
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
}
h1{
font-family:'Courier New', Courier, monospace;
font-size: 42px;
font-weight: 400;
}
.level-grid{
display: flex;
gap: 16px;
}
.level-card{
width: 120px;
height: 140px;
background: #222;
border: 1px solid #444;
border-radius: 12px;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
color: white;
transition: transform 0.15s, border-color 0.15s;
}
.level-card:hover:not(.locked){
transform: translateY(-4px);
border-color: var(--c);
}
.level-card.locked{
opacity: 0.4;
cursor: not-allowed;
}
.level-card.locked .swatch{
background: #555;
}
.name{
font-family:'Courier New', Courier, monospace;
font-size: 18px;
}
.back{
background: none;
border: 1px solid #555;
color: #aaa;
padding: 8px 24px;
border-radius: 20px;
cursor: pointer;
font-family:'Courier New', Courier, monospace;
font-size: 16px;
}
</style>