#!/usr/bin/env python. # -*- coding: utf-8 -*- # This file is part of A Robot's Conundrum # # A Robot's Conundrum is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # A Robot's Conundrum is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # A Robot's Conundrum. If not, see . # # ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' # # level2.py # -------------------- # date created : Fri Oct 12 2012 # copyright : (C) 2012 Niels G. W. Serup # maintained by : Niels G. W. Serup """ The second level. """ from __future__ import print_function import os import pygame import random import re import itertools import worldobject import level import player import trigger import tile import block import lever import fadeout from weight_indicator import WeightIndicator import logic.colourboxes def is_sorted(xs): return all(a <= b for a, b in itertools.izip(xs[:-1], xs[1:])) class Level2(level.Level): def __init__(self, game, graphics_dir, paused=False): level.Level.__init__(self, game, graphics_dir, size=(64*21, 48*20), paused=paused) self.dimensions = 21, 20 self.task_start = (1, 6) for i, j in self._positions(): self.tiles.append( tile.Tile(self, i * 64, (j + 4) * 48, self.imgs['ground1'])) self.sort_poss = [] for x in range(12): self.sort_poss.append(((x + 2) * 64, 6 * 48)) self.tiles.append( tile.Tile(self, (x + 2) * 64, 6 * 48, self.imgs['indoor1'])) self.symbolblocks = [] for x in range(12): b = block.Block(self, 64 * (x + 2), 48 * 10, self.imgs['symbolblock%02d' % (x + 1)], movable=True) self.symbolblocks.append(b) random.shuffle(self.symbolblocks) for i in range(len(self.symbolblocks)): self.symbolblocks[i].n = i random.shuffle(self.symbolblocks) self.objects.extend(self.symbolblocks) self.weighing_poss = ((7 * 64, 12 * 48), (9 * 64, 12 * 48)) for x, y in self.weighing_poss: self.tiles.append( tile.Tile(self, x, y, self.imgs['indoor3'])) self.objects.append( trigger.Trigger(self, x, y, [self.weigh], self.imgs['hole'], self.symbolblocks, visible=False, no_stop=True)) self.draw_background() self.weight_ind = WeightIndicator(self, 8, 8, 0, links=[]) self.objects.append(self.weight_ind) top = self.dimensions[0] for i in range(top): if i % 3 == 0: self.objects.append(block.Block( self, i * 64, 48 * 3, self.imgs['wall'], width=2 if i == top - 2 else 3, blit_area=(0, 0, 160, 192) if i == top - 2 else None)) self.objects.append(block.InvisBlock(self, i * 64, self.size[1])) for i in range(self.dimensions[1]): self.objects.append(block.InvisBlock(self, - 64, i * 48)) self.objects.append(block.InvisBlock(self, self.size[0], i * 48)) self.bottom_objects.append(worldobject.WithBackground( self, self.imgs['elevator_top'], 64 * (self.task_start[0] + 1), 48 * (self.task_start[1] + 10))) self.elevator = worldobject.WithBackground( self, self.imgs['elevator'], 64 * (self.task_start[0] + 1), 48 * (self.task_start[1] + 11), 48) self.bottom_objects.append(self.elevator) self._next_level_trigger = trigger.Trigger( self, 64 * (self.task_start[0] + 2), 48 * (self.task_start[1] + 10), [lambda _: self.try_goto_next_level()], self.imgs['hole'], [self.player], visible=False, no_stop=True) self.objects.append(self._next_level_trigger) self.bottom_objects.append(worldobject.WithBackground( self, self.imgs['elevator_bottom'], 64 * (self.task_start[0] + 1), 48 * (self.task_start[1] + 12))) self.player.set_pos(64 * 1, 48 * 4) self.player.set_init_pos() def weigh(self, x): a, b = None, None for bl in self.symbolblocks: if (bl.x, bl.y) == self.weighing_poss[0]: a = bl.n elif (bl.x, bl.y) == self.weighing_poss[1]: b = bl.n if a is not None and b is not None: self.weight_ind.change_state(-1 if a < b else 1 if a > b else 0) def can_go(self): calc = [None for i in range(12)] for bl in self.symbolblocks: p = (bl.x, bl.y) if p in self.sort_poss: calc[self.sort_poss.index(p)] = bl.n return not None in calc and (is_sorted(calc) or is_sorted(calc[::-1])) def try_goto_next_level(self): if not self.can_go(): return self.objects.remove(self._next_level_trigger) self._old_player_update = self.player.update self.player.update = lambda e, t, dt: self._old_player_update([], t, dt) self.update = self.update2 self._start_time = pygame.time.get_ticks() fadeout.Fadeout(self.game, self.goto_next_level, duration=1500) def update2(self, e, t, dt): level.Level.update(self, e, t, dt) start_offset = (t - self._start_time) / 25 self.elevator.z_px = 48 - start_offset self.player.y = 48 * (self.task_start[1] + 10) - start_offset def goto_next_level(self): self.game.goto_level(3) def restart(self): for obj in self.objects: obj.reset_pos()