Add Star Catcher minigame and chamber decorations
- Added new Star Catcher minigame where players catch falling stars - Golden stars worth 3 points, regular stars worth 1 point - 10 Void Essence awarded per point (higher rewards than Void Hunt) - Added 4 purchasable decorations: Crystal Orb, Void Flame, Ancient Tome, Moon Stone - Decorations appear in chamber with ambient pulsing animation - Persist decorations to localStorage
This commit is contained in:
10
WORKLOG.md
10
WORKLOG.md
@ -51,12 +51,16 @@ A whimsical pocket dimension where digital companions called "Voidlings" float a
|
|||||||
- Added sound effects system using Web Audio API (pet, feed, spawn, achievement, purchase, release)
|
- Added sound effects system using Web Audio API (pet, feed, spawn, achievement, purchase, release)
|
||||||
- Added mute toggle button to control sounds
|
- Added mute toggle button to control sounds
|
||||||
- Added Void Hunt minigame - click targets for 30 seconds to earn Void Essence
|
- Added Void Hunt minigame - click targets for 30 seconds to earn Void Essence
|
||||||
|
- Added Star Catcher minigame - catch falling stars for higher rewards (10 Void Essence per star)
|
||||||
|
- Added purchasable chamber decorations: Crystal Orb, Void Flame, Ancient Tome, Moon Stone
|
||||||
|
- Decorations appear in the chamber with ambient pulsing animation
|
||||||
|
|
||||||
### Next Steps
|
### Next Steps
|
||||||
1. Add more minigames
|
1. Add more minigames (DONE - added Star Catcher)
|
||||||
2. Add voidling evolution/combat system
|
2. Add voidling evolution/combat system
|
||||||
3. Add decorations for the chamber
|
3. Add more chamber decorations/ways to customize chamber
|
||||||
|
4. Add achievement for catching stars in Star Catcher
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Last updated: Session 5 complete - Added voidling shop with Void Essence currency*
|
*Last updated: Session 6 complete - Added Star Catcher minigame and chamber decorations*
|
||||||
|
|||||||
@ -113,6 +113,7 @@ interface ShopItem {
|
|||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
type: Voidling['type']
|
type: Voidling['type']
|
||||||
|
category: 'voidling' | 'consumable' | 'decoration'
|
||||||
color: string
|
color: string
|
||||||
glow: string
|
glow: string
|
||||||
shape: string
|
shape: string
|
||||||
@ -121,6 +122,22 @@ interface ShopItem {
|
|||||||
icon: string
|
icon: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Decoration {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
icon: string
|
||||||
|
x: number
|
||||||
|
y: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FallingStar {
|
||||||
|
id: number
|
||||||
|
x: number
|
||||||
|
y: number
|
||||||
|
speed: number
|
||||||
|
points: number
|
||||||
|
}
|
||||||
|
|
||||||
const VOIDLING_TYPES = [
|
const VOIDLING_TYPES = [
|
||||||
{ type: 'wisp', color: 'bg-purple-400', glow: 'shadow-purple-500/50', shape: 'rounded-full', description: 'Ethereal and floaty' },
|
{ type: 'wisp', color: 'bg-purple-400', glow: 'shadow-purple-500/50', shape: 'rounded-full', description: 'Ethereal and floaty' },
|
||||||
{ type: 'blob', color: 'bg-cyan-400', glow: 'shadow-cyan-500/50', shape: 'rounded-[40%]', description: 'Bouncy and playful' },
|
{ type: 'blob', color: 'bg-cyan-400', glow: 'shadow-cyan-500/50', shape: 'rounded-[40%]', description: 'Bouncy and playful' },
|
||||||
@ -131,14 +148,18 @@ const VOIDLING_TYPES = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const SHOP_ITEMS: ShopItem[] = [
|
const SHOP_ITEMS: ShopItem[] = [
|
||||||
{ id: 'wisp_egg', name: 'Wisp Egg', type: 'wisp', color: 'bg-purple-400', glow: 'shadow-purple-500/50', shape: 'rounded-full', cost: 50, description: 'Hatches into a wisp', icon: '🥚' },
|
{ id: 'wisp_egg', name: 'Wisp Egg', type: 'wisp', category: 'voidling', color: 'bg-purple-400', glow: 'shadow-purple-500/50', shape: 'rounded-full', cost: 50, description: 'Hatches into a wisp', icon: '🥚' },
|
||||||
{ id: 'blob_egg', name: 'Blob Egg', type: 'blob', color: 'bg-cyan-400', glow: 'shadow-cyan-500/50', shape: 'rounded-[40%]', cost: 50, description: 'Hatches into a blob', icon: '🥚' },
|
{ id: 'blob_egg', name: 'Blob Egg', type: 'blob', category: 'voidling', color: 'bg-cyan-400', glow: 'shadow-cyan-500/50', shape: 'rounded-[40%]', cost: 50, description: 'Hatches into a blob', icon: '🥚' },
|
||||||
{ id: 'spark_egg', name: 'Spark Egg', type: 'spark', color: 'bg-amber-400', glow: 'shadow-amber-500/50', shape: 'rounded-sm', cost: 75, description: 'Hatches into a spark', icon: '⚡' },
|
{ id: 'spark_egg', name: 'Spark Egg', type: 'spark', category: 'voidling', color: 'bg-amber-400', glow: 'shadow-amber-500/50', shape: 'rounded-sm', cost: 75, description: 'Hatches into a spark', icon: '⚡' },
|
||||||
{ id: 'ember_egg', name: 'Ember Egg', type: 'ember', color: 'bg-rose-400', glow: 'shadow-rose-500/50', shape: 'rounded-full', cost: 75, description: 'Hatches into an ember', icon: '🔥' },
|
{ id: 'ember_egg', name: 'Ember Egg', type: 'ember', category: 'voidling', color: 'bg-rose-400', glow: 'shadow-rose-500/50', shape: 'rounded-full', cost: 75, description: 'Hatches into an ember', icon: '🔥' },
|
||||||
{ id: 'glitch_egg', name: 'Glitch Egg', type: 'glitch', color: 'bg-green-400', glow: 'shadow-green-500/50', shape: 'rounded-lg', cost: 150, description: 'Rare unstable voidling', icon: '👾' },
|
{ id: 'glitch_egg', name: 'Glitch Egg', type: 'glitch', category: 'voidling', color: 'bg-green-400', glow: 'shadow-green-500/50', shape: 'rounded-lg', cost: 150, description: 'Rare unstable voidling', icon: '👾' },
|
||||||
{ id: 'crystal_egg', name: 'Crystal Egg', type: 'crystal', color: 'bg-blue-400', glow: 'shadow-blue-500/50', shape: 'rounded-sm', cost: 150, description: 'Rare sharp voidling', icon: '💎' },
|
{ id: 'crystal_egg', name: 'Crystal Egg', type: 'crystal', category: 'voidling', color: 'bg-blue-400', glow: 'shadow-blue-500/50', shape: 'rounded-sm', cost: 150, description: 'Rare sharp voidling', icon: '💎' },
|
||||||
{ id: 'treat', name: 'Void Treat', type: 'wisp', color: 'bg-yellow-400', glow: 'shadow-yellow-500/50', shape: 'rounded-full', cost: 20, description: 'All voidlings become happy', icon: '🍪' },
|
{ id: 'treat', name: 'Void Treat', type: 'wisp', category: 'consumable', color: 'bg-yellow-400', glow: 'shadow-yellow-500/50', shape: 'rounded-full', cost: 20, description: 'All voidlings become happy', icon: '🍪' },
|
||||||
{ id: 'star_fragment', name: 'Star Fragment', type: 'wisp', color: 'bg-white', glow: 'shadow-white/50', shape: 'rounded-full', cost: 200, description: 'Rare: +100 Void Essence!', icon: '⭐' },
|
{ id: 'star_fragment', name: 'Star Fragment', type: 'wisp', category: 'consumable', color: 'bg-white', glow: 'shadow-white/50', shape: 'rounded-full', cost: 200, description: 'Rare: +100 Void Essence!', icon: '⭐' },
|
||||||
|
{ id: 'crystal_orb', name: 'Crystal Orb', type: 'wisp', category: 'decoration', color: 'bg-blue-400', glow: 'shadow-blue-500/50', shape: 'rounded-full', cost: 100, description: 'A glowing orb for your chamber', icon: '🔮' },
|
||||||
|
{ id: 'void_flame', name: 'Void Flame', type: 'wisp', category: 'decoration', color: 'bg-purple-400', glow: 'shadow-purple-500/50', shape: 'rounded-full', cost: 120, description: 'An eternal purple flame', icon: '🕯️' },
|
||||||
|
{ id: 'ancient_book', name: 'Ancient Tome', type: 'wisp', category: 'decoration', color: 'bg-amber-600', glow: 'shadow-amber-500/50', shape: 'rounded-lg', cost: 150, description: 'Knowledge from the void', icon: '📕' },
|
||||||
|
{ id: 'moon_stone', name: 'Moon Stone', type: 'wisp', category: 'decoration', color: 'bg-zinc-300', glow: 'shadow-zinc-400/50', shape: 'rounded-full', cost: 200, description: 'A piece of the moon', icon: '🌑' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const ACHIEVEMENTS: Achievement[] = [
|
const ACHIEVEMENTS: Achievement[] = [
|
||||||
@ -222,9 +243,12 @@ export default function Chamber() {
|
|||||||
})
|
})
|
||||||
const [showGames, setShowGames] = useState(false)
|
const [showGames, setShowGames] = useState(false)
|
||||||
const [gameActive, setGameActive] = useState(false)
|
const [gameActive, setGameActive] = useState(false)
|
||||||
|
const [gameType, setGameType] = useState<'hunt' | 'stars' | null>(null)
|
||||||
const [gameScore, setGameScore] = useState(0)
|
const [gameScore, setGameScore] = useState(0)
|
||||||
const [gameTimeLeft, setGameTimeLeft] = useState(30)
|
const [gameTimeLeft, setGameTimeLeft] = useState(30)
|
||||||
const [gameTargets, setGameTargets] = useState<{id: number, x: number, y: number}[]>([])
|
const [gameTargets, setGameTargets] = useState<{id: number, x: number, y: number}[]>([])
|
||||||
|
const [fallingStars, setFallingStars] = useState<FallingStar[]>([])
|
||||||
|
const [decorations, setDecorations] = useState<Decoration[]>([])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
soundEngine.setMuted(isMuted)
|
soundEngine.setMuted(isMuted)
|
||||||
@ -248,7 +272,7 @@ export default function Chamber() {
|
|||||||
}, [gameActive])
|
}, [gameActive])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!gameActive) return
|
if (!gameActive || gameType !== 'hunt') return
|
||||||
|
|
||||||
const spawnTarget = () => {
|
const spawnTarget = () => {
|
||||||
const newTarget = {
|
const newTarget = {
|
||||||
@ -263,7 +287,41 @@ export default function Chamber() {
|
|||||||
const spawnInterval = setInterval(spawnTarget, 1500)
|
const spawnInterval = setInterval(spawnTarget, 1500)
|
||||||
|
|
||||||
return () => clearInterval(spawnInterval)
|
return () => clearInterval(spawnInterval)
|
||||||
}, [gameActive])
|
}, [gameActive, gameType])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!gameActive || gameType !== 'stars') return
|
||||||
|
|
||||||
|
const spawnStar = () => {
|
||||||
|
const newStar: FallingStar = {
|
||||||
|
id: Date.now() + Math.random(),
|
||||||
|
x: Math.random() * 80 + 10,
|
||||||
|
y: -5,
|
||||||
|
speed: Math.random() * 0.8 + 0.5,
|
||||||
|
points: Math.random() > 0.8 ? 3 : 1,
|
||||||
|
}
|
||||||
|
setFallingStars(prev => [...prev, newStar])
|
||||||
|
}
|
||||||
|
|
||||||
|
spawnStar()
|
||||||
|
const spawnInterval = setInterval(spawnStar, 800)
|
||||||
|
|
||||||
|
return () => clearInterval(spawnInterval)
|
||||||
|
}, [gameActive, gameType])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!gameActive || gameType !== 'stars') return
|
||||||
|
|
||||||
|
const moveStars = setInterval(() => {
|
||||||
|
setFallingStars(prev => {
|
||||||
|
return prev
|
||||||
|
.map(s => ({ ...s, y: s.y + s.speed }))
|
||||||
|
.filter(s => s.y < 110)
|
||||||
|
})
|
||||||
|
}, 50)
|
||||||
|
|
||||||
|
return () => clearInterval(moveStars)
|
||||||
|
}, [gameActive, gameType])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const savedVoidlings = localStorage.getItem('voidlings')
|
const savedVoidlings = localStorage.getItem('voidlings')
|
||||||
@ -292,6 +350,13 @@ export default function Chamber() {
|
|||||||
setUserStats(stats)
|
setUserStats(stats)
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const savedDecorations = localStorage.getItem('voidling_decorations')
|
||||||
|
if (savedDecorations) {
|
||||||
|
try {
|
||||||
|
setDecorations(JSON.parse(savedDecorations))
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -307,6 +372,10 @@ export default function Chamber() {
|
|||||||
localStorage.setItem('voidling_achievements', JSON.stringify(unlockedAchievements))
|
localStorage.setItem('voidling_achievements', JSON.stringify(unlockedAchievements))
|
||||||
}, [unlockedAchievements])
|
}, [unlockedAchievements])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
localStorage.setItem('voidling_decorations', JSON.stringify(decorations))
|
||||||
|
}, [decorations])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
ACHIEVEMENTS.forEach(achievement => {
|
ACHIEVEMENTS.forEach(achievement => {
|
||||||
if (!unlockedAchievements.includes(achievement.id)) {
|
if (!unlockedAchievements.includes(achievement.id)) {
|
||||||
@ -521,16 +590,23 @@ export default function Chamber() {
|
|||||||
setVoidlings(voidlings.filter(v => v.id !== id))
|
setVoidlings(voidlings.filter(v => v.id !== id))
|
||||||
}
|
}
|
||||||
|
|
||||||
function startGame() {
|
function startGame(type: 'hunt' | 'stars') {
|
||||||
|
setGameType(type)
|
||||||
setGameActive(true)
|
setGameActive(true)
|
||||||
setGameScore(0)
|
setGameScore(0)
|
||||||
setGameTimeLeft(30)
|
setGameTimeLeft(30)
|
||||||
setGameTargets([])
|
setGameTargets([])
|
||||||
|
setFallingStars([])
|
||||||
}
|
}
|
||||||
|
|
||||||
function endGame() {
|
function endGame() {
|
||||||
setGameActive(false)
|
setGameActive(false)
|
||||||
const reward = gameScore * 5
|
let reward = 0
|
||||||
|
if (gameType === 'hunt') {
|
||||||
|
reward = gameScore * 5
|
||||||
|
} else if (gameType === 'stars') {
|
||||||
|
reward = gameScore * 10
|
||||||
|
}
|
||||||
if (reward > 0) {
|
if (reward > 0) {
|
||||||
setUserStats(prev => {
|
setUserStats(prev => {
|
||||||
const newStats = { ...prev, voidEssence: prev.voidEssence + reward }
|
const newStats = { ...prev, voidEssence: prev.voidEssence + reward }
|
||||||
@ -539,6 +615,8 @@ export default function Chamber() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
setGameTargets([])
|
setGameTargets([])
|
||||||
|
setFallingStars([])
|
||||||
|
setGameType(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
function hitTarget(id: number) {
|
function hitTarget(id: number) {
|
||||||
@ -547,6 +625,15 @@ export default function Chamber() {
|
|||||||
setGameTargets(prev => prev.filter(t => t.id !== id))
|
setGameTargets(prev => prev.filter(t => t.id !== id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function catchStar(id: number) {
|
||||||
|
soundEngine.playPet()
|
||||||
|
const star = fallingStars.find(s => s.id === id)
|
||||||
|
if (star) {
|
||||||
|
setGameScore(prev => prev + star.points)
|
||||||
|
}
|
||||||
|
setFallingStars(prev => prev.filter(s => s.id !== id))
|
||||||
|
}
|
||||||
|
|
||||||
function purchaseItem(item: ShopItem) {
|
function purchaseItem(item: ShopItem) {
|
||||||
if (userStats.voidEssence < item.cost) return
|
if (userStats.voidEssence < item.cost) return
|
||||||
|
|
||||||
@ -566,6 +653,15 @@ export default function Chamber() {
|
|||||||
localStorage.setItem('voidling_stats', JSON.stringify(newStats))
|
localStorage.setItem('voidling_stats', JSON.stringify(newStats))
|
||||||
return newStats
|
return newStats
|
||||||
})
|
})
|
||||||
|
} else if (item.category === 'decoration') {
|
||||||
|
const newDecoration: Decoration = {
|
||||||
|
id: generateId(),
|
||||||
|
name: item.name,
|
||||||
|
icon: item.icon,
|
||||||
|
x: Math.random() * 70 + 15,
|
||||||
|
y: Math.random() * 50 + 30,
|
||||||
|
}
|
||||||
|
setDecorations(prev => [...prev, newDecoration])
|
||||||
} else {
|
} else {
|
||||||
const pos = getRandomPosition()
|
const pos = getRandomPosition()
|
||||||
const newVoidling: Voidling = {
|
const newVoidling: Voidling = {
|
||||||
@ -806,6 +902,20 @@ export default function Chamber() {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
{decorations.map((decoration) => (
|
||||||
|
<div
|
||||||
|
key={decoration.id}
|
||||||
|
className="absolute text-4xl pointer-events-none opacity-60 animate-pulse"
|
||||||
|
style={{
|
||||||
|
left: `${decoration.x}%`,
|
||||||
|
top: `${decoration.y}%`,
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{decoration.icon}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-6 text-center text-zinc-500 text-sm">
|
<div className="mt-6 text-center text-zinc-500 text-sm">
|
||||||
@ -916,12 +1026,29 @@ export default function Chamber() {
|
|||||||
</div>
|
</div>
|
||||||
<p className="text-xs text-zinc-400 mb-3">Catch as many targets as you can in 30 seconds. Each catch awards 5 Void Essence!</p>
|
<p className="text-xs text-zinc-400 mb-3">Catch as many targets as you can in 30 seconds. Each catch awards 5 Void Essence!</p>
|
||||||
<button
|
<button
|
||||||
onClick={() => { setShowGames(false); startGame(); }}
|
onClick={() => { setShowGames(false); startGame('hunt'); }}
|
||||||
className="w-full py-2 bg-gradient-to-r from-cyan-600 to-blue-600 hover:from-cyan-500 hover:to-blue-500 rounded-lg text-sm font-medium transition-all"
|
className="w-full py-2 bg-gradient-to-r from-cyan-600 to-blue-600 hover:from-cyan-500 hover:to-blue-500 rounded-lg text-sm font-medium transition-all"
|
||||||
>
|
>
|
||||||
Start Game
|
Start Game
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="p-4 bg-zinc-800/50 rounded-xl border border-zinc-700">
|
||||||
|
<div className="flex items-center gap-3 mb-2">
|
||||||
|
<span className="text-3xl">⭐</span>
|
||||||
|
<div>
|
||||||
|
<div className="font-bold">Star Catcher</div>
|
||||||
|
<div className="text-xs text-zinc-500">Catch falling stars!</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-zinc-400 mb-3">Catch falling stars in 30 seconds. Golden stars are worth 3 points! Each point awards 10 Void Essence!</p>
|
||||||
|
<button
|
||||||
|
onClick={() => { setShowGames(false); startGame('stars'); }}
|
||||||
|
className="w-full py-2 bg-gradient-to-r from-yellow-600 to-amber-600 hover:from-yellow-500 hover:to-amber-500 rounded-lg text-sm font-medium transition-all"
|
||||||
|
>
|
||||||
|
Start Game
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -934,11 +1061,11 @@ export default function Chamber() {
|
|||||||
⏱️ {gameTimeLeft}s
|
⏱️ {gameTimeLeft}s
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-zinc-900/80 px-6 py-2 rounded-xl border border-zinc-700">
|
<div className="bg-zinc-900/80 px-6 py-2 rounded-xl border border-zinc-700">
|
||||||
🎯 {gameScore}
|
{gameType === 'hunt' ? '🎯' : '⭐'} {gameScore}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{gameTargets.map(target => (
|
{gameType === 'hunt' && gameTargets.map(target => (
|
||||||
<button
|
<button
|
||||||
key={target.id}
|
key={target.id}
|
||||||
onClick={() => hitTarget(target.id)}
|
onClick={() => hitTarget(target.id)}
|
||||||
@ -948,6 +1075,21 @@ export default function Chamber() {
|
|||||||
✨
|
✨
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
{gameType === 'stars' && fallingStars.map(star => (
|
||||||
|
<button
|
||||||
|
key={star.id}
|
||||||
|
onClick={() => catchStar(star.id)}
|
||||||
|
className={`absolute w-12 h-12 rounded-full animate-pulse hover:scale-110 transition-transform pointer-events-auto flex items-center justify-center text-2xl shadow-lg ${
|
||||||
|
star.points === 3
|
||||||
|
? 'bg-gradient-to-r from-yellow-300 to-amber-500 shadow-amber-500/50'
|
||||||
|
: 'bg-gradient-to-r from-white to-yellow-200 shadow-yellow-300/50'
|
||||||
|
}`}
|
||||||
|
style={{ left: `${star.x}%`, top: `${star.y}%`, transform: 'translate(-50%, -50%)' }}
|
||||||
|
>
|
||||||
|
{star.points === 3 ? '🌟' : '⭐'}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -959,13 +1101,17 @@ export default function Chamber() {
|
|||||||
Game Over!
|
Game Over!
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-zinc-400 mb-4">
|
<p className="text-zinc-400 mb-4">
|
||||||
You caught <span className="text-yellow-400 font-bold">{gameScore}</span> targets!
|
{gameType === 'hunt' ? (
|
||||||
|
<>You caught <span className="text-yellow-400 font-bold">{gameScore}</span> targets!</>
|
||||||
|
) : (
|
||||||
|
<>You caught <span className="text-yellow-400 font-bold">{gameScore}</span> stars!</>
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-lg text-yellow-400 font-bold mb-4">
|
<p className="text-lg text-yellow-400 font-bold mb-4">
|
||||||
+{gameScore * 5} Void Essence
|
+{(gameType === 'hunt' ? gameScore * 5 : gameScore * 10)} Void Essence
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
onClick={() => { setGameScore(0); startGame(); }}
|
onClick={() => { setGameScore(0); startGame(gameType || 'hunt'); }}
|
||||||
className="w-full py-3 bg-gradient-to-r from-cyan-600 to-blue-600 hover:from-cyan-500 hover:to-blue-500 rounded-xl font-medium transition-all"
|
className="w-full py-3 bg-gradient-to-r from-cyan-600 to-blue-600 hover:from-cyan-500 hover:to-blue-500 rounded-xl font-medium transition-all"
|
||||||
>
|
>
|
||||||
Play Again
|
Play Again
|
||||||
|
|||||||
Reference in New Issue
Block a user