[英]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.