Aug-11-2024, 09:01 PM
i'm trying to dipslay player's health in the window but it doesn't appear
import os
import random
import math
import pygame
import sys
from os import listdir
from os.path import isfile, join
pygame.init()
pygame.display.set_caption("Platformer")
WIDTH, HEIGHT = 1000, 800
FPS = 60
PLAYER_VEL = 5
HEALTH_FONT = pygame.font.SysFont('comicsans', 32)
PLAYER_HIT = pygame.USEREVENT + 1
window = pygame.display.set_mode((WIDTH, HEIGHT))
def flip(sprites):
return [pygame.transform.flip(sprite, True, False) for sprite in sprites]
def load_sprite_sheets(dir1, dir2, width, height, direction=False):
path = join("assets", dir1, dir2)
images = [f for f in listdir(path) if isfile(join(path, f))]
all_sprites = {}
for image in images:
sprite_sheet = pygame.image.load(join(path, image)).convert_alpha()
sprites = []
for i in range(sprite_sheet.get_width() // width):
surface = pygame.Surface((width, height), pygame.SRCALPHA, 32)
rect = pygame.Rect(i * width, 0, width, height)
surface.blit(sprite_sheet, (0, 0), rect)
sprites.append(pygame.transform.scale2x(surface))
if direction:
all_sprites[image.replace(".png", "") + "_right"] = sprites
all_sprites[image.replace(".png", "") + "_left"] = flip(sprites)
else:
all_sprites[image.replace(".png", "")] = sprites
return all_sprites
def get_block(size):
path = join("assets", "Terrain", "Terrain.png")
image = pygame.image.load(path).convert_alpha()
surface = pygame.Surface((size, size), pygame.SRCALPHA, 32)
rect = pygame.Rect(96, 0, size, size)
surface.blit(image, (0, 0), rect)
return pygame.transform.scale2x(surface)
class Player(pygame.sprite.Sprite):
COLOR = (255, 0, 0)
GRAVITY = 1
SPRITES = load_sprite_sheets("MainCharacters", "MaskDude", 32, 32, True)
ANIMATION_DELAY = 3
def __init__(self, x, y, width, height):
super().__init__()
self.rect = pygame.Rect(x, y, width, height)
self.x_vel = 0
self.y_vel = 0
self.mask = None
self.direction = "left"
self.animation_count = 0
self.fall_count = 0
self.jump_count = 0
self.hit = False
self.hit_count = 0
def jump(self):
self.y_vel = -self.GRAVITY * 8
self.animation_count = 0
self.jump_count += 1
if self.jump_count == 1:
self.fall_count = 0
def move(self, dx, dy):
self.rect.x += dx
self.rect.y += dy
def make_hit(self):
self.hit = True
def move_left(self, vel):
self.x_vel = -vel
if self.direction != "left":
self.direction = "left"
self.animation_count = 0
def move_right(self, vel):
self.x_vel = vel
if self.direction != "right":
self.direction = "right"
self.animation_count = 0
def loop(self, fps):
self.y_vel += min(1, (self.fall_count / fps) * self.GRAVITY)
self.move(self.x_vel, self.y_vel)
if self.hit:
self.hit_count += 1
if self.hit_count > fps * 2:
self.hit = False
self.hit_count = 0
self.fall_count += 1
self.update_sprite()
def landed(self):
self.fall_count = 0
self.y_vel = 0
self.jump_count = 0
def hit_head(self):
self.count = 0
self.y_vel *= -1
def update_sprite(self):
sprite_sheet = "idle"
if self.hit:
sprite_sheet = "hit"
elif self.y_vel < 0:
if self.jump_count == 1:
sprite_sheet = "jump"
elif self.jump_count == 2:
sprite_sheet = "double_jump"
elif self.y_vel > self.GRAVITY * 2:
sprite_sheet = "fall"
elif self.x_vel != 0:
sprite_sheet = "run"
sprite_sheet_name = sprite_sheet + "_" + self.direction
sprites = self.SPRITES[sprite_sheet_name]
sprite_index = (self.animation_count //
self.ANIMATION_DELAY) % len(sprites)
self.sprite = sprites[sprite_index]
self.animation_count += 1
self.update()
def update(self):
self.rect = self.sprite.get_rect(topleft=(self.rect.x, self.rect.y))
self.mask = pygame.mask.from_surface(self.sprite)
def draw(self, win, offset_x):
win.blit(self.sprite, (self.rect.x - offset_x, self.rect.y))
class Object(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, name=None):
super().__init__()
self.rect = pygame.Rect(x, y, width, height)
self.image = pygame.Surface((width, height), pygame.SRCALPHA)
self.width = width
self.height = height
self.name = name
def draw(self, win, offset_x):
win.blit(self.image, (self.rect.x - offset_x, self.rect.y))
class Block(Object):
def __init__(self, x, y, size):
super().__init__(x, y, size, size)
block = get_block(size)
self.image.blit(block, (0, 0))
self.mask = pygame.mask.from_surface(self.image)
class Fire(Object):
ANIMATION_DELAY = 3
def __init__(self, x, y, width, height):
super().__init__(x, y, width, height, "fire")
self.fire = load_sprite_sheets("Traps", "Fire", width, height)
self.image = self.fire["off"][0]
self.mask = pygame.mask.from_surface(self.image)
self.animation_count = 0
self.animation_name = "off"
def on(self):
self.animation_name = "on"
def off(self):
self.animation_name = "off"
def loop(self):
sprites = self.fire[self.animation_name]
sprite_index = (self.animation_count //
self.ANIMATION_DELAY) % len(sprites)
self.image = sprites[sprite_index]
self.animation_count += 1
self.rect = self.image.get_rect(topleft=(self.rect.x, self.rect.y))
self.mask = pygame.mask.from_surface(self.image)
if self.animation_count // self.ANIMATION_DELAY > len(sprites):
self.animation_count = 0
def get_background(name):
image = pygame.image.load(join("assets", "Background", name))
_, _, width, height = image.get_rect()
tiles = []
for i in range(WIDTH // width + 1):
for j in range(HEIGHT // height + 1):
pos = (i * width, j * height)
tiles.append(pos)
return tiles, image
def draw(window, background, bg_image, player, objects, offset_x, player_health):
player_health_text = HEALTH_FONT.render('Health: ' + str(player_health), 1, (255, 255, 255))
window.blit(player_health_text, (WIDTH - player_health_text.get_width() - 10, 10))
for tile in background:
window.blit(bg_image, tile)
for obj in objects:
obj.draw(window, offset_x)
player.draw(window, offset_x)
pygame.display.update()
def handle_vertical_collision(player, objects, dy):
collided_objects = []
for obj in objects:
if pygame.sprite.collide_mask(player, obj):
if dy > 0:
player.rect.bottom = obj.rect.top
player.landed()
elif dy < 0:
player.rect.top = obj.rect.bottom
player.hit_head()
collided_objects.append(obj)
return collided_objects
def collide(player, objects, dx):
player.move(dx, 0)
player.update()
collided_object = None
for obj in objects:
if pygame.sprite.collide_mask(player, obj):
collided_object = obj
break
player.move(-dx, 0)
player.update()
return collided_object
def handle_move(player, objects):
keys = pygame.key.get_pressed()
player.x_vel = 0
collide_left = collide(player, objects, -PLAYER_VEL * 2)
collide_right = collide(player, objects, PLAYER_VEL * 2)
if keys[pygame.K_a] and not collide_left:
player.move_left(PLAYER_VEL)
if keys[pygame.K_d] and not collide_right:
player.move_right(PLAYER_VEL)
vertical_collide = handle_vertical_collision(player, objects, player.y_vel)
to_check = [collide_left, collide_right, *vertical_collide]
for obj in to_check:
if obj and obj.name == "fire":
player.make_hit()
def main(window):
clock = pygame.time.Clock()
background, bg_image = get_background("Blue.png")
player_health = 10
block_size = 96
player = Player(100, 100, 50, 50)
fire = Fire(100, HEIGHT - block_size - 64, 16, 32)
fire.on()
floor = [Block(i * block_size, HEIGHT - block_size, block_size)
for i in range(-WIDTH // block_size, (WIDTH * 2) // block_size)]
objects = [*floor, Block(0, HEIGHT - block_size * 2, block_size),
Block(block_size * 3, HEIGHT - block_size * 4, block_size), fire]
offset_x = 0
scroll_area_width = 200
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
break
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and player.jump_count < 2:
player.jump()
if event.type == PLAYER_HIT:
player_health -= 1
player.loop(FPS)
fire.loop()
handle_move(player, objects)
draw(window, background, bg_image, player, objects, offset_x, player_health)
if ((player.rect.right - offset_x >= WIDTH - scroll_area_width) and player.x_vel > 0) or (
(player.rect.left - offset_x <= scroll_area_width) and player.x_vel < 0):
offset_x += player.x_vel
pygame.quit()
quit()
if __name__ == "__main__":
main(window)
