我想为 Android 手机和平板电脑创建 Luckman 品种的吃豆人。但我无法对迷宫进行碰撞。
我尝试按照这些文件中的方式进行操作https://drive.google.com/file/d/1pwCDpU1UPzB7V7TV7-WmbyDLkpIDODry/view。但由于我的迷宫不是作为图片而是作为 .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"
如果对迷宫的每个部分都使用
Widget
,那么您可以使用 collide_widget()
的 Widget
方法来检测碰撞。首先定义矩形的类:
class MyRectangle(Widget):
def on_size(self, *args):
# Make sure sizes are positive
if self.width < 0:
self.x += self.width
self.width = -self.width
if self.height < 0:
self.y += self.height
self.height = -self.height
on_size()
只是为了确保尺寸大于 0,因为您的画布 Rectangles
有一些负尺寸。
然后,重写您的
luckman.kv
文件以使用 MyRectangle
类而不是 canvas
Rectangles
,如下所示:
<Player>:
size_hint: None, None
size: self.parent.width / 18, self.parent.height / 18
Image:
id: pacman
source: root.pac_img
allow_stretch: True
pos: root.pos
size: root.size
<GamePlay>:
canvas:
Rectangle:
source: "png/bg.png"
size: self.size
pacman: pacman_player
FloatLayout:
id: flt
# Верхний вход
# canvas:
# Color:
# rgb: [0, 0, 1]
# Верхний вход - правая стенка
MyRectangle:
pos: flt.width / 1.79, flt.height
size: flt.width / -43.2, flt.height / -6
# Верхний вход - левая стенка
MyRectangle:
pos: flt.width / 2.274, flt.height
size: flt.width / 43.2, flt.height / -6
# Верхний левый квадрат стенок
MyRectangle:
pos: flt.width / 2.274, flt.height / 1.2
size: flt.width / -15, flt.height / 96
MyRectangle:
pos: flt.width / 2.52, flt.height / 1.2
size: flt.width / -43.2, flt.height / 8
MyRectangle:
pos: flt.width / 2.52, flt.height / 1.055
size: flt.width / -2.85, flt.height / 96
MyRectangle:
pos: flt.width / 15, flt.height / 1.0444
size: flt.width / -43.2, flt.height / -4.7
MyRectangle:
pos: flt.width / 23.1, flt.height / 1.34
size: flt.width / 7.3, flt.height / -96
MyRectangle:
pos: flt.width / 2.6, flt.height / 1.34
size: flt.width / -7.7, flt.height / -96
MyRectangle:
pos: flt.width / 2.68, flt.height / 1.359
size: flt.width / 11, flt.height / 16.2
# Верхний левый средний квадрат
MyRectangle:
pos: flt.width / 7.29, flt.height / 1.0948
size: flt.width / 22, flt.height / -7.6
MyRectangle:
pos: flt.width / 3.92, flt.height / 1.0948
size: flt.width / 22, flt.height / -7.6
# Верхний правый квадрат стенок
MyRectangle:
pos: flt.width / 1.8, flt.height / 1.2
size: flt.width / 15, flt.height / 96
MyRectangle:
pos: flt.width / 1.631, flt.height / 1.2
size: flt.width / 43.2, flt.height / 8
MyRectangle:
pos: flt.width / 1.631, flt.height / 1.055
size: flt.width / 2.85, flt.height / 96
MyRectangle:
pos: flt.width / 1.06, flt.height / 1.0444
size: flt.width / 43.2, flt.height / -4.7
MyRectangle:
pos: flt.width / 1.035, flt.height / 1.34
size: flt.width / -7.3, flt.height / -96
MyRectangle:
pos: flt.width / 1.6043, flt.height / 1.34
size: flt.width / 7.7, flt.height / -96
MyRectangle:
pos: flt.width / 1.57, flt.height / 1.359
size: flt.width / -10, flt.height / 16.2
# Верхний правый средний квадрат
MyRectangle:
pos: flt.width / 1.207, flt.height / 1.0948
size: flt.width / 22, flt.height / -7.6
MyRectangle:
pos: flt.width / 1.324, flt.height / 1.0948
size: flt.width / -22, flt.height / -7.6
# Нижний вход - правая стенка
MyRectangle:
pos: flt.width / 1.79, flt.height * 0
size: flt.width / -43.2, flt.height / 6
# Нижний вход - левая стенка
MyRectangle:
pos: flt.width / 2.274, flt.height * 0
size: flt.width / 43.2, flt.height / 6
# Нижний левый квадрат стенок
MyRectangle:
pos: flt.width / 2.274, flt.height / 6.4
size: flt.width / -15, flt.height / 96
MyRectangle:
pos: flt.width / 2.52, flt.height / 6
size: flt.width / -43.2, flt.height / -8
MyRectangle:
pos: flt.width / 2.52, flt.height / 24
size: flt.width / -2.85, flt.height / 96
MyRectangle:
pos: flt.width / 15, flt.height / 24
size: flt.width / -43.2, flt.height / 4.7
MyRectangle:
pos: flt.width / 23.1, flt.height / 3.8
size: flt.width / 7.25, flt.height / -96
MyRectangle:
pos: flt.width / 2.6, flt.height / 3.8
size: flt.width / -7.7, flt.height / -96
MyRectangle:
pos: flt.width / 2.68, flt.height / 3.8
size: flt.width / 11, flt.height / -16.2
#Нижний Левый средний квадрат
MyRectangle:
pos: flt.width / 7.29, flt.height / 4.61
size: flt.width / 22, flt.height / -7.6
MyRectangle:
pos: flt.width / 3.92, flt.height / 4.61
size: flt.width / 22, flt.height / -7.6
# Нижний правый квадрат стенок
MyRectangle:
pos: flt.width / 1.8, flt.height / 6.4
size: flt.width / 15, flt.height / 96
MyRectangle:
pos: flt.width / 1.631, flt.height / 6
size: flt.width / 43.2, flt.height / -8
MyRectangle:
pos: flt.width / 1.631, flt.height / 24
size: flt.width / 2.85, flt.height / 96
MyRectangle:
pos: flt.width / 1.06, flt.height / 24
size: flt.width / 43.2, flt.height / 4.7
MyRectangle:
pos: flt.width / 1.035, flt.height / 3.8
size: flt.width / -7.25, flt.height / -96
MyRectangle:
pos: flt.width / 1.6043, flt.height / 3.8
size: flt.width / 7.6, flt.height / -96
MyRectangle:
id: stop
pos: flt.width / 1.57, flt.height / 3.8
size: flt.width / -10, flt.height / -16.2
#Нижний правый средний квадрат
MyRectangle:
pos: flt.width / 1.207, flt.height / 4.61
size: flt.width / 22, flt.height / -7.6
MyRectangle:
pos: flt.width / 1.324, flt.height / 4.61
size: flt.width / -22, flt.height / -7.6
#Центральные стороны
#Центральная левая горизонтальная стенка
MyRectangle:
pos: flt.width / 6.31, flt.height / 1.34
size: flt.width / 43.2, flt.height / -2.05
#Центральная правая горизонтальная стенка
MyRectangle:
pos: flt.width / 1.208, flt.height / 1.34
size: flt.width / 43.2, flt.height / -2.05
#Центальная верхняя стенка
MyRectangle:
pos: flt.width / 3.92, flt.height / 1.43
size: flt.width / 2., flt.height / -96
#Центр спавна призраков
MyRectangle:
pos: flt.width / 2.68, flt.height / 1.555
size: flt.width / 11, flt.height / 96
MyRectangle:
pos: flt.width / 1.57, flt.height / 1.555
size: flt.width / -10, flt.height / 96
MyRectangle:
pos: flt.width / 2.68, flt.height / 1.65
size: flt.width / 43.2, flt.height / 27
MyRectangle:
pos: flt.width / 1.57, flt.height / 1.65
size: flt.width / -43.2, flt.height / 27
MyRectangle:
pos: flt.width / 2.68, flt.height / 1.65
size: flt.width / 3.79, flt.height / -96
#Центальная средняя стенка
MyRectangle:
pos: flt.width / 3.92, flt.height / 1.786
size: flt.width / 2, flt.height / -96
#Центральная правая вертекальная стенка
MyRectangle:
pos: flt.width / 1.324, flt.height / 1.68
size: flt.width / -22, flt.height / 17.5
#Центральная левая вертекальная стенка
MyRectangle:
pos: flt.width / 3.92, flt.height / 1.68
size: flt.width / 22, flt.height / 17.5
#Центальная левая нижняя стенка
MyRectangle:
pos: flt.width / 6.31, flt.height / 1.945
size: flt.width / 3.25, flt.height / -96
#Центальняя правая нижняя стенка
MyRectangle:
pos: flt.width / 1.208, flt.height / 1.945
size: flt.width / -3.5, flt.height / -96
#Центральний нижний квадрат
MyRectangle:
pos: flt.width / 3.92, flt.height / 3.8
size: flt.width / 2, flt.height / 4.85
Player:
id: pacman_player
pos: flt.width / 2.13, flt.height / 5.7
<MyRectangle>:
size_hint: None, None
canvas:
Color:
rgb: [0, 0, 1]
Rectangle:
pos: root.pos
size: root.size
注意,
size
的Player
是在kv
中定义的,并且Image
使用相同的尺寸。这对于 collide_widget()
方法很重要。
此外,
FloatLayout
现在有一个id
以方便参考。 canvas
指令被 MyRectangle
实例替换,并且 <MyRectangle>
规则为 MyRectangle
的每个实例执行画布指令。
现在可以修改
update()
方法来检测碰撞:
def update(self, _dt):
self.pacman.move()
flt = self.ids.flt
for w in flt.children:
if w == self.pacman:
continue
if w.collide_widget(self.pacman):
print('collision:', w.pos, w.size, self.pacman.pos, self.pacman.size)
return