coding a fighting game based off of this video https://www.youtube.com/watch?v=s5bd9KMSSW4&ab_channel=CodingWithRuss and changed the spritesheets to characters from a different game series. When using the code, i changed the dimensions of the spritesheet but when running the code, the game shows the same 4 sprites instead of an small animation. Can someone tell me why it doesnt work?
if anyone wants to help and needs the code and the sprite sheet to help here they are
import pygame
class Fighter:
def __init__(self, x, y, data, sprite_sheet, animation_steps):
self.size = data[0]
self.image_scale = data[1]
self.offset = data[2]
self.flip = False
self.animation_list = self.load_images(sprite_sheet, animation_steps)
self.action = 0 # 0:idle #1:run #2:jump #3:attack1 #4: attack2 #5:hit #6:death
self.frame_index = 0
self.image = self.animation_list[self.action][self.frame_index]
self.update_time = pygame.time.get_ticks()
self.rect = pygame.Rect((x, y, 80, 180))
self.vel_y = 0
self.running = False
self.jump = False
self.attacking = False
self.attack_type = 0
self.health = 120
self.attack_cooldown = 0 # New cooldown timer
def load_images(self, sprite_sheet, animation_steps) :
animation_list = [ ]
sprite_sheet_height = sprite_sheet.get_height()
sprite_sheet_width = sprite_sheet.get_width()
num_animation_rows = len(animation_steps)
# If frames in width are not consistent, calculate based on steps and sheet width
for y, frames_in_row in enumerate(animation_steps) :
temp_img_list = [ ]
total_frames = animation_steps [ y ]
frame_width = sprite_sheet_width // total_frames # No of frames in the row
frame_height = sprite_sheet_height // num_animation_rows # No of rows in the sheet
print(
f"Loading row {y}: frame_width={frame_width}, frame_height={frame_height}, total_frames={total_frames}") # Debug
for x in range(total_frames) :
frame_x = x * frame_width
frame_y = y * frame_height
temp_img = sprite_sheet.subsurface((frame_x, frame_y, frame_width, frame_height))
scaled_img = pygame.transform.scale(temp_img, (
int(frame_width * self.image_scale), int(frame_height * self.image_scale)))
pygame.draw.rect(scaled_img, (255, 0, 0), scaled_img.get_rect(), 1) # Draw rectangle for debugging
temp_img_list.append(scaled_img)
print(f"Frame {x} in row {y}: dimensions={temp_img.get_rect()}") # Debug
animation_list.append(temp_img_list)
return animation_list
def move(self, screen_width, screen_height, surface, target):
speed = 10
gravity = 2
dx = 0
dy = 0
self.running = False
# Get keypresses
key = pygame.key.get_pressed()
# Cooldown logic
if self.attack_cooldown > 0:
self.attack_cooldown -= 1
else:
self.attacking = False
if not self.attacking:
if key[pygame.K_a]: # Move left
dx = -speed
self.running = True
if key[pygame.K_d]: # Move right
dx = speed
self.running = True
# Jump
if key[pygame.K_w] and self.rect.bottom >= screen_height - 110:
self.vel_y = -30
self.jump = True
# Attack
if key[pygame.K_r] or key[pygame.K_t]:
self.attack(surface, target)
if key[pygame.K_r]:
self.attack_type = 1
if key[pygame.K_t]:
self.attack_type = 2
# Apply gravity
self.vel_y += gravity
dy += self.vel_y
# Ensure player stays on screen
if self.rect.left + dx < 0:
dx = -self.rect.left
if self.rect.right + dx > screen_width:
dx = screen_width - self.rect.right
if self.rect.bottom + dy > screen_height - 110:
dy = screen_height - 110 - self.rect.bottom
self.vel_y = 0
# Ensure players face each other
self.flip = target.rect.centerx < self.rect.centerx
# Update player position
self.rect.x += dx
self.rect.y += dy
def update(self):
# Check what action the player is performing
if self.jump == True:
self.update_action(2) #Jumping action
if self.running:
self.update_action(1) # Running action
else:
self.update_action(0) # Idle action
animation_cooldown = 100
self.image = self.animation_list[self.action][self.frame_index]
if pygame.time.get_ticks() - self.update_time > animation_cooldown:
self.frame_index += 1
self.update_time = pygame.time.get_ticks()
if self.frame_index >= len(self.animation_list[self.action]):
self.frame_index = 0
def attack(self, surface, target):
if not self.attacking:
self.attacking = True
self.attack_cooldown = 30
attacking_rect = pygame.Rect(
self.rect.centerx - (2 * self.rect.width * self.flip),
self.rect.y,
2 * self.rect.width,
self.rect.height
)
if attacking_rect.colliderect(target.rect):
target.health -= 10
pygame.draw.rect(surface, (0, 255, 0), attacking_rect)
def update_action(self, new_action):
# Check if the new action is different from the current action
if new_action != self.action:
self.action = new_action
# Reset the animation settings
self.frame_index = 0
self.update_time = pygame.time.get_ticks()
def draw(self, surface):
img = pygame.transform.flip(self.image, self.flip, False)
surface.blit(img, (
self.rect.x - (self.offset[0] * self.image_scale),
self.rect.y - (self.offset[1] * self.image_scale)
))
and the main code
import pygame
from fighter import Fighter
pygame.init()
# create game window
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Fighter")
# set framerate
clock = pygame.time.Clock()
FPS = 60
# define colours
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
WHITE = (255, 255, 255)
# define warrior variables
WARRIOR_SIZE = 150
WARRIOR_SCALE = 1
WARRIOR_OFFSET = [ 87, 70 ]
WARRIOR_DATA = [ WARRIOR_SIZE, WARRIOR_SCALE, WARRIOR_OFFSET ]
WIZARD_SIZE = 500
WIZARD_SCALE = 1
WIZARD_OFFSET = [ 10, 103 ]
WIZARD_DATA = [ WIZARD_SIZE, WIZARD_SCALE, WIZARD_OFFSET ]
# load background image
bg_image = pygame.image.load("assets/images/background/background.png").convert_alpha()
# load spritesheets
warrior_sheet = pygame.image.load(
"assets/images/Sister-Complex-Kingpen-Of-Steel/Yu/pleaseactuallywork.png").convert_alpha()
wizard_sheet = pygame.image.load("assets/images/Ace-Defective/Junpei/Stupei.png").convert_alpha()
# define number of steps in each animation
WARRIOR_ANIMATION_STEPS = [ 10, 11, 8, 23, 7, 15, 5, 13 ]
WIZARD_ANIMATION_STEPS = [ 8, 8, 1, 8, 8, 3, 7 ]
# function for drawing background
def draw_bg() :
scaled_bg = pygame.transform.scale(bg_image, (SCREEN_WIDTH, SCREEN_HEIGHT))
screen.blit(scaled_bg, (0, 0))
# function for drawing fighter health bars
def draw_health_bar(health, x, y) :
ratio = health / 120
pygame.draw.rect(screen, WHITE, (x - 2, y - 2, 404, 34))
pygame.draw.rect(screen, RED, (x, y, 400, 30))
pygame.draw.rect(screen, YELLOW, (x, y, 400 * ratio, 30))
# create two instances of fighters
fighter_1 = Fighter(200, 310, WARRIOR_DATA, warrior_sheet, WARRIOR_ANIMATION_STEPS)
fighter_2 = Fighter(700, 310, WIZARD_DATA, wizard_sheet, WIZARD_ANIMATION_STEPS)
# game loop
run = True
while run :
clock.tick(FPS)
# draw background
draw_bg()
# show player stats
draw_health_bar(fighter_1.health, 20, 20)
draw_health_bar(fighter_2.health, 580, 20)
# move fighters
fighter_1.move(SCREEN_WIDTH, SCREEN_HEIGHT, screen, fighter_2)
# update fighters
fighter_1.update()
fighter_2.update()
# draw fighters
fighter_1.draw(screen)
fighter_2.draw(screen)
# update display
pygame.display.update()
# event handler
for event in pygame.event.get() :
if event.type == pygame.QUIT :
run = False
# exit pygame
pygame.quit()