112 lines
3.5 KiB
Python
112 lines
3.5 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
|
|
|
|
# Get nearby tiles once
|
|
nearby_tiles = world.get_nearby_tiles(self.rect)
|
|
|
|
# Horizontal collisions
|
|
for tile in nearby_tiles:
|
|
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 nearby_tiles:
|
|
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)
|