【Python-OpenCV】手势控制贪吃蛇

用手势玩转经典游戏:打造一个手势控制的贪吃蛇

你是否曾经想过,如果能用手势来控制游戏会是什么体验?今天,我要向大家介绍一个有趣的项目------手势控制贪吃蛇游戏。这个项目结合了计算机视觉和经典游戏,让你可以通过简单的手势来控制贪吃蛇的移动方向,带来全新的游戏体验。

游戏效果

先来看看游戏的实际效果:

如图所示,游戏界面分为左右两部分:左侧是摄像头捕捉的实时画面,显示了手部跟踪和方向识别;右侧是贪吃蛇游戏画面。玩家只需要用拇指和食指形成一个方向,贪吃蛇就会朝着相应的方向移动。

技术亮点

这个项目结合了多种技术,主要包括:

  1. 计算机视觉与手势识别:使用MediaPipe库进行实时手部跟踪和关键点检测
  2. 方向识别算法:基于拇指和食指之间的向量计算方向
  3. 游戏开发:使用Pygame构建贪吃蛇游戏
  4. 多媒体整合:结合视频处理、游戏渲染和音效系统

核心技术解析

1. 手势检测与方向识别

手势检测是游戏的核心部分,我们使用MediaPipe库来识别手部关键点,然后计算拇指和食指之间的向量来确定方向。

python 复制代码
def detect_direction(self, frame):
    # 转换为RGB格式
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    
    # 处理图像
    results = self.hands.process(rgb_frame)
    
    # 如果检测到手
    if results.multi_hand_landmarks:
        for hand_landmarks in results.multi_hand_landmarks:
            # 获取拇指和食指的关键点
            thumb_tip = hand_landmarks.landmark[self.mp_hands.HandLandmark.THUMB_TIP]
            index_tip = hand_landmarks.landmark[self.mp_hands.HandLandmark.INDEX_FINGER_TIP]
            
            # 计算拇指和食指的坐标
            thumb_x, thumb_y = int(thumb_tip.x * w), int(thumb_tip.y * h)
            index_x, index_y = int(index_tip.x * w), int(index_tip.y * h)
            
            # 计算拇指到食指的向量
            line_vector = (index_x - thumb_x, index_y - thumb_y)
            
            # 计算与各个坐标轴的夹角
            angles = {}
            for name, axis_vector in self.axes.items():
                dot_product = line_vector[0] * axis_vector[0] + line_vector[1] * axis_vector[1]
                cos_angle = dot_product / (vector_length * math.sqrt(axis_vector[0]**2 + axis_vector[1]**2))
                angle = math.acos(max(-1, min(1, cos_angle)))
                angles[name] = angle
            
            # 选择夹角最小的方向
            raw_direction = min(angles, key=angles.get)
            
            # 方向平滑处理
            # ...
            
            return self.last_direction

这段代码展示了如何从视频帧中检测手部,并计算出手势方向。我们首先获取拇指和食指的位置,然后计算它们之间的向量,接着计算这个向量与四个基本方向(上、下、左、右)的夹角,选择夹角最小的方向作为当前手势方向。

为了使方向变化更加平滑,我们还实现了方向缓冲和变化检测机制:

python 复制代码
# 如果连续检测到相同的新方向达到阈值,立即更新方向
if self.direction_change_count >= self.direction_change_threshold and raw_direction != self.last_direction:
    # 清空缓冲区并立即更新方向
    self.direction_buffer = [raw_direction] * self.buffer_size
    self.last_direction = raw_direction
else:
    # 正常的平滑处理
    self.direction_buffer.append(raw_direction)
    if len(self.direction_buffer) > self.buffer_size:
        self.direction_buffer.pop(0)
    
    # 获取缓冲区中最常见的方向
    if self.direction_buffer:
        counter = Counter(self.direction_buffer)
        smoothed_direction = counter.most_common(1)[0][0]
        self.last_direction = smoothed_direction

2. 贪吃蛇游戏逻辑

贪吃蛇游戏的核心逻辑包括蛇的移动、食物生成、碰撞检测等。我们还添加了一些创新功能,如食物邻近检测,让游戏更加友好:

python 复制代码
# 检查是否吃到食物 - 带有邻近检测
food_eaten = False

# 计算蛇头与食物在网格单元中的距离
head_cell_x, head_cell_y = new_head[0] // self.cell_size, new_head[1] // self.cell_size
food_cell_x, food_cell_y = self.food[0] // self.cell_size, self.food[1] // self.cell_size

# 检查蛇头是否在食物的邻近阈值范围内
if (abs(head_cell_x - food_cell_x) <= self.food_proximity and 
    abs(head_cell_y - food_cell_y) <= self.food_proximity):
    self.score += 1
    self.food = self._generate_food()
    food_eaten = True
    
    # 每得5分增加一次速度,但有最大限制
    if self.score % 5 == 0:
        self.speed = min(self.speed + 0.1, 1.5)

这段代码展示了我们如何实现食物邻近检测功能。传统的贪吃蛇游戏要求蛇头精确地碰到食物才能吃到,但在手势控制的环境中,这可能会让游戏变得过于困难。通过引入邻近检测,只要蛇头靠近食物一定范围内,就可以吃到食物,大大提高了游戏的可玩性。

3. 音效系统

为了增强游戏体验,我们还添加了音效系统,包括背景音乐、吃食物音效、转向音效和游戏结束音效:

python 复制代码
# 加载音效
sounds = {}
try:
    # 尝试加载音效文件
    sound_files = {
        "background": "background.mp3",
        "eat": "eat.mp3",
        "game_over": "game_over.mp3",
        "turn": "turn.mp3"
    }
    
    for sound_name, file_name in sound_files.items():
        sound_path = os.path.join(SOUND_DIR, file_name)
        if os.path.exists(sound_path):
            sounds[sound_name] = pygame.mixer.Sound(sound_path)
            if sound_name == "background":
                sounds[sound_name].set_volume(0.3)  # 降低背景音乐音量
    
    # 开始播放背景音乐
    if "background" in sounds:
        sounds["background"].play(-1)  # 无限循环
except Exception as e:
    print(f"加载音效时出错: {e}")
    # 如果出错,继续游戏但不使用音效

在游戏循环中,我们根据游戏状态变化播放相应的音效:

python 复制代码
# 根据游戏状态变化播放音效
if snake_game.score > previous_score:
    if "eat" in sounds:
        sounds["eat"].play()
    previous_score = snake_game.score

if snake_game.game_over and not previous_game_over:
    if "game_over" in sounds:
        sounds["game_over"].play()
    previous_game_over = True

游戏特色功能

除了基本的贪吃蛇游戏功能外,我们还添加了一些特色功能:

  1. 墙壁碰撞切换:玩家可以选择启用或禁用墙壁碰撞,启用时撞墙游戏结束,禁用时可以穿墙
  2. 食物邻近检测:只要蛇头靠近食物一定范围内,就可以吃到食物
  3. 方向变化平滑:通过方向缓冲和变化检测机制,使方向变化更加平滑
  4. 游戏速度调整:玩家可以手动调整游戏速度,游戏也会随着得分增加而自动加速
  5. 视觉反馈:实时显示手部跟踪、方向识别和游戏状态

如何开始

想要尝试这个游戏?只需要几个简单的步骤:

  1. 克隆仓库:

    复制代码
    git clone https://github.com/yourusername/gesture-snake.git
    cd gesture-snake
  2. 安装依赖:

    复制代码
    pip install -r requirements.txt
  3. 运行游戏:

    复制代码
    python run.py

游戏控制

  • 手势:用拇指和食指形成方向来控制蛇
  • P键:暂停/继续游戏
  • R键:游戏结束时重新开始
  • G键:显示/隐藏网格
  • W键:启用/禁用墙壁碰撞
  • H键:显示/隐藏帮助信息
  • M键:开启/关闭音乐
  • +/-键:增加/减少游戏速度
  • ESC键:退出游戏

结语

手势控制贪吃蛇游戏是一个有趣的项目,它展示了如何将计算机视觉技术与传统游戏相结合,创造出新的交互方式。这个项目不仅是一个有趣的游戏,也是学习计算机视觉、游戏开发和人机交互的好例子。

希望这个项目能给你带来灵感,激发你对技术和创新的热情。欢迎尝试、改进和分享这个项目!


项目地址:GitHub - Gesture Snake

如果你喜欢这个项目,别忘了给它点个星!

相关推荐
夜晚中的人海1 分钟前
【C语言】初阶数据结构相关习题(二)
c语言·开发语言·数据结构
武昌库里写JAVA14 分钟前
MacOS Python3安装
java·开发语言·spring boot·学习·课程设计
ElenaYu14 分钟前
mac安装cast
python·macos·cast
码农新猿类14 分钟前
帧差法识别
人工智能·opencv·计算机视觉
Dxy123931021617 分钟前
python如何设置excel单元格边框样式
开发语言·python·excel
chaodaibing34 分钟前
Python解析Excel入库如何做到行的拆分
开发语言·python·excel
zhqh1001 小时前
Opencv C++写中文(来自Gemini)
opencv
dudly1 小时前
Python类的力量:第五篇:魔法方法与协议——让类拥有Python的“超能力”
开发语言·python
ghost1431 小时前
C#学习第22天:网络编程
开发语言·学习·c#
zhengddzz1 小时前
从卡顿到丝滑:JavaScript性能优化实战秘籍
开发语言·javascript·性能优化