Beispiel #1
0
class Enemy():
    def __init__(self, enemyType, **kwargs):
        self.canvas = InstructionGroup()

        self.enemyType = enemyType
        self.sprite = Sprite()

        if self.enemyType == 'normal':
            self.setOffsetTheta(0)
            self.sprite.color.r = 0.0
            self.sprite.color.g = 0.2
            self.sprite.color.b = 0.5
        else:
            self.setOffsetTheta(math.pi / 2)
            self.sprite.color.r = 0.5
            self.sprite.color.g = 0.1
            self.sprite.color.b = 0.1

        self.health = 100

        self.pos = (0, 0)
        self.velocity = [0, 0]

        self.updateAppearance()

        self.canvas.add(self.sprite.canvas)

        self.shouldRemove = False

    def setOffsetTheta(self, offsetTheta):
        self.offsetTheta = offsetTheta
        self.otcos = math.cos(self.offsetTheta)
        self.otsin = math.sin(self.offsetTheta)


    def reset(self, isRespawned):
        sample = random.random()
        theta = math.pi * 2 * sample
        speed = 0.1
        self.isRespawned = isRespawned
        self.velocity = [math.cos(theta) * speed,
                         math.sin(theta) * speed]

    def setWorld(self, world):
        self.world = world

    def setCenterPos(self, centerPos):
    	self.pos = centerPos
        self.sprite.setCenterPos(centerPos)

    def decrement(self, beamState):
        delta = 0
        if beamState == 1:
            self.health -= 10
            if self.enemyType == 'normal':
                delta = 100
            else:
                delta = -500

        if self.health <= 0:
            self.shouldRemove = True
        else:
            self.updateAppearance()

        return delta



    def updateAppearance(self):
        baseSize = 30
        if not self.enemyType == 'normal':
            baseSize = 15

        factor = math.log(100 - self.health + 1)
        self.sprite.setSizeScalar(baseSize + factor * 10)

    def update(self, dt):
        worldVector = (self.world.direction[0] * self.world.speed,
                       self.world.direction[1] * self.world.speed)
        worldOffset = (worldVector[0] * self.otcos - worldVector[1] * self.otsin,
                       worldVector[0] * self.otsin - worldVector[1] * self.otcos)

        centerPos = (self.pos[0] + self.velocity[0] + worldOffset[0],
                     self.pos[1] + self.velocity[1] + worldOffset[1])

        if self.isRespawned:
            self.isRespawned = False

        if centerPos[0] < self.world.left:
            self.shouldRemove = True

        if centerPos[0] > self.world.right:
            self.shouldRemove = True

        if centerPos[1] < self.world.left:
            self.shouldRemove = True

        if centerPos[1] > self.world.right:
            self.shouldRemove = True

        self.setCenterPos(centerPos)
Beispiel #2
0
class Player():
    def __init__(self, playerCode, **kwargs):
        self.canvas = InstructionGroup()

        self.sprite = Sprite()

        self.playerCode = playerCode
        self.frameNum = 0

        self.bottomLeft = (0, 0)
        self.topRight = (700, 500)
        self.pos = (0, 0)

        self.direction = (0, 0)
        self.speed = 0
        self.targetDirection = (0, 0)
        self.targetSpeed = 0
        self.isTweeningDirection = False
        self.isTweeningSpeed = False
        self.newDirectionSince = 0
        self.newSpeedSince = 0
        self.directionChange = (0, 0)

        if playerCode == 'p2':
        	self.sprite.color.r = 1

        if playerCode == 'enemy1':
        	self.sprite.color.b = 1

        self.canvas.add(self.sprite.canvas)

    def reset(self):
        self.frameNum = 0

    def setBounds(self, bottomLeft, topRight):
        self.bottomLeft = bottomLeft
        self.topRight = topRight

    def setCenterPos(self, centerPos):
    	self.pos = centerPos
        self.sprite.setCenterPos(self.pos)

    def setPlayerKeyReport(self, playerKeyReport):
        self.playerKeyReport = playerKeyReport

    def update(self, dt):
        self.frameNum += 1
        self.updateDynamics()
        self.updateTweening()
        self.updatePosition()

    def updateDynamics(self):
        dX = 0
        dY = 0
        scale = 1
        speed = 0

        if self.playerKeyReport.up:
            dY = 1
        elif self.playerKeyReport.down:
            dY = -1

        if self.playerKeyReport.left:
            dX = -1
        elif self.playerKeyReport.right:
            dX = 1

        if not dY == 0 and not dX == 0:
            scale = SQRT_2_DIV_2

        if not dY == 0 or not dX == 0:
            speed = TOP_SPEED

        targetDirection = (dX * scale, dY * scale)
        wasNullDirection = (self.targetDirection[0] == 0 and self.targetDirection[1] == 0)
        isNullDirection = (targetDirection[0] == 0 and targetDirection[1] == 0)
        isNewTargetDirection = (not self.targetDirection[0] == targetDirection[0] or
                                not self.targetDirection[1] == targetDirection[1])
        if not isNullDirection and isNewTargetDirection:
            if wasNullDirection:
                self.targetDirection = targetDirection
                self.direction = targetDirection
            else:
                self.isTweeningDirection = True
                self.newDirectionSince = self.frameNum
                self.targetDirection = targetDirection
                self.calculateDirectionVector()

        isNewTargetSpeed = not self.targetSpeed == speed
        if isNewTargetSpeed:
            self.isTweeningSpeed = True
            self.newSpeedSince = self.frameNum
            self.targetSpeed = speed

    def updateTweening(self):
        self.updateSpeedTweening()
        self.accountForZeroSpeed()
        self.updateDirectionTweening()

    def updateSpeedTweening(self):
        if not self.isTweeningSpeed:
            return

        speedDelta = 1
        speedDirection = 1
        speedTweeningContinues = True
        if self.targetSpeed < self.speed:
            speedDirection = -1

        nextSpeed = self.speed + speedDirection * speedDelta
        if speedDirection == -1 and nextSpeed < self.targetSpeed:
            nextSpeed = self.targetSpeed
            speedTweeningContinues = False
        elif speedDirection == 1 and nextSpeed > self.targetSpeed:
            nextSpeed = self.targetSpeed
            speedTweeningContinues = False

        self.speed = nextSpeed
        self.isTweeningSpeed = speedTweeningContinues

    def accountForZeroSpeed(self):
        if self.speed == 0:
            self.isTweeningDirection = False
            self.targetDirection = (0, 0)
            self.direction = (0, 0)

    def calculateDirectionVector(self):
        subdivs = 5
        vector = (self.targetDirection[0] - self.direction[0],
                  self.targetDirection[1] - self.direction[1])
        vectorLength = math.sqrt(math.pow(vector[0], 2) + math.pow(vector[1], 2))
        self.directionChange = (vector[0] / (vectorLength * subdivs),
                                vector[1] / (vectorLength * subdivs))


    def updateDirectionTweening(self):
        if not self.isTweeningDirection:
            return

        nextDirection = self.direction
        directionTweeningContinues = True

        nextDirection = (self.direction[0] + self.directionChange[0],
                         self.direction[1] + self.directionChange[1])
        remainder = (nextDirection[0] - self.targetDirection[0],
                     nextDirection[1] - self.targetDirection[1])
        targetDirectionLen = math.sqrt(math.pow(self.targetDirection[0], 2) +
                                       math.pow(self.targetDirection[1], 2))
        # "unrotate" the remainder by the target direction so we
        # can compare distance along that line.
        if False:
            dotA = self.targetDirection[0] * remainder[0] / targetDirectionLen
            dotB = self.targetDirection[1] * remainder[1] / targetDirectionLen
            dot = dotA + dotB
            didOvershoot = (dot < 0)

        ## Check if we went out of the unit circle
        len = math.pow(nextDirection[0], 2) + math.pow(nextDirection[1], 2)
        didOvershoot = len > 1

        if didOvershoot:
            nextDirection = self.targetDirection
            directionTweeningContinues = False


        self.direction = nextDirection
        self.isTweeningDirection = directionTweeningContinues


    def updatePosition(self):
        if self.speed <= 0.001:
            return

        len = math.sqrt(math.pow(self.direction[0], 2) + math.pow(self.direction[1], 2))
        if len == 0:
            return
        newCoords = (self.pos[0] + self.direction[0] * self.speed / len,
                     self.pos[1] + self.direction[1] * self.speed / len)

        self.setCenterPos(newCoords)