diff --git a/src/App.vue b/src/App.vue
index fb1ebbb..185892a 100644
--- a/src/App.vue
+++ b/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':
diff --git a/src/components/PetGame.vue b/src/components/PetGame.vue
index c5382f6..9a394b8 100644
--- a/src/components/PetGame.vue
+++ b/src/components/PetGame.vue
@@ -62,7 +62,7 @@
{
+ [...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
});