0

The issue is in the update function where it basically prints all the frames of the spritesheet walking right at once instead of a single frame. I wanted to set a singular image to print due to which direction it's facing.

enter image description here

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        
        self.frames = [0]*4
        player_movement_spritesheets = Spritesheet(os.path.join('assets/player', 'movement.png'))
        self.sprites = []
        for i in range(4):
            for j in range(4):
                self.sprites.append((0, i*50, 32*(j+1), 50))
        #print(self.sprites)
        self.images = player_movement_spritesheets.images_at(self.sprites, black)
        self.ani = 4
        self.image = self.images[0]
        self.rect = self.image.get_rect()

    def control(self,x,y):
        self.movex += x
        self.movey += y  
    def update(self,boundary):
        new_rect = self.rect.copy()
        new_rect.x += self.movex
        new_rect.y += self.movey
        line_a = Polygon(boundary)
        line_b = Polygon([
                                (new_rect.x,                new_rect.y),
                                (new_rect.x+(player_sprite_width),new_rect.y),
                                (new_rect.x+(player_sprite_width),new_rect.y+(player_sprite_height)),
                                (new_rect.x,                new_rect.y+(player_sprite_height))])
            
            #print(line_a)
            #print(line_b)
    

About here


            if line_a.intersects(line_b):
                self.rect = new_rect.copy() 
                #Loop a direction frames and set other's to 0
                #Up left right down
                if self.movex>0: 
                    for i in range(len(self.frames)):
                        if i==2:
                            if self.frames[2]>self.ani:
                                self.frames[2]=0
                            else:
                                self.frames[2]+=1
                        else:
                            self.frames[i]=0
                     
                    if self.movey>0:
                        self.image = self.images[8+self.frames[2]]
                        self.image = pygame.transform.rotate(self.image, -23)
                    elif self.movey<0:
                        self.image = self.images[8+self.frames[2]]
                        self.image = pygame.transform.rotate(self.image, 23)
                    else:
                        self.image = self.images[8+self.frames[2]]

self.player.rect.x = 475
self.player.rect.y = 350
self.player_list = pygame.sprite.Group()
self.player_list.add(self.player)

 def draw(self,screen):
        if self.level < len(self.boundaries):   
            self.player_list.draw(screen)
Arundeep Chohan
  • 9,779
  • 5
  • 15
  • 32

1 Answers1

0

This is a helpful class for working with sprites use just import this file and use the change_state function. Hopefully, this is what you are looking for. Also after a close inspection of your code you not updating or using blit.

import pygame
from settings import *

class Sprite:
    def __init__(self, sprites):
        self.sprites = sprites

        # Number of frames in each state
        self.num_frames = {
            key: len(val) for key, val in self.sprites.items()
        }

        self.state = "idle"  # Current animation state
        self.frame = 0  # Current animation frame
        self.timer = 5  # number of frames between animation frames
        self.pos = (0, 0)
        print(self.num_frames)

    def update(self):
        self.timer -= 1
        if self.timer == 0:
            self.timer = 5  # Reset timer
            self.frame = (self.frame + 1) % self.num_frames[
                self.state]  # Loop through frames. Uses mod to reset to 0 once it passes last frame
            for frames in self.num_frames:
                if self.frame == self.num_frames[frames]:
                    self.frame = 0

    def get_rect(self):
        return self.sprites[self.state][self.frame].get_rect()

    def draw(self, screen,pos):
        screen.blit(self.sprites[self.state][self.frame],pos)

    def change_state(self, new_state):
        if new_state in self.sprites.keys():  # Only allow valid states
            self.state = new_state
            # self.frame = 0  # Reset frame
            # self.timer = 5  # Reset timer

        else:
            raise ValueError(
                f"Oops. {new_state} is not a valid state!")  # In case you mistype something in your code it'll tell you
Flow
  • 846
  • 9
  • 24