|
<script lang="ts"> |
|
import { onMount } from 'svelte'; |
|
import { fade } from 'svelte/transition'; |
|
import type { PicletInstance } from '$lib/db/schema'; |
|
import PicletInfo from './PicletInfo.svelte'; |
|
|
|
export let playerPiclet: PicletInstance; |
|
export let enemyPiclet: PicletInstance; |
|
export let playerHpPercentage: number; |
|
export let enemyHpPercentage: number; |
|
export let showIntro: boolean = false; |
|
|
|
|
|
const backgrounds = ['ruins', 'road', 'dinner', 'cave']; |
|
const selectedBackground = backgrounds[Math.floor(Math.random() * backgrounds.length)]; |
|
|
|
|
|
let playerVisible = false; |
|
let enemyVisible = false; |
|
let trainerVisible = true; |
|
|
|
onMount(() => { |
|
if (showIntro) { |
|
|
|
setTimeout(() => { |
|
trainerVisible = false; |
|
enemyVisible = true; |
|
}, 500); |
|
|
|
setTimeout(() => { |
|
playerVisible = true; |
|
}, 1500); |
|
} else { |
|
|
|
playerVisible = true; |
|
enemyVisible = true; |
|
trainerVisible = false; |
|
} |
|
}); |
|
</script> |
|
|
|
<div class="battle-field" style="background-image: url('/images/environments/{selectedBackground}.png')"> |
|
|
|
<div class="stripe-pattern"></div> |
|
|
|
|
|
{#if showIntro && trainerVisible} |
|
<div class="trainer-intro" transition:fade={{ duration: 300 }}> |
|
<img src="/images/default_trainer.png" alt="Trainer" /> |
|
</div> |
|
{/if} |
|
|
|
|
|
<div class="enemy-area"> |
|
<PicletInfo |
|
piclet={enemyPiclet} |
|
hpPercentage={enemyHpPercentage} |
|
isPlayer={false} |
|
/> |
|
|
|
{#if enemyVisible} |
|
<div class="piclet-sprite enemy-sprite" transition:fade={{ duration: 300 }}> |
|
<img |
|
src={enemyPiclet.imageUrl} |
|
alt={enemyPiclet.nickname} |
|
on:error={(e) => e.currentTarget.src = 'https://via.placeholder.com/120x120?text=Piclet'} |
|
/> |
|
</div> |
|
{/if} |
|
</div> |
|
|
|
|
|
<div class="player-area"> |
|
{#if playerVisible} |
|
<div class="piclet-sprite player-sprite" transition:fade={{ duration: 300 }}> |
|
<img |
|
src={playerPiclet.imageUrl} |
|
alt={playerPiclet.nickname} |
|
on:error={(e) => e.currentTarget.src = 'https://via.placeholder.com/120x120?text=Piclet'} |
|
/> |
|
</div> |
|
{/if} |
|
|
|
<PicletInfo |
|
piclet={playerPiclet} |
|
hpPercentage={playerHpPercentage} |
|
isPlayer={true} |
|
/> |
|
</div> |
|
</div> |
|
|
|
<style> |
|
.battle-field { |
|
height: 60vh; |
|
min-height: 400px; |
|
position: relative; |
|
background-size: cover; |
|
background-position: center; |
|
background-repeat: no-repeat; |
|
overflow: hidden; |
|
} |
|
|
|
.stripe-pattern { |
|
position: absolute; |
|
inset: 0; |
|
background: repeating-linear-gradient( |
|
45deg, |
|
transparent, |
|
transparent 10px, |
|
rgba(255, 255, 255, 0.05) 10px, |
|
rgba(255, 255, 255, 0.05) 20px |
|
); |
|
pointer-events: none; |
|
} |
|
|
|
.trainer-intro { |
|
position: absolute; |
|
top: 50%; |
|
left: 50%; |
|
transform: translate(-50%, -50%); |
|
z-index: 10; |
|
} |
|
|
|
.trainer-intro img { |
|
width: 200px; |
|
height: auto; |
|
filter: drop-shadow(0 4px 8px rgba(0,0,0,0.3)); |
|
} |
|
|
|
.enemy-area { |
|
position: absolute; |
|
top: 10%; |
|
right: 10%; |
|
display: flex; |
|
flex-direction: column; |
|
align-items: flex-end; |
|
gap: 1rem; |
|
} |
|
|
|
.player-area { |
|
position: absolute; |
|
bottom: 10%; |
|
left: 10%; |
|
display: flex; |
|
flex-direction: column; |
|
align-items: flex-start; |
|
gap: 1rem; |
|
} |
|
|
|
.piclet-sprite { |
|
width: 120px; |
|
height: 120px; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
} |
|
|
|
.piclet-sprite img { |
|
width: 100%; |
|
height: 100%; |
|
object-fit: contain; |
|
image-rendering: pixelated; |
|
filter: drop-shadow(0 4px 8px rgba(0,0,0,0.3)); |
|
} |
|
|
|
.enemy-sprite { |
|
order: 2; |
|
} |
|
|
|
.player-sprite { |
|
order: 1; |
|
transform: scaleX(-1); |
|
} |
|
|
|
@media (max-width: 768px) { |
|
.battle-field { |
|
height: 50vh; |
|
min-height: 300px; |
|
} |
|
|
|
.piclet-sprite { |
|
width: 80px; |
|
height: 80px; |
|
} |
|
|
|
.enemy-area { |
|
top: 5%; |
|
right: 5%; |
|
} |
|
|
|
.player-area { |
|
bottom: 5%; |
|
left: 5%; |
|
} |
|
} |
|
</style> |