调用元类基时出现类型错误

2024-10-01 18:51:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在写这个(现在真的很乱)代码,作为我学习中的一个练习。你知道吗

在我添加了

super(TetrisBoard, self).__init__()

在TetrisBoard__init__方法的代码行中,我不断得到以下错误:

# Error: Error when calling the metaclass bases
#     __init__() takes exactly 3 arguments (4 given)
# Traceback (most recent call last):
#   File "<maya console>", line 4, in <module>
# TypeError: Error when calling the metaclass bases
#     __init__() takes exactly 3 arguments (4 given) # 

我试着四处阅读,但我似乎真的不明白为什么会发生这种错误,以及额外的论点是从哪里来的。 这是我的密码:

import math
from abc import ABCMeta, abstractmethod

class Point(object):
    def __init__(self, x, y):
        super(Point, self).__init__()

        self.x = x
        self.y = y

    def rotatePoint(self, centerOfRotation, radians):
        coordinateRelativeToCenter = Point.pointOnNewPlane(self, centerOfRotation)

        newRelativeX = round(coordinateRelativeToCenter.x * math.cos(radians) - coordinateRelativeToCenter.y * math.sin(radians))
        newRelativeY = round(coordinateRelativeToCenter.x * math.sin(radians) + coordinateRelativeToCenter.y * math.cos(radians))

        coordinateRelativeToOrigin = Point.pointOnNewPlane(Point(newRelativeX, newRelativeY), Point(-centerOfRotation.x, -centerOfRotation.y))

        self.x = coordinateRelativeToOrigin.x
        self.y = coordinateRelativeToOrigin.y       

    def translatePoint(self, translateX, translateY):
       self.x += translateX
       self.y += translateY

    @classmethod 
    def pointOnNewPlane(cls, point, origin):
        resultPoint = Point(point.x, point.y)

        resultPoint.x -= origin.x
        resultPoint.y -= origin.y

        return resultPoint

    def getX(self):
        return self.x
    def getY(self):
        return self.y

class GameObjectManager(object):
    _gameObjects = [None]
    _freeId = 0

    @classmethod
    def nextId(cls):
        id = cls._freeId
        cls._updateFreeId()
        return id

    @classmethod
    def _updateFreeId(cls):
        try:
            cls._freeId = cls._gameObjects[cls._freeId:].index(None)
        except ValueError:
            cls._gameObjects.append(None)
            cls._updateFreeId

    @classmethod
    def addGameObject(cls, object):
        cls._gameObjects[object.getId()] = object

    @classmethod
    def deleteGameObject(cls, id):
        cls._gameObjects[id] = None

        if ( id  < cls._freeId ):
            cls.freeId = id     

    @classmethod
    def getObjects(cls):
        return cls._gameObjects

class CollisionManager(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def collides(self, positions):
       pass


class BoardCollisionManager(CollisionManager):
    def __init__(self, board):
       super(BoardCollisionManager, self).__init__()

       self.board = board

    def collides(self, id, position):
        return self.collidesWithOtherObjects(id, position) or self.collidesWithTheEnviroment(id, position)

    def collidesWithOtherObjects(self, id, positions):
        result = False

        for position in positions:
           if self.board.isCellOccupied(position) and self.board.getCell(position) != id:
               result = True
        return result

    def collidesWithTheEnviroment(self, id, positions):
        result = False

        for position in positions:
            if self.board.isOutsideBoardBounds(position):
                result = True
        return result

class GameObject(object):
    STATES = {"DEFAULT":0} 

    def __init__(self):
        super(GameObject, self).__init__()
        self._id = GameObjectManager.nextId()
        self.state = "DEFAULT"

    @abstractmethod
    def update(self):
        pass

    def getId(self):
        return self._id

class DrawableGameObject(GameObject):
    __metaclass__ = ABCMeta

    DEFAULT_SPEED = 1
    DEFAULT_DIRECTION = Point(0, -1)
    DEFAULT_ACCELERATION = 1

    def __init__(self):
        super(DrawableGameObject, self).__init__()

        self.speed = DrawableGameObject.DEFAULT_SPEED
        self.direction = DrawableGameObject.DEFAULT_DIRECTION
        self.acceleration = DrawableGameObject.DEFAULT_ACCELERATION

    @abstractmethod
    def draw(self, canvas):
        pass

    def nextPosition(self, position, direction, speed):
        return Point(position.x + (direction.x * speed), position.y + (direction.y * speed))


class TetrisBoard(DrawableGameObject):
    def __init__(self, width, height):
        super(TetrisBoard, self).__init__()

        self.width = width
        self.height = height
        self.state = []

        for row in range(height):
            self.state.append([None for dummy in range(width)])

    def drawShape(self, shape):
        for point in shape.getPoints():
            self.state[point.getY()][point.getX()] = shape.getId()

    def isCellOccupied(self, position):
        return True if self.getCell(position) is not None else False

    def getCell(self, position):
        return self.state[position.getY()][position.getX()]

    def isOutsideBoardBounds(self, position):
        return True if ((position.x > self.width or position.x < 0) or (position.y > self.height or position.y < 0)) else False

    def resetBoard(self):
        for row in self.state:
            for cell in row:
               cell = None

    def update(self):
        self.resetBoard()

    def draw(self, canvas):
        pass



class Shape(GameObject):
    def __init__(self, points, center=0):
        super(Shape, self).__init__()

        self.points = points
        self.center = center


    def rotateAroundCenter(self, radians):
        for point in self.points:
            point.rotatePoint(self.center, radians)

    def getPoints(self):
        return self.points

class Tetromino(DrawableGameObject):
    STATES = {"FALLING":0, "ANCHORED":1, "MOVINGLEFT":3, "MOVINGRIGHT":4, "ROTATING":5}

    def __init__(self, shape, collisionManager=None, position=Point(0, 0)):
        super(Tetromino, self).__init__()

        self.shape = shape
        self.collisionManager = collisionManager
        self.position = position

        self.acceleration = 0

    def update(self):
        if ( self.state == Tetromino.STATES["ANCHORED"] ):
            pass

        if ( self.state == Tetromino.STATES["ROTATING"]):
            self.shape.rotateAroundCenter(math.radians(90))

        if ( self.state == Tetromino.STATES["MOVINGLEFT"] ):
            self.direction.x = -1
        if ( self.state == Tetromino.STATES["MOVINGRIGHT"]):
            self.direction.x = 1

        nextPositions = [self.nextPosition(position, self.direction, self.speed) for position in self.shape.getPoints()]

        if ( self.collisionManager.collides(self._id, nextPositions)):
            nextPositions = self.shape.getPoints()
        self.shape.points = nextPositions

        self.state = Tetromino.STATES["FALLING"]

    def draw(self, canvas):
        canvas.drawShape(self.shape)

    def moveLeft(self):
        self.state = Tetromino.STATES["MOVINGLEFT"]

    def moveRight(self):
        self.state = Tetromino.STATES["MOVINGRIGHT"]

    def rotate(self):
        self.state = Tetromino.STATES["ROTATING"]

感谢所有能解释我错在哪里的人。你知道吗

编辑:我不确定它是否重要,但我正在Maya 2017 update 4实例中运行此代码

  • 修正了@Isma指出的代码中的一些错误

Tags: inselfidreturnifinitdefposition
1条回答
网友
1楼 · 发布于 2024-10-01 18:51:40

您的代码运行良好,除了以下方法中缺少一些“self”引用(您是直接调用board而不是自板)地址:

def collidesWithOtherObjects(self, id, positions):
    result = False

    for position in positions:
       if self.board.isCellOccupied(position) and self.board.getCell(position) != id:
           result = True
    return result

def collidesWithTheEnviroment(self, id, positions):
    result = False

    for position in positions:
        if self.board.isOutsideBoardBounds(position):
            result = True
    return result

编辑

如果仍然存在错误,可以尝试以不同的方式初始化超类:

如果您使用的是python 3,则可以简化对以下对象的调用:

super().__init__()

您也可以通过调用下面的__init__方法来初始化您的超类,尽管这不是最好的方法,但它可能会帮助您找到问题,请阅读以下内容以获取更多信息:Understanding Python super() with __init__() methods

DrawableGameObject.__init__(self)

相关问题 更多 >

    热门问题