commit 008741169e356592929681d68befee88d023da0f Author: The-Tysonator Date: Mon Apr 24 12:35:00 2023 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bc6664a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_STORE +venv/ \ No newline at end of file diff --git a/images/background.png b/images/background.png new file mode 100755 index 0000000..2c62d96 Binary files /dev/null and b/images/background.png differ diff --git a/images/background1.png b/images/background1.png new file mode 100755 index 0000000..b8fa3e5 Binary files /dev/null and b/images/background1.png differ diff --git a/images/background2.png b/images/background2.png new file mode 100755 index 0000000..caf084a Binary files /dev/null and b/images/background2.png differ diff --git a/images/background3.png b/images/background3.png new file mode 100755 index 0000000..f31a2b7 Binary files /dev/null and b/images/background3.png differ diff --git a/images/background4.png b/images/background4.png new file mode 100755 index 0000000..9d4e1bd Binary files /dev/null and b/images/background4.png differ diff --git a/images/background_editor.png b/images/background_editor.png new file mode 100755 index 0000000..482d88d Binary files /dev/null and b/images/background_editor.png differ diff --git a/images/button_custom.png b/images/button_custom.png new file mode 100755 index 0000000..625bce9 Binary files /dev/null and b/images/button_custom.png differ diff --git a/images/button_edit.png b/images/button_edit.png new file mode 100755 index 0000000..3532be9 Binary files /dev/null and b/images/button_edit.png differ diff --git a/images/button_exit.png b/images/button_exit.png new file mode 100755 index 0000000..87811dc Binary files /dev/null and b/images/button_exit.png differ diff --git a/images/button_load.png b/images/button_load.png new file mode 100755 index 0000000..bc4bcda Binary files /dev/null and b/images/button_load.png differ diff --git a/images/button_music.png b/images/button_music.png new file mode 100755 index 0000000..9adf4b7 Binary files /dev/null and b/images/button_music.png differ diff --git a/images/button_restart.png b/images/button_restart.png new file mode 100755 index 0000000..0958fb8 Binary files /dev/null and b/images/button_restart.png differ diff --git a/images/button_save.png b/images/button_save.png new file mode 100755 index 0000000..de6bca9 Binary files /dev/null and b/images/button_save.png differ diff --git a/images/button_start.png b/images/button_start.png new file mode 100755 index 0000000..9c5b47b Binary files /dev/null and b/images/button_start.png differ diff --git a/images/door.png b/images/door.png new file mode 100755 index 0000000..4c432d4 Binary files /dev/null and b/images/door.png differ diff --git a/images/enemy.png b/images/enemy.png new file mode 100755 index 0000000..f52269e Binary files /dev/null and b/images/enemy.png differ diff --git a/images/ghost.png b/images/ghost.png new file mode 100755 index 0000000..0f676d7 Binary files /dev/null and b/images/ghost.png differ diff --git a/images/guy1.png b/images/guy1.png new file mode 100755 index 0000000..e258cb0 Binary files /dev/null and b/images/guy1.png differ diff --git a/images/guy2.png b/images/guy2.png new file mode 100755 index 0000000..4308670 Binary files /dev/null and b/images/guy2.png differ diff --git a/images/guy3.png b/images/guy3.png new file mode 100755 index 0000000..e258cb0 Binary files /dev/null and b/images/guy3.png differ diff --git a/images/guy4.png b/images/guy4.png new file mode 100755 index 0000000..b09e895 Binary files /dev/null and b/images/guy4.png differ diff --git a/images/left.png b/images/left.png new file mode 100755 index 0000000..6bc22b2 Binary files /dev/null and b/images/left.png differ diff --git a/images/middle.png b/images/middle.png new file mode 100755 index 0000000..001c381 Binary files /dev/null and b/images/middle.png differ diff --git a/images/right.png b/images/right.png new file mode 100755 index 0000000..e71a584 Binary files /dev/null and b/images/right.png differ diff --git a/images/test.png b/images/test.png new file mode 100755 index 0000000..53caba4 Binary files /dev/null and b/images/test.png differ diff --git a/images/water1.png b/images/water1.png new file mode 100755 index 0000000..495e49c Binary files /dev/null and b/images/water1.png differ diff --git a/images/water10.png b/images/water10.png new file mode 100755 index 0000000..6104842 Binary files /dev/null and b/images/water10.png differ diff --git a/images/water11.png b/images/water11.png new file mode 100755 index 0000000..d55b0f1 Binary files /dev/null and b/images/water11.png differ diff --git a/images/water12.png b/images/water12.png new file mode 100755 index 0000000..8be082b Binary files /dev/null and b/images/water12.png differ diff --git a/images/water13.png b/images/water13.png new file mode 100755 index 0000000..e4750ff Binary files /dev/null and b/images/water13.png differ diff --git a/images/water14.png b/images/water14.png new file mode 100755 index 0000000..d6bc749 Binary files /dev/null and b/images/water14.png differ diff --git a/images/water15.png b/images/water15.png new file mode 100755 index 0000000..124ea45 Binary files /dev/null and b/images/water15.png differ diff --git a/images/water16.png b/images/water16.png new file mode 100755 index 0000000..18d4c56 Binary files /dev/null and b/images/water16.png differ diff --git a/images/water2.png b/images/water2.png new file mode 100755 index 0000000..d9d67af Binary files /dev/null and b/images/water2.png differ diff --git a/images/water3.png b/images/water3.png new file mode 100755 index 0000000..2e24038 Binary files /dev/null and b/images/water3.png differ diff --git a/images/water4.png b/images/water4.png new file mode 100755 index 0000000..9d52acf Binary files /dev/null and b/images/water4.png differ diff --git a/images/water5.png b/images/water5.png new file mode 100755 index 0000000..0c17e43 Binary files /dev/null and b/images/water5.png differ diff --git a/images/water6.png b/images/water6.png new file mode 100755 index 0000000..fecc906 Binary files /dev/null and b/images/water6.png differ diff --git a/images/water7.png b/images/water7.png new file mode 100755 index 0000000..e4802a5 Binary files /dev/null and b/images/water7.png differ diff --git a/images/water8.png b/images/water8.png new file mode 100755 index 0000000..90a3173 Binary files /dev/null and b/images/water8.png differ diff --git a/images/water9.png b/images/water9.png new file mode 100755 index 0000000..4950590 Binary files /dev/null and b/images/water9.png differ diff --git a/level_editor.py b/level_editor.py new file mode 100755 index 0000000..b1c2cc6 --- /dev/null +++ b/level_editor.py @@ -0,0 +1,168 @@ +# Imports +import pygame +import pickle +from os import path +# Set Up +pygame.init() +fps = 60 +clock = pygame.time.Clock() +tile_size = 48 +cols = 35 +margin = 100 +screen_width = tile_size * cols +screen_height = 900 + margin +screen = pygame.display.set_mode((screen_width, screen_height)) +pygame.display.set_caption('Level Editor') +clicked = False +level = 1 +white = (255, 255, 255) +black = (0, 0, 0) +font = pygame.font.SysFont('Futura', 24) +#load images +background = pygame.image.load('images/background_editor.png') +left = pygame.image.load("images/left.png") +middle = pygame.image.load('images/middle.png') +right = pygame.image.load("images/right.png") +water = pygame.image.load('images/water1.png') +enemy = pygame.image.load('images/enemy.png') +door = pygame.image.load('images/door.png') +button_save = pygame.image.load('images/button_save.png') +button_load = pygame.image.load('images/button_load.png') +button_exit = pygame.image.load("images/button_exit.png") +# Create Empty World +world_data = [] +for row in range(35): + r = [0] * 35 + world_data.append(r) +# Output Text +def draw_text(text, font, text_col, x, y): + img = font.render(text, True, text_col) + screen.blit(img, (x, y)) +# Grid +def draw_vertical(): + for c in range(36): + # Vertical Lines + pygame.draw.line(screen, white, (c * tile_size, 0), (c * tile_size, screen_height - margin -36)) +def draw_horizontal(): + for c in range(19): + # Horizontal Lines + pygame.draw.line(screen, white, (0, c * tile_size), (screen_width, c * tile_size)) +# Draw World +def draw_world(): + for row in range(18): + for column in range(35): + if world_data[row][column] > 0: + # Left + if world_data[row][column] == 1: + image = pygame.transform.scale(left, (tile_size, tile_size)) + screen.blit(image, (column * tile_size, row * tile_size)) + # Middle + elif world_data[row][column] == 2: + image = pygame.transform.scale(middle, (tile_size, tile_size)) + screen.blit(image, (column * tile_size, row * tile_size)) + # Right + if world_data[row][column] == 3: + image = pygame.transform.scale(right, (tile_size, tile_size)) + screen.blit(image, (column * tile_size, row * tile_size )) + # Water + elif world_data[row][column] == 4: + image = pygame.transform.scale(water, (tile_size, tile_size)) + screen.blit(image, (column * tile_size, row * tile_size)) + # Enemy + if world_data[row][column] == 5: + image = pygame.transform.scale(enemy, (tile_size, int(tile_size * 0.75))) + screen.blit(image, (column * tile_size, row * tile_size + (tile_size * 0.25))) + # Door + if world_data[row][column] == 6: + image = pygame.transform.scale(door, (tile_size, int(tile_size * 0.75))) + screen.blit(image, (column * tile_size, row * tile_size + (tile_size * 0.25))) +# Button Class +class Button(): + # Init + def __init__(self, x, y, image): + self.image = image + self.images = pygame.transform.scale(image, (100,55)) + self.rect = self.images.get_rect() + self.rect.topleft = (x, y) + self.clicked = False + # Draw + def draw(self): + self.clicked = False + pos = pygame.mouse.get_pos() + if self.rect.collidepoint(pos): + if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False: + self.clicked = True + screen.blit(self.images, (self.rect.x, self.rect.y)) + return self.clicked +# Scale and Initialise Classes +background = pygame.transform.scale(background, (1750,865)) +load_button = Button(screen_width // 2 - 330, screen_height - 95, button_load) +save_button = Button(screen_width // 2 - 50, screen_height - 95, button_save) +exit_button = Button(screen_width // 2 + 250, screen_height - 95, button_exit) +# Game Loop +run = True +while run: + # Clock + clock.tick(fps) + # Background + screen.fill(black) + screen.blit(background, (0, 0)) + # Grid + draw_vertical() + draw_horizontal() + draw_world() + #text showing current level + draw_text(f'Level: {level}', font, white, tile_size, screen_height - 80) + draw_text('Press W or S to change level', font, white, tile_size, screen_height - 60) + # Load Button + if load_button.draw(): + #load in level data + if path.exists(f'levels/custom/level_{level}'): + pickle_in = open(f'levels/custom/level_{level}', 'rb') + world_data = pickle.load(pickle_in) + else: + pickle_out = open(f'levels/custom/level_{level}', 'wb') + pickle.dump(world_data, pickle_out) + pickle_out.close() + # Save Button + if save_button.draw(): + pickle_out = open(f'levels/custom/level_{level}', 'wb') + pickle.dump(world_data, pickle_out) + pickle_out.close() + # Exit Button + if exit_button.draw(): + run = False + # Event Handler + for event in pygame.event.get(): + # Quit Game + if event.type == pygame.QUIT: + run = False + # Clicks To Chnage Tiles + if event.type == pygame.MOUSEBUTTONDOWN and clicked == False: + clicked = True + mouse_position = pygame.mouse.get_pos() + x = mouse_position[0] // tile_size + y = mouse_position[1] // tile_size + # Check That The Coordinates Are Within The Tile Area + if x < 35 and y < 18: + # Update Tile Value + if pygame.mouse.get_pressed()[0] == 1: + world_data[y][x] += 1 + if world_data[y][x] > 6: + world_data[y][x] = 0 + elif pygame.mouse.get_pressed()[2] == 1: + world_data[y][x] -= 1 + if world_data[y][x] < 0: + world_data[y][x] = 6 + if event.type == pygame.MOUSEBUTTONUP: + clicked = False + # Change Level + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_w: + level += 1 + elif event.key == pygame.K_s and level > 1: + level -= 1 + #update game display window + pygame.display.update() +# Quit Pygame +pygame.quit() \ No newline at end of file diff --git a/levels/custom/level_1 b/levels/custom/level_1 new file mode 100755 index 0000000..9cb651e Binary files /dev/null and b/levels/custom/level_1 differ diff --git a/levels/custom/level_10 b/levels/custom/level_10 new file mode 100644 index 0000000..ccfb08f Binary files /dev/null and b/levels/custom/level_10 differ diff --git a/levels/custom/level_2 b/levels/custom/level_2 new file mode 100755 index 0000000..19c3d4c Binary files /dev/null and b/levels/custom/level_2 differ diff --git a/levels/custom/level_3 b/levels/custom/level_3 new file mode 100755 index 0000000..d849dbc Binary files /dev/null and b/levels/custom/level_3 differ diff --git a/levels/custom/level_4 b/levels/custom/level_4 new file mode 100755 index 0000000..d849dbc Binary files /dev/null and b/levels/custom/level_4 differ diff --git a/levels/custom/level_5 b/levels/custom/level_5 new file mode 100644 index 0000000..ccfb08f Binary files /dev/null and b/levels/custom/level_5 differ diff --git a/levels/custom/level_6 b/levels/custom/level_6 new file mode 100644 index 0000000..4607613 Binary files /dev/null and b/levels/custom/level_6 differ diff --git a/levels/custom/level_7 b/levels/custom/level_7 new file mode 100644 index 0000000..ccfb08f Binary files /dev/null and b/levels/custom/level_7 differ diff --git a/levels/custom/level_8 b/levels/custom/level_8 new file mode 100644 index 0000000..ccfb08f Binary files /dev/null and b/levels/custom/level_8 differ diff --git a/levels/custom/level_9 b/levels/custom/level_9 new file mode 100644 index 0000000..ccfb08f Binary files /dev/null and b/levels/custom/level_9 differ diff --git a/levels/storymode/level_1 b/levels/storymode/level_1 new file mode 100755 index 0000000..498a3ce Binary files /dev/null and b/levels/storymode/level_1 differ diff --git a/main.py b/main.py new file mode 100755 index 0000000..8a70883 --- /dev/null +++ b/main.py @@ -0,0 +1,448 @@ +# Imports +import pygame +import pygame.locals +import pygame_textbox +import os +from os import path +from threading import Thread +import pickle +import time +import random +# Set Up +pygame.init() +tile_size = 50 +screen_width = tile_size * 35 +screen_height = (900) +screen = pygame.display.set_mode((screen_width, screen_height)) +pygame.display.set_caption("Unexpected Adventure") +fps = 60 +clock = pygame.time.Clock() +level = 1 +main_menu = True +game_over = False +white = (255, 255, 255) +font = pygame.font.SysFont('Futura', 24) +doesnt_exist = False +scroll = [0,0] +# Load Images +background1 = pygame.image.load("images/background4.png").convert_alpha() +background2 = pygame.image.load("images/background3.png").convert_alpha() +background3 = pygame.image.load("images/background2.png").convert_alpha() +background4 = pygame.image.load("images/background1.png").convert_alpha() +left = pygame.image.load("images/left.png").convert_alpha() +middle = pygame.image.load("images/middle.png").convert() +right = pygame.image.load("images/right.png").convert_alpha() +door = pygame.image.load("images/door.png").convert_alpha() +button_edit = pygame.image.load("images/button_edit.png").convert() +button_custom = pygame.image.load("images/button_custom.png").convert() +button_start = pygame.image.load("images/button_start.png").convert() +button_exit = pygame.image.load("images/button_exit.png").convert() +button_music = pygame.image.load("images/button_music.png").convert() +button_restart = pygame.image.load("images/button_restart.png").convert() +# Sprite Groups +water_group = pygame.sprite.Group() +enemy_group = pygame.sprite.Group() +door_group = pygame.sprite.Group() +# World Class +class World(): + # Init + def __init__(self, data): + self.tile_list = [] + row_count = 0 + for row in data: + column_count = 0 + for tile in row: + if tile == 1: + tile = pygame.transform.scale(left, (tile_size, tile_size)) + tile_rect = tile.get_rect() + tile_rect.x = column_count * tile_size + tile_rect.y = row_count * tile_size + tile = (tile, tile_rect) + self.tile_list.append(tile) + elif tile == 2: + tile = pygame.transform.scale(middle, (tile_size, tile_size)) + tile_rect = tile.get_rect() + tile_rect.x = column_count * tile_size + tile_rect.y = row_count * tile_size + tile = (tile, tile_rect) + self.tile_list.append(tile) + elif tile == 3: + tile = pygame.transform.scale(right, (tile_size, tile_size)) + tile_rect = tile.get_rect() + tile_rect.x = column_count * tile_size + tile_rect.y = row_count * tile_size + tile = (tile, tile_rect) + self.tile_list.append(tile) + elif tile == 4: + water = Water(column_count * tile_size, row_count * tile_size + (tile_size // 2)) + water_group.add(water) + elif tile == 5: + enemy = Enemy(column_count * tile_size, row_count * tile_size + 15, row_count, column_count, data) + enemy_group.add(enemy) + elif tile == 6: + door = Door(column_count * tile_size, row_count * tile_size - (tile_size // 2)) + door_group.add(door) + column_count += 1 + row_count +=1 + # Draw World + def draw(self): + for tile in self.tile_list: + screen.blit(tile[0], (tile[1].x - scroll[0] + screen_width // 2, tile[1].y - scroll[1] + screen_height // 2)) +# Water +class Water(pygame.sprite.Sprite): + # Init + def __init__(self, x, y): + pygame.sprite.Sprite.__init__(self) + image = pygame.image.load("images/water1.png").convert_alpha() + self.image = pygame.transform.scale(image, (tile_size, tile_size)) + self.rect = self.image.get_rect() + self.rect.x = x + self.rect.y = y -25 + self.images = [] + self.image_index = 1 + for number in range(1, 17): + img = pygame.image.load(f"images/water{number}.png").convert_alpha() + img = pygame.transform.scale(img, (tile_size, tile_size)) + self.images.append(img) + self.image = self.images[self.image_index] + self.counter = 0 + # Update + def update(self): + self.image_index += 1 + if self.image_index < len(self.images): + self.image = self.images[self.image_index] + else: + self.image_index = 0 + self.image = self.images[self.image_index] + def render(self, screen): + screen.blit(self.image, (self.rect.x - scroll[0] + screen_width // 2, self.rect.y - scroll[1] + screen_height // 2)) +# Enemy Class +class Enemy(pygame.sprite.Sprite): + # Init + def __init__(self, x, y, row_count, column_count, data): + pygame.sprite.Sprite.__init__(self) + self.image = pygame.image.load("images/enemy.png").convert_alpha() + self.rect = self.image.get_rect() + self.rect.x = x + self.rect.y = y + self.move_direction = 5 + self.move_counter = 0 + self.row_count = row_count + self.column_count = column_count + self.data = data + # Update + def update(self): + if self.data[self.row_count + 1][self.column_count] == 2: + + self.rect.x += self.move_direction + self.move_counter += 1 + if self.move_counter > 10: + self.move_direction *= - 1 + self.move_counter*= -1 + def render(self, screen): + screen.blit(self.image, (self.rect.x - scroll[0] + screen_width // 2, self.rect.y - scroll[1] + screen_height // 2)) +# Door +class Door(pygame.sprite.Sprite): + # Init + def __init__(self, x, y): + pygame.sprite.Sprite.__init__(self) + image = pygame.image.load("images/door.png").convert_alpha() + self.image = pygame.transform.scale(image, (tile_size, tile_size + 26)) + self.rect = self.image.get_rect() + self.rect.x = x + self.rect.y = y + def render(self, screen): + screen.blit(self.image, (self.rect.x - scroll[0] + screen_width // 2, self.rect.y - scroll[1] + screen_height // 2)) +# Button Class +class Button(): + # Init + def __init__(self, x, y, image): + self.image = image + self.rect = self.image.get_rect() + self.rect.x = x + self.rect.y = y + # Draw Button + def draw(self): + mouse_position = pygame.mouse.get_pos() + clicked = False + if self.rect.collidepoint(mouse_position): + if pygame.mouse.get_pressed()[0] == 1: + clicked = True + time.sleep(0.2) + screen.blit(self.image, self.rect) + return clicked +# Player Class +class Player(): + # Init + def __init__(self, x, y): + self.reset(x, y) + self.game_over = False + self.image_index = 0 + # Move Player + def update(self, game_over , main_menu): + # Frame Rate + clock.tick(fps) + # Move Player + dx = 0 + dy = 0 + if game_over == False: + key = pygame.key.get_pressed() + # Jump + if key[pygame.K_w] and self.jumped == False and self.in_air == False: + self.vel_y = -15 + self.jumped = True + elif key[pygame.K_w] == False: + self.jumped = False + # Left + if key[pygame.K_a]: + dx -= 7 + self.direction = "left" + # Right + elif key[pygame.K_d]: + dx += 7 + self.direction = "right" + # Animations + if key[pygame.K_a] == False and key[pygame.K_d] == False: + if self.direction == "left": + self.image = self.images_left[0] + elif self.direction == "right": + self.image = self.images_right[0] + else: + self.index += 1 + if self.index >= len(self.images_right) or self.index >= len(self.images_left): + self.index = 0 + if self.direction == "left": + self.image = self.images_left[self.index] + elif self.direction == "right": + self.image = self.images_right[self.index] + # Gravity + self.vel_y += 1 + if self.vel_y > 10: + self.vel_y = 15 + dy += self.vel_y + # Collisions + self.in_air = True + for tile in world.tile_list: + # Animations + if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height): + if dx < 0: + self.image = self.images_left[0] + else: + self.image = self.images_right[0] + # X and Y + if tile[1].colliderect(self.rect.x + dx, self.rect.y, self.width, self.height): + dx = 0 + # Vertical + if tile[1].colliderect(self.rect.x, self.rect.y + dy, self.width, self.height): + if self.vel_y >= 0: + dy = tile[1].top - self.rect.bottom + self.in_air = False + elif self.vel_y < 0: + dy = tile[1].bottom - self.rect.top + self.vel_y = 0 + # Collision With Door + if pygame.sprite.spritecollide(self, door_group, False): + main_menu = True + # Game Over Conditions + if self.rect.bottom > screen_height: + game_over = True + elif pygame.sprite.spritecollide(self, water_group, False): + game_over = True + elif pygame.sprite.spritecollide(self, enemy_group, False): + game_over = True + # Game Over + if game_over == True: + self.image = self.dead_image + self.rect.y -= 5 + # Update Coordinates + self.rect.x += dx + self.rect.y += dy + # Draw Player + screen.blit(self.image, (self.rect.x - scroll[0] + screen_width // 2, self.rect.y - scroll[1] + screen_height // 2)) + return game_over, main_menu + # Reset Player + def reset(self, x, y): + # Set Up + self.images_right = [] + self.images_left = [] + self.index = 0 + # Load Images + for num in range(1, 5): + img_right = pygame.image.load(f"images/guy{num}.png").convert_alpha() + 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("images/ghost.png").convert_alpha() + self.image = self.images_right[0] + # Rect + 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() + # Other Variables + self.direction = 0 + self.vel_y = 0 + self.jumped = False + self.in_air = True +# Level Editor +def level_editor(): + print(os.path.join(os.getcwd(), "venv", "bin", "python3.9")) + os.system(os.path.join(os.getcwd(), "venv", "bin", "python3.9") + " " + os.path.join(os.getcwd(), "level_editor.py")) +# Draw Text +def draw_text(text, font, text_col, x, y): + img = font.render(text, True, text_col) + screen.blit(img, (x, y)) +# Scale and Initialise Classes +background1 = pygame.transform.scale(background1, (2000, 1000)) +background2 = pygame.transform.scale(background2, (2000, 1000)) +background3 = pygame.transform.scale(background3, (2000, 1000)) +background4 = pygame.transform.scale(background4, (2000, 1000)) +start_button = pygame.transform.scale(button_start, (200, 100)) +exit_button = pygame.transform.scale(button_exit, (80, 35)) +player = Player(100, screen_height - 180) +start_button = Button(screen_width // 2 -100 , screen_height // 2 - 100, start_button) +exit_button = Button(screen_width // 2 - 40, screen_height // 2 + 50, exit_button) +edit_button = Button(screen_width // 2 -250, screen_height // 2 + 30, button_edit) +custom_button = Button(screen_width // 2 + 150 , screen_height // 2 + 30 , button_custom) +music_button = Button(screen_width // 2 + 700 , screen_height // 2 - 400 , button_music) +menu_button = Button(screen_width //2 + 700 , screen_height //2 - 300, button_exit) +restart_button = Button(screen_width // 2 - 50, screen_height // 2 , button_restart) +# Background Music +pygame.mixer.music.load("sounds/music.mp3") +pygame.mixer.music.play(-1) +paused = False +# Game Loop +run = True +while run: + # FPS + clock.tick(fps) + screen.fill((0,0,0)) + # QUIT + events = pygame.event.get() + for event in events: + if event.type == pygame.QUIT: + run = False + # Draw Background + screen.blit(background4, (0 - scroll[0]* 0.2, 0)) + screen.blit(background3, (0 - scroll[0]* 0.4, 0)) + screen.blit(background2, (0 - scroll[0]* 0.5, 0)) + screen.blit(background1, (0 - scroll[0]* 0.6, 0)) + + + screen.blit(background4, (2000 - scroll[0]* 0.2, 0)) + screen.blit(background3, (2000 - scroll[0]* 0.4, 0)) + screen.blit(background2, (2000 - scroll[0]* 0.5, 0)) + screen.blit(background1, (2000 - scroll[0]* 0.6, 0)) + + + screen.blit(background4, (-2000 - scroll[0]* 0.2, 0)) + screen.blit(background3, (-2000 - scroll[0]* 0.4, 0)) + screen.blit(background2, (-2000 - scroll[0]* 0.5, 0)) + screen.blit(background1, (-2000 - scroll[0]* 0.6, 0)) + + + + + # Menu + if main_menu: + game_over = False + # Start + if start_button.draw(): + enemy_group.empty() + water_group.empty() + door_group.empty() + if path.exists(f"levels/storymode/level_{level}"): + pickle_in = open(f"levels/storymode/level_{level}", "rb") + level_data = pickle.load(pickle_in) + world = World(level_data) + main_menu = False + player.reset(100, screen_height - 130) + doesnt_exist = False + # Level Editor + elif edit_button.draw() == True: + thread = Thread(target = level_editor) + thread.start() + doesnt_exist = False + # Custom Maps + if custom_button.draw(): + enemy_group.empty() + water_group.empty() + door_group.empty() + selected_level = pygame_textbox.textinput() + if path.exists(f"levels/custom/level_{selected_level}"): + pickle_in = open(f"levels/custom/level_{selected_level}", "rb") + level_data = pickle.load(pickle_in) + world = World(level_data) + main_menu = False + screen = pygame.display.set_mode((screen_width, screen_height)) + pygame.display.set_caption("Unexpected Adventure") + player.reset(100, screen_height - 130) + doesnt_exist = False + else: + doesnt_exist = True + screen = pygame.display.set_mode((screen_width, screen_height)) + pygame.display.set_caption("Unexpected Adventure") + player.reset(100, screen_height - 130) + if doesnt_exist: + draw_text("Level Doesn't Exist", font, white, screen_width // 2 - 75, screen_height // 2 + 17) + # Exit + if exit_button.draw(): + run = False + # Music + if music_button.draw(): + if paused == False: + pygame.mixer.music.pause() + paused = True + else: + pygame.mixer.music.unpause() + paused = False + # Game + if main_menu == False: + + + + + # Draw World + world.draw() + water_group.update() + for water in water_group: + water.render(screen) + enemy_group.update() + for enemy in enemy_group: + enemy.render(screen) + door_group.update() + for door in door_group: + door.render(screen) + # Update Player + game_over, main_menu = player.update(game_over , main_menu) + scroll[0] += (player.rect.x - scroll[0])*0.02 + scroll[1] = 450 + + + # Music Button + if music_button.draw(): + if paused == False: + pygame.mixer.music.pause() + paused = True + else: + pygame.mixer.music.unpause() + paused = False + # Menu Button + if menu_button.draw(): + player.reset(100, screen_height - 130) + enemy_group.empty() + water_group.empty() + door_group.empty() + main_menu = True + game_over = False + # Restart Button + if game_over == True: + if restart_button.draw(): + player.reset(100, screen_height - 130) + game_over = False + # Update Display + pygame.display.update() +# Quit Pygame +pygame.quit() diff --git a/pygame_textbox.py b/pygame_textbox.py new file mode 100755 index 0000000..4a24a7d --- /dev/null +++ b/pygame_textbox.py @@ -0,0 +1,32 @@ +# Imports +import pygame_textinput +import pygame +# Set Up +pygame.init() +# Class +def textinput(): + # Window + screen = pygame.display.set_mode((300, 50)) + pygame.display.set_caption("Enter level number") + # Set Up + textinput = pygame_textinput.TextInput() + clock = pygame.time.Clock() + # Game Loop + run = True + while run: + # Background + screen.fill((225, 225, 225)) + events = pygame.event.get() + # QUIT + for event in events: + if event.type == pygame.QUIT: + exit() + # Feed Events + if textinput.update(events): + run = False + return textinput.get_text() + # Output + screen.blit(textinput.get_surface(), (10, 10)) + # Display + pygame.display.update() + clock.tick(30) \ No newline at end of file diff --git a/pygame_textinput.py b/pygame_textinput.py new file mode 100755 index 0000000..7099b52 --- /dev/null +++ b/pygame_textinput.py @@ -0,0 +1,128 @@ +import os.path +import pygame +import pygame.locals as pl +pygame.font.init() +class TextInput: + def __init__( + self, + initial_string="", + font_family="", + font_size=35, + antialias=True, + text_color=(0, 0, 0), + cursor_color=(0, 0, 1), + repeat_keys_initial_ms=400, + repeat_keys_interval_ms=35, + max_string_length=-1, + password=False): + self.antialias = antialias + self.text_color = text_color + self.font_size = font_size + self.max_string_length = max_string_length + self.password = password + self.input_string = initial_string + if not os.path.isfile(font_family): + font_family = pygame.font.match_font(font_family) + self.font_object = pygame.font.Font(font_family, font_size) + self.surface = pygame.Surface((1, 1)) + self.surface.set_alpha(0) + self.keyrepeat_counters = {} + self.keyrepeat_intial_interval_ms = repeat_keys_initial_ms + self.keyrepeat_interval_ms = repeat_keys_interval_ms + self.cursor_surface = pygame.Surface((int(self.font_size / 20 + 1), self.font_size)) + self.cursor_surface.fill(cursor_color) + self.cursor_position = len(initial_string) + self.cursor_visible = True + self.cursor_switch_ms = 500 + self.cursor_ms_counter = 0 + self.clock = pygame.time.Clock() + def update(self, events): + for event in events: + if event.type == pygame.KEYDOWN: + self.cursor_visible = True + if event.key not in self.keyrepeat_counters: + if not event.key == pl.K_RETURN: + self.keyrepeat_counters[event.key] = [0, event.unicode] + if event.key == pl.K_BACKSPACE: + self.input_string = ( + self.input_string[:max(self.cursor_position - 1, 0)] + + self.input_string[self.cursor_position:] + ) + self.cursor_position = max(self.cursor_position - 1, 0) + elif event.key == pl.K_DELETE: + self.input_string = ( + self.input_string[:self.cursor_position] + + self.input_string[self.cursor_position + 1:] + ) + elif event.key == pl.K_RETURN: + return True + elif event.key == pl.K_RIGHT: + self.cursor_position = min(self.cursor_position + 1, len(self.input_string)) + elif event.key == pl.K_LEFT: + self.cursor_position = max(self.cursor_position - 1, 0) + elif event.key == pl.K_END: + self.cursor_position = len(self.input_string) + elif event.key == pl.K_HOME: + self.cursor_position = 0 + elif len(self.input_string) < self.max_string_length or self.max_string_length == -1: + self.input_string = ( + self.input_string[:self.cursor_position] + + event.unicode + + self.input_string[self.cursor_position:] + ) + self.cursor_position += len(event.unicode) + elif event.type == pl.KEYUP: + if event.key in self.keyrepeat_counters: + del self.keyrepeat_counters[event.key] + for key in self.keyrepeat_counters: + self.keyrepeat_counters[key][0] += self.clock.get_time() + if self.keyrepeat_counters[key][0] >= self.keyrepeat_intial_interval_ms: + self.keyrepeat_counters[key][0] = ( + self.keyrepeat_intial_interval_ms + - self.keyrepeat_interval_ms + ) + event_key, event_unicode = key, self.keyrepeat_counters[key][1] + pygame.event.post(pygame.event.Event(pl.KEYDOWN, key=event_key, unicode=event_unicode)) + string = self.input_string + if self.password: + string = "*" * len(self.input_string) + self.surface = self.font_object.render(string, self.antialias, self.text_color) + self.cursor_ms_counter += self.clock.get_time() + if self.cursor_ms_counter >= self.cursor_switch_ms: + self.cursor_ms_counter %= self.cursor_switch_ms + self.cursor_visible = not self.cursor_visible + if self.cursor_visible: + cursor_y_pos = self.font_object.size(self.input_string[:self.cursor_position])[0] + if self.cursor_position > 0: + cursor_y_pos -= self.cursor_surface.get_width() + self.surface.blit(self.cursor_surface, (cursor_y_pos, 0)) + self.clock.tick() + return False + def get_surface(self): + return self.surface + def get_text(self): + return self.input_string + def get_cursor_position(self): + return self.cursor_position + def set_text_color(self, color): + self.text_color = color + def set_cursor_color(self, color): + self.cursor_surface.fill(color) + def clear_text(self): + self.input_string = "" + self.cursor_position = 0 +if __name__ == "__main__": + pygame.init() + textinput = TextInput() + screen = pygame.display.set_mode((1000, 200)) + clock = pygame.time.Clock() + while True: + screen.fill((225, 225, 225)) + events = pygame.event.get() + for event in events: + if event.type == pygame.QUIT: + exit() + textinput.update(events) + screen.blit(textinput.get_surface(), (10, 10)) + pygame.display.update() + clock.tick(30) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..49f851d --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pygame==2.3.0 diff --git a/sounds/music.mp3 b/sounds/music.mp3 new file mode 100755 index 0000000..724b31f Binary files /dev/null and b/sounds/music.mp3 differ