Sprites not updating?

Started by
2 comments, last by NUCLEAR RABBIT 3 years, 10 months ago

Hello,

I am just starting to learn pygame and I am running into a little bit of trouble. I am attempting to have the character do an idle animation while nothing is being pressed. I tried looping through each sprite frame and drawing it to the screen, but only one sprite in the animation is being displayed while the character is idle. If someone can please help point me in the right direction I would greatly appreciate it!

game.py

###############################################
#
#   Testing using PyGame to make a 2D game
#
###############################################

import time
import random
import os
import pygame
import Constants
from Menu import Menu
from SpriteSheet import SpriteSheet
from Player import Player

# initalizations
pygame.init()

def run_game():
    game_is_running = True
    pygame.key.set_repeat(1, 25)

    menu = Menu()
    player = Player(500, 500)

    # main game loop
    while game_is_running:
        Constants.CLOCK.tick(Constants.FPS)

        # draws the player sprite
        player.draw(player.getState())

        pygame.display.update()

        # event handling
        for events in pygame.event.get():
            # exits the window
            if events.type == pygame.QUIT:
                game_is_running = False

            # checking kayboard inputs
            if events.type == pygame.KEYDOWN:
                if events.key == pygame.K_d:
                    player.moveRight()

                elif events.key == pygame.K_a:
                    player.moveLeft()

##---------------------------------------------------------------------------------------------------------------------

run_game()

Player.py

#########################################3
#
#   Player Class
#
##########################################

import pygame
import Enemy
import Constants
from SpriteSheet import SpriteSheet

class Player:
    def __init__(self, x, y):
        super().__init__()
        self.name = "ERIS"
        self.health = 100
        self.xpos = x
        self.ypos = y
        self.dead = False
        self.looking_right = False
        self.looking_left = False
        self.spriteSheet = SpriteSheet("rogue like idle.png")
        self.state = "IDLE"

        # initializing animations
        self.idle_sprites = []
        self.running_sprites = []

        for i in range(0, 3):
            self.idle_sprites.append(self.spriteSheet.get_sprite((i*100), 0, 100, 100).convert())

    def takeDamage(self, enemy):
        self.health -= enemy.damage

        if self.health <= 0:
            self.dead = True

    def getState(self):
        return self.state

    def moveRight(self):
        if -40 <= self.xpos <= Constants.WIN_WIDTH:
            self.xpos += Constants.VELOCITY
        if self.xpos >= 940:
            self.xpos = 940
        self.looking_left = False
        self.looking_right = True

    def moveLeft(self):
        if -40 <= self.xpos <= Constants.WIN_WIDTH:
            self.xpos -= Constants.VELOCITY
        if self.xpos < -40:
            self.xpos = -40
        self.looking_left = True
        self.looking_right = False

    def draw(self, PLAYER_STATE):
        if PLAYER_STATE == "IDLE":
            for frame in self.idle_sprites:
                Constants.WINDOW.blit(frame, (self.xpos, self.ypos))

Constants.py

#########################################################
#
#   Constant class - global constants used in diff files
#
#########################################################

import pygame
import os

# Window Constants
FPS = 60
WIN_HIEGHT = 600
WIN_WIDTH = 1000
VELOCITY = 7
WIN_NAME = ":: UNTITLED ::"

# colors
BLACK = (0, 0, 0)

CLOCK = pygame.time.Clock()

# creating the game window
WINDOW = pygame.display.set_mode((WIN_WIDTH, WIN_HIEGHT))
pygame.display.set_caption(WIN_NAME)

# game assests
GAME_TITLE_IMAGE = pygame.image.load(os.path.join("assets", "menu_title.png")).convert_alpha()

SpriteSheet.py

###########################################
#
#   SpriteSheet class
#
###########################################

import pygame
import os
import Constants

class SpriteSheet:
    def __init__(self, filename):
        self.sprite_sheet = pygame.image.load(os.path.join("assets", "player_sprites", filename)).convert()

    def get_sprite(self, x, y, width, height):
        sprite = pygame.Surface((width, height)).convert()

        sprite.blit(self.sprite_sheet, (0,0), (x, y, width, height))

        return sprite

Menu.py

#####################################
#
#   Menu class
#
#####################################

import Constants
import pygame

class Menu:
    def __init__(self):
        self.paused = False

    def displayMainMenu(self):
        Constants.WINDOW.fill(Constants.BLACK)
        Constants.WINDOW.blit(Constants.GAME_TITLE_IMAGE, (50, 50))
Advertisement

That's a lot of code to quickly digest but I think your problem is here:

def draw(self, PLAYER_STATE):
        if PLAYER_STATE == "IDLE":
            for frame in self.idle_sprites:
                Constants.WINDOW.blit(frame, (self.xpos, self.ypos))

You are basically drawing all your images at once each frame. What you want to do is have ‘frame’ to be a member variable that is updated in relation to some given time having passed. Usually you'll have an ‘update’ function that does this and also calculates the new position, direction etc. Don't modify internal state during keypress events and such because you want to keep the state changes in one place, otherwise you quickly lose control over the order in which things are executed.

Hope this makes any sense, otherwise just ask or look at some tutorial code that implements this.

@Prototype thank you, I got it working now!

This topic is closed to new replies.

Advertisement