简体   繁体   中英

Type Error when calling the metaclass bases

I'm working on this ( right now really messy ) code for an exercise in my studies.

After I've added the

super(TetrisBoard, self).__init__()

line to my code in the TetrisBoard __init__ method I keep getting the following error:

# 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) # 

I've tried reading around but I really can't seem to wrap my head around why this error happens and where the extra argument comes from. Here is my code:

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"]

Thanks to anyone who will explain where I'm doing wrong.

EDIT: I'm not sure it is significant but I'm running this code inside a Maya 2017 update 4 instance

  • Corrected some error in the code pointed out by @Isma

Your code is working fine except for some missing "self" references in the following methods (you were calling board directly instead of 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

Edit

If you still have the error, you might try to initialize the super class in a different way:

If you are using python 3 you can simplify your call to:

super().__init__()

You can also initialize your super class by calling the __init__ method like below, although this is not the best way, it may help you to find the problem, read the following for more info: Understanding Python super() with __init__() methods

DrawableGameObject.__init__(self)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM