You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python Kivy中为KV绘制的迷宫实现碰撞检测?

问题描述

我正在为安卓手机和平板开发一款吃豆人变种游戏Luckman,但无法为在.kv文件中绘制的迷宫实现碰撞检测。我曾尝试过一种针对图片迷宫的碰撞检测方法,但我的迷宫是通过.kv文件中的图形对象绘制的,因此该方法无效。

main.py

from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.widget import Widget
from kivy.uix.anchorlayout import AnchorLayout

from player import *
from kivy.clock import Clock

from kivy.core.window import Window

class GamePlay(Screen):
    width = Window.width
    height = Window.height

    pacman = Player()

    def __init__(self, **kwargs):
        super(GamePlay,self).__init__(**kwargs)

    def on_touch_down(self, touch):
        self.start_pos = touch.pos
        return True

    def on_touch_move(self, touch):
        # Calculate swipe distance and direction
        swipe_distance_x = abs(touch.pos[0] - self.start_pos[0])
        swipe_distance_y = abs(touch.pos[1] - self.start_pos[1])
        swipe_threshold = 50  # Adjust threshold based on your needs

        # Detect swipe directions
        if swipe_distance_y > swipe_threshold:
            if touch.pos[1] > self.start_pos[1]:
                self.pacman.velocity = (0, 1)
                self.pacman.number_update_pac_img = "up"
            else:
                self.pacman.velocity = (0, -1)
                self.pacman.number_update_pac_img = "down"
        elif swipe_distance_x > swipe_threshold:
            if touch.pos[0] > self.start_pos[0]:
                self.pacman.velocity = (1, 0)
                self.pacman.number_update_pac_img = "right"
            else:
                self.pacman.velocity = (-1, 0)
                self.pacman.number_update_pac_img = "left"

        return True

    def update(self, dt):
        self.pacman.move()

class LuckmanApp(App):
    def build(self):
        game = GamePlay()
        Clock.schedule_interval(game.update, 1.0/60.0)

        return game

if __name__ == '__main__':
    LuckmanApp().run()

luckman.kv

<Player>:
    Image:
        id: "pacman"
        source: root.pac_img
        allow_stretch: True
        pos: root.pos
        size: self.parent.width / 18, self.parent.height / 18

<GamePlay>:
    canvas:
        Rectangle:
            source: "png/bg.png"
            size: self.size
    
    pacman: pacman_player

    FloatLayout:
        # Верхний вход
        canvas:
            Color:
                rgb: [0, 0, 1]
            # Верхний вход - правая стенка
            Rectangle:
                pos: self.width / 1.79, self.height
                size: self.width / -43.2, self.height / -6
            # Верхний вход - левая стенка
            Rectangle:
                pos: self.width / 2.274, self.height
                size: self.width / 43.2, self.height / -6
            # Верхний левый квадрат стенок
            Rectangle:
                pos: self.width / 2.274, self.height / 1.2
                size: self.width / -15, self.height / 96
            Rectangle:
                pos: self.width / 2.52, self.height / 1.2
                size: self.width / -43.2, self.height / 8
            Rectangle:
                pos: self.width / 2.52, self.height / 1.055
                size: self.width / -2.85, self.height / 96
            Rectangle:
                pos: self.width / 15, self.height / 1.0444
                size: self.width / -43.2, self.height / -4.7
            Rectangle:
                pos: self.width / 23.1, self.height / 1.34
                size: self.width / 7.3, self.height / -96
            Rectangle:
                pos: self.width / 2.6, self.height / 1.34
                size: self.width / -7.7, self.height / -96
            Rectangle:
                pos: self.width / 2.68, self.height / 1.359
                size: self.width / 11, self.height / 16.2
            # Верхний левый средний квадрат 
            Rectangle:
                pos: self.width / 7.29, self.height / 1.0948
                size: self.width / 22, self.height / -7.6
            Rectangle:
                pos: self.width / 3.92, self.height / 1.0948
                size: self.width / 22, self.height / -7.6

            # Верхний правый квадрат стенок
            Rectangle:
                pos: self.width / 1.8, self.height / 1.2
                size: self.width / 15, self.height / 96
            Rectangle:
                pos: self.width / 1.631, self.height / 1.2
                size: self.width / 43.2, self.height / 8
            Rectangle:
                pos: self.width / 1.631, self.height / 1.055
                size: self.width / 2.85, self.height / 96
            Rectangle:
                pos: self.width / 1.06, self.height / 1.0444
                size: self.width / 43.2, self.height / -4.7
            Rectangle:
                pos: self.width / 1.035, self.height / 1.34
                size: self.width / -7.3, self.height / -96
            Rectangle:
                pos: self.width / 1.6043, self.height / 1.34
                size: self.width / 7.7, self.height / -96
            Rectangle:
                pos: self.width / 1.57, self.height / 1.359
                size: self.width / -10, self.height / 16.2
            # Верхний правый  средний квадрат 
            Rectangle:
                pos: self.width / 1.207, self.height / 1.0948
                size: self.width / 22, self.height / -7.6
            Rectangle:
                pos: self.width / 1.324, self.height / 1.0948
                size: self.width / -22, self.height / -7.6


            # Нижний вход - правая стенка
            Rectangle:
                pos: self.width / 1.79, self.height * 0
                size: self.width / -43.2, self.height / 6
            # Нижний вход - левая стенка
            Rectangle:
                pos: self.width / 2.274, self.height * 0
                size: self.width / 43.2, self.height / 6
            # Нижний левый квадрат стенок
            Rectangle:
                pos: self.width / 2.274, self.height / 6.4
                size: self.width / -15, self.height / 96
            Rectangle:
                pos: self.width / 2.52, self.height / 6
                size: self.width / -43.2, self.height / -8
            Rectangle:
                pos: self.width / 2.52, self.height / 24
                size: self.width / -2.85, self.height / 96
            Rectangle:
                pos: self.width / 15, self.height / 24
                size: self.width / -43.2, self.height / 4.7
            Rectangle:
                pos: self.width / 23.1, self.height / 3.8
                size: self.width / 7.25, self.height / -96
            Rectangle:
                pos: self.width / 2.6, self.height / 3.8
                size: self.width / -7.7, self.height / -96
            Rectangle:
                pos: self.width / 2.68, self.height / 3.8
                size: self.width / 11, self.height / -16.2
            #Нижний Левый средний квадрат 
            Rectangle:
                pos: self.width / 7.29, self.height / 4.61
                size: self.width / 22, self.height / -7.6
            Rectangle:
                pos: self.width / 3.92, self.height / 4.61
                size: self.width / 22, self.height / -7.6

            # Нижний правый квадрат стенок
            Rectangle:
                pos: self.width / 1.8, self.height / 6.4
                size: self.width / 15, self.height / 96
            Rectangle:
                pos: self.width / 1.631, self.height / 6
                size: self.width / 43.2, self.height / -8
            Rectangle:
                pos: self.width / 1.631, self.height / 24
                size: self.width / 2.85, self.height / 96
            Rectangle:
                pos: self.width / 1.06, self.height / 24
                size: self.width / 43.2, self.height / 4.7
            Rectangle:
                pos: self.width / 1.035, self.height / 3.8
                size: self.width / -7.25, self.height / -96
            Rectangle:
                pos: self.width / 1.6043, self.height / 3.8
                size: self.width / 7.6, self.height / -96
            Rectangle:
                id: stop
                pos: self.width / 1.57, self.height / 3.8
                size: self.width / -10, self.height / -16.2
            #Нижний правый средний квадрат 
            Rectangle:
                pos: self.width / 1.207, self.height / 4.61
                size: self.width / 22, self.height / -7.6
            Rectangle:
                pos: self.width / 1.324, self.height / 4.61
                size: self.width / -22, self.height / -7.6


            #Центральные стороны

            #Центральная левая горизонтальная стенка
            Rectangle:
                pos: self.width / 6.31, self.height / 1.34
                size: self.width / 43.2, self.height / -2.05

            #Центральная правая горизонтальная стенка
            Rectangle:
                pos: self.width / 1.208, self.height / 1.34
                size: self.width / 43.2, self.height / -2.05
            
            #Центальная верхняя стенка
            Rectangle:
                pos: self.width / 3.92, self.height / 1.43
                size: self.width / 2., self.height / -96

            #Центр спавна призраков
            Rectangle:
                pos: self.width / 2.68, self.height / 1.555
                size: self.width / 11, self.height / 96
            Rectangle:
                pos: self.width / 1.57, self.height / 1.555
                size: self.width / -10, self.height / 96
            Rectangle:
                pos: self.width / 2.68, self.height / 1.65
                size: self.width / 43.2, self.height / 27
            Rectangle:
                pos: self.width / 1.57, self.height / 1.65
                size: self.width / -43.2, self.height / 27
            Rectangle:
                pos: self.width / 2.68, self.height / 1.65
                size: self.width / 3.79, self.height / -96
                
            #Центальная средняя стенка
            Rectangle:
                pos: self.width / 3.92, self.height / 1.786
                size: self.width / 2, self.height / -96
                
            #Центральная правая вертекальная стенка
            Rectangle:
                pos: self.width / 1.324, self.height / 1.68
                size: self.width / -22, self.height / 17.5
            #Центральная левая вертекальная стенка
            Rectangle:
                pos: self.width / 3.92, self.height / 1.68
                size: self.width / 22, self.height / 17.5
                
            #Центальная левая нижняя стенка
            Rectangle:
                pos: self.width / 6.31, self.height / 1.945
                size: self.width / 3.25, self.height / -96
            #Центальняя правая нижняя стенка
            Rectangle:
                pos: self.width / 1.208, self.height / 1.945
                size: self.width / -3.5, self.height / -96
            #Центральний нижний квадрат
            Rectangle:
                pos: self.width / 3.92, self.height / 3.8
                size: self.width / 2, self.height / 4.85

        Player:
            id: pacman_player
            pos: self.width / 2.13, self.height / 5.7

player.py

from kivy.uix.widget import Widget
from kivy.properties import StringProperty, NumericProperty, ReferenceListProperty
from kivy.vector import Vector

class Player(Widget):    
    pac_img = StringProperty("png/pacman/pacman_down.gif")

    number_update_pac_img = "None"

    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos

        #update pacman gifts
        if self.number_update_pac_img == "up":
            self.pac_img = "png/pacman/pacman_up.gif"
        if self.number_update_pac_img == "down":
            self.pac_img = "png/pacman/pacman_down.gif"
        if self.number_update_pac_img == "left":
            self.pac_img = "png/pacman/pacman_left.gif"
        if self.number_update_pac_img == "right":
            self.pac_img = "png/pacman/pacman_right.gif"

内容的提问来源于stack exchange,提问作者Undertaker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 00:30:53