[PyGame] platformer enemy animation - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Game Development (https://python-forum.io/forum-11.html) +--- Thread: [PyGame] platformer enemy animation (/thread-38813.html) |
platformer enemy animation - Yegor123 - Nov-27-2022 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() RE: platformer enemy animation - deanhystad - Nov-28-2022 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. RE: platformer enemy animation - sudoku6 - May-02-2023 I would still like to ask how your game works, because so far I have only practiced in C# RE: platformer enemy animation - Windspar - May-03-2023 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() # etc3. enumerate is your friend. for row_count, row in enumerate(data): for col_count, tile in enumerate(row): # code4. Rects has some nice short hand. self.rect = image.get_rect(topleft=(x, y)) |