Python Forum
[PyGame] platformer enemy animation
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] platformer enemy animation
#1
Im making a platformer and I wanted to make animated enemies ive been lookin up tutorials on how to do that and It doesnt work here is my code. the code here is just normal there isnt any animation added to the enemies yet
from pickle import FALSE
import pygame

from pygame.locals import *

pygame.init()
Clock = pygame.time.Clock()
fps = 60


screen_width =  800
screen_height = 800

screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption('One Piece Platformer')

#define game variables
tile_size = 40
game_over = 0
Main_menu = True

#load image
bg_img = pygame.image.load("sky.png")
sun_img = pygame.image.load("sun.png")
restart_img = pygame.image.load("restart.png")
start_img = pygame.image.load("start.png")
exit_img = pygame.image.load("exit.png")

class Button():
     def __init__(self, x, y, image):
        self.image = image
        self.rect= self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.clicked = FALSE

     def draw(self):
        action = False

        #get mouse position
        pos = pygame.mouse.get_pos()

        #check mouseover and clicked conditions
        if self.rect.collidepoint(pos):
            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                action = True
                self.clicked = True

        if pygame.mouse.get_pressed()[0] == 0:
            self.clicked = False
                 

        #draw button
        screen.blit(self.image, self.rect)

        return action



class Player():
    def __init__(self, x, y):
       self.reset(x, y)



    def update(self, game_over):
        dx = 0
        dy = 0
        walk_cooldown = 5

        if game_over == 0:
            #get keypresses
            key = pygame.key.get_pressed()
            if key[pygame.K_UP] and self.jumped == False:
                self.vel_y = -15
                self.jumped = True
            if key[pygame.K_LEFT]:
                dx -= 5
                self.counter += 1
                self.direction = -1
            if key[pygame.K_RIGHT]:
                dx += 5
                self.counter += 1
                self.direction = 1
            if key[pygame.K_LEFT] == False and key[pygame.K_RIGHT] == False:
                self.counter = 0
                self.index = 0
                if self.direction == 1:
                    self.image = self.images_right[self.index]
                if self.direction == -1:
                    self.image = self.images_left[self.index]


            #handle animation
            if self.counter > walk_cooldown:
                self.counter = 0    
                self.index += 1
                if self.index >= len(self.images_right):
                    self.index = 0
                if self.direction == 1:
                    self.image = self.images_right[self.index]
                if self.direction == -1:
                    self.image = self.images_left[self.index]


            #add gravity
            self.vel_y += 1
            if self.vel_y > 10:
                self.vel_y = 10
            dy += self.vel_y

            #check for collision
            for tile in world.tile_list:
                #check for collision in x direction
                if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
                    dx = 0
                #check for collision in y direction
                if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
                    #check if below the ground i.e. jumping
                    if self.vel_y < 0:
                        dy = tile[1].bottom - self.rect.top
                        self.vel_y = 0
                    #check if above the ground i.e. falling
                    elif self.vel_y >= 0:
                        dy = tile[1].top - self.rect.bottom
                        self.vel_y = 0
                        self.jumped = False
                        

            #check for collision with enemies
            if pygame.sprite.spritecollide(self, pirate_group, False):
                game_over = -1

            #check for collision with lava
            if pygame.sprite.spritecollide(self, lava_group, False):
                game_over = -1

            #update player coordinates
            self.rect.x += dx
            self.rect.y += dy

        elif game_over == -1:
            self.image = self.dead_image
            if self.rect.y > 800:
             self.rect.y -= 5
          
        #draw player onto screen
        screen.blit(self.image, self.rect)
        

        return game_over

    
    def reset(self, x, y):
        self.images_right = []
        self.images_left = []
        self.index = 0
        self.count = 0
        for num in range (1,3):
            img_right = pygame.image.load(f'guy{num}.png')
            img_right = pygame.transform.scale(img_right, (30, 50))
            img_left = pygame.transform.flip(img_right, True, False)
            self.images_right.append(img_right)
            self.images_left.append(img_left)
        self.dead_image = pygame.image.load('ghost.png')
        self.image = self.images_right[self.index]
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.width = self.image.get_width()
        self.height = self.image.get_height()
        self.vel_y = 0
        self.jumped = False
        self.direction = 0

         
class World():
   def __init__(self, data):
        self.tile_list = []

        #load images
        dirt_img = pygame.image.load("dirt.png")
        grass_img = pygame.image.load("grass.png")
        
       
        
        #tile and enemie positioning
        row_count = 0
        for row in data: 
            col_count = 0
            for tile in row:
                if tile == 1:
                    img = pygame.transform.scale(dirt_img, (tile_size, tile_size)) 
                    img_rect = img.get_rect()
                    img_rect.x = col_count * tile_size
                    img_rect.y = row_count * tile_size
                    tile = (img, img_rect) 
                    self.tile_list.append(tile)              
                if tile == 2:
                    img = pygame.transform.scale(grass_img, (tile_size, tile_size)) 
                    img_rect = img.get_rect()
                    img_rect.x = col_count * tile_size
                    img_rect.y = row_count * tile_size
                    tile = (img, img_rect) 
                    self.tile_list.append(tile)   
                if tile == 3:   
                    pirate = Enemy(col_count * tile_size, row_count * tile_size -6)        
                    pirate_group.add(pirate)
                if tile == 6:
                    lava = Lava(col_count * tile_size, row_count * tile_size + (tile_size // 2))
                    lava_group.add(lava)
                if tile == 9:
                    water = Water(col_count * tile_size, row_count * tile_size + (tile_size // 2)) 
                    water_group.add(water)
                col_count += 1
            row_count += 1


                


        
               

   def draw(self):
        for tile in self.tile_list:
            screen.blit(tile[0], tile[1])
            
           



# adding enemies
class Enemy(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('pirate1.png')
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y 
        self.move_direction = 1
        self.move_counter = 0

    def update(self):
        self.rect.x += self.move_direction
        self.move_counter += 1
        if abs(self.move_counter) > 50:
            self.move_direction *= -1
            self.move_counter *= -1

class Lava(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        img = pygame.image.load('lava.png')
        self.image = pygame.transform.scale(img, (tile_size, tile_size // 2))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y 

class Water(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        img = pygame.image.load('water.png')
        self.image = pygame.transform.scale(img, (tile_size, tile_size // 2))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y 




    
 
world_data = world_data = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,],
[1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 2, 2, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 5, 0, 0, 0, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1,], 
[1, 7, 0, 0, 2, 2, 2, 0, 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 1,], 
[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 0, 0, 0, 0, 1,], 
[1, 0, 2, 0, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,], 
[1, 0, 0, 2, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 1,], 
[1, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 1,],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,],  
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 1,], 
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 1, 1, 1, 1, 1, 1,], 
[1, 0, 0, 0, 0, 2, 2, 2, 2, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1,],  
[1, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,], 
[1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,]
]


player = Player(100, screen_height - 130)

#sprite groups help manage multiple sprite object methods for collision detection
pirate_group = pygame.sprite.Group()
lava_group = pygame.sprite.Group()
water_group = pygame.sprite.Group()

world = World(world_data)

# create buttons
restart_button = Button(screen_width // 2 - 50, screen_height // 2 + 100, restart_img)
start_button = Button(screen_width // 2 - 350, screen_height // 2, start_img) 
exit_button = Button(screen_width // 2 + 150, screen_height // 2, exit_img) 


run = True
while run:
    
    Clock.tick(fps)

    screen.blit(bg_img, (0,0))
    screen.blit(sun_img, (100,100))

    if Main_menu == True:
        if exit_button.draw():
            run = False
        if start_button.draw():
            Main_menu = False
    else:
        world.draw()

        if game_over == 0:
            pirate_group.update()
        
        pirate_group.draw(screen)
        lava_group.draw(screen)
        water_group.draw(screen)

        game_over = player.update(game_over)

        #if player has died
        if game_over == -1:
            if restart_button.draw():
                player.reset(100, screen_height - 130)
                game_over = 0


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

    pygame.display.update()

pygame.quit()
Yoriz write Nov-27-2022, 07:14 PM:
Please post all code, output and errors (in their entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Reply
#2
You should not be trying to add animation to your game. Try making one animated monster with no game play, no fancy background, nothing but the thing you are trying to learn. If you cannot get that to work, edit your code to a small sample (dozen lines or so) that doesn't require as many image files (2 or 3 max) and post that.
Yegor123 likes this post
Reply
#3
I would still like to ask how your game works, because so far I have only practiced in C#
Reply
#4
Tips.
1. You do not want to load images in sprite class. This will load the image again making another copy in memory.
2. Convert your images. Otherwise pygame will do this every turn. If it needs too.
class ImageHandler:
    def __init__(self):
        self.lava = pygame.image.load(path_to_lava).convert()
        # etc
3. enumerate is your friend.
for row_count, row in enumerate(data):
    for col_count, tile in enumerate(row):
        # code
4. Rects has some nice short hand.
self.rect = image.get_rect(topleft=(x, y))
99 percent of computer problems exists between chair and keyboard.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
Question [PyGame] Problem with collision of player and enemy Nekotrooper 1 683 Dec-08-2023, 03:29 PM
Last Post: deanhystad
  How to make enemy chase me in pygame? Jan_97 3 4,398 Nov-23-2021, 05:08 PM
Last Post: Jan_97
  [PyGame] pygame, help with making a function to detect collision between player and enemy. Kris1996 3 3,341 Mar-07-2020, 12:32 PM
Last Post: Kris1996
  Tkinter platformer game Linch1 1 5,203 Mar-10-2019, 03:17 AM
Last Post: Windspar
  Napkin Platformer abscorpy 3 2,817 Jan-26-2019, 03:20 PM
Last Post: Windspar
  platformer problem abscorpy 1 2,427 Dec-11-2018, 11:08 PM
Last Post: Windspar
  platformer problem abscorpy 4 3,633 Nov-27-2018, 08:46 PM
Last Post: nilamo
  Help On Platformer Spectroxis 2 11,318 Apr-27-2017, 09:56 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020