#import modules import pygame import pickle from os import path #initialize pygame pygame.init() clock = pygame.time.Clock() FPS = 60 #game window TILE_SIZE = 50 COLS = 20 margin = 100 SCREEN_WIDTH = TILE_SIZE * COLS SCREEN_HEIGHT = (TILE_SIZE * COLS) + margin screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption('Level Editor') #load images moon_img = pygame.image.load('img/moon.png') moon_img = pygame.transform.scale(moon_img, (TILE_SIZE, TILE_SIZE)) background_img = pygame.image.load('img/background.png') background_img = pygame.transform.scale(background_img, (SCREEN_WIDTH, SCREEN_HEIGHT - margin)) tile_img = pygame.image.load('img/tile.png') bluetile_img = pygame.image.load('img/bluetile.png') spike_img = pygame.image.load('img/spike.png') toxic_img = pygame.image.load('img/toxic.png') gem_img = pygame.image.load('img/gem.png') portal_img = pygame.image.load('img/portal.png') save_img = pygame.image.load('img/save_btnplaceholder.png') load_img = pygame.image.load('img/load_btnplaceholder.png') #define game variables clicked = False level = 1 #define colours WHITE = (255, 255, 255) GREEN = (144, 201, 120) FONT = pygame.font.SysFont('Futura', 24) #create empty tile list world_data = [] for row in range(20): r = [0] * 20 world_data.append(r) #create boundary for tile in range(0, 20): world_data[19][tile] = 2 world_data[0][tile] = 1 world_data[tile][0] = 1 world_data[tile][19] = 1 #function for outputting text onto the screen def draw_text(text, FONT, text_col, x, y): img = FONT.render(text, True, text_col) screen.blit(img, (x, y)) def draw_grid(): for c in range(21): #vertical lines pygame.draw.line(screen, WHITE, (c * TILE_SIZE, 0), (c * TILE_SIZE, SCREEN_HEIGHT - margin)) #horizontal lines pygame.draw.line(screen, WHITE, (0, c * TILE_SIZE), (SCREEN_WIDTH, c * TILE_SIZE)) def draw_world(): for row in range(20): for col in range(20): if world_data[row][col] > 0: if world_data[row][col] == 1: #dirt blocks img = pygame.transform.scale(tile_img, (TILE_SIZE, TILE_SIZE)) screen.blit(img, (col * TILE_SIZE, row * TILE_SIZE)) if world_data[row][col] == 2: #bluetile img = pygame.transform.scale(bluetile_img, (TILE_SIZE, TILE_SIZE)) screen.blit(img, (col * TILE_SIZE, row * TILE_SIZE)) if world_data[row][col] == 3: #enemy blocks img = pygame.transform.scale(spike_img, (TILE_SIZE, int(TILE_SIZE * 0.75))) screen.blit(img, (col * TILE_SIZE, row * TILE_SIZE + (TILE_SIZE * 0.25))) if world_data[row][col] == 4: #toxic img = pygame.transform.scale(toxic_img, (TILE_SIZE, TILE_SIZE // 2)) screen.blit(img, (col * TILE_SIZE, row * TILE_SIZE + (TILE_SIZE // 2))) if world_data[row][col] == 5: #gem img = pygame.transform.scale(gem_img, (TILE_SIZE // 2, TILE_SIZE // 2)) screen.blit(img, (col * TILE_SIZE + (TILE_SIZE // 4), row * TILE_SIZE + (TILE_SIZE // 4))) if world_data[row][col] == 6: #exit img = pygame.transform.scale(portal_img, (TILE_SIZE, int(TILE_SIZE * 1.5))) screen.blit(img, (col * TILE_SIZE, row * TILE_SIZE - (TILE_SIZE // 2))) class Button(): def __init__(self, x, y, image): self.image = image self.rect = self.image.get_rect() self.rect.topleft = (x, 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.x, self.rect.y)) return action #create load and save buttons save_button = Button(SCREEN_WIDTH // 2 - 150, SCREEN_HEIGHT - 80, save_img) load_button = Button(SCREEN_WIDTH // 2 + 50, SCREEN_HEIGHT - 80, load_img) #main game loop run = True while run: clock.tick(FPS) #draw background screen.fill(GREEN) screen.blit(background_img, (0, 0)) screen.blit(moon_img, (TILE_SIZE * 2, TILE_SIZE * 2)) #load and save level if save_button.draw(): #save level data pickle_out = open(f'level{level}_data', 'wb') pickle.dump(world_data, pickle_out) pickle_out.close() if load_button.draw(): #load in level data if path.exists(f'level{level}_data'): pickle_in = open(f'level{level}_data', 'rb') world_data = pickle.load(pickle_in) #show the grid and draw the level tiles draw_grid() draw_world() #text showing current level draw_text(f'Level: {level}', FONT, WHITE, TILE_SIZE, SCREEN_HEIGHT - 80) draw_text('Press UP or DOWN to change level', FONT, WHITE, TILE_SIZE, SCREEN_HEIGHT - 40) #event handler for event in pygame.event.get(): #quit game if event.type == pygame.QUIT: run = False #mouseclicks to change tiles if event.type == pygame.MOUSEBUTTONDOWN and clicked == False: clicked = True pos = pygame.mouse.get_pos() x = pos[0] // TILE_SIZE y = pos[1] // TILE_SIZE #check that the coordinates are within the tile area if x < 20 and y < 20: #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 #up and down key presses to change level number if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: level += 1 elif event.key == pygame.K_DOWN and level > 1: level -= 1 #update game display window pygame.display.update() pygame.quit()