#-------------------------------------------------------------------------------------------------------------------------------------# #│ Name: 2024 - TE PUNGA - PyGame Programming │ #│ │ #│ Author: Aidan Plummer │ #│ │ #│ Created: 21/06/2024 │ #│ Copyright: © Aidan Plummer 2024 │ #│ License: All rights reserved. This code is the intellectual property of Aidan Plummer. │ #│ You are granted permission to use this code for personal and educational purposes only. │ #│ Any commercial use, distribution, or modification of this code requires explicit permission from the author. │ #-------------------------------------------------------------------------------------------------------------------------------------# import pygame from pygame.locals import * pygame.init() clock = pygame.time.Clock() fps = 60 screen_width = 1000 screen_height = 1000 screen = pygame.display.set_mode((screen_width,screen_height)) # Define game variables tile_size = 50 game_over = 0 main_menu = True # Load Images sun_img = pygame.image.load('img/sun.png') bg_img = pygame.image.load('img/sky.png') restart_img = pygame.image.load('img/restart_btn.png') start_img = pygame.image.load('img/start_btn.png') exit_img = pygame.image.load('img/exit_btn.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 # Game over loop if game_over == 0: # Get Keypresses key = pygame.key.get_pressed() if key[pygame.K_SPACE] and self.jumped == False and self.in_air == False: self.vel_y = -15 self.jumped = True if key[pygame.K_SPACE] == False: self.jumped = False if key[pygame.K_a]: dx -= 5 self.counter += 1 self.direction = -1 if key[pygame.K_d]: dx += 5 self.counter += 1 self.direction = 1 if key[pygame.K_d] == False and key[pygame.K_a] == 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 collisions self.in_air = True 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 ground i.e. jumping if self.vel_y < 0: dy = tile[1].bottom - self.rect.top # Check if below ground i.e. falling if self.vel_y >= 0: dy = tile[1].top - self.rect.bottom self.in_air = False # Check for collision with blobs if pygame.sprite.spritecollide(self, blob_group, False): game_over = -1 # Check for collision with lava tiles if pygame.sprite.spritecollide(self, lava_group, False): game_over = -1 # Update player coordanates self.rect.x += dx self.rect.y += dy if self.rect.bottom > screen_height: self.rect.bottom = screen_height dy = 0 elif game_over == -1: self.image = self.dead_image if self.rect.y > -150: self.rect.y -= 5 # Draw player onto screen screen.blit(self.image, self.rect) pygame.draw.rect(screen, (255,255,255), self.rect, 2) return game_over def reset(self, x, y): self.images_right = [] self.images_left = [] self.index = 0 self.counter = 0 for num in range(1,5): img_right = pygame.image.load(f'img/guy{num}.png') img_right = pygame.transform.scale(img_right, (40,80)) 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('img/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 self.in_air = True class World(): def __init__(self,data): self.tile_list = [] # Load Images dirt_img = pygame.image.load('img/dirt.png') grass_img = pygame.image.load('img/grass.png') 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: blob = Enemy(col_count * tile_size, row_count * tile_size + 15) blob_group.add(blob) if tile == 6: lava = Lava(col_count * tile_size, row_count * tile_size + (tile_size // 2)) lava_group.add(lava) 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], 2) class Enemy(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load('img/blob.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('img/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 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1], [1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 2, 2, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 7, 0, 5, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 1], [1, 7, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 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, 0, 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, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 2, 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, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 2, 2, 2, 2, 1], [1, 0, 0, 0, 0, 0, 2, 2, 2, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 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) blob_group = pygame.sprite.Group() lava_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 start_button.draw(): main_menu = False if exit_button.draw(): run = False else: world.draw() if game_over == 0: blob_group.update() blob_group.draw(screen) lava_group.draw(screen) game_over = player.update(game_over) # If the 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()