Example #1
0
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()
Example #2
0
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)
Example #3
0
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()