python项目实战 3D宠物狗

Stable Diffusion核心原理与实战部署:从扩散模型到AIGC应用 扩散模型作为生成式AI的核心技术,通过模拟物理扩散的逆过程,实现了从噪声数据中生成高质量内容的能力。其核心原理在于训练一个噪声预测器,通过逐步去噪将随机噪声转化为结构化的图像或数据。这项技术的工程价值在于,通过引入潜空间压缩,大幅降低了高维图像生成的计算复杂度,使得在消费级GPU上运行成为可能,从而推动了AIGC技术的普及。在实际应用场景中,它已成为图像生成、创意设计和内容创作的重要工具。本文聚焦于Stable Diffusion这一开源实现,深入解析其扩散模型与VAE编码器的协同工作机制,并详细介绍基于D 阅读详情

目录

项目架构

pet_model.py

renderer.py

gui.py

main.py

效果展示


项目架构

python3Dpet/
├── main.py                 # 主程序入口
├── pet/
│   └── pet_model.py       # 宠物逻辑模型
├── graphics/
│   └── renderer.py        # 3D渲染引擎
├── ui/
│   └── gui.py            # 用户界面系统
└── README.md             # 项目说明文档

pet_model.py

"""
Virtual Pet Model - Compact Version
"""

import time
import random
from typing import Dict, Any, List

class VirtualDog:
    """虚拟小狗"""
    
    def __init__(self, name: str = "Buddy"):
        # 基本信息
        self.name = name
        self.level = 1
        self.age = 0
        self.experience = 0
        
        # 核心属性 (0-100)
        self.hunger = 50.0
        self.happiness = 50.0
        self.health = 100.0
        self.energy = 100.0
        self.cleanliness = 100.0
        
        # 状态
        self.mood = "neutral"
        self.is_sleeping = False
        self.last_update = time.time()
        
        # 统计
        self.total_food_eaten = 0
        self.times_petted = 0
        
        # 衰减速率
        self.decay_rates = {'hunger': 0.8, 'happiness': 0.3, 'health': 0.1, 'energy': 0.5, 'cleanliness': 0.2}
        
        print(f"Created virtual dog: {name}")
    
    def update(self) -> Dict[str, Any]:
        """更新宠物状态"""
        current_time = time.time()
        dt = min(current_time - self.last_update, 10.0)
        
        old_mood = self.mood
        self._apply_decay(dt)
        self._update_mood()
        self._update_level()
        
        self.last_update = current_time
        
        return {'mood_changed': (old_mood, self.mood)} if self.mood != old_mood else {}
    
    def _apply_decay(self, dt: float):
        """应用属性衰减"""
        self.hunger = min(100, self.hunger + self.decay_rates['hunger'] * dt)
        self.happiness = max(0, self.happiness - self.decay_rates['happiness'] * dt)
        self.energy = max(0, self.energy - self.decay_rates['energy'] * dt)
        self.cleanliness = max(0, self.cleanliness - self.decay_rates['cleanliness'] * dt)
        
        # 健康衰减
        health_decay = self.decay_rates['health'] * dt
        if self.hunger > 80: health_decay *= 3
        if self.cleanliness < 20: health_decay *= 2
        self.health = max(0, self.health - health_decay)
    
    def _update_mood(self):
        """更新心情"""
        if self.health < 30: self.mood = "sick"
        elif self.hunger > 80: self.mood = "hungry"
        elif self.energy < 20: self.mood = "sleepy"
        elif self.happiness > 85 and self.energy > 70: self.mood = "excited"
        elif self.happiness > 70 and self.health > 60: self.mood = "happy"
        elif self.happiness < 30 or self.health < 40: self.mood = "sad"
        else: self.mood = "neutral"
    
    def _update_level(self):
        """更新等级"""
        if self.experience >= self.level * 100:
            self.level += 1
            print(f"{self.name} leveled up to level {self.level}!")
    
    def feed(self, food_type: str = "regular") -> Dict[str, Any]:
        """喂食"""
        if self.is_sleeping:
            return {'success': False, 'message': f"{self.name} is sleeping!"}
        if self.hunger < 10:
            return {'success': False, 'message': f"{self.name} is not hungry right now"}
        
        # 应用效果
        hunger_reduction = 25 if food_type == "regular" else 15
        happiness_boost = 5 if food_type == "regular" else 15
        
        self.hunger = max(0, self.hunger - hunger_reduction)
        self.happiness = min(100, self.happiness + happiness_boost)
        self.experience += 10
        self.total_food_eaten += 1
        
        return {'success': True, 'message': f"{self.name} enjoyed the meal! Woof!"}
    
    def play(self, game_type: str = "fetch") -> Dict[str, Any]:
        """玩耍"""
        if self.is_sleeping:
            return {'success': False, 'message': f"{self.name} is sleeping!"}
        if self.energy < 10:
            return {'success': False, 'message': f"{self.name} is too tired to play!"}
        
        # 应用效果
        happiness_boost = 25 if game_type == "fetch" else 20
        energy_cost = 20 if game_type == "fetch" else 15
        
        self.happiness = min(100, self.happiness + happiness_boost)
        self.energy = max(0, self.energy - energy_cost)
        self.experience += 15
        
        messages = [f"{self.name} runs around happily! Woof!", f"{self.name} wags tail excitedly!",
                   f"{self.name} jumps with joy!", f"{self.name} loves playing with you!"]
        
        return {'success': True, 'message': random.choice(messages)}
    
    def pet(self) -> Dict[str, Any]:
        """抚摸"""
        self.happiness = min(100, self.happiness + 10)
        self.experience += 5
        self.times_petted += 1
        
        messages = [f"{self.name} purrs contentedly!", f"{self.name} nuzzles against your hand!",
                   f"{self.name} looks at you with loving eyes!", f"{self.name} wags tail gently!"]
        
        return {'success': True, 'message': random.choice(messages)}
    
    def clean(self) -> Dict[str, Any]:
        """清洁"""
        if self.cleanliness > 95:
            return {'success': False, 'message': f"{self.name} is already very clean!"}
        
        self.cleanliness = min(100, self.cleanliness + 30)
        self.health = min(100, self.health + 5)
        self.experience += 8
        
        return {'success': True, 'message': f"{self.name} is now squeaky clean!"}
    
    def toggle_sleep(self) -> Dict[str, Any]:
        """切换睡眠"""
        self.is_sleeping = not self.is_sleeping
        
        if self.is_sleeping:
            return {'success': True, 'message': f"{self.name} curls up and falls asleep..."}
        else:
            self.energy = min(100, self.energy + 20)
            return {'success': True, 'message': f"{self.name} stretches and wakes up!"}
    
    def get_status_summary(self) -> Dict[str, Any]:
        """获取状态摘要"""
        return {
            'name': self.name, 'type': 'dog', 'level': self.level, 'age': self.age,
            'mood': self.mood, 'is_sleeping': self.is_sleeping,
            'stats': {'hunger': self.hunger, 'happiness': self.happiness, 'health': self.health,
                     'energy': self.energy, 'cleanliness': self.cleanliness},
            'experience': self.experience, 'total_food_eaten': self.total_food_eaten,
            'times_petted': self.times_petted
        }
    
    def get_detailed_info(self) -> str:
        """获取详细信息"""
        return f"""=== {self.name} the Dog ===
Level: {self.level} | Age: {self.age} days | Experience: {self.experience}
Mood: {self.mood} | Sleeping: {'Yes' if self.is_sleeping else 'No'}

=== Stats ===
Hunger: {self.hunger:.1f}/100 | Happiness: {self.happiness:.1f}/100
Health: {self.health:.1f}/100 | Energy: {self.energy:.1f}/100
Cleanliness: {self.cleanliness:.1f}/100

=== Statistics ===
Total food eaten: {self.total_food_eaten} | Times petted: {self.times_petted}"""
    
    def needs_attention(self) -> List[str]:
        """需要注意的事项"""
        needs = []
        if self.hunger > 80: needs.append("Very hungry - needs food!")
        elif self.hunger > 60: needs.append("Getting hungry")
        
        if self.happiness < 20: needs.append("Very sad - needs attention!")
        elif self.happiness < 40: needs.append("Feeling down")
        
        if self.health < 30: needs.append("Poor health - needs care!")
        elif self.health < 50: needs.append("Health declining")
        
        if self.energy < 20 and not self.is_sleeping: needs.append("Very tired - should sleep")
        elif self.energy < 40: needs.append("Getting tired")
        
        if self.cleanliness < 20: needs.append("Very dirty - needs cleaning!")
        elif self.cleanliness < 40: needs.append("Getting dirty")
        
        return needs
    
    def get_mood_description(self) -> str:
        """获取心情描述"""
        descriptions = {
            'happy': f"{self.name} is wagging tail and looking content!",
            'sad': f"{self.name} looks down and needs some love...",
            'excited': f"{self.name} is bouncing around with energy!",
            'sleepy': f"{self.name} is yawning and looking drowsy...",
            'hungry': f"{self.name} is looking at you hopefully for food!",
            'neutral': f"{self.name} is calm and relaxed.",
            'sick': f"{self.name} doesn't look well and needs care..."
        }
        return descriptions.get(self.mood, f"{self.name} seems okay.")

# 工厂函数和名字列表
def create_virtual_dog(name: str = "Buddy") -> VirtualDog:
    """创建虚拟小狗"""
    return VirtualDog(name)

DOG_NAMES = ["Buddy", "Max", "Charlie", "Cooper", "Rocky", "Bear", "Tucker", "Duke",
             "Jack", "Toby", "Oliver", "Riley", "Zeus", "Leo", "Henry", "Bentley"]

def get_random_dog_name() -> str:
    """获取随机名字"""
    return random.choice(DOG_NAMES)

renderer.py

"""
3D渲染器
"""

import pygame
import math
import random
from typing import Dict, Any

class CuteDog3D:
    """可爱3D小狗"""
    
    def __init__(self):
        self.animation_time = 0.0
        self.bounce_height = 0.0
        self.tail_swing = 0.0
        self.ear_twitch = 0.0
        self.is_blinking = False
        self.blink_timer = 0.0
        
        # 颜色主题
        self.colors = {
            'body': (220, 180, 140), 'accent': (180, 140, 100), 'belly': (255, 220, 180),
            'ears': (200, 160, 120), 'eyes': (80, 50, 30), 'nose': (50, 50, 50),
            'tongue': (255, 120, 150), 'paws': (140, 100, 60), 'highlight': (255, 240, 200)
        }
    
    def update(self, dt: float, mood: str, is_sleeping: bool):
        """更新动画"""
        self.animation_time += dt
        self.blink_timer += dt
        
        # 眨眼
        if self.blink_timer > 3.0:
            self.is_blinking = True
            if self.blink_timer > 3.2:
                self.is_blinking = False
                self.blink_timer = 0.0
        
        # 根据心情调整动画
        if mood in ['happy', 'excited']:
            self.bounce_height = math.sin(self.animation_time * 4) * 15
            self.tail_swing = math.sin(self.animation_time * 10) * 60
            self.ear_twitch = math.sin(self.animation_time * 6) * 8
        elif mood == 'sad':
            self.bounce_height = -8
            self.tail_swing = 20
            self.ear_twitch = -15
        elif is_sleeping:
            self.bounce_height = math.sin(self.animation_time * 3) * 3
            self.tail_swing = 30
            self.ear_twitch = -5
        else:
            self.bounce_height = math.sin(self.animation_time * 2) * 5
            self.tail_swing = math.sin(self.animation_time * 4) * 40 + 30
            self.ear_twitch = math.sin(self.animation_time * 3) * 5
    
    def draw_body(self, surface, center_x, center_y, scale=1.0):
        """绘制身体"""
        body_width, body_height = int(160 * scale), int(100 * scale)
        body_y = center_y + int(self.bounce_height)
        
        # 阴影
        shadow_rect = pygame.Rect(center_x - body_width//2 + 6, body_y - body_height//2 + 6, body_width, body_height)
        shadow_surface = pygame.Surface((body_width, body_height), pygame.SRCALPHA)
        shadow_surface.fill((0, 0, 0, 60))
        surface.blit(shadow_surface, shadow_rect.topleft)
        
        # 身体
        body_rect = pygame.Rect(center_x - body_width//2, body_y - body_height//2, body_width, body_height)
        pygame.draw.ellipse(surface, self.colors['body'], body_rect)
        pygame.draw.ellipse(surface, self.colors['accent'], body_rect, 3)
        
        # 高光
        highlight_rect = pygame.Rect(center_x - body_width//3, body_y - body_height//2 + 10, body_width//2, body_height//3)
        highlight_surface = pygame.Surface(highlight_rect.size, pygame.SRCALPHA)
        pygame.draw.ellipse(highlight_surface, (*self.colors['highlight'], 120), (0, 0, highlight_rect.width, highlight_rect.height))
        surface.blit(highlight_surface, highlight_rect.topleft)
        
        # 肚子
        belly_rect = pygame.Rect(center_x - 50, body_y - 30 + 20, 100, 60)
        pygame.draw.ellipse(surface, self.colors['belly'], belly_rect)
        
        return body_y
    
    def draw_head(self, surface, center_x, body_y, scale, mood, is_sleeping):
        """绘制头部"""
        head_radius = int(60 * scale)
        head_y = body_y - int(80 * scale) + int(self.bounce_height * 0.5)
        
        # 头部阴影和主体
        pygame.draw.circle(surface, (0, 0, 0, 40), (center_x + 5, head_y + 5), head_radius)
        pygame.draw.circle(surface, self.colors['body'], (center_x, head_y), head_radius)
        pygame.draw.circle(surface, self.colors['accent'], (center_x, head_y), head_radius, 4)
        
        # 嘴巴
        snout_x, snout_y = center_x + 35, head_y + 15
        snout_rect = pygame.Rect(snout_x - 25, snout_y - 17, 50, 35)
        pygame.draw.ellipse(surface, self.colors['accent'], snout_rect)
        
        # 耳朵
        for i, ear_x in enumerate([center_x - 30, center_x + 30]):
            ear_y = head_y - 35 + (self.ear_twitch if i == 0 else -self.ear_twitch * 0.7)
            ear_points = [(ear_x, ear_y + 20), (ear_x - 12, ear_y - 50), (ear_x + 12, ear_y - 50)]
            pygame.draw.polygon(surface, self.colors['ears'], ear_points)
            pygame.draw.polygon(surface, self.colors['accent'], ear_points, 3)
        
        # 眼睛
        eye_radius, eye_offset = 18, 25
        for eye_x in [center_x - eye_offset, center_x + eye_offset]:
            if is_sleeping or self.is_blinking:
                pygame.draw.arc(surface, (50, 50, 50), (eye_x - eye_radius, head_y - 18, eye_radius * 2, 6), 0, math.pi, 4)
            else:
                pygame.draw.circle(surface, (255, 255, 255), (eye_x, head_y - 15), eye_radius)
                pygame.draw.circle(surface, self.colors['eyes'], (eye_x, head_y - 15), 12)
                pygame.draw.circle(surface, (255, 255, 255), (eye_x - 4, head_y - 19), 6)
        
        # 鼻子
        pygame.draw.circle(surface, self.colors['nose'], (snout_x, snout_y - 8), 10)
        pygame.draw.circle(surface, (120, 120, 120), (snout_x - 3, snout_y - 11), 4)
        
        # 舌头(开心时)
        if not is_sleeping and mood in ['happy', 'excited']:
            tongue_rect = pygame.Rect(snout_x - 10, snout_y + 5, 20, 25)
            pygame.draw.ellipse(surface, self.colors['tongue'], tongue_rect)
        
        return head_y
    
    def draw_tail(self, surface, center_x, body_y, scale):
        """绘制尾巴"""
        tail_length, tail_width = 80, 20
        tail_base_x, tail_base_y = center_x - 70, body_y - 15
        
        # 计算尾巴末端
        swing_angle = max(-90, min(-10, -45 + self.tail_swing))
        tail_angle_rad = math.radians(swing_angle)
        tail_end_x = tail_base_x + int(tail_length * math.cos(tail_angle_rad))
        tail_end_y = tail_base_y + int(tail_length * math.sin(tail_angle_rad))
        
        # 绘制尾巴段
        for i in range(15):
            t = i / 14
            seg_x = int(tail_base_x + (tail_end_x - tail_base_x) * t)
            seg_y = int(tail_base_y + (tail_end_y - tail_base_y) * t)
            seg_size = int(tail_width * (1 - t * 0.5))
            
            tail_color = tuple(int(c * (1 - t * 0.3)) for c in self.colors['accent'])
            pygame.draw.circle(surface, tail_color, (seg_x, seg_y), seg_size)
    
    def draw_legs(self, surface, center_x, body_y, scale):
        """绘制腿部"""
        leg_positions = [(center_x - 45, 25), (center_x + 45, 25), (center_x - 25, 20), (center_x + 25, 20)]
        
        for i, (leg_x, leg_width) in enumerate(leg_positions):
            leg_height = 35
            leg_y = body_y + 35
            
            # 腿部
            leg_rect = pygame.Rect(leg_x - leg_width//2, leg_y - leg_height//2, leg_width, leg_height)
            color = self.colors['accent'] if i < 2 else self.colors['body']
            pygame.draw.ellipse(surface, color, leg_rect)
            
            # 爪子
            paw_radius = 12 if i < 2 else 10
            paw_y = leg_y + leg_height//2
            pygame.draw.circle(surface, self.colors['paws'], (leg_x, paw_y), paw_radius)
    
    def draw_special_effects(self, surface, center_x, center_y, scale, mood):
        """绘制特效"""
        if mood in ['happy', 'excited']:
            # 爱心特效
            for i in range(3):
                heart_x = center_x + random.randint(-60, 60)
                heart_y = center_y - 120 + random.randint(-15, 15) + int(math.sin(self.animation_time * 3 + i) * 12)
                
                for dx, dy in [(-6, 0), (6, 0), (0, 8)]:
                    pygame.draw.circle(surface, (255, 150, 180), (heart_x + dx, heart_y + dy), 8)

class Simple3DRenderer:
    """简化3D渲染器"""
    
    def __init__(self, width=1200, height=800):
        self.width, self.height = width, height
        self.screen = pygame.display.set_mode((width, height))
        pygame.display.set_caption("Virtual Pet - Cute Dog 3D View")
        
        # 相机参数
        self.camera_distance = 200
        self.camera_angle_x = 15
        self.camera_angle_y = 0
        self.zoom_factor = 1.5
        self.min_zoom, self.max_zoom = 0.8, 4.0
        
        # 鼠标拖拽
        self.is_dragging = False
        self.last_mouse_pos = (0, 0)
        self.drag_sensitivity = 0.3
        
        self.dog_model = CuteDog3D()
        self.bg_colors = {'top': (135, 206, 250), 'bottom': (144, 238, 144)}
        
        print("✅ 3D渲染器初始化完成")
    
    def handle_zoom(self, zoom_delta):
        """处理缩放"""
        zoom_speed = 0.15
        if zoom_delta > 0:
            self.zoom_factor = min(self.max_zoom, self.zoom_factor + zoom_speed)
        else:
            self.zoom_factor = max(self.min_zoom, self.zoom_factor - zoom_speed)
    
    def start_drag(self, mouse_pos):
        """开始拖拽"""
        self.is_dragging = True
        self.last_mouse_pos = mouse_pos
    
    def end_drag(self):
        """结束拖拽"""
        self.is_dragging = False
    
    def update_drag(self, mouse_pos):
        """更新拖拽"""
        if not self.is_dragging:
            return
        
        dx = mouse_pos[0] - self.last_mouse_pos[0]
        dy = mouse_pos[1] - self.last_mouse_pos[1]
        
        self.camera_angle_y += dx * self.drag_sensitivity
        self.camera_angle_x += dy * self.drag_sensitivity
        self.camera_angle_x = max(-45, min(45, self.camera_angle_x))
        self.camera_angle_y = self.camera_angle_y % 360
        
        self.last_mouse_pos = mouse_pos
    
    def draw_gradient_background(self):
        """绘制渐变背景"""
        for y in range(self.height):
            ratio = y / self.height
            r = int(self.bg_colors['top'][0] * (1 - ratio) + self.bg_colors['bottom'][0] * ratio)
            g = int(self.bg_colors['top'][1] * (1 - ratio) + self.bg_colors['bottom'][1] * ratio)
            b = int(self.bg_colors['top'][2] * (1 - ratio) + self.bg_colors['bottom'][2] * ratio)
            pygame.draw.line(self.screen, (r, g, b), (0, y), (self.width, y))
    
    def draw_ground(self):
        """绘制地面"""
        ground_center = (self.width // 2, self.height - 100)
        ground_radius = int(100 * self.zoom_factor)
        
        # 地面阴影
        shadow_radius = int(120 * self.zoom_factor)
        shadow_surface = pygame.Surface((shadow_radius * 2, shadow_radius * 2), pygame.SRCALPHA)
        for i in range(shadow_radius):
            alpha = int(30 * (1 - i / shadow_radius))
            pygame.draw.circle(shadow_surface, (0, 0, 0, alpha), (shadow_radius, shadow_radius), shadow_radius - i)
        
        shadow_rect = shadow_surface.get_rect(center=(ground_center[0], ground_center[1] + 20))
        self.screen.blit(shadow_surface, shadow_rect)
        
        # 主地面
        pygame.draw.circle(self.screen, (100, 180, 100), ground_center, ground_radius)
    
    def render(self, pet_status: Dict[str, Any]):
        """渲染场景"""
        # 背景和地面
        self.draw_gradient_background()
        self.draw_ground()
        
        # 更新小狗
        mood = pet_status.get('mood', 'neutral')
        is_sleeping = pet_status.get('is_sleeping', False)
        self.dog_model.update(0.016, mood, is_sleeping)
        
        # 绘制小狗
        center_x, center_y = self.width // 2, self.height // 2 - 50
        scale = self.zoom_factor
        
        # 按顺序绘制各部分
        self.dog_model.draw_tail(self.screen, center_x, center_y, scale)
        body_y = self.dog_model.draw_body(self.screen, center_x, center_y, scale)
        self.dog_model.draw_legs(self.screen, center_x, body_y, scale)
        head_y = self.dog_model.draw_head(self.screen, center_x, body_y, scale, mood, is_sleeping)
        self.dog_model.draw_special_effects(self.screen, center_x, center_y, scale, mood)
        
        # 状态指示器
        self._draw_status_indicators(pet_status, center_x, head_y - 80)
        self._draw_controls_hint()
        self._draw_zoom_indicator()
    
    def _draw_status_indicators(self, pet_status, x, y):
        """绘制状态指示器"""
        mood = pet_status.get('mood', 'neutral')
        is_sleeping = pet_status.get('is_sleeping', False)
        name = pet_status.get('name', 'Buddy')
        
        # 状态文字
        if is_sleeping:
            status_text = f"{name}: Sleeping..."
            bg_color = (100, 100, 200, 180)
        else:
            mood_texts = {'happy': 'Happy!', 'sad': 'Feeling sad...', 'excited': 'So excited!',
                         'sleepy': 'Getting sleepy...', 'hungry': 'Hungry!', 'neutral': 'Feeling good'}
            status_text = f"{name}: {mood_texts.get(mood, 'Doing well')}"
            
            mood_colors = {'happy': (50, 200, 50, 180), 'sad': (200, 50, 50, 180), 'excited': (255, 200, 50, 180),
                          'sleepy': (150, 150, 200, 180), 'hungry': (255, 150, 100, 180), 'neutral': (150, 150, 150, 180)}
            bg_color = mood_colors.get(mood, (150, 150, 150, 180))
        
        # 绘制状态框
        font = pygame.font.Font(None, 24)
        text_surface = font.render(status_text, True, (255, 255, 255))
        text_rect = text_surface.get_rect(center=(x, y))
        
        padding = 20
        bg_width, bg_height = text_rect.width + padding * 2, text_rect.height + padding
        bg_surface = pygame.Surface((bg_width, bg_height), pygame.SRCALPHA)
        
        # 圆角矩形
        corner_radius = 15
        pygame.draw.rect(bg_surface, bg_color, (corner_radius, 0, bg_width - 2*corner_radius, bg_height))
        pygame.draw.rect(bg_surface, bg_color, (0, corner_radius, bg_width, bg_height - 2*corner_radius))
        
        for corner_x, corner_y in [(corner_radius, corner_radius), (bg_width - corner_radius, corner_radius),
                                  (corner_radius, bg_height - corner_radius), (bg_width - corner_radius, bg_height - corner_radius)]:
            pygame.draw.circle(bg_surface, bg_color, (corner_x, corner_y), corner_radius)
        
        bg_rect = pygame.Rect(x - bg_width//2, y - bg_height//2, bg_width, bg_height)
        self.screen.blit(bg_surface, bg_rect.topleft)
        self.screen.blit(text_surface, text_rect)
    
    def _draw_controls_hint(self):
        """绘制控制提示"""
        font = pygame.font.Font(None, 16)
        hints = ["Mouse: Drag to rotate", "Wheel: Zoom", "ESC: Quit"]
        
        hint_width, hint_height = 200, len(hints) * 18 + 10
        hint_x, hint_y = 10, self.height - hint_height - 10
        
        # 背景
        hint_bg = pygame.Surface((hint_width, hint_height), pygame.SRCALPHA)
        hint_bg.fill((0, 0, 0, 100))
        self.screen.blit(hint_bg,(hint_x, hint_y))
        # 绘制边框
        pygame.draw.rect(self.screen, (255, 255, 255, 120), (hint_x, hint_y, hint_width, hint_height), 1)
        
        y_offset = hint_y + 8
        for hint in hints:
            text_surface = font.render(hint, True, (255, 255, 255))
            shadow_surface = font.render(hint, True, (0, 0, 0))
            self.screen.blit(shadow_surface, (hint_x + 6, y_offset + 1))
            self.screen.blit(text_surface, (hint_x + 5, y_offset))
            y_offset += 18
    
    def _draw_zoom_indicator(self):
        """绘制缩放指示器"""
        zoom_bar_width, zoom_bar_height = 100, 10
        zoom_bar_x, zoom_bar_y = self.width - zoom_bar_width - 20, 20
        
        # 背景
        zoom_bg = pygame.Surface((zoom_bar_width + 10, zoom_bar_height + 20), pygame.SRCALPHA)
        zoom_bg.fill((0, 0, 0, 120))
        self.screen.blit(zoom_bg, (zoom_bar_x - 5, zoom_bar_y - 5))
        
        # 缩放条
        pygame.draw.rect(self.screen, (100, 100, 100), (zoom_bar_x, zoom_bar_y + 10, zoom_bar_width, zoom_bar_height))
        
        # 当前缩放位置
        zoom_ratio = (self.zoom_factor - self.min_zoom) / (self.max_zoom - self.min_zoom)
        zoom_pos = int(zoom_ratio * zoom_bar_width)
        pygame.draw.rect(self.screen, (255, 255, 100), (zoom_bar_x, zoom_bar_y + 10, zoom_pos, zoom_bar_height))
        
        # 缩放文字
        font = pygame.font.Font(None, 16)
        zoom_text = f"Zoom: {self.zoom_factor:.1f}x"
        text_surface = font.render(zoom_text, True, (255, 255, 255))
        self.screen.blit(text_surface, (zoom_bar_x, zoom_bar_y - 5))

gui.py

"""
Virtual Pet GUI
"""

import pygame
import time
import math
from typing import Callable, Dict, Any, List, Tuple

class InteractionItem:
    """交互项"""
    
    def __init__(self, x, y, width, height, text, key, callback=None):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.key = key
        self.callback = callback
        self.hovered = False
        self.enabled = True
        
        # 颜色
        self.colors = {
            'normal': (40, 40, 40), 'hovered': (80, 80, 80), 'disabled': (20, 20, 20),
            'border': (150, 150, 150), 'text': (255, 255, 255), 'text_disabled': (100, 100, 100),
            'key': (255, 255, 0)
        }
    
    def update(self, mouse_pos):
        """更新悬停状态"""
        self.hovered = self.rect.collidepoint(mouse_pos) and self.enabled
    
    def draw(self, surface, font):
        """绘制交互项"""
        # 选择颜色
        if not self.enabled:
            bg_color, text_color = self.colors['disabled'], self.colors['text_disabled']
        elif self.hovered:
            bg_color, text_color = self.colors['hovered'], self.colors['text']
        else:
            bg_color, text_color = self.colors['normal'], self.colors['text']
        
        # 绘制背景
        pygame.draw.rect(surface, bg_color, self.rect)
        pygame.draw.rect(surface, self.colors['border'], self.rect, 1)
        
        # 绘制快捷键
        key_text = f"[{self.key}]"
        key_surface = font.render(key_text, True, self.colors['key'])
        key_rect = key_surface.get_rect(midleft=(self.rect.x + 10, self.rect.centery))
        surface.blit(key_surface, key_rect)
        
        # 绘制主文字
        text_surface = font.render(self.text, True, text_color)
        text_rect = text_surface.get_rect(midleft=(self.rect.x + 50, self.rect.centery))
        surface.blit(text_surface, text_rect)
        
        # 悬停效果
        if self.hovered:
            pygame.draw.rect(surface, (255, 255, 255), self.rect, 2)
    
    def handle_click(self, mouse_pos):
        """处理点击"""
        return self.rect.collidepoint(mouse_pos) and self.enabled

class StatusBar:
    """状态条"""
    
    def __init__(self, x, y, width, height, label, color):
        self.rect = pygame.Rect(x, y, width, height)
        self.label = label
        self.color = color
        self.value = 0.0
        self.max_value = 100.0
        self.target_value = 0.0
        self.animation_speed = 2.0
        
        # 颜色
        self.bg_color = (40, 40, 40)
        self.border_color = (200, 200, 200)
        self.text_color = (255, 255, 255)
    
    def set_value(self, value):
        """设置目标值"""
        self.target_value = max(0, min(self.max_value, value))
    
    def update(self, dt):
        """更新动画"""
        if abs(self.value - self.target_value) > 0.1:
            diff = self.target_value - self.value
            self.value += diff * self.animation_speed * dt
        else:
            self.value = self.target_value
    
    def draw(self, surface, font):
        """绘制状态条"""
        # 背景
        pygame.draw.rect(surface, self.bg_color, self.rect)
        
        # 填充部分
        fill_width = int((self.value / self.max_value) * self.rect.width)
        if fill_width > 0:
            fill_rect = pygame.Rect(self.rect.x, self.rect.y, fill_width, self.rect.height)
            intensity = max(0.3, self.value / self.max_value)
            bar_color = tuple(int(c * intensity) for c in self.color)
            pygame.draw.rect(surface, bar_color, fill_rect)
            
            # 高光效果
            if fill_width > 4:
                gloss_rect = pygame.Rect(fill_rect.x, fill_rect.y, fill_rect.width, fill_rect.height // 3)
                gloss_color = tuple(min(255, c + 40) for c in bar_color)
                gloss_surface = pygame.Surface(gloss_rect.size, pygame.SRCALPHA)
                gloss_surface.fill((*gloss_color, 128))
                surface.blit(gloss_surface, gloss_rect)
        
        # 边框
        pygame.draw.rect(surface, self.border_color, self.rect, 2)
        
        # 标签
        label_surface = font.render(self.label, True, self.text_color)
        label_rect = label_surface.get_rect(midleft=(self.rect.x - 80, self.rect.centery))
        surface.blit(label_surface, label_rect)
        
        # 数值
        value_text = f"{int(self.value)}"
        value_surface = font.render(value_text, True, self.text_color)
        value_rect = value_surface.get_rect(midleft=(self.rect.right + 8, self.rect.centery))
        surface.blit(value_surface, value_rect)

class MessageBox:
    """消息框"""
    
    def __init__(self, text, duration=3.0):
        self.text = text
        self.duration = duration
        self.start_time = time.time()
        self.alpha = 255
        self.slide_offset = 50
        self.current_offset = self.slide_offset
    
    def update(self, dt):
        """更新动画"""
        elapsed = time.time() - self.start_time
        
        # 滑入动画
        if self.current_offset > 0:
            self.current_offset = max(0, self.current_offset - dt * 150)
        
        # 淡出动画
        fade_start = self.duration - 1.0
        if elapsed > fade_start:
            fade_progress = (elapsed - fade_start) / (self.duration - fade_start)
            self.alpha = int(255 * (1 - fade_progress))
    
    def is_expired(self):
        """检查是否过期"""
        return time.time() - self.start_time > self.duration
    
    def draw(self, surface, font, x, y):
        """绘制消息框"""
        if self.alpha <= 0:
            return
        
        text_surface = font.render(self.text, True, (255, 255, 255))
        padding = 15
        box_width = text_surface.get_width() + padding * 2
        box_height = text_surface.get_height() + padding * 2
        draw_y = y + self.current_offset
        
        # 背景
        box_surface = pygame.Surface((box_width, box_height), pygame.SRCALPHA)
        box_color = (0, 0, 0, min(200, self.alpha))
        box_surface.fill(box_color)
        
        box_rect = pygame.Rect(x - box_width // 2, draw_y - box_height // 2, box_width, box_height)
        surface.blit(box_surface, box_rect.topleft)
        
        # 边框
        border_surface = pygame.Surface((box_width, box_height), pygame.SRCALPHA)
        pygame.draw.rect(border_surface, (255, 255, 255, min(255, self.alpha)), border_surface.get_rect(), 2)
        surface.blit(border_surface, box_rect.topleft)
        
        # 文字
        text_surface.set_alpha(self.alpha)
        text_rect = text_surface.get_rect(center=box_rect.center)
        surface.blit(text_surface, text_rect)

class VirtualPetGUI:
    """虚拟宠物GUI - 精简版"""
    
    def __init__(self, screen):
        self.screen = screen
        self.width = screen.get_width()
        self.height = screen.get_height()
        
        # 字体
        pygame.font.init()
        try:
            self.font_large = pygame.font.Font(None, 28)
            self.font_medium = pygame.font.Font(None, 18)
            self.font_small = pygame.font.Font(None, 14)
        except:
            self.font_large = pygame.font.SysFont('arial', 28)
            self.font_medium = pygame.font.SysFont('arial', 18)
            self.font_small = pygame.font.SysFont('arial', 14)
        
        # 面板区域 - 调整避免重叠
        self.status_panel_rect = pygame.Rect(20, 20, 300, 220)
        self.interaction_panel_rect = pygame.Rect(self.width - 260, 20, 240, 280)
        
        # 组件容器
        self.interaction_items = {}
        self.status_bars = {}
        self.messages = []
        
        # 创建UI组件
        self._create_interaction_items()
        self._create_status_bars()
        
        # 动画属性
        self.animation_time = 0.0
        self.panel_alpha = 0
        self.target_panel_alpha = 180
        
        print("GUI初始化完成")
    
    def _create_interaction_items(self):
        """创建交互项"""
        item_width, item_height = 200, 32
        start_x = self.interaction_panel_rect.x + 15
        start_y = self.interaction_panel_rect.y + 45
        item_spacing = 36
        
        configs = [
            ('feed', '1', 'Feed (+5 Hunger)'),
            ('play', '2', 'Play (+5 Happiness)'),
            ('pet', '3', 'Pet (+5 Happiness)'),
            ('clean', '4', 'Clean (+5 Cleanliness)'),
            ('sleep', '5', 'Sleep/Wake')
        ]
        
        for i, (name, key, text) in enumerate(configs):
            y = start_y + i * item_spacing
            self.interaction_items[name] = InteractionItem(start_x, y, item_width, item_height, text, key)
    
    def _create_status_bars(self):
        """创建状态条"""
        bar_width, bar_height = 140, 12
        start_x = self.status_panel_rect.x + 100
        start_y = self.status_panel_rect.y + 120
        bar_spacing = 18
        
        configs = [
            ('hunger', start_y, 'Hunger', (255, 165, 0)),
            ('happiness', start_y + bar_spacing, 'Happy', (255, 255, 0)),
            ('health', start_y + bar_spacing * 2, 'Health', (0, 255, 0)),
            ('energy', start_y + bar_spacing * 3, 'Energy', (0, 150, 255)),
            ('cleanliness', start_y + bar_spacing * 4, 'Clean', (150, 200, 255))
        ]
        
        for name, y, label, color in configs:
            self.status_bars[name] = StatusBar(start_x, y, bar_width, bar_height, label, color)
    
    def set_interaction_callback(self, item_name, callback):
        """设置回调函数"""
        if item_name in self.interaction_items:
            self.interaction_items[item_name].callback = callback
    
    def show_message(self, message, duration=3.0):
        """显示消息"""
        self.messages.append(MessageBox(message, duration))
        if len(self.messages) > 5:
            self.messages = self.messages[-5:]
    
    def handle_events(self, events):
        """处理事件"""
        mouse_pos = pygame.mouse.get_pos()
        
        # 更新悬停状态
        for item in self.interaction_items.values():
            item.update(mouse_pos)
        
        for event in events:
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                # 检查交互项点击
                for name, item in self.interaction_items.items():
                    if item.handle_click(event.pos):
                        self._execute_interaction(name, item)
                        break
            
            elif event.type == pygame.KEYDOWN:
                # 键盘快捷键
                key_map = {
                    pygame.K_1: 'feed', pygame.K_2: 'play', pygame.K_3: 'pet',
                    pygame.K_4: 'clean', pygame.K_5: 'sleep'
                }
                
                if event.key in key_map:
                    action = key_map[event.key]
                    if action in self.interaction_items:
                        item = self.interaction_items[action]
                        self._execute_interaction(action, item)
    
    def _execute_interaction(self, name, item):
        """执行交互"""
        if not item.enabled or not item.callback:
            return
        
        try:
            result = item.callback()
            if result and isinstance(result, dict):
                message = result.get('message', '')
                if message:
                    self.show_message(message)
        except Exception as e:
            self.show_message(f"Action failed: {str(e)}")
    
    def update(self, dt):
        """更新GUI"""
        self.animation_time += dt
        
        # 面板透明度动画
        alpha_diff = self.target_panel_alpha - self.panel_alpha
        if abs(alpha_diff) > 1:
            self.panel_alpha += alpha_diff * 5 * dt
        
        # 更新状态条
        for status_bar in self.status_bars.values():
            status_bar.update(dt)
        
        # 更新消息
        self.messages = [msg for msg in self.messages if not msg.is_expired()]
        for message in self.messages:
            message.update(dt)
    
    def update_pet_status(self, pet_stats):
        """更新宠物状态"""
        stats = pet_stats.get('stats', {})
        
        # 更新状态条
        for stat_name, status_bar in self.status_bars.items():
            value = stats.get(stat_name, 0)
            status_bar.set_value(value)
        
        # 启用/禁用交互
        is_sleeping = pet_stats.get('is_sleeping', False)
        self.interaction_items['feed'].enabled = not is_sleeping
        self.interaction_items['play'].enabled = not is_sleeping and stats.get('energy', 0) >= 10
        self.interaction_items['clean'].enabled = stats.get('cleanliness', 0) < 95
    
    def draw_status_panel(self, pet_stats):
        """绘制状态面板"""
        # 背景
        panel_surface = pygame.Surface(self.status_panel_rect.size, pygame.SRCALPHA)
        panel_surface.fill((0, 0, 0, int(self.panel_alpha)))
        self.screen.blit(panel_surface, self.status_panel_rect)
        
        # 边框
        pygame.draw.rect(self.screen, (255, 255, 255), self.status_panel_rect, 2)
        
        # 标题
        title_surface = self.font_medium.render("Pet Status", True, (255, 255, 255))
        title_rect = title_surface.get_rect(centerx=self.status_panel_rect.centerx, y=self.status_panel_rect.y + 10)
        self.screen.blit(title_surface, title_rect)
        
        # 基本信息
        y_offset = 35
        info_lines = [
            f"Name: {pet_stats.get('name', 'Unknown')}",
            f"Type: {pet_stats.get('type', 'unknown')}",
            f"Level: {pet_stats.get('level', 1)}",
            f"Age: {pet_stats.get('age', 0)} days",
            f"Mood: {pet_stats.get('mood', 'neutral')}"
        ]
        
        for line in info_lines:
            text_surface = self.font_small.render(line, True, (255, 255, 255))
            self.screen.blit(text_surface, (self.status_panel_rect.x + 15, self.status_panel_rect.y + y_offset))
            y_offset += 16
        
        # 状态条
        for status_bar in self.status_bars.values():
            status_bar.draw(self.screen, self.font_small)
    
    def draw_interaction_panel(self):
        """绘制交互面板"""
        # 背景
        panel_surface = pygame.Surface(self.interaction_panel_rect.size, pygame.SRCALPHA)
        panel_surface.fill((0, 0, 0, int(self.panel_alpha)))
        self.screen.blit(panel_surface, self.interaction_panel_rect)
        
        # 边框
        pygame.draw.rect(self.screen, (255, 255, 255), self.interaction_panel_rect, 2)
        
        # 标题
        title_surface = self.font_medium.render("Actions", True, (255, 255, 255))
        title_rect = title_surface.get_rect(centerx=self.interaction_panel_rect.centerx, y=self.interaction_panel_rect.y + 10)
        self.screen.blit(title_surface, title_rect)
        
        # 交互项
        for item in self.interaction_items.values():
            item.draw(self.screen, self.font_small)
        
        # 帮助文字
        help_lines = ["Quick Keys:", "1-5: Actions", "F1: Help", "F2: Pet info"]
        y_offset = 220
        for line in help_lines:
            help_surface = self.font_small.render(line, True, (180, 180, 180))
            self.screen.blit(help_surface, (self.interaction_panel_rect.x + 10, self.interaction_panel_rect.y + y_offset))
            y_offset += 14
    
    def draw_messages(self):
        """绘制消息"""
        if not self.messages:
            return
        
        message_y = self.height - 120
        for message in self.messages[-3:]:
            message.draw(self.screen, self.font_medium, self.width // 2, message_y)
            message_y -= 40
    
    def draw_fps(self, fps):
        """绘制FPS"""
        fps_text = f"FPS: {fps}"
        fps_surface = self.font_small.render(fps_text, True, (255, 255, 255))
        self.screen.blit(fps_surface, (self.width - 80, self.height - 20))
    
    def render(self, pet_stats, fps=0):
        """渲染GUI"""
        self.update_pet_status(pet_stats)
        self.draw_status_panel(pet_stats)
        self.draw_interaction_panel()
        self.draw_messages()
        
        if fps > 0:
            self.draw_fps(fps)

main.py

"""
Virtual Pet Game
"""

import pygame
import sys
import time
from typing import Dict, Any

from pet.pet_model import VirtualDog, create_virtual_dog, get_random_dog_name
from graphics.renderer import Simple3DRenderer
from ui.gui import VirtualPetGUI

class VirtualDogGame:
    """虚拟宠物游戏"""
    
    def __init__(self):
        print("=== Virtual Pet Game - Starting ===")
        
        # 初始化Pygame
        try:
            pygame.init()
            print("✅ Pygame initialized")
        except pygame.error as e:
            print(f"❌ Failed to initialize Pygame: {e}")
            sys.exit(1)
        
        # 创建游戏窗口
        try:
            self.renderer = Simple3DRenderer(1200, 800)
            self.gui = VirtualPetGUI(self.renderer.screen)
            self.clock = pygame.time.Clock()
            print("✅ Game window created")
        except pygame.error as e:
            print(f"❌ Failed to create window: {e}")
            sys.exit(1)
        
        # 创建虚拟宠物
        pet_name = get_random_dog_name()
        self.pet = create_virtual_dog(pet_name)
        print(f"✅ Created pet: {pet_name}")
        
        # 游戏状态
        self.running = True
        self.fps_target = 60
        self.last_update = time.time()
        
        # 性能统计
        self.frame_count = 0
        self.fps_display = 60
        self.fps_update_time = time.time()
        
        # 设置GUI回调
        self._setup_gui_callbacks()
        
        print("🎮 Game ready! Controls: 1-5 keys, mouse drag/wheel, ESC to quit")
    
    def _setup_gui_callbacks(self):
        """设置GUI回调函数"""
        callbacks = {
            'feed': self.pet.feed,
            'play': self.pet.play,
            'pet': self.pet.pet,
            'clean': self.pet.clean,
            'sleep': self.pet.toggle_sleep
        }
        
        for action, callback in callbacks.items():
            self.gui.set_interaction_callback(action, callback)
        
        print("✅ GUI callbacks configured")
    
    def handle_input(self):
        """处理输入"""
        events = pygame.event.get()
        
        for event in events:
            # 退出事件
            if event.type == pygame.QUIT:
                print("👋 User clicked close")
                self.running = False
            
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    print("👋 User pressed ESC")
                    self.running = False
                elif event.key == pygame.K_F1:
                    self._show_help()
                elif event.key == pygame.K_F2:
                    self._show_pet_info()
            
            # 鼠标控制
            elif event.type == pygame.MOUSEWHEEL:
                self.renderer.handle_zoom(event.y)
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                self.renderer.start_drag(event.pos)
            elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
                self.renderer.end_drag()
            elif event.type == pygame.MOUSEMOTION and pygame.mouse.get_pressed()[0]:
                self.renderer.update_drag(event.pos)
        
        # 传递事件给GUI
        self.gui.handle_events(events)
    
    def _show_help(self):
        """显示帮助"""
        help_text = """
=== VIRTUAL PET GAME HELP ===

CONTROLS:
• Mouse: Click buttons to interact
• Keys 1-5: Quick actions (Feed, Play, Pet, Clean, Sleep)
• Mouse wheel: Zoom in/out
• Mouse drag: Rotate view
• F1: Show this help
• F2: Show pet details
• ESC: Quit game

GAMEPLAY:
• Keep your pet happy and healthy
• Feed when hungry
• Play to increase happiness
• Clean to maintain hygiene
• Let pet sleep when tired
• Watch stats and mood changes

Have fun with your virtual pet!
        """
        print(help_text)
        self.gui.show_message("Help displayed in console", 2.0)
    
    def _show_pet_info(self):
        """显示宠物信息"""
        info = self.pet.get_detailed_info()
        print("\n" + info + "\n")
        
        # 检查需要注意的事项
        needs = self.pet.needs_attention()
        if needs:
            print("⚠️  ATTENTION NEEDED:")
            for need in needs:
                print(f"   • {need}")
        else:
            print("✅ Pet is doing well!")
        
        self.gui.show_message("Pet info displayed in console", 2.0)
    
    def update_game_logic(self, dt):
        """更新游戏逻辑"""
        # 更新宠物状态
        pet_changes = self.pet.update()
        
        # 处理状态变化
        if pet_changes:
            for change_type, change_data in pet_changes.items():
                if change_type == 'mood_changed':
                    old_mood, new_mood = change_data
                    mood_desc = self.pet.get_mood_description()
                    self.gui.show_message(f"Mood changed: {new_mood}", 2.0)
                    print(f"🎭 Mood: {old_mood} → {new_mood}")
                    print(f"   {mood_desc}")
                
                elif change_type == 'age_increased':
                    days = change_data
                    self.gui.show_message(f"{self.pet.name} is now {self.pet.age} days old!", 3.0)
                    print(f"🎂 {self.pet.name} aged {days} day(s)! Now {self.pet.age} days old")
        
        # 检查需要提醒的事项
        needs = self.pet.needs_attention()
        if needs and len(needs) > 0:
            # 每30秒最多提醒一次
            current_time = time.time()
            if not hasattr(self, 'last_reminder') or current_time - self.last_reminder > 30:
                urgent_need = needs[0]  # 显示最紧急的需求
                self.gui.show_message(f"⚠️ {urgent_need}", 4.0)
                self.last_reminder = current_time
        
        # 更新GUI
        self.gui.update(dt)
    
    def render_frame(self):
        """渲染帧"""
        # 获取宠物状态
        pet_status = self.pet.get_status_summary()
        
        # 渲染3D场景
        self.renderer.render(pet_status)
        
        # 渲染GUI覆盖层
        self.gui.render(pet_status, int(self.fps_display))
        
        # 更新显示
        pygame.display.flip()
    
    def update_fps_counter(self):
        """更新FPS计数器"""
        self.frame_count += 1
        current_time = time.time()
        
        # 每秒更新一次FPS显示
        if current_time - self.fps_update_time >= 1.0:
            self.fps_display = self.frame_count / (current_time - self.fps_update_time)
            self.frame_count = 0
            self.fps_update_time = current_time
    
    def run(self):
        """运行游戏主循环"""
        print("🎮 Starting game loop...")
        
        # 显示欢迎消息
        welcome_msg = f"Welcome! Meet {self.pet.name} your virtual dog!"
        self.gui.show_message(welcome_msg, 4.0)
        
        # 主游戏循环
        while self.running:
            # 计算时间增量
            current_time = time.time()
            dt = current_time - self.last_update
            self.last_update = current_time
            
            # 限制最大时间步长(防止暂停后的巨大跳跃)
            dt = min(dt, 0.1)
            
            try:
                # 处理输入
                self.handle_input()
                
                # 更新游戏逻辑
                self.update_game_logic(dt)
                
                # 渲染画面
                self.render_frame()
                
                # 更新FPS计数
                self.update_fps_counter()
                
                # 控制帧率
                self.clock.tick(self.fps_target)
                
            except Exception as e:
                print(f"❌ Error in game loop: {e}")
                import traceback
                traceback.print_exc()
                break
        
        # 游戏结束清理
        self.cleanup()
    
    def cleanup(self):
        """清理资源"""
        print("🧹 Cleaning up...")
        
        # 显示最终统计
        final_stats = self.pet.get_status_summary()
        print(f"\n=== FINAL STATS for {final_stats['name']} ===")
        print(f"Level: {final_stats['level']}")
        print(f"Age: {final_stats['age']} days")
        print(f"Total food eaten: {final_stats['total_food_eaten']}")
        print(f"Times petted: {final_stats['times_petted']}")
        print(f"Final mood: {final_stats['mood']}")
        
        # 退出Pygame
        pygame.quit()
        print("👋 Thanks for playing! Goodbye!")

def main():
    """主函数"""
    try:
        # 创建并运行游戏
        game = VirtualDogGame()
        game.run()
    except KeyboardInterrupt:
        print("\n🛑 Game interrupted by user")
    except Exception as e:
        print(f"💥 Fatal error: {e}")
        import traceback
        traceback.print_exc()
    finally:
        # 确保Pygame正确退出
        try:
            pygame.quit()
        except:
            pass
        sys.exit(0)

if __name__ == "__main__":
    main()

效果展示

交互式控制 - 鼠标拖拽旋转视角、滚轮缩放; 快捷键操作 - 数字键 1-5 快速执行动作

实时反馈 - 状态变化提醒、心情描述;  可视化界面 - 状态条、按钮、消息系统

宠物系统:

- 五大属性管理:饥饿度、快乐度、健康值、能量值、清洁度

- 智能心情系统:根据属性自动切换心情(开心、悲伤、兴奋、困倦、饥饿、生病)

- 成长系统:经验值积累、等级提升

- 行为动画:根据心情展现不同动作和表情

Gemini Pro 3.1实战指南:多模态原生协同如何重构工作流 多模态AI已从‘能看能听’迈入‘统一语义理解’新阶段。其核心原理是跨模态对齐——将文字、图像、音频等不同数据映射至同一嵌入空间,实现视觉特征与文本向量的直接语义计算。这种技术价值在于打破人机交互的格式壁垒,让AI真正理解模糊指令、识别手写涂改、关联截图图标与语音情绪,从而支撑真实办公场景中的端到端任务接管。典型应用覆盖PDF智能分析、会议纪要生成、跨境电商选品、中文文案创作及实时旅行规划等高频需求。本文聚焦Gemini Pro 3.1在多模态原生协同与动态上下文管理两大能力上的工程化落地,提供可即用的提示词 阅读详情

相关推荐

AI技术 Newsletter 深度解析:科研、工程与商业三层过滤机制

AI技术通讯是连接前沿研究与产业落地的关键信息枢纽,其核心价值在于对论文、开源项目与产品动态的系统性筛选与解读。基于扩散模型、微调技术(如DreamBooth)、自动驾驶数据引擎等热点方向,这类Newsletter通过学术雷达扫描、工程可行性验证和商业信号解码三重机制,将海量噪音转化为可执行洞见。它不仅揭示Stable Diffusion生态演进、Tesla FSD数据闭环等典型范式,更聚焦GPU资源约束下的实操边界、提示词工程中的语义漂移、小样本微调的稳定性陷阱等真实挑战,为工程师提供复现路径,为产品经理

cuanwei9356的博客 512

Python实践项目讲解:如何用制作一个桌面宠物

制作一个桌面宠物(Desktop Pet)在Python中通常涉及多个步骤,包括创建宠物的图形界面、添加动画效果、处理用户交互等。

m0_65482549的博客 5647

3.99万的人形机器人来了,宇树也开源了自己的核心技术

宇树科技发布全球首款4万元内人形机器人Unitree R1,将于8月开启众筹。这款1.28米高的机器人拥有23个自由度关节,支持开源开发,续航2小时,比同类型产品便宜60%以上。宇树通过自研技术和开源生态,试图定义消费级人形机器人标准。该产品不仅价格亲民,还提供完整SDK和硬件接口,鼓励用户自由改造。这一突破性产品或将开启家用机器人新纪元,让高端科技真正走入寻常百姓家。

weixin_42321517的博客 1301

Stability AI生成模型完全指南:3步上手AI创作新时代

探索Stability AI生成模型的强大能力,这是一款能够创建高质量图像和视频内容的先进人工智能工具。无论你是设计师、内容创作者还是AI爱好者,这份指南将帮助你快速掌握这个强大的创作工具,开启你的AI艺术之旅。 ## 🎨 核心概念:理解Stability AI的创作魔法 Stability AI生成模型基于深度学习技术,能够将文字描述转化为视觉内容。想象一下,你只需要输入"一个戴魔法帽的猫

gitblog_00146的博客 348

NAVSIM端到端自动驾驶闭环评测与论文复现指南

端到端自动驾驶模型评测正面临开环静态评估与闭环仿真之间的根本矛盾:NuScenes数据丰富但缺乏反馈,NuPlan闭环真实却场景贫瘠。NAVSIM通过动态场景图谱(DSG)技术,在保持大规模真实世界数据(如NuScenes、Waymo)基础上,构建可执行、可反馈、可量化的闭环评测通路,实现数据丰富度与闭环真实性的统一。其三级漏斗式评估框架——以Critical Violation Rate(CVR)和Near-Miss Frequency(NMF)为核心的安全性优先机制,直指L4落地中最不可妥协的工程底线。

weixin_33805743的博客 387

家庭机器人价值对齐:ROBOTVALUES数据集构建方法论

家庭服务机器人正从‘能做’迈向‘该做’的关键阶段,其核心挑战已不再是物体识别或路径规划等物理世界感知问题,而是社会世界中的意图理解与价值判断。价值对齐(Value Alignment)作为人机共融的基础能力,要求机器人理解行为背后的家庭语义——如‘蹲下系鞋带’承载的是‘自主性支持’而非单纯动作执行。ROBOTVALUES数据集以‘价值事件’为最小单元,融合行为、意图与价值三元组标注,并通过家庭成员反向验证、跨模态线索对齐和情境参数注入,显著提升模型在晨间准备、情绪响应、代际互动等真实场景中的接受度与舒适度。

aodanchui1057的博客 387

多模态检索新选择:通义千问3-VL-Reranker-8B全解析

本文介绍了如何在星图GPU平台上自动化部署通义千问3-VL-Reranker-8B镜像,实现多模态检索重排序功能。用户可快速构建图文、文本-视频等跨模态匹配系统,典型应用于电商商品精准搜索、企业知识库文档与图片的语义对齐等场景,显著提升检索准确率。

weixin_29215509的博客 386

AI工程师必读:高信息密度技术简报的实操方法论

AI技术资讯不是泛泛而谈的趋势罗列,而是面向工程落地的知识载体。其核心在于将前沿模型(如Stable Diffusion、DreamBooth)、开源工具链与真实约束(算力边界、数据规模、部署安全)深度耦合,形成可验证、可复现、可决策的‘操作情报’。这类简报的价值,源于对技术演进逻辑的解构能力——比如识别DreamBooth的‘3–5张图’并非经验之谈,而是由微调收敛性与过拟合阈值决定的数学约束;又如Stable Diffusion API的‘开箱即用’背后,隐藏着safetensors加载、token截断

vanadiumlin 325

通义千问3-VL-Reranker-8B快速上手:3步启动本地Web UI服务(含端口配置)

本文介绍了如何在星图GPU平台上自动化部署通义千问3-VL-Reranker-8B镜像,快速启动本地Web UI服务。该多模态重排序模型能够深入理解图文混合查询,智能优化搜索结果排序,典型应用于提升宠物社区、电商平台等内容检索的精准度与用户体验。

weixin_35696112的博客 274

时序约束实战:从setup/hold到时钟路径约束的深度解析

本文深度解析数字设计中的时序约束实战,重点探讨如何从setup/hold检查的核心原理出发,理解并应用时钟路径约束。文章通过剖析Path Requirement的计算逻辑,结合同频、倍频及异步时钟域等典型场景,提供了从解读时序报告到编写、调试SDC约束的系统方法,帮助工程师有效应对复杂SoC设计中的时序收敛挑战。

weixin_29291185的博客 105

从仿真到实践:两级直接耦合放大电路的静态工作点协同调试指南

本文详细解析了两级直接耦合放大电路的静态工作点协同调试方法,从仿真到实践提供系统指南。重点介绍了Rc2电阻调整技巧、集电极电位测量方法及常见问题排查,帮助工程师解决各级静态工作点相互影响的难题,提升模拟电路设计效率。

weixin_29189373的博客 124

开源AI动作视频产线:本地部署高保真人体运动生成

AI动作生成技术正从黑盒服务走向可解释、可定制的端到端管线。其核心原理是融合2D姿态估计与3D运动建模,通过扩散模型(Motion Diffusion Model)实现符合生物力学规律的动作合成,并结合神经渲染(NeRF)与可微分渲染输出高保真视频。该技术显著提升内容生产效率与数据主权保障,广泛应用于短视频创作、虚拟偶像驱动、教育动画制作及非遗动作复原等场景。本文聚焦于一条完全开源、支持本地部署、模块化组装的AI动作视频产线,深度整合MoveNet、MediaPipe Holistic、MDM与PyTorc

weixin_30367169的博客 430

Vue 实现华视身份证读卡器功能

在www.downcc.com下载“华视cvr100驱动”安装程序; 华视电子官网有相应的文档说明和程序下载 一、服务安装 选择安装目录: 启动读卡服务: 安装成功会有如图所示: 注意事项: 安装开发包必须使用管理员权限,因为windows服务和读卡器设备驱动程序均需要管理员权限,否则会安装失败。 win10需要修改组策略才有管理员权限。 二、服务的使用 打开浏览器,输入地址http://127.0.0.1:19196/mainpage,回车 点击openDevice: 点.

zyqgt960812的博客 6503

AI约束机制:从提示词到智能体,构建可靠AI应用的核心方法

在人工智能领域,大语言模型凭借其强大的生成能力,已成为技术应用的热点。然而,其基于概率的生成原理,在缺乏有效引导时,容易产生目标偏差,导致输出结果与用户意图不符。为解决这一问题,约束机制应运而生,它通过角色定义、任务分解、输出格式规范和质量控制四大支柱,将AI的“自由意志”与具体任务目标对齐,从而释放其真正的技术价值。这一机制广泛应用于智能体开发、自动化办公和行业问答等场景,是确保AI应用可靠、可控的关键。本文深入探讨了从基础提示词工程到复杂智能体框架的约束设计,并结合无限制生图、知识库问答等热词,提供了实

weixin_34117211的博客 345

智能车竞赛新手必看:用AD21从零画一块英飞凌TC264核心板(附开源PCB文件)

本文详细介绍了使用Altium Designer 21(AD21)从零开始设计英飞凌TC264核心板的完整流程,涵盖原理图绘制、PCB布线到最终DRC检查的全过程。针对智能车竞赛新手,提供了实用的硬件设计技巧和开源PCB文件,帮助快速掌握TC264核心板开发。

weixin_27017211的博客 246

【STM32实物】基于STM32的扫地机器人/小车控制系统设计

扫地机器人系统采用分层结构设计,主要包括底层硬件控制层、中间数据处理层和上层用户交互层。底层硬件控制层负责对各个硬件模块进行控制和数据采集,中间数据处理层负责对采集到的数据进行处理和解算,上层用户交互层负责与用户进行交互并显示系统状态信息。

嵌入式阿齐Archie 1万+

机器人公司倒金字塔组织危局:技术决策与工程执行的断层解析

在具身智能与四足机器人快速发展背景下,技术复杂度跃升正持续挑战传统研发组织模式。当算法创新、多模态感知、机电系统集成等高阶能力高度集中于少数核心人员,而执行层依赖标准化流程与外包协作时,便极易形成‘决策窄颈’与‘知识断层’——这不仅是管理效率问题,更是技术资产沉淀失效、专利落地受阻、客户现场问题难以闭环的根本原因。本文聚焦‘运动控制总架构师’‘多模态感知融合’‘整机机电系统’三大关键技术锚点,结合‘技术可行性办公室’‘现场工程师’‘工程师成长加速器’三类结构性桥梁,探讨如何在抽象层与具象层之间构建可复用、可

weixin_33895695的博客 395

​​手把手教你学PCIE--ATU 的 Bar 匹配模式与地址匹配模式详解​

摘要: ATU(地址转换单元)提供两种地址匹配模式:Bar匹配模式基于PCI设备的BAR寄存器自动映射虚拟地址(只需配置物理基址),适用于标准PCI设备DMA;地址匹配模式需显式配置虚拟与物理地址范围,适合自定义映射场景。核心区别在于匹配依据(BAR自动推导vs人工定义),Bar模式简化配置,地址模式更灵活。

MHD0815的博客 380

机器人不是C-3PO,而是三条务实演进路径的集合

机器人并非科幻中全能拟人化的终点,而是一类基于感知、决策与执行能力的智能机电系统。其技术本质源于传感器融合、实时控制与环境建模等基础原理,核心价值在于提升结构化场景下的作业精度、弱交互场景中的服务确定性,以及人机协同中的能力增强。当前主流应用已覆盖工业自动化、酒店配送、手术辅助与家庭清洁等领域,但普遍受限于灵巧操作的物理瓶颈、开放环境的语义盲区及长时序任务的认知局限。本文聚焦真实工程进展,解析工业自主化、服务延伸化与人类增强化这三条并行演进路径,揭示机器人从实验室原型走向家庭落地的关键技术断点与实践逻辑。

405

AI测试:手把手教你用AI做Web自动化测试「喂饭教程」

本文介绍了基于MCP协议和使用 mcp-use + playwright-mcp 构建智能Web自动化测试框架的实践方法。通过整合大语言模型的理解能力与测试工具可靠性,该方案支持用自然语言描述测试流程,自动转换为可执行的测试步骤,提升测试效率,支持复杂场景和多步骤流程,为自动化测试提供了新思路。

blues_C的博客 1281

BLDC&PMSM电机控制器硬件设计工程(八)72V 10kW电机控制器原理图工程及库文件

电机控制器基本需求:接口类型;MCU平台;通信接口;供电;信号采集;信号输出;功率;EMC或者认证需求。

小幽余生不加糖 373

GPT-4o实时多模态交互:从语音延迟到统一表征的技术跃迁

多模态交互是人工智能走向自然人机协作的核心范式,其本质在于打破文本、语音、图像等模态间的语义鸿沟,实现统一表征与协同理解。传统方案依赖模块拼接与分段处理,导致信息衰减与高延迟;而以GPT-4o为代表的新型架构采用原生统一序列建模,将音频波形、图像块、文本token映射至共享离散空间,配合流式推理与轻量神经编解码,首次将端到端语音交互延迟压至200ms以内——这不仅是工程优化,更是对‘实时性’的重新定义。该能力正驱动教育陪练、老年监护、智能家居、智能客服及工业设计等场景发生体验级变革,尤其在需要低延迟响应与跨

weixin_34080571的博客 365

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

ESP32-S3自制超迷你语音助手:从硬件选型到本地AI模型部署全攻略

语音识别作为人机交互的核心技术,其原理是将声音信号转化为机器可理解的指令。在嵌入式领域,边缘计算使得设备无需依赖云端即可实现本地智能处理,这尤其适用于对实时性和隐私保护要求高的场景。TensorFlow Lite Micro等轻量级框架的出现,让在资源受限的微控制器上部署神经网络模型成为可能,极大地推动了离线语音交互技术的发展。这种技术为智能家居、可穿戴设备等提供了高响应、低功耗的解决方案。本文聚焦于如何利用ESP32-S3主控芯片,结合I2S数字麦克风与本地语音识别模型,亲手打造一个完全可控、注重隐私的超

weixin_30729609的博客 392

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

AI全栈实战 | 3.9-01 爬虫入门:requests 加 BeautifulSoup 三分钟跑通,但 90% 的人栽在这 4 个“礼貌“问题上

⚠️:本文内容仅用于。请遵守目标站点的服务条款与相关法律法规,不得对目标服务造成负担,不得采集、传播个人隐私数据。技术是中性的,边界在你手里。爬虫的入门技术(requests 发请求 + BeautifulSoup 解析)三分钟就能学会。真正区分"会用爬虫"和"会做爬虫的人"的,是这篇我们跑通"请求→解析→存储"的最小闭环,然后重点把"合规与礼貌"这根弦给你绷上。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 421

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

从一段视频到可漫游的 4D 有声场景:思路拆解与最小复现手记

只需一段手机视频,你就能生成可"走进去"的 4D 有声场景:转头时狗叫声方向随之变化,走近时声音更清晰。本文拆解 Video-to-4DAVScene 的核心思路,手把手带你用几十行 Python 搭出最小管线,把视频中的运动物体变成带空间位置的声源,并附上三个真实踩坑的排障经验,代码可直接跑。🎧

helloagent的博客 239

【每天一个 Python 小案例30】Python 基础知识综合小项目:我的工具盒

作为系列收官,本篇把前 29 篇的知识点合成一个能直接用的命令行工具"我的工具盒":计算器(用 ast 解析表达式,不碰 eval)、单位换算与温度转换(一张换算表 + 特例分支)、记账与分类统计(Decimal + JSON 持久化)、以及用"字典当命令表"把菜单和业务逻辑解耦的主循环。文中对比了 eval 的安全隐患与 ast 白名单的做法,解释了 lambda 闭包在字典里的写法与晚绑定陷阱,并在最后给出整个系列的知识地图,把变量、数据结构、控制流、函数、类、异常、文件、标准库八块内容对应到具体篇目。

xinjiyaya的博客 427
上一篇: 机器学习-线性模型
下一篇: Python内存模型与对象系统深度解析
刀客123
博客等级 码龄11年 800粉丝 120原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值