good version
This commit is contained in:
parent
687a83922f
commit
11c01fb1ea
|
|
@ -0,0 +1,617 @@
|
||||||
|
<template>
|
||||||
|
<div class="game-overlay" @click.self="handleClose">
|
||||||
|
<div class="game-container">
|
||||||
|
<h2 class="game-title">猜拳遊戲</h2>
|
||||||
|
|
||||||
|
<div v-if="!gameStarted" class="game-intro">
|
||||||
|
<p>3回合制</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="gameStarted" class="game-status">
|
||||||
|
<div class="score">
|
||||||
|
<span>你: {{ playerScore }}</span>
|
||||||
|
<span>第{{ currentRound }}/3局</span>
|
||||||
|
<span>電腦: {{ cpuScore }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="result" class="result-display" ref="resultDisplayRef">
|
||||||
|
<div class="hands" :class="{ 'shake': waiting }">
|
||||||
|
<div class="hand player-hand" :class="{ 'slide-in-left': !waiting }">
|
||||||
|
<div class="hand-icon" :class="`icon-${playerChoice}`"></div>
|
||||||
|
</div>
|
||||||
|
<div class="vs">VS</div>
|
||||||
|
<div class="hand cpu-hand" :class="{ 'slide-in-right': !waiting }">
|
||||||
|
<div class="hand-icon" :class="`icon-${cpuChoice}`"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="result-text" :class="[result, { 'bounce-in': !waiting }]">{{ resultText }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!gameOver" class="choices">
|
||||||
|
<button
|
||||||
|
v-for="choice in choices"
|
||||||
|
:key="choice.id"
|
||||||
|
class="choice-btn"
|
||||||
|
@click="play(choice.id)"
|
||||||
|
:disabled="waiting"
|
||||||
|
>
|
||||||
|
<div class="choice-icon" :class="`icon-${choice.id}`"></div>
|
||||||
|
<span>{{ choice.name }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="gameOver" class="game-over">
|
||||||
|
<div class="final-result" :class="finalResult">
|
||||||
|
<div class="result-icon" :class="`icon-${finalResult}`"></div>
|
||||||
|
<h3>{{ finalResultText }}</h3>
|
||||||
|
</div>
|
||||||
|
<button class="action-btn" @click="playAgain">再玩一次</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="close-btn" @click="handleClose">
|
||||||
|
{{ gameOver ? '完成' : '取消' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
|
||||||
|
const emit = defineEmits(['close', 'complete']);
|
||||||
|
|
||||||
|
const choices = [
|
||||||
|
{ id: 'rock', name: '石頭' },
|
||||||
|
{ id: 'paper', name: '布' },
|
||||||
|
{ id: 'scissors', name: '剪刀' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const gameStarted = ref(false);
|
||||||
|
const gameOver = ref(false);
|
||||||
|
const currentRound = ref(1);
|
||||||
|
const playerScore = ref(0);
|
||||||
|
const cpuScore = ref(0);
|
||||||
|
const playerChoice = ref('');
|
||||||
|
const cpuChoice = ref('');
|
||||||
|
const result = ref('');
|
||||||
|
const waiting = ref(false);
|
||||||
|
|
||||||
|
const resultText = computed(() => {
|
||||||
|
if (result.value === 'win') return '你贏了!';
|
||||||
|
if (result.value === 'lose') return '你輸了!';
|
||||||
|
return '平手!';
|
||||||
|
});
|
||||||
|
|
||||||
|
const finalResult = computed(() => {
|
||||||
|
if (playerScore.value > cpuScore.value) return 'win';
|
||||||
|
if (playerScore.value < cpuScore.value) return 'lose';
|
||||||
|
return 'draw';
|
||||||
|
});
|
||||||
|
|
||||||
|
const finalResultText = computed(() => {
|
||||||
|
if (finalResult.value === 'win') return '勝利!';
|
||||||
|
if (finalResult.value === 'lose') return '失敗...';
|
||||||
|
return '平手';
|
||||||
|
});
|
||||||
|
|
||||||
|
function play(choice) {
|
||||||
|
if (waiting.value || gameOver.value) return;
|
||||||
|
|
||||||
|
gameStarted.value = true;
|
||||||
|
waiting.value = true;
|
||||||
|
playerChoice.value = choice;
|
||||||
|
|
||||||
|
// CPU makes a random choice
|
||||||
|
const cpuIndex = Math.floor(Math.random() * 3);
|
||||||
|
cpuChoice.value = choices[cpuIndex].id;
|
||||||
|
|
||||||
|
// Determine winner
|
||||||
|
setTimeout(() => {
|
||||||
|
const outcome = determineWinner(choice, cpuChoice.value);
|
||||||
|
result.value = outcome;
|
||||||
|
|
||||||
|
if (outcome === 'win') {
|
||||||
|
playerScore.value++;
|
||||||
|
} else if (outcome === 'lose') {
|
||||||
|
cpuScore.value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if game is over
|
||||||
|
setTimeout(() => {
|
||||||
|
if (currentRound.value >= 3) {
|
||||||
|
gameOver.value = true;
|
||||||
|
} else {
|
||||||
|
currentRound.value++;
|
||||||
|
result.value = '';
|
||||||
|
waiting.value = false;
|
||||||
|
}
|
||||||
|
}, 1500);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
function determineWinner(player, cpu) {
|
||||||
|
if (player === cpu) return 'draw';
|
||||||
|
if (
|
||||||
|
(player === 'rock' && cpu === 'scissors') ||
|
||||||
|
(player === 'paper' && cpu === 'rock') ||
|
||||||
|
(player === 'scissors' && cpu === 'paper')
|
||||||
|
) {
|
||||||
|
return 'win';
|
||||||
|
}
|
||||||
|
return 'lose';
|
||||||
|
}
|
||||||
|
|
||||||
|
function playAgain() {
|
||||||
|
gameStarted.value = false;
|
||||||
|
gameOver.value = false;
|
||||||
|
currentRound.value = 1;
|
||||||
|
playerScore.value = 0;
|
||||||
|
cpuScore.value = 0;
|
||||||
|
result.value = '';
|
||||||
|
waiting.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClose() {
|
||||||
|
if (gameOver.value && finalResult.value === 'win') {
|
||||||
|
emit('complete', true); // Won the game
|
||||||
|
} else {
|
||||||
|
emit('complete', false); // Didn't win
|
||||||
|
}
|
||||||
|
emit('close');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.game-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 150;
|
||||||
|
font-family: 'DotGothic16', sans-serif;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-container {
|
||||||
|
background: #f5f5dc;
|
||||||
|
border: 4px solid #8b4513;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 280px;
|
||||||
|
max-height: 90vh;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
animation: slide-up 0.3s ease-out;
|
||||||
|
overflow-y: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-title {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
margin: 0 0 6px 0;
|
||||||
|
color: #8b4513;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-intro {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
color: #8b4513;
|
||||||
|
font-size: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-status {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #8b4513;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-display {
|
||||||
|
margin: 6px 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hands {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hands.shake {
|
||||||
|
animation: shake-hands 0.5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shake-hands {
|
||||||
|
0%, 100% { transform: translateX(0); }
|
||||||
|
25% { transform: translateX(-5px) rotate(-5deg); }
|
||||||
|
75% { transform: translateX(5px) rotate(5deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand.slide-in-left {
|
||||||
|
animation: slide-in-left 0.5s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand.slide-in-right {
|
||||||
|
animation: slide-in-right 0.5s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slide-in-left {
|
||||||
|
from {
|
||||||
|
transform: translateX(-50px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slide-in-right {
|
||||||
|
from {
|
||||||
|
transform: translateX(50px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand span {
|
||||||
|
font-size: 10px;
|
||||||
|
color: #8b4513;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hand-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vs {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #8b4513;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-text {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-text.bounce-in {
|
||||||
|
animation: bounce-in 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce-in {
|
||||||
|
0% {
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-text.win {
|
||||||
|
background: #90EE90;
|
||||||
|
color: #006400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-text.lose {
|
||||||
|
background: #FFB6C1;
|
||||||
|
color: #8b0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-text.draw {
|
||||||
|
background: #FFE4B5;
|
||||||
|
color: #8b4513;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choices {
|
||||||
|
display: flex;
|
||||||
|
gap: 5px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-btn {
|
||||||
|
flex: 1;
|
||||||
|
background: #fff;
|
||||||
|
border: 3px solid #8b4513;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 6px 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2px;
|
||||||
|
font-family: 'DotGothic16', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-btn:hover:not(:disabled) {
|
||||||
|
background: #fffacd;
|
||||||
|
transform: scale(1.05);
|
||||||
|
animation: pulse 0.6s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% { transform: scale(1.05); }
|
||||||
|
50% { transform: scale(1.1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-btn:active:not(:disabled) {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-btn:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-btn span {
|
||||||
|
font-size: 9px;
|
||||||
|
color: #8b4513;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-icon, .hand-icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pixel Art Icons */
|
||||||
|
.icon-rock::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: transparent;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
box-shadow:
|
||||||
|
-2px -2px 0 #888, -1px -2px 0 #888, 0 -2px 0 #888, 1px -2px 0 #888,
|
||||||
|
-3px -1px 0 #888, -2px -1px 0 #aaa, -1px -1px 0 #aaa, 0 -1px 0 #aaa, 1px -1px 0 #aaa, 2px -1px 0 #888,
|
||||||
|
-3px 0 0 #888, -2px 0 0 #aaa, -1px 0 0 #666, 0 0 0 #666, 1px 0 0 #aaa, 2px 0 0 #888,
|
||||||
|
-2px 1px 0 #888, -1px 1px 0 #aaa, 0 1px 0 #aaa, 1px 1px 0 #888,
|
||||||
|
-1px 2px 0 #888, 0 2px 0 #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-paper::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: transparent;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
box-shadow:
|
||||||
|
-2px -3px 0 #ffcc99, -1px -3px 0 #ffcc99, 0 -3px 0 #ffcc99, 1px -3px 0 #ffcc99, 2px -3px 0 #ffcc99,
|
||||||
|
-3px -2px 0 #ffcc99, -2px -2px 0 #ffcc99, -1px -2px 0 #ffcc99, 0 -2px 0 #ffcc99, 1px -2px 0 #ffcc99, 2px -2px 0 #ffcc99, 3px -2px 0 #ffcc99,
|
||||||
|
-3px -1px 0 #ffcc99, -2px -1px 0 #ffcc99, -1px -1px 0 #ffcc99, 0 -1px 0 #ffcc99, 1px -1px 0 #ffcc99, 2px -1px 0 #ffcc99, 3px -1px 0 #ffcc99,
|
||||||
|
-3px 0 0 #ffcc99, -2px 0 0 #ffcc99, -1px 0 0 #ffaa77, 0 0 0 #ffaa77, 1px 0 0 #ffaa77, 2px 0 0 #ffcc99, 3px 0 0 #ffcc99,
|
||||||
|
-3px 1px 0 #ffcc99, -2px 1px 0 #ffcc99, -1px 1px 0 #ffcc99, 0 1px 0 #ffcc99, 1px 1px 0 #ffcc99, 2px 1px 0 #ffcc99, 3px 1px 0 #ffcc99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-scissors::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: transparent;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
box-shadow:
|
||||||
|
-3px -2px 0 #888, -2px -2px 0 #888,
|
||||||
|
-3px -1px 0 #888, -2px -1px 0 #888,
|
||||||
|
-2px 0 0 #888, -1px 0 0 #888, 0 0 0 #888, 1px 0 0 #888, 2px 0 0 #888,
|
||||||
|
-1px 1px 0 #888, 0 1px 0 #888, 1px 1px 0 #888,
|
||||||
|
2px -2px 0 #888, 3px -2px 0 #888,
|
||||||
|
2px -1px 0 #888, 3px -1px 0 #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-over {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.final-result {
|
||||||
|
font-size: 13px;
|
||||||
|
margin: 6px 0;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Trophy icon for win */
|
||||||
|
.icon-win::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: transparent;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
box-shadow:
|
||||||
|
/* Cup top */
|
||||||
|
-3px -4px 0 #ffd700, -2px -4px 0 #ffd700, -1px -4px 0 #ffd700, 0 -4px 0 #ffd700, 1px -4px 0 #ffd700, 2px -4px 0 #ffd700, 3px -4px 0 #ffd700,
|
||||||
|
/* Cup body */
|
||||||
|
-2px -3px 0 #ffd700, -1px -3px 0 #ffed4e, 0 -3px 0 #ffed4e, 1px -3px 0 #ffed4e, 2px -3px 0 #ffd700,
|
||||||
|
-2px -2px 0 #ffd700, -1px -2px 0 #ffed4e, 0 -2px 0 #ffed4e, 1px -2px 0 #ffed4e, 2px -2px 0 #ffd700,
|
||||||
|
-2px -1px 0 #ffd700, -1px -1px 0 #ffed4e, 0 -1px 0 #ffed4e, 1px -1px 0 #ffed4e, 2px -1px 0 #ffd700,
|
||||||
|
-2px 0 0 #ffd700, -1px 0 0 #ffd700, 0 0 0 #ffd700, 1px 0 0 #ffd700, 2px 0 0 #ffd700,
|
||||||
|
/* Base */
|
||||||
|
-1px 1px 0 #b8860b, 0 1px 0 #b8860b, 1px 1px 0 #b8860b,
|
||||||
|
-2px 2px 0 #b8860b, -1px 2px 0 #b8860b, 0 2px 0 #b8860b, 1px 2px 0 #b8860b, 2px 2px 0 #b8860b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Broken heart icon for lose */
|
||||||
|
.icon-lose::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: transparent;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
box-shadow:
|
||||||
|
/* Left side of heart */
|
||||||
|
-3px -2px 0 #ff6b6b, -2px -2px 0 #ff6b6b,
|
||||||
|
-4px -1px 0 #ff6b6b, -3px -1px 0 #ff6b6b, -2px -1px 0 #ff6b6b, -1px -1px 0 #ff6b6b,
|
||||||
|
-4px 0 0 #ff6b6b, -3px 0 0 #ff6b6b, -2px 0 0 #ff6b6b, -1px 0 0 #ff6b6b,
|
||||||
|
/* Right side of heart */
|
||||||
|
1px -2px 0 #ff6b6b, 2px -2px 0 #ff6b6b,
|
||||||
|
0 -1px 0 #ff6b6b, 1px -1px 0 #ff6b6b, 2px -1px 0 #ff6b6b, 3px -1px 0 #ff6b6b,
|
||||||
|
0 0 0 #ff6b6b, 1px 0 0 #ff6b6b, 2px 0 0 #ff6b6b, 3px 0 0 #ff6b6b,
|
||||||
|
/* Bottom crack (broken) */
|
||||||
|
-3px 1px 0 #ff6b6b, -1px 1px 0 #ff6b6b, 1px 1px 0 #ff6b6b,
|
||||||
|
-2px 2px 0 #ff6b6b, 0 2px 0 #ff6b6b,
|
||||||
|
-1px 3px 0 #ff6b6b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handshake icon for draw */
|
||||||
|
.icon-draw::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: transparent;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
box-shadow:
|
||||||
|
/* Left hand */
|
||||||
|
-4px -1px 0 #ffcc99, -3px -1px 0 #ffcc99, -2px -1px 0 #ffcc99,
|
||||||
|
-4px 0 0 #ffcc99, -3px 0 0 #ffcc99, -2px 0 0 #ffcc99, -1px 0 0 #ffcc99,
|
||||||
|
-4px 1px 0 #ffcc99, -3px 1px 0 #ffcc99, -2px 1px 0 #ffcc99,
|
||||||
|
/* Right hand */
|
||||||
|
1px -1px 0 #ffcc99, 2px -1px 0 #ffcc99, 3px -1px 0 #ffcc99,
|
||||||
|
0 0 0 #ffcc99, 1px 0 0 #ffcc99, 2px 0 0 #ffcc99, 3px 0 0 #ffcc99,
|
||||||
|
1px 1px 0 #ffcc99, 2px 1px 0 #ffcc99, 3px 1px 0 #ffcc99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.final-result h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.final-result.win {
|
||||||
|
background: #90EE90;
|
||||||
|
color: #006400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.final-result.lose {
|
||||||
|
background: #FFB6C1;
|
||||||
|
color: #8b0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.final-result.draw {
|
||||||
|
background: #FFE4B5;
|
||||||
|
color: #8b4513;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px;
|
||||||
|
background: #4CAF50;
|
||||||
|
border: 3px solid #2e7d32;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: white;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: 'DotGothic16', sans-serif;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn:hover {
|
||||||
|
background: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px;
|
||||||
|
background: #cd853f;
|
||||||
|
border: 3px solid #8b4513;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: white;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: 'DotGothic16', sans-serif;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn:hover {
|
||||||
|
background: #d2691e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slide-up {
|
||||||
|
from {
|
||||||
|
transform: translateY(50px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
:disabled="stage === 'egg'"
|
:disabled="stage === 'egg'"
|
||||||
@info="showPetInfo = !showPetInfo"
|
@info="showPetInfo = !showPetInfo"
|
||||||
@feed="$emit('action', 'feed')"
|
@feed="$emit('action', 'feed')"
|
||||||
@play="$emit('action', 'play')"
|
@playMenu="showPlayMenu = true"
|
||||||
@sleep="$emit('action', 'sleep')"
|
@sleep="$emit('action', 'sleep')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -199,6 +199,20 @@
|
||||||
@close="showPetInfo = false"
|
@close="showPetInfo = false"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- Play Menu -->
|
||||||
|
<PlayMenu
|
||||||
|
v-if="showPlayMenu"
|
||||||
|
@select="handlePlaySelect"
|
||||||
|
@close="showPlayMenu = false"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Mini Games -->
|
||||||
|
<GuessingGame
|
||||||
|
v-if="currentGame === 'guessing'"
|
||||||
|
@close="currentGame = ''"
|
||||||
|
@complete="handleGameComplete"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Inventory Screen -->
|
<!-- Inventory Screen -->
|
||||||
<InventoryScreen
|
<InventoryScreen
|
||||||
v-if="showInventory"
|
v-if="showInventory"
|
||||||
|
|
@ -239,6 +253,8 @@ import FortuneStickAnimation from './FortuneStickAnimation.vue';
|
||||||
import FortuneResult from './FortuneResult.vue';
|
import FortuneResult from './FortuneResult.vue';
|
||||||
import PetInfoScreen from './PetInfoScreen.vue';
|
import PetInfoScreen from './PetInfoScreen.vue';
|
||||||
import InventoryScreen from './InventoryScreen.vue';
|
import InventoryScreen from './InventoryScreen.vue';
|
||||||
|
import PlayMenu from './PlayMenu.vue';
|
||||||
|
import GuessingGame from './GuessingGame.vue';
|
||||||
import guanyinLots from '../assets/guanyin_100_lots.json';
|
import guanyinLots from '../assets/guanyin_100_lots.json';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
@ -285,6 +301,8 @@ const currentLotNumber = ref(null);
|
||||||
const consecutiveSaintCount = ref(0);
|
const consecutiveSaintCount = ref(0);
|
||||||
const showPetInfo = ref(false);
|
const showPetInfo = ref(false);
|
||||||
const showInventory = ref(false);
|
const showInventory = ref(false);
|
||||||
|
const showPlayMenu = ref(false);
|
||||||
|
const currentGame = ref(''); // '', 'training', 'guessing', 'ball'
|
||||||
const inventory = ref(new Array(16).fill(null));
|
const inventory = ref(new Array(16).fill(null));
|
||||||
// Initialize some items
|
// Initialize some items
|
||||||
inventory.value[0] = { id: 'cookie', name: '幸運餅乾', description: '增加一點快樂值', count: 5, iconClass: 'icon-cookie' };
|
inventory.value[0] = { id: 'cookie', name: '幸運餅乾', description: '增加一點快樂值', count: 5, iconClass: 'icon-cookie' };
|
||||||
|
|
@ -343,6 +361,25 @@ function handleJiaobeiClose() {
|
||||||
consecutiveSaintCount.value = 0;
|
consecutiveSaintCount.value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Play Game Selection ---
|
||||||
|
function handlePlaySelect(gameType) {
|
||||||
|
showPlayMenu.value = false;
|
||||||
|
console.log('Selected game:', gameType);
|
||||||
|
|
||||||
|
// Show the selected game
|
||||||
|
currentGame.value = gameType;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleGameComplete(won) {
|
||||||
|
console.log('Game completed, won:', won);
|
||||||
|
currentGame.value = '';
|
||||||
|
|
||||||
|
if (won) {
|
||||||
|
// Reward: increase happiness
|
||||||
|
emit('action', 'play');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- 求籤流程函數 ---
|
// --- 求籤流程函數 ---
|
||||||
|
|
||||||
function handleStickComplete(number) {
|
function handleStickComplete(number) {
|
||||||
|
|
@ -914,58 +951,22 @@ async function startFeeding(type) {
|
||||||
foodVisible.value = true;
|
foodVisible.value = true;
|
||||||
console.log('Food visible:', foodVisible.value);
|
console.log('Food visible:', foodVisible.value);
|
||||||
|
|
||||||
// Calculate food position: in front of pet, at mouth height
|
// Calculate food position: directly above pet's mouth
|
||||||
// Food drops in front (not directly at mouth)
|
|
||||||
const foodSize = 10 * pixelSize;
|
const foodSize = 10 * pixelSize;
|
||||||
const frontOffsetX = isFacingRight.value ? -foodSize - 5 : width + 5; // In front of pet
|
|
||||||
const mouthY = 8.5; // Mouth is at row 8-9
|
const mouthY = 8.5; // Mouth is at row 8-9
|
||||||
|
|
||||||
// Set horizontal position (in front of pet)
|
// Food drops right in front of pet's mouth (don't move the pet)
|
||||||
let targetFoodX = petX.value + frontOffsetX;
|
// Position food based on which way pet is facing
|
||||||
|
const mouthOffsetX = isFacingRight.value ? -foodSize - 2 : width + 2;
|
||||||
// Only avoid poop areas if there's actual poop
|
foodX.value = petX.value + mouthOffsetX;
|
||||||
const areas = getPoopAreas();
|
|
||||||
if (areas.length > 0) {
|
|
||||||
const maxPoopRight = Math.max(...areas.map(a => a.right));
|
|
||||||
if (targetFoodX < maxPoopRight + 10) {
|
|
||||||
// Move food to the right of poop areas
|
|
||||||
targetFoodX = maxPoopRight + 15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure food stays within bounds
|
|
||||||
const cw = containerRef.value?.clientWidth || 300;
|
|
||||||
targetFoodX = Math.max(10, Math.min(cw - 40, targetFoodX));
|
|
||||||
|
|
||||||
foodX.value = targetFoodX;
|
|
||||||
foodX.value = targetFoodX;
|
|
||||||
foodY.value = 0; // Start from top of screen
|
foodY.value = 0; // Start from top of screen
|
||||||
|
|
||||||
// Calculate target Y (at mouth level)
|
// Calculate target Y (at mouth level)
|
||||||
const targetY = petY.value + (mouthY * pixelSize) - (foodSize / 2);
|
const targetY = petY.value + (mouthY * pixelSize) - (foodSize / 2);
|
||||||
|
|
||||||
// Only avoid poop areas vertically if there's actual poop
|
console.log('Food dropping to:', foodX.value, targetY, 'Pet at:', petX.value, petY.value);
|
||||||
let safeTargetY = targetY;
|
|
||||||
if (areas.length > 0) {
|
|
||||||
const maxPoopBottom = Math.max(...areas.map(a => a.bottom));
|
|
||||||
safeTargetY = Math.min(targetY, maxPoopBottom - foodSize - 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move pet to food
|
// Animate falling to pet's mouth
|
||||||
const targetPetX = isFacingRight.value ? targetFoodX - width - 5 : targetFoodX + (10 * pixelSize) + 5;
|
|
||||||
|
|
||||||
// Force pet to be at the correct position to eat
|
|
||||||
// This ensures that even if the food was moved due to bounds/poop, the pet is there
|
|
||||||
petX.value = targetPetX;
|
|
||||||
|
|
||||||
// Simple animation sequence
|
|
||||||
// 1. Drop food
|
|
||||||
// 2. Pet moves to food
|
|
||||||
// 3. Pet eats (mouth open/close)
|
|
||||||
|
|
||||||
// ... (Existing feeding logic would go here, but we rely on state='eating' triggers from parent)
|
|
||||||
|
|
||||||
// Animate falling to front of pet
|
|
||||||
const duration = 800;
|
const duration = 800;
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
|
|
||||||
|
|
@ -975,7 +976,7 @@ async function startFeeding(type) {
|
||||||
const progress = Math.min(elapsed / duration, 1);
|
const progress = Math.min(elapsed / duration, 1);
|
||||||
// Ease out for smoother landing
|
// Ease out for smoother landing
|
||||||
const eased = 1 - Math.pow(1 - progress, 3);
|
const eased = 1 - Math.pow(1 - progress, 3);
|
||||||
foodY.value = eased * safeTargetY;
|
foodY.value = eased * targetY;
|
||||||
|
|
||||||
if (progress < 1) {
|
if (progress < 1) {
|
||||||
requestAnimationFrame(animateFall);
|
requestAnimationFrame(animateFall);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,212 @@
|
||||||
|
<template>
|
||||||
|
<div class="play-menu-overlay" @click.self="$emit('close')">
|
||||||
|
<div class="play-menu-container">
|
||||||
|
<h2 class="menu-title">選擇遊戲</h2>
|
||||||
|
|
||||||
|
<div class="game-options">
|
||||||
|
<button
|
||||||
|
class="game-option"
|
||||||
|
@click="selectGame('training')"
|
||||||
|
>
|
||||||
|
<div class="option-icon icon-training"></div>
|
||||||
|
<div class="option-name">訓練</div>
|
||||||
|
<div class="option-desc">攻擊訓練</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="game-option"
|
||||||
|
@click="selectGame('guessing')"
|
||||||
|
>
|
||||||
|
<div class="option-icon icon-rps"></div>
|
||||||
|
<div class="option-name">猜拳</div>
|
||||||
|
<div class="option-desc">剪刀石頭布</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="game-option"
|
||||||
|
@click="selectGame('ball')"
|
||||||
|
>
|
||||||
|
<div class="option-icon icon-ball"></div>
|
||||||
|
<div class="option-name">接球</div>
|
||||||
|
<div class="option-desc">反應小遊戲</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="close-btn" @click="$emit('close')">取消</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const emit = defineEmits(['close', 'select']);
|
||||||
|
|
||||||
|
function selectGame(gameType) {
|
||||||
|
emit('select', gameType);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.play-menu-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 100;
|
||||||
|
font-family: 'DotGothic16', sans-serif;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-menu-container {
|
||||||
|
background: #f5f5dc;
|
||||||
|
border: 4px solid #8b4513;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 15px;
|
||||||
|
min-width: 200px;
|
||||||
|
max-width: 90%;
|
||||||
|
max-height: 85%;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
overflow-y: auto;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-title {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0 0 12px 0;
|
||||||
|
color: #8b4513;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-options {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-option {
|
||||||
|
background: #fff;
|
||||||
|
border: 3px solid #8b4513;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
text-align: center;
|
||||||
|
font-family: 'DotGothic16', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-option:hover {
|
||||||
|
background: #fffacd;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-option:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin: 0 auto 5px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pixel Art Icons */
|
||||||
|
.icon-training::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: transparent;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
box-shadow:
|
||||||
|
/* Explosion/Impact shape */
|
||||||
|
0 0 0 #ff0000,
|
||||||
|
-2px -2px 0 #ff4400, 2px -2px 0 #ff4400,
|
||||||
|
-3px 0 0 #ff6600, -2px 0 0 #ff4400, 0 0 0 #ff0000, 2px 0 0 #ff4400, 3px 0 0 #ff6600,
|
||||||
|
-2px 2px 0 #ff4400, 2px 2px 0 #ff4400,
|
||||||
|
/* Outer glow */
|
||||||
|
-4px -1px 0 #ffaa00, 4px -1px 0 #ffaa00,
|
||||||
|
-4px 1px 0 #ffaa00, 4px 1px 0 #ffaa00,
|
||||||
|
-1px -4px 0 #ffaa00, 1px -4px 0 #ffaa00,
|
||||||
|
-1px 4px 0 #ffaa00, 1px 4px 0 #ffaa00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-rps::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: transparent;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
box-shadow:
|
||||||
|
/* Fist shape */
|
||||||
|
-1px -3px 0 #ffcc99, 0 -3px 0 #ffcc99, 1px -3px 0 #ffcc99,
|
||||||
|
-2px -2px 0 #ffcc99, -1px -2px 0 #ffcc99, 0 -2px 0 #ffcc99, 1px -2px 0 #ffcc99, 2px -2px 0 #ffcc99,
|
||||||
|
-2px -1px 0 #ffcc99, -1px -1px 0 #ffcc99, 0 -1px 0 #ffcc99, 1px -1px 0 #ffcc99, 2px -1px 0 #ffcc99,
|
||||||
|
-2px 0 0 #ffcc99, -1px 0 0 #ffcc99, 0 0 0 #ffaa77, 1px 0 0 #ffcc99, 2px 0 0 #ffcc99,
|
||||||
|
-2px 1px 0 #ffcc99, -1px 1px 0 #ffcc99, 0 1px 0 #ffcc99, 1px 1px 0 #ffcc99, 2px 1px 0 #ffcc99,
|
||||||
|
-1px 2px 0 #ffcc99, 0 2px 0 #ffcc99, 1px 2px 0 #ffcc99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-ball::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: transparent;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
box-shadow:
|
||||||
|
/* Ball shape */
|
||||||
|
-1px -3px 0 #000, 0 -3px 0 #000, 1px -3px 0 #000,
|
||||||
|
-2px -2px 0 #000, -1px -2px 0 #fff, 0 -2px 0 #fff, 1px -2px 0 #fff, 2px -2px 0 #000,
|
||||||
|
-3px -1px 0 #000, -2px -1px 0 #fff, -1px -1px 0 #fff, 0 -1px 0 #000, 1px -1px 0 #fff, 2px -1px 0 #fff, 3px -1px 0 #000,
|
||||||
|
-3px 0 0 #000, -2px 0 0 #fff, -1px 0 0 #000, 0 0 0 #000, 1px 0 0 #000, 2px 0 0 #fff, 3px 0 0 #000,
|
||||||
|
-3px 1px 0 #000, -2px 1px 0 #fff, -1px 1px 0 #fff, 0 1px 0 #000, 1px 1px 0 #fff, 2px 1px 0 #fff, 3px 1px 0 #000,
|
||||||
|
-2px 2px 0 #000, -1px 2px 0 #fff, 0 2px 0 #fff, 1px 2px 0 #fff, 2px 2px 0 #000,
|
||||||
|
-1px 3px 0 #000, 0 3px 0 #000, 1px 3px 0 #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-name {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #8b4513;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-desc {
|
||||||
|
font-size: 10px;
|
||||||
|
color: #a0522d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
background: #cd853f;
|
||||||
|
border: 3px solid #8b4513;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: 'DotGothic16', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn:hover {
|
||||||
|
background: #d2691e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="top-menu">
|
<div class="top-menu">
|
||||||
<button class="icon-btn icon-stats" @click="$emit('info')" title="Status"></button>
|
<button class="icon-btn icon-stats" @click="$emit('info')" title="Status"></button>
|
||||||
<button class="icon-btn icon-feed" @click="$emit('feed')" :disabled="disabled" title="Feed"></button>
|
<button class="icon-btn icon-feed" @click="$emit('feed')" :disabled="disabled" title="Feed"></button>
|
||||||
<button class="icon-btn icon-play" @click="$emit('play')" :disabled="disabled" title="Play"></button>
|
<button class="icon-btn icon-play" @click="$emit('playMenu')" :disabled="disabled" title="Play"></button>
|
||||||
<button class="icon-btn icon-sleep" @click="$emit('sleep')" :disabled="disabled" title="Sleep"></button>
|
<button class="icon-btn icon-sleep" @click="$emit('sleep')" :disabled="disabled" title="Sleep"></button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -15,7 +15,7 @@ const props = defineProps({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
defineEmits(['info', 'feed', 'play', 'sleep']);
|
defineEmits(['info', 'feed', 'playMenu', 'sleep']);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue