[英]variable that is set to True in if statement never becomes False
我有一个矩形坐标列表,正在迭代以测试与每个坐标的碰撞。 列表如下所示: self.rectangle_list = [(200, 30, 100, 10), (200, 60, 100, 10), (200, 90, 100, 10), (200, 120, 100, 10), (200, 150, 100, 10)]
。 我的for循环代码如下。
mouse_x, mouse_y = event_obj.pos # mouse_x, mouse_y are the coordinates of the mouse.
for rects in self.rectangle_list:
x, y, w, h = rects
if x <= mouse_x <= x + w and y <= mouse_y <= y + h:
self.hovering = True
else:
self.hovering = False
print(self.hovering)
当我打印出self.hovering
,只有当鼠标光标在列表中最后一个矩形的坐标中时,它才会变为True。
当我在if
语句下移动self.hovering
,它可以工作,但是在不满足if
条件时,请勿将self.hovering
设置回False。
重现该问题的示例代码如下:
import pygame as pg
class RenderRects:
def __init__(self, surface, rects_to_render=0):
self.surface = surface
self.rects_to_render = rects_to_render
self.rectangle_list = []
self.hovering = False
def render_rects(self):
y_padding = 0
for rects in range(self.rects_to_render):
y_padding += 30
menu_items_rect = (200, y_padding, 100, 10)
pg.draw.rect(self.surface, (255, 0, 0), menu_items_rect)
if len(self.rectangle_list) > 5:
del self.rectangle_list[4:]
self.rectangle_list.append(menu_items_rect)
def check_for_rect_collision(self, event_obj):
#-----------------Where problem is-----------#
mx, my = event_obj.pos
for rects in self.rectangle_list:
x, y, w, h = rects
if x <= mx <= x + w and y <= my <= y + h:
self.hovering = True
else:
self.hovering = False
print(self.hovering)
#-----------------Where problem is-----------#
def update_rects(self, event_obj):
if event_obj.type == pg.MOUSEMOTION:
self.check_for_rect_collision(event_obj)
def main():
WIDTH = 800
HEIGHT = 600
display = pg.display.set_mode((WIDTH, HEIGHT))
R = RenderRects(display, rects_to_render=5)
running = True
while running:
for e in pg.event.get():
if e.type == pg.QUIT:
running = False
pg.quit()
quit()
R.update_rects(e)
display.fill((255, 255, 255))
R.render_rects()
pg.display.flip()
if __name__ == '__main__':
main()
您可以为列表中的每个矩形在循环内设置self.hovering
。 这意味着,在循环之后, self.hovering
的值self.hovering
对应于最后一个矩形的“悬停状态”。
我认为您想在循环之前设置self.hovering = False
,如果其中一个矩形符合您的条件,则在循环中将其设置为True
。 这样, self.hovering == True
仅在至少一个矩形与您的条件匹配时才成立。
这是您的问题的一个简单示例:
numbers = [2,3,4]
contains_odd = False
for number in numbers:
if number % 2 == 0:
contains_odd = False # this is wrong!
else:
contains_odd = True
# contains_odd == (numbers[2] % 2 == 1) == False
解决方案是:
numbers = [2,3,4]
contains_odd = False
for number in numbers:
if number % 2 == 1:
contains_odd = True
# contains_odd == True
您的if
陈述式有问题:
if x <= mouse_x <= x + w and y <= mouse_y <= y + h:
self.hovering = True
您不能像在以下情况中那样小于/大于: x <= mouse_x <= x + w
。 这确实可以转换为:
if x <= (mouse_x <= x + w) ....
并且由于True == 1
和False == 0
,所以这意味着如果mouse_x <= x + w
为True
,则x <= (mouse_x <= x + w)
实际上变为x <= 1
编辑-添加了其他问题解释 (建议给迈克尔·霍夫 ( Michael Hoff )
您的循环也有问题。 在循环中, 为每个矩形对设置变量self.hovering
。 这意味着您将不断用当前矩形的状态覆盖self.hovering
的值---如果任何一个矩形都在悬停,则不会。
相反,因为你不在乎self.hovering
是有史以来 True
,你应该只设置在值True
情况:
self.hovering = False # assume it's not hovering at first
for rects in self.rectangle_list:
x, y, w, h = rects
if x <= mouse_x and mouse_x <= x + w and y <= mouse_y and mouse_y <= y + h:
self.hovering = True # now it will always be True
虽然这解决了循环问题,但仍然有点低效,因为即使您找到使self.hovering = True
的对,它仍将继续循环对。 要在找到“好”对时停止循环,可以使用break
,它会过早地结束循环。
self.hovering = False # assume it's not hovering at first
for rects in self.rectangle_list:
x, y, w, h = rects
if x <= mouse_x and mouse_x <= x + w and y <= mouse_y and mouse_y <= y + h:
self.hovering = True # now it will always be True
break # exit the loop, since we've found what we're looking for
代码在列表中进行迭代,并且在每个步骤之后self.hovering都会更改。 因此,最后一个矩形决定打印哪个值,因为它是唯一影响它的值,因为在循环之外调用了打印功能。
更新 :
如果希望在任何矩形适合的情况下将其设置为True,则可以使用:
any([x <= mouse_x <= x + w and y <= mouse_y <= y + h for x,y,w,h in self.rectangle_list])
Any是一个内置函数,可将其作为参数进行迭代。 只要iterable中的任何值为True,否则返回True。 在这种情况下,给它一个由所谓的列表理解创建的列表。 列表理解等效于以下内容:
lis = []
for x, y, w, h in self.rectangle_list:
lis.append(x <= mouse_x <= x + w and y <= mouse_y <= y + h)
但是,它不需要先创建一个空列表,因此更加紧凑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.