Example #1
0
class Player(Physics):
    def __init__(self, world, onPlayerDead):
        super().__init__(
            (TILE_MAP_WIDTH / 2) * TILE_SIZE,
            -100,
            40,
            64
        )
        self.onPlayerDead = onPlayerDead
        self.invtry = []
        self.world = world
        self.didJump = False
        self.hp = 20
        self.theta = None  # angle of attack
        self.atk_counter = 0
        self.atk_speed = 25
        self.atk_strength = 3
        self.atk_range = 30000
        self.isFlipped = False
        self.hitCount = 0
        self.equipment = Equipment(world, self)
        self.too_fast = 0  # Fall damage
        self.score = 0
        self.stepFreq = 0


    def onOrePickup(self):
        self.score += 1

    def update(self):
        super().update()
        self.move()
        self.attack()
        self.fall_damage()
        self.equipment.update()
        PLAYER_HURT.update()
        PLAYER_WALKING.update()
        PLAYER_FALLING.update()
        PLAYER_JUMPING.update()
        PLAYER_BREATHING.update()



    def move(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_a]:
            self.x_vel -= WALK_ACCN

        if keys[pygame.K_d]:
            self.x_vel += WALK_ACCN

        if self.x_vel > WALK_SPEED:
            self.x_vel = WALK_SPEED
        
        if self.x_vel < -WALK_SPEED:
            self.x_vel = -WALK_SPEED
    

        if keys[pygame.K_SPACE] and not self.didJump:
            audio.onJump()
            self.didJump = True
            self.y_vel = -JUMP_POWER

        self.x_vel = self.x_vel * 0.8


    def playMove(self):
        if self.stepFreq == 0:
            audio.onStep()
            self.stepFreq = 20
        else:
            self.stepFreq -= 1


    def health_bar(self, screen):
        if self.hp > 0:
            colour = (0, 255, 0)
            if self.hp < 10:
                colour = (240, 235, 86)
                if self.hp < 5:
                    colour = (240, 0 , 0)

            pygame.draw.rect(screen, colour, (SCREEN_WIDTH/2 - 20, SCREEN_HEIGHT/2 - (self.height * 0.6), self.hp*2, 5))




    def render(self, screen, camera):
        imageInflate = 12
        xPos = self.x - camera.x - imageInflate
        yPos = self.y - camera.y

        isFalling = self.y_vel > 0.05
        isJumping = self.y_vel < -0.05
        isWalking = abs(self.x_vel) > 0.05 and not (isFalling or isJumping)

        if self.x_vel < 0:
            self.isFlipped = True

        if self.x_vel > 0:
            self.isFlipped = False

        width = self.width + imageInflate * 2

        if self.hitCount > 0:
            self.hitCount -= 1
            PLAYER_HURT.draw(screen, xPos, yPos, width, self.height, self.isFlipped)
        elif isWalking:
            self.playMove()
            PLAYER_WALKING.draw(screen, xPos, yPos, width, self.height, self.isFlipped)
        elif isFalling:
            PLAYER_FALLING.draw(screen, xPos, yPos, width, self.height, self.isFlipped)
        elif isJumping:
            PLAYER_JUMPING.draw(screen, xPos, yPos, width, self.height, self.isFlipped)
        else: 
            PLAYER_BREATHING.draw(screen, xPos, yPos, width, self.height, self.isFlipped)

        self.health_bar(screen)
        self.equipment.render(screen, camera)

      
                
    def onHitFloor(self):
        super().onHitFloor()
        self.didJump = False
        if abs(self.y_vel) > 0.2:
            audio.onDrop()


    def onHitByEntity(self, amount, x, y):
        diffX = self.x - x
        HIT_AMOUNT = 10
        self.x_vel += HIT_AMOUNT if diffX > 0 else -HIT_AMOUNT
        self.onHurt(amount)

    def onHurt(self, amount):
        self.hp -= amount
        self.hitCount = 10
        PLAYER_HURT.reset()
        self.world.camera.shake(10)
        if (self.hp < 0):
            audio.onPlayerHit()
            self.onPlayerDead()
        else:
            audio.onPlayerDead()



    def fall_damage(self):
        if self.y_vel > 8:
            self.too_fast = self.y_vel
        if self.too_fast != 0 and self.floor:
            self.onHurt(self.too_fast/7)
            self.too_fast = 0


    def attack(self):
        mouse = pygame.mouse.get_pressed()
        
        self.theta = None
        distance = TILE_SIZE * 0.9

        if mouse[0] == 1:
            mp = pygame.mouse.get_pos()
            x_dist = SCREEN_WIDTH/2 - mp[0]
            y_dist = mp[1] - SCREEN_HEIGHT/2

            theta = np.angle(x_dist + y_dist * 1j) + np.pi

            targetX = (distance * np.cos(theta)) + self.x + self.width / 2
            targetY = -distance * np.sin(theta) + self.y + self.height / 2

            if self.atk_counter == 0:
                self.theta = theta
                self.world.tileMap.damageTile(targetX, targetY, 0.2)
                self.equipment.onAttack()

            self.atk_counter += 1

        elif self.atk_counter != 0:
            self.atk_counter += 1

        if self.atk_counter == self.atk_speed:
            self.atk_counter = 0