piclets / src /lib /components /Battle /BattleField.svelte
Fraser's picture
MORE
7428b13
raw
history blame
4.36 kB
<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;
// Random background selection
const backgrounds = ['ruins', 'road', 'dinner', 'cave'];
const selectedBackground = backgrounds[Math.floor(Math.random() * backgrounds.length)];
// Animation states
let playerVisible = false;
let enemyVisible = false;
let trainerVisible = true;
onMount(() => {
if (showIntro) {
// Intro animation sequence
setTimeout(() => {
trainerVisible = false;
enemyVisible = true;
}, 500);
setTimeout(() => {
playerVisible = true;
}, 1500);
} else {
// Skip intro
playerVisible = true;
enemyVisible = true;
trainerVisible = false;
}
});
</script>
<div class="battle-field" style="background-image: url('/images/environments/{selectedBackground}.png')">
<!-- Striped overlay pattern -->
<div class="stripe-pattern"></div>
<!-- Trainer intro image -->
{#if showIntro && trainerVisible}
<div class="trainer-intro" transition:fade={{ duration: 300 }}>
<img src="/images/default_trainer.png" alt="Trainer" />
</div>
{/if}
<!-- Enemy area -->
<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>
<!-- Player area -->
<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); /* Mirror player sprite */
}
@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>