Files
games/2022-2d-shooter/code/player.py
T

147 lines
3.7 KiB
Python

# library imports
import pygame
from pygame.math import Vector2 as vector
from os import walk
class Player(pygame.sprite.Sprite):
def __init__(self,pos, groups, path, collision_sprites):
super().__init__(groups)
self.import_assets(path)
self.frame_index = 0
self.status = 'down_idle'
# sprite
self.image = self.animations[self.status][self.frame_index]
self.rect = self.image.get_rect(center = pos)
# movement
self.pos = vector(self.rect.center)
self.direction = vector()
self.speed = 200
# collisions
self.hitbox = self.rect.inflate(0,-self.rect.height / 2)
self.collision_sprites = collision_sprites
self.attacking = False
def get_status(self):
# idle
if self.direction.x == 0 and self.direction.y == 0:
self.status = self.status.split('_')[0] + '_idle'
# attacking
if self.attacking:
self.status = self.status.split('_')[0] + '_attack'
def import_assets(self, path):
self.animations = {}
for index,folder in enumerate(walk(path)):
if index == 0:
for name in folder[1]:
self.animations[name] = []
else:
for file_name in sorted(folder[2], key = lambda string: int(string.split('.')[0])):
path = folder[0] + '/' + file_name
surf = pygame.image.load(path).convert_alpha()
key = folder[0].split('/')[3]
self.animations[key].append(surf)
def input(self):
keys = pygame.key.get_pressed()
if not self.attacking:
# horizontal input
if keys[pygame.K_RIGHT]:
self.direction.x = 1
self.status = 'right'
elif keys[pygame.K_LEFT]:
self.direction.x = -1
self.status = 'left'
else:
self.direction.x = 0
# vertical input
if keys[pygame.K_UP]:
self.direction.y = -1
self.status = 'up'
elif keys[pygame.K_DOWN]:
self.direction.y = 1
self.status = 'down'
else:
self.direction.y = 0
if keys[pygame.K_SPACE]:
self.attacking = True
self.direction = vector()
self.frame_index = 0
def move(self,dt):
# normalize movement
if self.direction.magnitude() != 0:
self.direction = self.direction.normalize()
# vertical movement + hitbox
self.pos.y += self.direction.y * self.speed * dt
self.hitbox.centery = round(self.pos.y)
self.rect.centery = self.hitbox.centery
self.collision('vertical')
# horizontal movement + hitbox
self.pos.x += self.direction.x * self.speed * dt
self.hitbox.centerx = round(self.pos.x)
self.rect.centerx = self.hitbox.centerx
self.collision('horizontal')
def animate(self,dt):
current_animation = self.animations[self.status]
self.frame_index += 10 * dt
if self.frame_index >= len(current_animation):
self.frame_index = 0
if self.attacking:
self.attacking = False
self.image = current_animation[int(self.frame_index)]
def collision(self,direction):
for sprite in self.collision_sprites.sprites():
if sprite.hitbox.colliderect(self.hitbox):
# if hasattr(sprite,'name') and sprite.name == '':
# pygame.quit
# sys.exit
if direction == 'horizontal':
if self.direction.x > 0: #moving right
self.hitbox.right = sprite.hitbox.left
self.rect.centerx = self.hitbox.centerx
self.pos.x = self.hitbox.centerx
if self.direction.x < 0: #moving right
self.hitbox.left = sprite.hitbox.right
self.rect.centerx = self.hitbox.centerx
self.pos.x = self.hitbox.centerx
else:
if self.direction.y > 0: # moving down
self.hitbox.bottom = sprite.hitbox.top
self.rect.centery = self.hitbox.centery
self.pos.y = self.hitbox.centery
if self.direction.y < 0: # moving up
self.hitbox.top = sprite.hitbox.bottom
self.rect.centery = self.hitbox.centery
self.pos.y = self.hitbox.centery
def update(self,dt):
self.input()
self.get_status()
self.move(dt)
self.animate(dt)