宠物部分
Change-Id: I57d26086523c2588778f55873c36c58a2597d6fc
diff --git a/src/components/pet/index.tsx b/src/components/pet/index.tsx
index c859b68..51871bc 100644
--- a/src/components/pet/index.tsx
+++ b/src/components/pet/index.tsx
@@ -1,91 +1,109 @@
-import React, { useState, useEffect } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
+import styles from './pet.module.css'; // 确保这个路径对
-const petList = [
- {
- id: 'cat01',
- name: '喵喵',
- image: '/pets/cat.png',
- mood: '开心',
- hunger: 50,
- },
- {
- id: 'dog01',
- name: '汪汪',
- image: '/pets/dog.png',
- mood: '饥饿',
- hunger: 70,
- }
-];
+const PetGame: React.FC = () => {
+ const petRef = useRef<HTMLDivElement>(null);
+ const [mood, setMood] = useState(50);
+ const [hunger, setHunger] = useState(50);
-const PetGame = () => {
- const [selectedPetIndex, setSelectedPetIndex] = useState(0);
- const [petStates, setPetStates] = useState(petList);
-
- // 定时每 5 秒减少一点饥饿值
+ // 从 localStorage 恢复状态
useEffect(() => {
- const timer = setInterval(() => {
- setPetStates(prev =>
- prev.map((pet, index) =>
- index === selectedPetIndex
- ? {
- ...pet,
- hunger: Math.min(100, pet.hunger + 2),
- mood: pet.hunger > 80 ? '生气' : pet.mood
- }
- : pet
- )
- );
- }, 5000);
- return () => clearInterval(timer);
- }, [selectedPetIndex]);
+ const saved = localStorage.getItem('petState');
+ if (saved) {
+ const { mood: savedMood, hunger: savedHunger } = JSON.parse(saved);
+ setMood(savedMood);
+ setHunger(savedHunger);
+ }
+ }, []);
+ // 每分钟更新状态并保存
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setMood(prev => {
+ const newMood = Math.min(prev + 1, 100);
+ savePetState(newMood, hunger);
+ return newMood;
+ });
+ setHunger(prev => {
+ const newHunger = Math.max(prev - 1, 0);
+ savePetState(mood, newHunger);
+ return newHunger;
+ });
+ }, 60000); // 每分钟一次
+
+ return () => clearInterval(interval);
+ }, [mood, hunger]);
+
+ // 保存状态到 localStorage
+ const savePetState = (newMood: number, newHunger: number) => {
+ localStorage.setItem('petState', JSON.stringify({ mood: newMood, hunger: newHunger }));
+ };
+
+ // 拖动功能(保留)
+ useEffect(() => {
+ const pet = petRef.current;
+ if (!pet) return;
+
+ let offsetX = 0;
+ let offsetY = 0;
+ let isDragging = false;
+
+ const handleMouseDown = (e: MouseEvent) => {
+ isDragging = true;
+ const rect = pet.getBoundingClientRect();
+ offsetX = e.clientX - rect.left;
+ offsetY = e.clientY - rect.top;
+ };
+
+ const handleMouseMove = (e: MouseEvent) => {
+ if (isDragging && pet) {
+ pet.style.left = `${e.clientX - offsetX}px`;
+ pet.style.top = `${e.clientY - offsetY}px`;
+ }
+ };
+
+ const handleMouseUp = () => {
+ isDragging = false;
+ };
+
+ pet.addEventListener('mousedown', handleMouseDown);
+ document.addEventListener('mousemove', handleMouseMove);
+ document.addEventListener('mouseup', handleMouseUp);
+
+ return () => {
+ pet.removeEventListener('mousedown', handleMouseDown);
+ document.removeEventListener('mousemove', handleMouseMove);
+ document.removeEventListener('mouseup', handleMouseUp);
+ };
+ }, []);
+
+ // 喂食按钮逻辑
const handleFeed = () => {
- setPetStates(prev =>
- prev.map((pet, index) =>
- index === selectedPetIndex
- ? {
- ...pet,
- hunger: Math.max(0, pet.hunger - 20),
- mood: '开心'
- }
- : pet
- )
- );
+ const newHunger = Math.min(hunger + 10, 100);
+ setHunger(newHunger);
+ savePetState(mood, newHunger);
};
- const handlePet = () => {
- setPetStates(prev =>
- prev.map((pet, index) =>
- index === selectedPetIndex
- ? { ...pet, mood: '超级开心' }
- : pet
- )
- );
+ // 互动按钮逻辑
+ const handleInteract = () => {
+ const newMood = Math.min(mood + 10, 100);
+ setMood(newMood);
+ savePetState(newMood, hunger);
};
- const currentPet = petStates[selectedPetIndex];
-
return (
- <div style={{ textAlign: 'center', padding: 20 }}>
- <h2>当前宠物:{currentPet.name}</h2>
- <img
- src={currentPet.image}
- alt={currentPet.name}
- style={{ width: 200, height: 200, cursor: 'pointer' }}
- onClick={handlePet}
- />
- <p>情绪:{currentPet.mood}</p>
- <p>饥饿值:{currentPet.hunger}/100</p>
+ <div className={styles.cardContainer}>
+ <div className={styles.card}>
+ <p className={styles.text}>情绪:{mood}</p>
+ <p className={styles.text}>饥饿值:{hunger}/100</p>
- <button onClick={handleFeed}>🍖 喂食</button>
+ <button className={styles.feedButton} onClick={handleFeed}>
+ 🍖 喂食
+ </button>
- <div style={{ marginTop: 20 }}>
- <h4>切换宠物:</h4>
- {petStates.map((pet, index) => (
- <button key={pet.id} onClick={() => setSelectedPetIndex(index)} style={{ marginRight: 8 }}>
- {pet.name}
- </button>
- ))}
+ <button className={styles.feedButton} onClick={handleInteract}>
+ 🐾 摸摸头 / 玩游戏
+ </button>
</div>
</div>
);
diff --git a/src/components/pet/pet.module.css b/src/components/pet/pet.module.css
new file mode 100644
index 0000000..833729a
--- /dev/null
+++ b/src/components/pet/pet.module.css
@@ -0,0 +1,71 @@
+/* 外部容器:左右布局 */
+.wrapper {
+ background:none;
+ border:none;
+ box-shadow: none;
+ display: flex;
+ align-items: flex-start;
+ justify-content: center;
+ padding: 40px;
+ gap: 60px;
+}
+
+/* 宠物区域 */
+.petSection {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.petImage {
+ width: 200px;
+ height: 200px;
+ object-fit: cover;
+ cursor: pointer;
+ margin-bottom: 12px;
+}
+
+/* 卡片区域:紧跟宠物图下方,模拟右下角 */
+.cardContainer {
+ align-self: flex-end; /* 让它贴底部对齐 */
+ width: 280px;
+}
+
+.card {
+
+ border-radius: 16px;
+
+ padding: 20px;
+}
+
+.text {
+ font-size: 16px;
+ margin: 12px 0;
+ color: #333;
+}
+
+.feedButton {
+ width: 100%;
+ padding: 12px;
+ font-size: 16px;
+ background-color: #ff9800;
+ color: white;
+ border: none;
+ border-radius: 10px;
+ cursor: pointer;
+ margin: 16px 0;
+ transition: background-color 0.2s;
+}
+
+.feedButton:hover {
+ background-color: #fb8c00;
+}
+
+.switchSection {
+ margin-top: 20px;
+}
+
+.switchTitle {
+ font-weight: 600;
+ font-size: 14px;
+}