【问题标题】:Changes to instance of a Class made by a tick() method aren't having a permanent effect通过 tick() 方法对类实例的更改不会产生永久影响
【发布时间】:2014-07-18 07:25:27
【问题描述】:

我正在开发一款涉及车辆类的游戏。它具有用于记录位置的 mapx 和 mapy 对象,以及还具有 x 和 y 对象的航点列表。游戏的每个滴答声,我都会遍历存储在列表中的所有 Vehicle 实例并调用方法 tick(),它应该将 mapx 和 mapy 值 1 移动到更接近列表中第一个航路点的 x 和 y 值。该方法的代码如下:

def Tick(self,universe):
        print("tick vehicle")
        print(self.waypoint[0].__dict__)
        if self.mapx > self.waypoint[0].x:
            self.mapx -= 1
            print("L")
        if self.mapx < self.waypoint[0].x:
            self.mapx += 1
            print("R")

        if self.mapy > self.waypoint[0].y:
            self.mapy -= 1
            print("U")
        if self.mapy < self.waypoint[0].y:
            self.mapy += 1
            print("D")

        print("Vehicle:"+str(self.mapx)+","+str(self.mapy))

我发现当游戏运行时,Vehicle 实例的 mapx 和 mapy 值根本没有改变,尽管所有 print() 调用都表明正在遵循正确的 if/then 语句。 tick() 方法不能改变 self 的属性有什么原因吗?

编辑:这是完整的车辆类:

import math

class Vehicle:
    def __init__(self,x,y):
        self.waypoint = []
        self.systems = []

        self.mapx = x
        self.mapy = y

        self.hp = 200
        self.regen = 1

        self.holding = {
            "Iron" : 0,
            "Coal" : 0,
            "Nickel" : 0,
            "RareEarthMetals" : 0,
            "Copper" : 0,
            "Oil" : 0,
            "Soy" : 0,
            "Algae" : 0,
            "Steel" : 0,
            "Stainless" : 0,
            "Machinery" : 0,
            "Robots" : 0,
            "Biotech" : 0,
            "Electronics" : 0,
            "Microchips" : 0,
            "Plastic" : 0,
            "Wire" : 0,
            "ConsumerGoods" : 0,
            "Food" : 0,
            "FastFood" : 0}

    def Tick(self,universe):
        print("tick vehicle")
        print(self.waypoint[0].__dict__)
        print("Vehicle Before:"+str(self.mapx)+","+str(self.mapy))
        if self.mapx > self.waypoint[0].x:
            self.mapx -= 1
            print("L")
        if self.mapx < self.waypoint[0].x:
            self.mapx += 1
            print("R")

        if self.mapy > self.waypoint[0].y:
            self.mapy -= 1
            print("U")
        if self.mapy < self.waypoint[0].y:
            self.mapy += 1
            print("D")

        print("Vehicle After:"+str(self.mapx)+","+str(self.mapy))

        if (self.mapx == self.waypoint[0].x) and (self.mapy == self.waypoint[0].y):
            if self.waypoint[0].type == "temp":
                current = self.waypoint[0]
                self.waypoint.remove(current)
            elif self.waypoint[0].type == "looping":
                current = self.waypoint[0]
                self.waypoint.remove(current)
                self.waypoint.append(current)

        for system in self.systems:
            if (self.mapx == system[0].mapx) and (self.mapy == system[0].mapy):
                if system[1].action == "RX":
                    for planet in system[0].planetList:
                        if planet.storedCommodities[system[1].subject] > 0:
                            quantity = planet.storedCommodities[system[1].subject]
                            planet.storedCommodities[system[1].subject] = 0
                            self.holding[system[1].subject] = quantity

                if system[1].action == "TX":
                    quantity = self.holding[system[1].subject]
                    system[0].planetList[system[1].destination].storedCommodities[system[1].subject] = quantity
                    self.holding[system[1].subject] = 0

        for otherVehicle in universe.vehicleList:
            if math.sqrt( (otherVehicle.mapx - self.mapx)**2 + (otherVehicle.mapy - self.mapy)**2 ) <= 5: self.attack(otherVehicle)

        if self.hp < 200:
            self.hp += self.regen

    def attack(self,otherVehicle):
        pass#pew pew pew

这是调用vehicle.Tick(self)的主循环:

def Tick(self):
        for system in self.systemList:
            system.Tick()

        for vehicle in self.vehicleList:
            vehicle.Tick(self)

【问题讨论】:

  • 在函数顶部添加另一个print。我敢打赌你会发现坐标在改变,只是每次你进入函数时它们都会被重置。这意味着问题出在您没有向我们展示的代码中。
  • 很好,它是。有什么想法可能导致这种情况吗?设置不是很复杂,我的主循环有一个 vehicleList 列表对象。通过在列表上的 .append() 调用中调用构造函数来添加车辆。然后,当游戏进行时,它调用的每个循环 for vehicle in self.vehicleList: vehicle.tick(self)
  • 为什么要强迫我们去尝试和猜测?提供一个minimal example 来重现您的问题。
  • 那是奇怪的部分:当 irecreate 这个设置在一个最小的例子中,问题不会发生。我添加了完整的代码,以防我没有注意到这会影响到这一点。

标签: python class methods namespaces self


【解决方案1】:

所以,我之所以回答这个问题,是因为经过大量调查后,我发现这些症状的原因是一个完全独立的问题,我认为不适合这里。当我在 for each 循环中调用 print(vehicle) 时,它是一个不同的内存地址,尽管它只是一辆车。我不确定 Python 是否应该这样做,返回对象的副本而不是对象本身,但这就是导致此问题的原因。

编辑:我是个大白痴,我没有意识到我的车辆列表不是一个实际的列表,而是来自多处理的列表管理器。很抱歉浪费了您的时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 2011-12-31
    • 2019-02-27
    相关资源
    最近更新 更多