我正在进行坦克游戏,我有坦克和子弹物。当我开火时,执行以下方法:
def newshot(self,tank):
shot = bullet()
shot.loc = tank.loc
shot.speed = tank.direction
self.shots.append(shot)
loc是一个列表,显示位置[x,y],速度和方向是显示速度[dx,dy]的列表。
为了移动每个项目符号,将速度向量添加到for循环中的位置。但每当我改变子弹的位置时,我的坦克的位置也会发生变化(我在for循环之前和之后打印出一个坦克位置)。 我做了什么解决了我的问题是,而不是做
shot.loc = tank.loc
我做了
shot.loc = [tank.loc[0],tank.loc[1]]
我的问题是区别在哪里?
答案 0 :(得分:2)
您复制了引用而不是值,这意味着两个变量指向同一个对象。
来自https://docs.python.org/2/library/copy.html:
Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变或包含可变项的集合,有时需要一个副本,因此可以更改一个副本而不更改另一个副本。
将tank.loc
列表复制到shot.loc
的最简单方法是对整个列表进行切片:
shot.loc = tank.loc[:]
但请参阅https://stackoverflow.com/a/2612815/768176了解其他有效建议。
答案 1 :(得分:1)
使用时:
shot.loc = tank.loc
shot.loc
和tank.loc
是对同一列表的引用。
要复制列表,请使用:
shot.loc = tank.loc[:]
答案 2 :(得分:0)
您需要deepcopy
列表。即:
import copy
shot.loc = copy.deepcopy(tank.loc)
这是它的工作原理:
a = [[1, 2, 3], [4, 5, 6]]
b = a
a[0][1] = 10
print a
# [[1, 10, 3], [4, 5, 6]]
print b # b changes too -> Not a deepcopy.
# [[1, 10, 3], [4, 5, 6]]
import copy
b = copy.deepcopy(a)
a[0][1] = 9
print a
#[[1, 9, 3], [4, 5, 6]]
print b # b doesn't change -> Deep Copy
#[[1, 10, 3], [4, 5, 6]]