good version
This commit is contained in:
parent
3c9a7f1e7b
commit
687a83922f
11
src/App.vue
11
src/App.vue
|
|
@ -51,10 +51,19 @@ function handleAction(action) {
|
||||||
sleep();
|
sleep();
|
||||||
break;
|
break;
|
||||||
case 'medicine':
|
case 'medicine':
|
||||||
// Heal the pet
|
// Heal the pet with animation
|
||||||
if (state.value === 'sick') {
|
if (state.value === 'sick') {
|
||||||
|
if (petGameRef.value) {
|
||||||
|
// Trigger medicine animation
|
||||||
|
petGameRef.value.startFeeding('medicine').then(() => {
|
||||||
stats.value.health = 100;
|
stats.value.health = 100;
|
||||||
state.value = 'idle';
|
state.value = 'idle';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback if ref not ready
|
||||||
|
stats.value.health = 100;
|
||||||
|
state.value = 'idle';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'stats':
|
case 'stats':
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
|
|
||||||
<!-- 食物 -->
|
<!-- 食物 -->
|
||||||
<div
|
<div
|
||||||
v-if="state === 'eating' && foodVisible"
|
v-if="foodVisible"
|
||||||
class="food-item"
|
class="food-item"
|
||||||
:style="{
|
:style="{
|
||||||
left: foodX + 'px',
|
left: foodX + 'px',
|
||||||
|
|
@ -681,6 +681,8 @@ const foodX = ref(0);
|
||||||
const foodY = ref(0);
|
const foodY = ref(0);
|
||||||
const foodStage = ref(0); // 0, 1, 2
|
const foodStage = ref(0); // 0, 1, 2
|
||||||
const foodVisible = ref(false);
|
const foodVisible = ref(false);
|
||||||
|
const currentFoodType = ref('food'); // 'food' or 'medicine'
|
||||||
|
const isMedicineActive = ref(false);
|
||||||
|
|
||||||
// Playing State
|
// Playing State
|
||||||
const ballX = ref(0);
|
const ballX = ref(0);
|
||||||
|
|
@ -725,6 +727,56 @@ const currentPixels = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const currentFoodPixels = 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 sprite = FOOD_SPRITES[foodStage.value];
|
||||||
const pxs = [];
|
const pxs = [];
|
||||||
if(!sprite) return pxs;
|
if(!sprite) return pxs;
|
||||||
|
|
@ -774,7 +826,7 @@ function moveRandomly() {
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('moveRandomly called. State:', props.state);
|
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();
|
updateHeadIconsPosition();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -841,10 +893,26 @@ function moveRandomly() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feeding Logic
|
// 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;
|
foodStage.value = 0;
|
||||||
foodVisible.value = true;
|
foodVisible.value = true;
|
||||||
|
console.log('Food visible:', foodVisible.value);
|
||||||
|
|
||||||
// Calculate food position: in front of pet, at mouth height
|
// Calculate food position: in front of pet, at mouth height
|
||||||
// Food drops in front (not directly at mouth)
|
// Food drops in front (not directly at mouth)
|
||||||
|
|
@ -886,6 +954,10 @@ async function startFeeding() {
|
||||||
// Move pet to food
|
// Move pet to food
|
||||||
const targetPetX = isFacingRight.value ? targetFoodX - width - 5 : targetFoodX + (10 * pixelSize) + 5;
|
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
|
// Simple animation sequence
|
||||||
// 1. Drop food
|
// 1. Drop food
|
||||||
// 2. Pet moves to food
|
// 2. Pet moves to food
|
||||||
|
|
@ -938,6 +1010,7 @@ async function startFeeding() {
|
||||||
|
|
||||||
// Finish eating
|
// Finish eating
|
||||||
foodVisible.value = false;
|
foodVisible.value = false;
|
||||||
|
isMedicineActive.value = false;
|
||||||
emit('update:state', 'idle');
|
emit('update:state', 'idle');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1030,11 +1103,21 @@ onUnmounted(() => {
|
||||||
watch(() => props.state, (newState) => {
|
watch(() => props.state, (newState) => {
|
||||||
updateHeadIconsPosition();
|
updateHeadIconsPosition();
|
||||||
if (newState === 'eating') {
|
if (newState === 'eating') {
|
||||||
|
// Only start default feeding if we aren't already doing medicine
|
||||||
|
if (!isMedicineActive.value) {
|
||||||
startFeeding();
|
startFeeding();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Reset feeding state if interrupted
|
// Reset feeding state if interrupted
|
||||||
|
if (newState !== 'eating') {
|
||||||
isMouthOpen.value = false;
|
isMouthOpen.value = false;
|
||||||
foodVisible.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
|
// Expose shakeHead function to parent component
|
||||||
defineExpose({
|
defineExpose({
|
||||||
shakeHead
|
shakeHead,
|
||||||
|
startFeeding
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue