Home > other >  pygame: sprite's action not changing
pygame: sprite's action not changing

Time:03-07

I've been trying to make a game similar to a tower defense game in pygame. Essentially, there are zombies walking on a path, and you have to shoot them (the crosshair is your mouse). There are 3 files I have: crosshair.py, spritesheet.py, and main.py. I am able to get the walking animation from my sprite sheet, however, when I want it to walk up or down, the direction it's looking in doesn't change.

This is what the sprite sheet looks like:

enter image description here

Here is my code:

spritesheet.py:

import pygame

class SpriteSheet(pygame.sprite.Sprite):
    def __init__(self, width, height, sheet):
        super().__init__()
        self.action = 2
        self.width = width
        self.height = height
        self.sheet = sheet
    
    def get_image(self):
        self.animation_list = []

        for _ in range(4):
            temp_list = []
            for count in range(4):
                self.image = pygame.Surface((self.width, self.height))
                self.image.blit(self.sheet, (0, 0), (count * self.width, self.action * self.height, self.width, self.height))
                self.image.set_colorkey('Black')

                temp_list.append(self.image)

            self.animation_list.append(temp_list)

main.py:

import pygame
from crosshair import Crosshair
from spritesheet import SpriteSheet

pygame.init()

# Clock/Time 
clock = pygame.time.Clock()
FPS = 60

# Make Screen
screen_w = 1000
screen_h = 650
screen = pygame.display.set_mode((screen_w, screen_h))

crosshair = Crosshair('crosshair_white.png', screen)

# Load background
bg = pygame.image.load('background.jpg').convert_alpha()
bg = pygame.transform.scale(bg, (screen_w, screen_h))

# Handle Zombie Sheet
zombie_sheet = pygame.image.load('zombie_img.png').convert_alpha()
sprite_sheet = SpriteSheet(32, 48, zombie_sheet)
sprite_sheet.get_image()

frame = 0

run = True

zombie_x = 0
zombie_y = 400

while run:
    screen.fill('Black')

    screen.blit(bg, (0, 0))

    # Zombie Management
    screen.blit(sprite_sheet.animation_list[sprite_sheet.action][int(frame)], (zombie_x, zombie_y))
    if frame > 3.9:
        frame = 0
    else:
        frame  = 0.07

    dx = 0
    dy = 0

    if zombie_x < 300:
        dx = 0.5
    elif 300 <= zombie_x < 390:
        dx = 0.5
        dy = -0.25
    elif 390 <= zombie_x < 460 and zombie_y > 210:
        dy = -0.5
    elif zombie_x < 460 and zombie_y <= 210:
        dx = 0.5
        dy = -0.25
    elif 460 <= zombie_x < 510:
        dx = 0.5
    elif 510 <= zombie_x < 570:
        dx = 0.5
        dy = 0.25
    elif zombie_y < 270:
        dy = 0.5
    elif 570 <= zombie_x < 630 and zombie_y >= 270:
        dx = 0.5
        dy = 0.5
    elif 630 <= zombie_x < 760:
        dx = 0.5
    elif 760 <= zombie_x < 830:
        dx = 0.5
        dy = 0.5
    elif zombie_x >= 830:
        dx = 0.5

    zombie_x  = dx
    zombie_y  = dy

    crosshair.update()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            crosshair.shoot()

    pygame.display.update()
    clock.tick(FPS)

pygame.quit()

I'm not going to post the code for crosshair.py because I don't think it's nessecary.

Bassically, I want to change the action over here by writing sprite_sheet.action = 3:

elif 390 <= zombie_x < 460 and zombie_y > 210:
------->
        dy = -0.5

However, it doesn't change, and I know this problem isn't due to the surfaces I made being incorrect, because if I manually change self.action to a different number, it works.

If any other information is needed, I'll be happy to provide, but just know that these are the only two files I have except for crosshair.py.

Thanks in advance.

CodePudding user response:

I didn't test it but I think you create the same images for all directions in get_image() because all of them use the same self.action

for _ in range(4):

    # ... code ...

    self.image.blit(self.sheet, (0, 0), 
                 (count * self.width, 
                  self.action * self.height,   # <--- self.action
                  self.width, 
                  self.height))

but they should use value from for _ in range(4)

for direction in range(4):   # <--- direction

    # ... code ...

    self.image.blit(self.sheet, (0, 0), 
                 (count * self.width, 
                  direction * self.height,   # <--- direction
                  self.width, 
                  self.height))

Full function:

    def get_image(self):
        self.animation_list = []

        for direction in range(4):   # <--- direction

            temp_list = []

            for count in range(4):
                self.image = pygame.Surface((self.width, self.height))

                self.image.blit(self.sheet, (0, 0), 
                     (count * self.width, 
                      direction * self.height,   # <--- direction from `for 
                      self.width, 
                      self.height))

                self.image.set_colorkey('Black')

                temp_list.append(self.image)

            self.animation_list.append(temp_list)
  • Related