Pic 1 and 2 are animation skill of player. How can I create a hitbox like Pic 3 when collide with wall, floor, ...? Pic 4 is problem I got
Moreover, when player face to the left, the Image of player turns over and Character appear in different position its like Pic 5. I want when I face to the left, the Character stand still
1:
2:
3:
4:
5:
My sprites code:
import pygame
from settings import *
from pygame.math import Vector2 as vecto
from support import import_folder
from pygame.transform import scale
from pygame.transform import flip
class Player(pygame.sprite.Sprite):
def __init__(self, pos, group, collision_group):
super().__init__(group)
# self.image = scale(self.animations['right'][0], (64, 64))
self.image = pygame.image.load('../Fantasy/img/player/right/right.png')
self.rect = self.image.get_rect(topleft = pos)
self.import_player_assets()
#player movement
self.direction = vecto()
self.speed = 8
self.gravity = 0.8
self.jump_speed = 16
self.status = 'right'
self.frame_index = 0
self.animation_speed = 0.15
self.collsion_group = collision_group
self.on_floor = False
self.isRight = True
self.attacking = False
self.attack_time = None
self.attack_cooldown = 400
def import_player_assets(self):
player_path = '../Fantasy/img/player/'
self.animations = {'left':[],'left_idle':[],'right':[],'right_idle':[],'move': [], 'right_attack': [], 'left_attack':[], 'get_hit': [], 'die': []}
for animation in self.animations.keys():
full_path = player_path + animation
self.animations[animation] = import_folder(full_path)
def get_status(self):
if self.direction.x == 0 and self.direction.y == 0:
if not 'idle' in self.status and not 'attack' in self.status:
self.status = self.status + '_idle'
if self.attacking:
self.direction.x = 0
self.direction.y = 0
if not 'attack' in self.status:
if 'idle' in self.status:
self.status =self.status.replace('idle', 'attack')
else:
self.status = self.status + '_attack'
else:
self.status = self.status.replace('_attack', '')
def animate(self):
animation = self.animations[self.status]
self.frame_index += self.animation_speed
if self.frame_index >= len(animation):
self.frame_index = 0
self.image = animation[int(self.frame_index)]
self.display_surface = pygame.display.get_surface()
def input(self):
if not self.attacking:
#move left and right
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
self.direction.x = -1
self.status = 'left'
elif key[pygame.K_RIGHT]:
self.direction.x = 1
self.status = 'right'
else: self.direction.x = 0
# jump
if key[pygame.K_SPACE] and self.on_floor:
self.direction.y -= self.jump_speed
#attack
if key[pygame.K_c] and not self.attacking:
self.attacking = True
self.attack_time = pygame.time.get_ticks()
def move(self):
self.rect.x += self.direction.x * self.speed
def att_cooldown(self):
current_time = pygame.time.get_ticks()
if self.attacking:
if current_time - self.attack_time >= self.attack_cooldown:
self.attacking = False
def horizontal_collision(self):
for sprite in self.collsion_group.sprites():
if sprite.rect.colliderect(self.rect):
if self.direction.x < 0:
self.rect.left = sprite.rect.right
if self.direction.x > 0:
self.rect.right = sprite.rect.left
def vertical_collision(self):
for sprite in self.collsion_group.sprites():
if sprite.rect.colliderect(self.rect):
if self.direction.y < 0:
self.rect.top = sprite.rect.bottom
self.direction.y = 0
if self.direction.y > 0:
self.rect.bottom = sprite.rect.top
self.on_floor = True
self.direction.y = 0
if self.on_floor and self.direction.y != 0:
self.on_floor = False
def apply_gravity(self):
self.direction.y += self.gravity
self.rect.y += self.direction.y
def update(self):
self.input()
self.move()
self.horizontal_collision()
self.apply_gravity()
self.vertical_collision()
self.get_status()
self.animate()
self.att_cooldown()
class Tile(pygame.sprite.Sprite):
def __init__(self, pos, group):
super().__init__(group)
self.image = pygame.Surface((TILE_SIZE, TILE_SIZE))
self.image.fill(TILE_COLOR)
self.rect = self.image.get_rect(topleft = pos)