I've made platformer game in python using pygame. Regular map with background, ground and player with movement and animations of standing and running. I have two pictures of jumping animation. I want to display first picture when player is moving up and then when player is going down i want to display second image. I've managed to play jumping animation when player is off the ground but it's kind of buggy and laggy. Please help me fix it.
import pygame
pygame.init()
clock = pygame.time.Clock()
fps = 60
screen_height = 680
screen_width = 1200
tile_size = 45
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption(('My First Game'))
class Player():
aa = 0
def __init__(self, x, y):
self.images_stand = []
self.images_stand1 = []
self.images_right = []
self.images_left = []
self.images_jump = []
self.images_jump1 = []
self.index = 0
self.counter = 0
self.index_run = 0
self.counter_run = 0
self.index_jump = 0
self.counter_jump = 0
for num in range(1, 3):
img_stand = pygame.image.load(f'animations/player_animation/player_stand{num}.png')
img_stand = pygame.transform.scale(img_stand, (65, 84))
img_stand1 = pygame.transform.flip(img_stand, True, False)
self.images_stand.append(img_stand)
self.images_stand1.append(img_stand1)
for numb in range(1, 3):
img_right = pygame.image.load(f'animations/player_animation/player_run{numb}.png')
img_right = pygame.transform.scale(img_right, (65, 84))
img_left = pygame.transform.flip(img_right, True, False)
self.images_right.append(img_right)
self.images_left.append(img_left)
for numbs in range(1, 3):
img_jump = pygame.image.load(f'animations/player_animation/player_jump{numbs}.png')
img_jump = pygame.transform.scale(img_jump, (65, 84))
img_jump1 = pygame.transform.flip(img_jump, True, False)
self.images_jump.append(img_jump)
self.images_jump1.append(img_jump1)
self.image = self.images_stand[self.index]
self.image = self.images_right[self.index_run]
self.image = self.images_jump[self.index_jump]
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
def update(self):
dx = 0
dy = 0
stand_cooldown = 15
run_cooldown = 2
jump_cooldown = 9
key = pygame.key.get_pressed()
if self.vel_y < 0:
self.counter_jump += 1
if key[pygame.K_SPACE] and self.jumped == False and self.vel_y == 0:
self.vel_y = -15
self.jumped = True
print(self.vel_y)
if key[pygame.K_SPACE] == False:
self.jumped = False
if key[pygame.K_LEFT]:
if self.vel_y == 0:
self.counter_run += 1
self.counter = 0
self.direction = -1
self.aa = -1
dx -= 7
if key[pygame.K_RIGHT]:
if self.vel_y == 0:
self.counter_run += 1
self.counter = 0
self.direction = 1
self.aa = 1
dx += 7
if key[pygame.K_RIGHT] == False and key[pygame.K_LEFT] == False and key[pygame.K_SPACE] == False:
self.counter_run = 0
self.index_run = 0
if self.direction == 1:
self.image_run = self.images_right[self.index_run]
if self.direction == -1:
self.image_run = self.images_left[self.index_run]
#Animation
self.counter += 1
if self.counter > stand_cooldown:
self.counter = 0
self.index += 1
if self.index >= len(self.images_stand):
self.index = 0
if self.aa == 1 or self.aa == 0:
self.image = self.images_stand[self.index]
if self.aa == -1:
self.image = self.images_stand1[self.index]
if self.counter_run > run_cooldown:
self.counter_run = 0
self.index_run += 1
if self.index_run >= len(self.images_right):
self.index_run = 0
if self.direction == 1:
self.image = self.images_right[self.index_run]
if self.direction == -1:
self.image = self.images_left[self.index_run]
if self.counter_jump > jump_cooldown:
self.counter_jump = 0
self.index_jump += 1
if self.index_jump >= len(self.images_jump):
self.index_jump = 0
self.image = self.images_jump[self.index_jump]
#GRAVITY
self.vel_y += .5
if self.vel_y > 15:
self.vel_y = 15
dy += self.vel_y
#COLLISIONS
for tile in map.tile_list:
#CHECK X
if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height):
dx = 0
#CEHACK Y
if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height):
if self.vel_y < 0:
dy = tile[1].bottom - self.rect.top
self.vel_y = 0
elif self.vel_y >= 0:
dy = tile[1].top - self.rect.bottom
self.vel_y = 0
self.rect.x += dx
self.rect.y += dy
if self.rect.bottom > screen_height:
self.rect.bottom = screen_height
dy = 0
screen.blit(self.image, self.rect)
pygame.draw.rect(screen, (255, 255, 255), self.rect, 2)
class Map():
def __init__(self, data):
self.tile_list = []
ground_img = pygame.image.load('grounds/ground.png')
dirt_img = pygame.image.load('grounds/dirt.png')
row_count = 0
for row in data:
col_count = 0
for tile in row:
if tile == 1:
img = pygame.transform.scale(ground_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(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)
col_count += 1
row_count += 1
def draw(self):
for tile in self.tile_list:
screen.blit(tile[0], tile[1])
pygame.draw.rect(screen, (255, 255, 255), tile[1], 1)
map_data =[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2]
]
bg_img = pygame.image.load('backgrounds/background.png')
player = Player(100, screen_height - 180)
map = Map(map_data)
run = True
while run:
clock.tick(fps)
screen.blit(bg_img, (0, 0))
map.draw()
player.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.update()
pygame.quit()