good version
This commit is contained in:
parent
3c9a7f1e7b
commit
687a83922f
15
src/App.vue
15
src/App.vue
|
|
@ -51,10 +51,19 @@ function handleAction(action) {
|
|||
sleep();
|
||||
break;
|
||||
case 'medicine':
|
||||
// Heal the pet
|
||||
// Heal the pet with animation
|
||||
if (state.value === 'sick') {
|
||||
stats.value.health = 100;
|
||||
state.value = 'idle';
|
||||
if (petGameRef.value) {
|
||||
// Trigger medicine animation
|
||||
petGameRef.value.startFeeding('medicine').then(() => {
|
||||
stats.value.health = 100;
|
||||
state.value = 'idle';
|
||||
});
|
||||
} else {
|
||||
// Fallback if ref not ready
|
||||
stats.value.health = 100;
|
||||
state.value = 'idle';
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'stats':
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
<!-- 食物 -->
|
||||
<div
|
||||
v-if="state === 'eating' && foodVisible"
|
||||
v-if="foodVisible"
|
||||
class="food-item"
|
||||
:style="{
|
||||
left: foodX + 'px',
|
||||
|
|
@ -681,6 +681,8 @@ const foodX = ref(0);
|
|||
const foodY = ref(0);
|
||||
const foodStage = ref(0); // 0, 1, 2
|
||||
const foodVisible = ref(false);
|
||||
const currentFoodType = ref('food'); // 'food' or 'medicine'
|
||||
const isMedicineActive = ref(false);
|
||||
|
||||
// Playing State
|
||||
const ballX = ref(0);
|
||||
|
|
@ -725,6 +727,56 @@ const currentPixels = computed(() => {
|
|||
});
|
||||
|
||||
const currentFoodPixels = computed(() => {
|
||||
if (currentFoodType.value === 'medicine') {
|
||||
// Diagonal Pill Pixel Art
|
||||
const pillPalette = {
|
||||
'B': '#1a1a1a', // Black Outline
|
||||
'R': '#e74c3c', // Red
|
||||
'L': '#ff7979', // Light Red (Highlight)
|
||||
'W': '#ecf0f1', // White
|
||||
'S': '#bdc3c7', // Shadow (Grey)
|
||||
'H': '#ffffff', // Pure White Highlight
|
||||
'0': 'transparent'
|
||||
};
|
||||
|
||||
// 12x12 Grid
|
||||
const pillSprite = [
|
||||
"0000000BBB00",
|
||||
"000000BRRRB0",
|
||||
"00000BRHLRB0",
|
||||
"0000BRRRRRB0",
|
||||
"000BWRRRRB00",
|
||||
"00BWWRRRB000",
|
||||
"0BWWWWRB0000",
|
||||
"0BSWWWWB0000",
|
||||
"00BSSWB00000",
|
||||
"000BBB000000",
|
||||
"000000000000",
|
||||
"000000000000"
|
||||
];
|
||||
|
||||
// Apply stage (bite)
|
||||
const stage = foodStage.value;
|
||||
const pxs = [];
|
||||
pillSprite.forEach((row, y) => {
|
||||
[...row].forEach((ch, x) => {
|
||||
if (ch === '0') return;
|
||||
|
||||
// Bite logic: Eat from bottom-left/bottom
|
||||
// Stage 1: Remove bottom chunk
|
||||
if (stage === 1 && (y > 7 || (y > 5 && x < 4))) return;
|
||||
// Stage 2: Remove most of it
|
||||
if (stage === 2 && y > 4) return;
|
||||
|
||||
pxs.push({
|
||||
x, y,
|
||||
color: pillPalette[ch]
|
||||
});
|
||||
});
|
||||
});
|
||||
return pxs;
|
||||
}
|
||||
|
||||
const sprite = FOOD_SPRITES[foodStage.value];
|
||||
const pxs = [];
|
||||
if(!sprite) return pxs;
|
||||
|
|
@ -774,7 +826,7 @@ function moveRandomly() {
|
|||
}
|
||||
|
||||
console.log('moveRandomly called. State:', props.state);
|
||||
if (props.state === 'sleep' || props.state === 'dead' || props.state === 'eating') {
|
||||
if (props.state === 'sleep' || props.state === 'dead' || props.state === 'eating' || isMedicineActive.value) {
|
||||
updateHeadIconsPosition();
|
||||
return;
|
||||
}
|
||||
|
|
@ -841,10 +893,26 @@ function moveRandomly() {
|
|||
}
|
||||
|
||||
// Feeding Logic
|
||||
async function startFeeding() {
|
||||
// Reset food
|
||||
|
||||
async function startFeeding(type) {
|
||||
console.log('Starting feeding:', type);
|
||||
|
||||
if (type === 'medicine') {
|
||||
currentFoodType.value = 'medicine';
|
||||
isMedicineActive.value = true;
|
||||
} else {
|
||||
// If default feeding, ensure we don't override medicine
|
||||
if (isMedicineActive.value) {
|
||||
console.log('Skipping default feeding because medicine is active');
|
||||
return;
|
||||
}
|
||||
currentFoodType.value = 'food';
|
||||
isMedicineActive.value = false;
|
||||
}
|
||||
|
||||
foodStage.value = 0;
|
||||
foodVisible.value = true;
|
||||
console.log('Food visible:', foodVisible.value);
|
||||
|
||||
// Calculate food position: in front of pet, at mouth height
|
||||
// Food drops in front (not directly at mouth)
|
||||
|
|
@ -886,6 +954,10 @@ async function startFeeding() {
|
|||
// Move pet to food
|
||||
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
|
||||
|
|
@ -938,6 +1010,7 @@ async function startFeeding() {
|
|||
|
||||
// Finish eating
|
||||
foodVisible.value = false;
|
||||
isMedicineActive.value = false;
|
||||
emit('update:state', 'idle');
|
||||
}
|
||||
|
||||
|
|
@ -1030,11 +1103,21 @@ onUnmounted(() => {
|
|||
watch(() => props.state, (newState) => {
|
||||
updateHeadIconsPosition();
|
||||
if (newState === 'eating') {
|
||||
startFeeding();
|
||||
// Only start default feeding if we aren't already doing medicine
|
||||
if (!isMedicineActive.value) {
|
||||
startFeeding();
|
||||
}
|
||||
} else {
|
||||
// Reset feeding state if interrupted
|
||||
isMouthOpen.value = false;
|
||||
foodVisible.value = false;
|
||||
if (newState !== 'eating') {
|
||||
isMouthOpen.value = false;
|
||||
foodVisible.value = false;
|
||||
isMedicineActive.value = false;
|
||||
// Reset type back to food when done
|
||||
if (!foodVisible.value) {
|
||||
currentFoodType.value = 'food';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -1065,7 +1148,8 @@ async function shakeHead() {
|
|||
|
||||
// Expose shakeHead function to parent component
|
||||
defineExpose({
|
||||
shakeHead
|
||||
shakeHead,
|
||||
startFeeding
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue