def main(): pygame.init() screen = display.set_mode(DISPLAY, FLAGS, DEPTH) display.set_caption("Use arrows to move!") timer = time.Clock() up = down = left = right = space = False bg = Surface((BLOCK_SIZE, BLOCK_SIZE)) bg.convert() bg.fill(Color("#000000")) current_level = Level(LEVEL_W, LEVEL_H) player = Player(100, 100) entities = pygame.sprite.Group() entities.add(player) while True: timer.tick(FPS) for e in pygame.event.get(): if e.type == QUIT: raise SystemExit, "QUIT" if e.type == KEYDOWN and e.key == K_ESCAPE: raise SystemExit, "ESCAPE" if e.type == KEYDOWN and e.key == K_UP: up = True if e.type == KEYDOWN and e.key == K_DOWN: down = True if e.type == KEYDOWN and e.key == K_LEFT: left = True if e.type == KEYDOWN and e.key == K_RIGHT: right = True if e.type == KEYDOWN and e.key == K_SPACE: space = True if e.type == KEYUP and e.key == K_UP: up = False if e.type == KEYUP and e.key == K_DOWN: down = False if e.type == KEYUP and e.key == K_LEFT: left = False if e.type == KEYUP and e.key == K_RIGHT: right = False if e.type == KEYUP and e.key == K_SPACE: space = False if e.type == MOUSEBUTTONUP: pos = pygame.mouse.get_pos() print current_level._identify_img(pos[0]/BLOCK_SIZE, pos[1]/BLOCK_SIZE) # draw background for y in range(LEVEL_H): for x in range(LEVEL_W): screen.blit(bg, (x * BLOCK_SIZE, y * BLOCK_SIZE)) # update player, draw everything else player.update(up, down, left, right, space, current_level) player.draw(screen) #entities.draw(screen) current_level.draw(screen) pygame.display.flip()
class Game(States): def __init__(self): States.__init__(self) self.next = 'gameover' self.player = Player(self) self.platforms = pg.sprite.Group() self.all_sprites = pg.sprite.Group() self.all_sprites.add(self.player) self.PLATFORM_LIST = [Platform(0, HEIGHT - 40, 150, 10), Platform(950, 850, 150, 10), Platform(950, 650, 150, 10), Platform(950, 450, 150, 10), Platform(950, 250, 150, 10), Platform(950, 50, 150, 10)] self.create_plat() self.score = 0 self.load_data() def cleanup(self): print('cleaning up Game Level One state stuff') States.__init__(self) self.next = 'gameover' self.player = Player(self) self.platforms = pg.sprite.Group() self.all_sprites = pg.sprite.Group() self.all_sprites.add(self.player) self.PLATFORM_LIST = [Platform(0, HEIGHT - 40, 150, 10), Platform(950, 850, 150, 10), Platform(950, 650, 150, 10), Platform(950, 450, 150, 10), Platform(950, 250, 150, 10), Platform(950, 50, 150, 10)] self.create_plat() self.score = 0 self.load_data() def startup(self): print('starting Game Level One state stuff') def get_event(self, event): if event.type == pg.KEYDOWN: print('Game Level One State keydown') if event.type == pg.MOUSEBUTTONDOWN: pg.mixer.music.play() self.done = True if event.type == pg.KEYDOWN: if event.key == pg.K_w: self.player.jump() def load_data(self): #Load the high score. with open((HS_FILE), 'r') as f: try: self.highscore = int(f.read()) except: self.highscore = 0 def update(self, screen, dt): self.draw(screen) self.player.update() self.player.runAnim(dt) if self.player.vel.y > 0: hits = pg.sprite.spritecollide(self.player, self.platforms, False) if hits: self.player.pos.y = hits[0].rect.top + 1 self.player.vel.y = 0 #Scrolling functionality. if self.player.rect.top <= HEIGHT / 4: self.player.pos.y += max(abs(self.player.vel.y), 2) for plat in self.platforms: plat.rect.y += max(abs(self.player.vel.y), 2) if plat.rect.top >= HEIGHT: plat.kill() self.score += 10 if self.score > self.highscore: self.highscore = self.score with open((HS_FILE), 'w') as f: f.write(str(self.score)) if self.player.rect.bottom > HEIGHT: for sprite in self.all_sprites: sprite.rect.y -= max(self.player.vel.y, 10) if sprite.rect.bottom < 0: sprite.kill() if len(self.platforms) == 0: pg.mixer.music.play() self.done = True #Spawn new platforms. while len(self.platforms) < 10: width = random.randrange(50, 150) p = Platform(random.randrange(0, WIDTH-width), random.randrange(-75, -30), 150, 10) self.platforms.add(p) self.all_sprites.add(p) def create_plat(self): for platform in self.PLATFORM_LIST: self.platforms.add(platform) self.all_sprites.add(platform) def draw_text(self, text, size, color, x, y): self.font = loadCustomFont('Fonts/Amatic_SC/amatic_sc.ttf', 72) text_surface = self.font.render(text, True, color) text_rect = text_surface.get_rect() text_rect.midtop = (x, y) screen.blit(text_surface, text_rect) def draw(self, screen): screen.fill((255, 255, 0)) #Draw the test platform. for plat in self.platforms: plat.draw() #Draw the player. self.player.draw() self.draw_text('Score: ' + str(self.score), 12, (0,0,0), 125, 10) self.draw_text('Highscore: ' + str(self.highscore), 22, (0,0,0), 1750, 10)
class Game: def __init__(self): # init gui self.frame = Frame() self.frame.pack() self.canvas = Canvas(self.frame, width=WINDOW_WIDTH, height=WINDOW_HEIGHT, bg="black") self.canvas.pack() self.is_game_over = False self.should_quit = False self.hud = HUD(0, 0, 0) # init entities self.creatures = [] self.player = Player( Location(randint(1, TILES_X - 2), randint(1, TILES_Y - 2))) self.players_turn = True self.hud.update(self.player) # initialize the first level self.levels = [] self.levels_discovered = 0 self.init_level(TILES_X, TILES_Y, SQUARE_SIZE, upstairs=False, fountains=FOUNTAINS_PER_LEVEL) self.make_adjacent_tiles_visible(self.player.location) # bind keys self.canvas.bind('w', self.move_player_north) self.canvas.bind('s', self.move_player_south) self.canvas.bind('a', self.move_player_west) self.canvas.bind('d', self.move_player_east) self.canvas.bind('e', self.interact) self.canvas.bind('x', self.attack) self.canvas.bind('z', self.sleep) self.canvas.bind('k', self.kill_player) self.canvas.bind('<Escape>', self.quit) self.canvas.focus_set() def init_level(self, tiles_x, tiles_y, downstairs=True, upstairs=True, fountains=0): """Initializes level layout with given parameters""" level = Level(tiles_x, tiles_y, self.player.location) if upstairs: level.init_upstairs(self.player.location) if downstairs: location = level.nearest_suitable_tile( Location(randint(1, tiles_x - 2), randint(1, tiles_y - 2))) level.init_downstairs(location) if fountains > 0: for _ in range(fountains): location = level.nearest_suitable_tile( Location(randint(1, tiles_x - 2), randint(1, tiles_y - 2))) level.init_fountain(location) self.levels.append(level) self.creatures.append([]) number_of_creatures = min(self.levels_discovered + 3, level.number_of_tiles_allowing_spawn() // 2, 1) self.init_creatures(number_of_creatures + 3, self.levels_discovered) def init_creatures(self, how_many, z_level): """Initializes a specified number of creatures (currently only skeletons) on a given z-level""" creatures = [] for _ in range(how_many): location = Location(randint(1, self.levels[z_level].tiles_x - 2), randint(1, self.levels[z_level].tiles_y - 2), z_level) location = self.levels[z_level].nearest_suitable_tile(location) creatures.append(Skeleton(location)) self.creatures[z_level] += creatures def run(self): while not self.is_game_over: self.draw() self.update_models() while not self.should_quit: self.draw_game_over_screen() def draw(self): """Draws level layout, player and all entities at player's level and also updates HUD""" self.levels[self.player.location.z].draw(self.canvas) self.player.draw(self.canvas) for entity in self.creatures[self.player.location.z]: if self.levels[entity.location.z].get_tile( entity.location).visible: entity.draw(self.canvas) else: entity.erase(self.canvas) self.hud.update(self.player) self.hud.draw(self.canvas) self.canvas.update() def erase(self): self.levels[self.player.location.z].erase(self.canvas) self.canvas.delete(ALL) def update_models(self): if not self.players_turn: for entity in self.creatures[self.player.location.z]: if entity.is_alive: self.move_entity(entity) self.players_turn = True if self.player.health <= 0: self.is_game_over = True def entity_move_effects(self, entity, prev_location, current_location): self.levels[entity.location.z].get_tile( prev_location).accessible = True self.levels[entity.location.z].get_tile( current_location).accessible = False def player_move_effects(self, prev_location, current_location): self.entity_move_effects(self.player, prev_location, current_location) self.player.decrease_health(HEALTH_DECREASE_PER_TURN) self.make_adjacent_tiles_visible(self.player.location, self.player.visibility_range) self.players_turn = False def move_player_north(self, _): location = Location(self.player.location.x, self.player.location.y - 1) if self.levels[self.player.location.z].is_tile_available(location): x1, y1, z1 = self.player.location.get_xyz() self.player.move_north() x2, y2, z2 = self.player.location.get_xyz() self.player_move_effects(Location(x1, y1, z1), Location(x2, y2, z2)) def move_player_south(self, _): location = Location(self.player.location.x, self.player.location.y + 1) if self.levels[self.player.location.z].is_tile_available(location): x1, y1, z1 = self.player.location.get_xyz() self.player.move_south() x2, y2, z2 = self.player.location.get_xyz() self.player_move_effects(Location(x1, y1, z1), Location(x2, y2, z2)) def move_player_west(self, _): location = Location(self.player.location.x - 1, self.player.location.y) if self.levels[self.player.location.z].is_tile_available(location): x1, y1, z1 = self.player.location.get_xyz() self.player.move_west() x2, y2, z2 = self.player.location.get_xyz() self.player_move_effects(Location(x1, y1, z1), Location(x2, y2, z2)) def move_player_east(self, _): location = Location(self.player.location.x + 1, self.player.location.y) if self.levels[self.player.location.z].is_tile_available(location): x1, y1, z1 = self.player.location.get_xyz() self.player.move_east() x2, y2, z2 = self.player.location.get_xyz() self.player_move_effects(Location(x1, y1, z1), Location(x2, y2, z2)) def make_adjacent_tiles_visible(self, location, visibility_range=VISIBILITY_RANGE): """Makes all tiles within visibility range from given location visible""" locations = [] x, y, z = location.get_xyz() for x_off in range(-visibility_range, visibility_range + 1): for y_off in range(-visibility_range, visibility_range + 1): locations.append(Location(x + x_off, y + y_off)) self.levels[z].make_tiles_visible(locations) def interact(self, _): """Makes player interact with an object in player's location. If any changes to player's z-coordinate were made, then the previous level is erased. If player's z-coordinate is greater than the number of levels discovered, then generate a new level.""" x, y, z = self.player.location.get_xyz() if self.levels[z].tiles[x][y].interactive: previous_lvl = self.player.location.z self.levels[z].tiles[x][y].interact_with(self.player) current_lvl = self.player.location.z if previous_lvl != current_lvl: # if player changed levels self.player.location.z = previous_lvl self.erase() self.player.location.z = current_lvl if self.player.location.z == self.levels_discovered + 1: # if player has found a new level self.levels_discovered += 1 self.init_level(TILES_X, TILES_Y, fountains=FOUNTAINS_PER_LEVEL) self.make_adjacent_tiles_visible(self.player.location) def attack(self, _): """Naive implementation of an attack. Searches in all directions (C, N, E, S, W) for an entity with the lowest amount of hp and attacks it. If no such entity is found, then nothing happens (player still loses his turn)""" x, y, z = self.player.location.get_xyz() directions = [[x, y, z], [x, y - 1, z], [x - 1, y, z], [x + 1, y, z], [x, y + 1, z]] creature_found = False dir_index = 0 creature_to_attack = None while dir_index < len(directions): direction = directions[dir_index] for creature in self.creatures[direction[2]]: rules = [ creature.location.x == direction[0], creature.location.y == direction[1], creature.is_alive, not creature_found ] if all(rules): if creature_to_attack is None: creature_to_attack = creature elif creature_to_attack.health > creature.health: creature_to_attack = creature dir_index += 1 if creature_to_attack is not None: self.player.attack(creature_to_attack) if not creature_to_attack.is_alive: creature_to_attack.give_experience_to(self.player) self.levels[creature_to_attack.location.z].get_tile( creature_to_attack.location).accessible = True self.players_turn = False def sleep(self, _): self.players_turn = False def kill_player(self, _): self.player.health = 0 self.players_turn = False def move_entity(self, entity): dist = entity.location.distance_from(self.player.location) if dist == 1: entity.attack(self.player) elif dist <= entity.visibility_range: self.move_entity_towards_target(entity, self.player, entity.visibility_range) else: self.move_entity_randomly(entity) def move_entity_towards_target(self, entity, target, max_steps): self.current_record = max_steps + 1 self.all_steps = [] def pathfinder(x, y, target, steps, steps_taken): if steps == max_steps or isinstance( self.levels[target.location.z].tiles[x][y], Wall): return elif target.location.x == x and target.location.y == y: if steps < self.current_record: self.current_record = steps self.all_steps = steps_taken return else: for loc in [[x, y - 1], [x - 1, y], [x + 1, y], [x, y + 1]]: pathfinder(loc[0], loc[1], target, steps + 1, steps_taken + [loc]) pathfinder(entity.location.x, entity.location.y, target, 0, []) if self.all_steps != []: step = self.all_steps[0] x1, y1, _ = entity.location.get_xyz() entity.move_to_location( Location(step[0], step[1], entity.location.z)) x2, y2, _ = entity.location.get_xyz() self.entity_move_effects(entity, Location(x1, y1, entity.location.z), Location(x2, y2, entity.location.z)) def move_entity_randomly(self, entity): # randomly generate direction add_to_x = randint(-1, 1) add_to_y = (randint(-1, 1) if add_to_x == 0 else 0) # move by size of one square in one direction new_location = Location(entity.location.x + add_to_x, entity.location.y + add_to_y, entity.location.z) # if it's possible to move into that location, then do so if (new_location.is_within_bounds( 0, 0, self.levels[self.player.location.z].tiles_x, self.levels[self.player.location.z].tiles_y) and self.levels[ self.player.location.z].get_tile(new_location).accessible): x1, y1, _ = entity.location.get_xyz() entity.move_to_location(new_location) x2, y2, _ = entity.location.get_xyz() self.entity_move_effects(entity, Location(x1, y1, entity.location.z), Location(x2, y2, entity.location.z)) def quit(self, _): self.is_game_over = True self.should_quit = True def draw_game_over_screen(self): self.erase() self.canvas.create_text(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2, text="YOU LOST!\n YOUR SCORE: " + str(self.player.exp), font=("Times New Roman", 40), fill="white", anchor="c") self.canvas.create_text(WINDOW_HEIGHT // 2, WINDOW_HEIGHT // 1.5, text="Press any [Esc] to quit", fill="white", anchor="w") self.canvas.update()