Projectdd/player.py

115 lines
3.4 KiB
Python

import pygame
from settings import *
class Player:
def __init__(self, x, y):
# Position & Size
self.rect = pygame.Rect(x, y, PLAYER_WIDTH, PLAYER_HEIGHT)
# Movement
self.velocity = pygame.Vector2(0, 0)
self.acceleration = pygame.Vector2(0, 0)
# State
self.on_ground = False
self.facing_right = True
# Stats
self.health = MAX_HEALTH
# ==========================================================
# UPDATE
# ==========================================================
def update(self, dt, world):
self.handle_input()
self.apply_physics(dt)
self.handle_collisions(world)
# ==========================================================
# INPUT
# ==========================================================
def handle_input(self):
keys = pygame.key.get_pressed()
self.acceleration.x = 0
# Horizontal movement
if keys[pygame.K_a]:
self.acceleration.x = -PLAYER_ACCELERATION
self.facing_right = False
if keys[pygame.K_d]:
self.acceleration.x = PLAYER_ACCELERATION
self.facing_right = True
# Apply friction
self.acceleration.x += self.velocity.x * PLAYER_FRICTION
# Jump
if keys[pygame.K_SPACE] and self.on_ground:
self.velocity.y = JUMP_FORCE
self.on_ground = False
# ==========================================================
# PHYSICS
# ==========================================================
def apply_physics(self, dt):
# Apply gravity
self.acceleration.y = GRAVITY
# Update velocity
self.velocity += self.acceleration * dt
# Clamp fall speed
if self.velocity.y > MAX_FALL_SPEED:
self.velocity.y = MAX_FALL_SPEED
# Move horizontally
self.rect.x += self.velocity.x * dt
# Move vertically
self.rect.y += self.velocity.y * dt
# ==========================================================
# COLLISIONS
# ==========================================================
def handle_collisions(self, world):
self.on_ground = False
# Horizontal collisions
for tile in world.get_nearby_tiles(self.rect):
if tile["rect"].colliderect(self.rect) and tile["solid"]:
if self.velocity.x > 0: # Moving right
self.rect.right = tile["rect"].left
elif self.velocity.x < 0: # Moving left
self.rect.left = tile["rect"].right
self.velocity.x = 0
# Vertical collisions
for tile in world.get_nearby_tiles(self.rect):
if tile["rect"].colliderect(self.rect) and tile["solid"]:
if self.velocity.y > 0: # Falling
self.rect.bottom = tile["rect"].top
self.on_ground = True
elif self.velocity.y < 0: # Jumping up
self.rect.top = tile["rect"].bottom
self.velocity.y = 0
# ==========================================================
# DRAW
# ==========================================================
def draw(self, screen, camera):
draw_rect = camera.apply(self.rect)
pygame.draw.rect(screen, (255, 50, 50), draw_rect)
if SHOW_COLLIDERS:
pygame.draw.rect(screen, (0, 255, 0), draw_rect, 2)