我有一个for循环,该循环应该迭代等于数组长度的次数。循环运行正确的次数,但是索引没有正确增加。
我尝试用i = i + 1手动递增i,但这似乎并没有改变任何东西。
room = [['x','x','x','x','x'],['x','.','.','.','x'],['x','.','.','.','x'],['x','.','.','.','x'],['x','x','x','x','x']]
entities = []
class Entity:
def __init__(self, x_pos, y_pos):
self.x_pos = x_pos
self.y_pos = y_pos
self.new_x_pos = x_pos
self.new_y_pos = y_pos
def Move(self, x_move, y_move):
self.new_y_pos = self.y_pos + y_move
self.new_x_pos = self.x_pos + x_move
if self.CheckCollision(self) is True:
print("collision")
if self.CheckCollision(self) is False:
self.new_x_pos = self.x_pos
self.new_y_pos = self.y_pos
def CheckCollision(self, entity1):
for i in range(len(entities)-1):
#this loop here. It runs twice, but the value of i is zero for both iterations
entity = entities[i]
print(i)
if entity1.new_y_pos == entity.y_pos:
if entity1.new_x_pos == entity.x_pos:
return True
break
else:
return False
calipso = Entity(1, 1)
entities.append(calipso)
joseph = Entity(3,2)
entities.append(joseph)
print(entities)
calipso.Move(1,1)
print(calipso.x_pos, calipso.y_pos, sep=' ')
我希望我增加for循环的每次迭代,因此对于第一次迭代,i === 0,对于第二次迭代,i === 1。目前,两次迭代的i === 0,我不知道为什么。
答案 0 :(得分:1)
for
循环存在一些问题。首先,如果y
位置匹配,但x
值不匹配,则什么也不会发生。但是,除非出现这种情况,否则for
循环将始终在第一次迭代后退出,因为如果位置重合,则会调用return True
(顺便说一下,由于return True
,您不会之后就不需要break
了。否则,它将返回False
。
因此在Move
内,CheckCollision
被调用两次,每个if
语句一次,这就是i
被打印两次,0
两次的原因。
要解决此问题,您必须让CheckCollision
返回False
外 for
循环,以便它检查所有实体以确保它不会碰撞任何东西。
要考虑的最后一件事是,您永远不要检查entity1
和entity
没有引用同一对象。在某些情况下会导致实体与自身发生碰撞!在没有完全修改方法本身以使其与其他答案相同的情况下,要解决的唯一选项是将每种id
附加到某种唯一的entity
,但要修改方法(与其他答案一样)绝对是更好的选择。
从风格上讲,类的方法名称应始终以小写字母开头(因此您的方法应为move
,checkCollision
等)。
编辑:在这种情况下,i
永远也不会进入1
。这是因为len(entities)
是2
,所以for
循环将从0
到1
,不包括结尾,所以无论它停止了什么在第一次迭代之后。但是,如果您有更多的实体,则会遇到上述问题。
答案 1 :(得分:1)
我已经重构了您的代码,以便checkCollision方法按照我认为的含义工作。查看代码中的注释。我更改了方法的名称,以小写字母开头。
class Entity:
def __init__(self, x_pos, y_pos):
self.x_pos = x_pos
self.y_pos = y_pos
self.new_x_pos = x_pos
self.new_y_pos = y_pos
def move(self, x_move, y_move):
self.new_x_pos = self.x_pos + x_move
self.new_y_pos = self.y_pos + y_move
if self.checkCollision() is True:
# We don't update x_pos and y_pos here since collision means entity shouldn't move
print("collision")
return False
else: # You need to use ELSE here so that you don't end up calling checkCollision twice
# if checkCollision returned a False, then we can update the position of entity
self.x_pos = self.new_x_pos
self.y_pos = self.new_y_pos
return True
def checkCollision(self):
for entity in entities:
# Iterate through every entity other than self and see if their position is the same as self's possible new position
if entity != self and entity.x_pos == self.new_x_pos and entity.y_pos == self.new_y_pos:
return True
# Return false if no collision occurs after checking through every entity
return False
calipso = Entity(1, 1)
entities.append(calipso)
joseph = Entity(3,2)
entities.append(joseph)
calipso.move(1,1) # successful move
print(calipso.x_pos, calipso.y_pos, sep=' ') # prints 2 2 after succesful move
calipso.move(1,0) # collision with joseph, fails
print(calipso.x_pos, calipso.y_pos, sep=' ') # prints 2 2, calipso did not move