import pygame import sys import pickle # Initialize Pygame pygame.init() # Screen dimensions screen_width = 1000 screen_height = 1000 tile_size = 50 black = (0, 0, 0) player_size = 65 # Create the screen screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("Pygame Structure") grid = True def draw_grid(): if grid: # Draw vertical lines for x in range(0, screen_width, tile_size): pygame.draw.line(screen, black, (x, 0), (x, screen_height)) # Draw horizontal lines for y in range(0, screen_height, tile_size): pygame.draw.line(screen, black, (0, y), (screen_width, y)) def crop_image(image): # Get the bounding box of the non-transparent part of the image rect = image.get_bounding_rect() # Calculate the height difference height_diff = image.get_height() - rect.height # Create a new surface with the same width as the bounding box and the original height cropped_image = pygame.Surface((rect.width, image.get_height()), pygame.SRCALPHA, 32).convert_alpha() # Blit the cropped part of the original image onto the new surface, keeping it at the bottom cropped_image.blit(image, (0, height_diff), rect) return cropped_image def scale_image(image, scale): # Get the size of the image width, height = image.get_size() # Calculate new size new_width = int(width * scale) new_height = int(height * scale) # Scale the image scaled_image = pygame.transform.scale(image, (new_width, new_height)) return scaled_image # Load the background image background_image = pygame.image.load('images/Background/BG2.png') background_image = pygame.transform.scale(background_image, (screen_width, screen_height)) # Load images idle_images = [crop_image(pygame.transform.scale(pygame.image.load(f'images/Player/idle ({i}).png'), (player_size, player_size))) for i in range(1, 16)] run_images = [crop_image(pygame.transform.scale(pygame.image.load(f'images/Player/Run ({i}).png'), (player_size, player_size))) for i in range(1, 16)] jump_images = [crop_image(pygame.transform.scale(pygame.image.load(f'images/Player/Jump ({i}).png'), (player_size, player_size))) for i in range(1, 16)] # Load tile images tiles = { 1: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/1.png'), (tile_size, tile_size))), 2: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/2.png'), (tile_size, tile_size))), 3: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/3.png'), (tile_size, tile_size))), 4: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/4.png'), (tile_size, tile_size))), 5: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/5.png'), (tile_size, tile_size))), 6: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/6.png'), (tile_size, tile_size))), 7: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/7.png'), (tile_size, tile_size))), 8: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/8.png'), (tile_size, tile_size))), 9: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/9.png'), (tile_size, tile_size))), 10: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/10.png'), (tile_size, tile_size))), 11: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/11.png'), (tile_size, tile_size))), 12: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/12.png'), (tile_size, tile_size))), 13: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/13.png'), (tile_size, tile_size))), 14: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/14.png'), (tile_size, tile_size))), 15: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/15.png'), (tile_size, tile_size))), 16: crop_image(pygame.transform.scale(pygame.image.load('Images/tiles2/16.png'), (tile_size, tile_size))), } # Player class with handle_movement method class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.idle_images = idle_images self.run_images = run_images self.jump_images = jump_images self.image = self.idle_images[0] self.rect = self.image.get_rect() self.rect.center = (screen_width // 2, screen_height // 2) self.vel_y = 0 self.on_ground = False self.flip = False self.anim_index = 0 self.anim_speed = 0.5 self.anim_images = self.idle_images self.vel_x = 0 def update(self, blocks): keys = pygame.key.get_pressed() self.handle_movement(keys) self.handle_animation() # Gravity self.vel_y += 0.75 if self.vel_y > 10: self.vel_y = 10 # Update vertical position self.rect.y += self.vel_y self.check_collision(blocks, 'vertical') # Screen collision (vertical) if self.rect.bottom > screen_height: self.rect.bottom = screen_height self.vel_y = 0 self.on_ground = True elif self.rect.top < 0: self.rect.top = 0 # Update horizontal position self.rect.x += self.vel_x self.check_collision(blocks, 'horizontal') # Screen collision (horizontal) if self.rect.right > screen_width: self.rect.right = screen_width elif self.rect.left < 0: self.rect.left = 0 def handle_movement(self, keys): self.vel_x = 0 if keys[pygame.K_LEFT]: self.vel_x = -3 self.flip = True self.anim_images = self.run_images elif keys[pygame.K_RIGHT]: self.vel_x = 3 self.flip = False self.anim_images = self.run_images else: self.anim_images = self.idle_images if (keys[pygame.K_SPACE] or keys[pygame.K_UP]) and self.on_ground: self.vel_y = -15 self.on_ground = False def handle_animation(self): self.anim_index += self.anim_speed if self.anim_index >= len(self.anim_images): self.anim_index = 0 self.image = self.anim_images[int(self.anim_index)] if self.flip: self.image = pygame.transform.flip(self.image, True, False) def check_collision(self, blocks, direction): if direction == 'vertical': collisions = pygame.sprite.spritecollide(self, blocks, False) for block in collisions: if self.vel_y > 0: self.rect.bottom = block.rect.top self.vel_y = 0 self.on_ground = True elif self.vel_y < 0: self.rect.top = block.rect.bottom self.vel_y = 0 elif direction == 'horizontal': collisions = pygame.sprite.spritecollide(self, blocks, False) for block in collisions: if self.vel_x > 0: # Moving right self.rect.right = block.rect.left elif self.vel_x < 0: # Moving left self.rect.left = block.rect.right self.vel_x = 0 # Block class class Block(pygame.sprite.Sprite): def __init__(self, image, x, y): super().__init__() self.image = image self.rect = self.image.get_rect() self.rect.topleft = (x, y) def load_level_data(level_file): with open(level_file, 'rb') as file: level_data = pickle.load(file) return level_data def create_level(level_data): blocks = pygame.sprite.Group() for row_index, row in enumerate(level_data): for col_index, tile in enumerate(row): if tile != 0: if tile not in tiles: print(f"Error: Tile {tile} at position ({row_index}, {col_index}) not found in tiles dictionary.") continue # Skip missing tiles block_image = tiles[tile] block = Block(block_image, col_index * tile_size, row_index * tile_size) blocks.add(block) return blocks # Create player sprite group player = Player() all_sprites = pygame.sprite.Group(player) # Load level data and create blocks level_data = load_level_data('Levels/level_3') # Replace with the correct level file name blocks = create_level(level_data) all_sprites.add(blocks) # Main loop clock = pygame.time.Clock() running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # Update all_sprites.update(blocks) # Draw screen.blit(background_image, (0, 0)) draw_grid() all_sprites.draw(screen) # Update display pygame.display.flip() clock.tick(60) # Quit Pygame pygame.quit() sys.exit()