Python Pygame:与瓷砖碰撞不起作用
我目前正在为pygame开发一个抽象层,在尝试检查和地图的冲突时遇到了一个问题。我能够加载和显示地图,以及存储可碰撞的矩形。当我打印矩形列表时,我看到一切都准备就绪,但是当我迭代每个矩形并尝试检查与另一个矩形的碰撞时,即使这些矩形没有碰撞,它也总是返回true。另外,当我试图通过在每个矩形上绘制一个红色轮廓的矩形来调试所有矩形时,不会绘制任何东西,即使当我打印矩形时,它会打印一个存在的矩形 以下是框架中的一些片段:Python Pygame:与瓷砖碰撞不起作用,python,pygame,Python,Pygame,我目前正在为pygame开发一个抽象层,在尝试检查和地图的冲突时遇到了一个问题。我能够加载和显示地图,以及存储可碰撞的矩形。当我打印矩形列表时,我看到一切都准备就绪,但是当我迭代每个矩形并尝试检查与另一个矩形的碰撞时,即使这些矩形没有碰撞,它也总是返回true。另外,当我试图通过在每个矩形上绘制一个红色轮廓的矩形来调试所有矩形时,不会绘制任何东西,即使当我打印矩形时,它会打印一个存在的矩形 以下是框架中的一些片段: class Tilemap(object): """This is the ti
class Tilemap(object):
"""This is the tilemap object, it takes an array of strings as its object, and places a surface where you have it in the strings. It only supports one surface per map, so you have to make multiple maps for floor, walls, etc."""
def __init__(self, level_surface,level_string = None, string_char = "#", surface = None, surface_dim = Vector2(50, 50),surface_color = (255, 255, 255)):
self.level = level_string
self.char = string_char
self.surface = surface
if self.surface is None:
self.surface = pygame.Surface(surface_dim)
self.surface.fill(surface_color)
self.surface_width = self.surface.get_rect().w
self.surface_height = self.surface.get_rect().h
self.collision_list = []
for y in xrange(len(self.level)):
for x in xrange(len(self.level[y])):
if self.level[y][x] is self.char:
self.collision_list.insert(len(self.collision_list), Rect((x) * self.surface_width,(y) * self.surface_height, self.surface_width, self.surface_height))
print self.collision_list
for y in xrange(len(self.level)):
for x in xrange(len(self.level[y])):
if self.level[y][x] is self.char:
level_surface.blit(self.surface.convert_alpha(), (self.surface_width * x, self.surface_height * y))
def replace_char_with(self, level_surface,char = ".", surface = None):
for y in xrange(len(self.level)):
for x in xrange(len(self.level[y])):
if self.level[y][x] is char:
level_surface.blit(surface.convert_alpha(), (surface.get_width() * x, surface.get_height() * y))
def check_col(self, rect):
for tilerect in self.collision_list:
if rect.x + rect.w > tilerect.x or rect.y + rect.h > tilerect.y or rect.x < tilerect.x + tilerect.w or rect.y < tilerect.y + tilerect.h:
return True
else:
return False
def debug_draw(self, screen):
for rect in self.collision_list:
pygame.draw.rect(screen, (255, 0, 0), rect, 2)
从中创建玩家的精灵类:
class Sprite(object):
def __init__(self, surface = None, initial_position = (100, 100)):
self.surface = surface
self.rect = self.surface.get_rect(center = initial_position)
self.acceleration = Vector2(0, 0)
self.delta_time = None
self.dummyrect = self.rect
self.colliding = False
def update(self, delta_time):
self.dummyrect = self.rect.move(self.acceleration.x * delta_time, self.acceleration.y * delta_time)
if not self.colliding:
self.rect = self.dummyrect
else:
self.dummyrect = self.rect
self.delta_time = delta_time
def draw(self, screen):
screen.blit(self.surface, self.rect)
def draw_to_cam(self, screen,camera):
screen.blit(self.surface, camera.to_camera_coords(Vector2(self.rect.x, self.rect.y)))
def collide(self, rectangle):
if self.rect.x + self.rect.w > rectangle.x:
self.rect.x -= 1;
if self.rect.x < rectangle.x + rectangle.w:
self.rect.x += 1
if self.rect.y < rectangle.y + rectangle.h:
self.rect.y += 1;
if self.rect.y + self.rect.h > rectangle.y:
self.rect.y -= 1;
def set_accel_x(self, new_val):
self.acceleration.x = new_val
def set_accel_y(self, new_val):
self.acceleration.y = new_val
def apply_drag(self, drag_mul = 1):
if self.acceleration.x > 0:
self.acceleration.x -= self.delta_time * drag_mul
else:
self.acceleration.x += self.delta_time * drag_mul
if self.acceleration.y > 0:
self.acceleration.y -= self.delta_time * drag_mul
else:
self.acceleration.y += self.delta_time * drag_mul
if self.acceleration.x < 0.1 or self.acceleration.x > -0.1:
self.acceleration.x = 0
if self.acceleration.x < 0.1 or self.acceleration.x > -0.1:
self.acceleration.x = 0
if self.acceleration.y < 0.1 or self.acceleration.y > -0.1:
self.acceleration.y = 0
if self.acceleration.y < 0.1 or self.acceleration.y > -0.1:
self.acceleration.y = 0
def get_center(self):
return Vector2(self.rect.centerx, self.rect.centery)
类精灵(对象):
定义初始位置(自,表面=无,初始位置=(100100)):
self.surface=曲面
self.rect=self.surface.get_rect(中心=初始位置)
自加速=矢量2(0,0)
self.delta_time=无
self.dummyrect=self.rect
自碰撞=错误
def更新(自身、增量时间):
self.dummyrect=self.rect.move(self.acceleration.x*delta_时间,self.acceleration.y*delta_时间)
如果不是自碰撞:
self.rect=self.dummyrect
其他:
self.dummyrect=self.rect
self.delta_time=delta_time
def提取(自身,屏幕):
screen.blit(self.surface、self.rect)
def draw_to_cam(自身、屏幕、摄像头):
blit(self.surface,camera.to_camera_coords(Vector2(self.rect.x,self.rect.y)))
def碰撞(自身,矩形):
如果self.rect.x+self.rect.w>rectangle.x:
自校正x-=1;
如果self.rect.xrectangle.y:
自校正y-=1;
def设置加速(自身、新值):
自加速.x=新值
def设置加速(自身、新值):
自加速y=新值
def应用阻力(自身,阻力=1):
如果自加速.x>0:
self.加速度.x-=self.delta\u时间*阻力
其他:
self.acceleration.x+=self.delta\u时间*阻力
如果自加速y>0:
self.加速度.y-=self.delta\u时间*阻力
其他:
self.acceleration.y+=self.delta\u时间*阻力
如果自加速.x<0.1或自加速.x>-0.1:
自加速.x=0
如果自加速.x<0.1或自加速.x>-0.1:
自加速.x=0
如果自加速.y<0.1或自加速.y>-0.1:
自加速y=0
如果自加速.y<0.1或自加速.y>-0.1:
自加速y=0
def get_中心(自我):
返回向量2(self.rect.centerx、self.rect.centery)
这是涉及的三个主要片段,我不知道为什么每次都会返回冲突,但它似乎是这样。如果有人能回答,或者至少能解释为什么会发生这种情况,请帮助一个兄弟 在碰撞检查中需要一些
和
例如:
def check_col(self, rect):
for tilerect in self.collision_list:
collide_x = False
collide_y = False
# check x axis for collision
if self.rect.x + self.rect.w > tilerect.x:
collide_x = True
elif self.rect.x < tilerect.x + tilerect.w:
collide_x = True
# check y axis for collision
if self.rect.y < tilerect.y + tilerect.h:
collide_y = True
elif self.rect.y + self.rect.h > tilerect.y:
collide_y = True
# act on a collision on both axis
if collide_x and collide_y:
return True
else:
return False
def check_col(self,rect):
对于self.collision\u列表中的til竖立:
碰撞_x=错误
碰撞y=错误
#检查x轴是否存在碰撞
如果self.rect.x+self.rect.w>til.x:
碰撞_x=真
elif self.rect.xtil.y:
碰撞_y=真
#作用于两个轴上的碰撞
如果碰撞x和碰撞y:
返回真值
其他:
返回错误
您的check\u col函数使用了所有的“or”运算符,这意味着您只要满足一个条件,就会为碰撞返回true。这是您的代码:
def check_col(self, rect):
for tilerect in self.collision_list:
if rect.x + rect.w > tilerect.x or rect.y + rect.h > tilerect.y or rect.x < tilerect.x + tilerect.w or rect.y < tilerect.y + tilerect.h:
return True
else:
return False
def check_col(self,rect):
对于self.collision\u列表中的til竖立:
如果rect.x+rect.w>tilpright.x或rect.y+rect.h>tilpright.y或rect.x
你想要的是更像这样的东西:
def check_col(self, rect):
for tilerect in self.collision_list:
if ((rect.x + rect.w > tilerect.x and rect.x <= tilerect.x + tilerect.width) or
(tilerect.x + tilerect.width > rect.x and tilerect.x <= rect.x + rect.width)) and
((rect.y + rect.h > tilerect.y and rect.y <= tilerect.y + tilerect.height) or
(tilerect.y + tilerect.height > rect.y and tilerect.y <= rect.y + rect.height))
return true
else:
return false
def check_col(self,rect):
对于self.collision\u列表中的til竖立:
如果((rect.x+rect.w>tilprillet.x和rect.x rect.x和tilprillet.x tilprillet.y和rect.y rect.y和tilprillet.y)你是在测试两个矩形点上的矩形吗?对于[1]else@monkey,我不完全知道他想要用这些矩形做什么(非常确定基于网格的,在这种情况下有更好的方法),所以我只是修改了他的代码来工作。您更改的函数不是他的碰撞检测函数,而是他的碰撞反应函数。执行碰撞检测的函数是TileMap类中的check_col。@Haz您似乎是正确的。两个函数都执行相同的逻辑,但都有相同的错误。class Sprite(对象):
应派生自pygame.sprite.sprite
。您的碰撞应使用Rect
的碰撞函数或sprite
的碰撞函数,具体取决于其Rect on Rect还是Rect on sprite。
def check_col(self, rect):
for tilerect in self.collision_list:
if ((rect.x + rect.w > tilerect.x and rect.x <= tilerect.x + tilerect.width) or
(tilerect.x + tilerect.width > rect.x and tilerect.x <= rect.x + rect.width)) and
((rect.y + rect.h > tilerect.y and rect.y <= tilerect.y + tilerect.height) or
(tilerect.y + tilerect.height > rect.y and tilerect.y <= rect.y + rect.height))
return true
else:
return false