# This file is part of ROBOTGAME # # ROBOTGAME 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. # # ROBOTGAME 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 # ROBOTGAME. If not, see . # # ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' # # level1.py # -------------------- # date created : Tue Aug 7 2012 # copyright : (C) 2012 Sakse Dalum # maintained by : Sakse Dalum """ The first level. """ import os import pygame import random import re import itertools import level import player import tile import block import boulder import lever import trigger import logic.rollingstone import logic.colourboxes class Level1(level.Level): def __init__(self, game, graphics_dir, paused=False): level.Level.__init__(self, game, graphics_dir, size=(64 * 100, 48 * 100), paused=paused) self.task_completions = [] self.dimensions = 50, 50 self.set_darkness(0) for i in range(self.dimensions[0]): for j in range(self.dimensions[1]): self.tiles.append( tile.Tile(self, i*64, j*48, self.imgs['ground1'])) self.player.set_pos(64 * 15, 48 * 15) self.player.set_init_pos() for i in range(self.dimensions[0]): self.objects.append(block.InvisBlock(self, i * 64, 0)) self.objects.append(block.InvisBlock(self, i * 64, (self.dimensions[1]) * 48)) for i in range(self.dimensions[1]): self.objects.append(block.InvisBlock(self, -64, i * 48)) self.objects.append(block.InvisBlock(self, self.dimensions[0] * 64, i * 48)) ### Task 2: Rolling stone task2_size = 15, 10 task2_pos = (64 * 20, 48 * 20) playfield, nsteps, directions = ( logic.rollingstone.generate_simple_unsolved_solvable_extra( task2_size[0], task2_size[1], 7, 30)) for i, j in playfield: self.objects.append( block.Block(self, task2_pos[0] + 64 * i, task2_pos[1] + 48 * j, self.imgs['block1'], movable=True)) arrow_blocks = [] n = 0 for i in directions: arrow_blocks.append( block.ArrowBlock(self, task2_pos[0] + 64 * (task2_size[0] - n), task2_pos[1] + 48 * (task2_size[1] + 2), i.next_pos((0, 0)))) n += 1 self.objects.extend(arrow_blocks) self.objects.append(lever.Lever(self, task2_pos[0] + 64 * 3, task2_pos[1] - 48 * 2, [arrow_block.activate for arrow_block in arrow_blocks], toggling=True, anim='lever_updown')) b = boulder.Boulder(self, task2_pos[0], task2_pos[1] - 48, direction=(0, 1)) self.objects.append(b) self.objects.append(lever.Lever(self, task2_pos[0] + 64 * 2, task2_pos[1] - 48 * 2, [b.activate], anim='lever_updown')) # Moat sides for i in range(-1, task2_size[1]): self.add_tile(task2_pos[0] - 64, task2_pos[1] + 48 * i, 'moat_vertical') for i in range(task2_size[1] - 2): self.add_tile(task2_pos[0] + 64 * task2_size[0], task2_pos[1] + 48 * i, 'moat_vertical') for i in range(6, task2_size[0]): self.add_tile(task2_pos[0] + 64 * i, task2_pos[1] - 48, 'moat_horizontal') for i in range(task2_size[0] - 2): self.add_tile(task2_pos[0] + 64 * i, task2_pos[1] + 48 * task2_size[1], 'moat_horizontal') # Corners self.add_tile(task2_pos[0] + 64 * task2_size[0], task2_pos[1] - 48, 'moat_corner_north_flip') self.add_tile(task2_pos[0] - 64, task2_pos[1] + 48 * task2_size[1], 'moat_corner_south') # Start self.add_tile(task2_pos[0] + 64 * 2, task2_pos[1] - 48, 'moat_horizontal') self.add_tile(task2_pos[0] + 64 * 3, task2_pos[1] - 48, 'moat_end_horizontal_flip') self.add_tile(task2_pos[0] + 64 * 5, task2_pos[1] - 48, 'moat_end_horizontal') self.add_tile(task2_pos[0] - 64, task2_pos[1] - 48 * 2, 'moat_corner_north') self.add_tile(task2_pos[0], task2_pos[1] - 48 * 2, 'moat_horizontal') self.add_tile(task2_pos[0] + 64, task2_pos[1] - 48 * 2, 'moat_corner_north_flip') self.add_tile(task2_pos[0] + 64, task2_pos[1] - 48, 'moat_corner_south') # End self.add_tile(task2_pos[0] + 64 * task2_size[0], task2_pos[1] + 48 * (task2_size[1] - 2), 'moat_corner_south') self.add_tile(task2_pos[0] + 64 * (task2_size[0] + 1), task2_pos[1] + 48 * (task2_size[1] - 2), 'moat_corner_north_flip') self.add_tile(task2_pos[0] + 64 * (task2_size[0] + 1), task2_pos[1] + 48 * (task2_size[1] - 1), 'moat_vertical') self.add_tile(task2_pos[0] + 64 * (task2_size[0] + 1), task2_pos[1] + 48 * (task2_size[1]), 'moat_corner_south_flip') self.add_tile(task2_pos[0] + 64 * (task2_size[0]), task2_pos[1] + 48 * (task2_size[1]), 'moat_end_horizontal') self.add_tile(task2_pos[0] + 64 * (task2_size[0] - 2), task2_pos[1] + 48 * (task2_size[1]), 'moat_end_horizontal_flip') self.objects.append( trigger.Trigger(self, task2_pos[0] + 64 * (task2_size[0]), task2_pos[1] + 48 * (task2_size[1] - 1), [self.complete_task, b.fall], self.imgs['hole'], [b], signal=[0, 2])) ### Task 3: Colour blocks task3_pos = (64 * 15, 48 * 18) # Abstract "boxes", actually colour fields boxes = logic.colourboxes.generate_colour_boxes(1, 3) boxes += boxes boxes += [logic.colourboxes.generate_random_box(1) for _ in range(3)] random.shuffle(boxes) pos_colour = {} for box, (x, y) in zip(boxes, itertools.product(range(3), range(3))): # self.tiles.append(tile.Tile(self, x * 64 + task3_pos[0], # y * 48 + task3_pos[1], # self.imgs['ground1'])) pos_colour[(x, y)] = box self.add_tile(task3_pos[0] + 64 * x, task3_pos[1] + 48 * y, 'indoor%d' % random.randint(1, 6), blocking=False) action_blocks = [block.ActionBlock(self, 64 * i + task3_pos[0], task3_pos[1], movable=True) for i in range(3)] self.objects.extend(action_blocks) wells = [block.ColorWell(self, task3_pos[0] + 64, task3_pos[1] + 48 * 5)] self.objects.extend(wells) def update_wells(block): cur_boxes = [] for block in action_blocks: box = pos_colour.get(((block.x - task3_pos[0]) / 64, (block.y - task3_pos[1] - 48) / 48)) if box: cur_boxes.append(box) if not cur_boxes: well_colours = [(0, 0, 0)] * len(wells) else: well_colours = logic.colourboxes.get_colours(cur_boxes) for i in range(len(wells)): wells[i].set_colour(*well_colours[i]) for b in action_blocks: b.action = update_wells self.objects.append( lever.Lever(self, task3_pos[0] + 64, task3_pos[1] + 48 * 4, [lambda *x: (self.complete_task(3) if (len([w for w in wells if (w.well_colour == (255, 255, 255)) ]) == len(wells)) else lambda: None)])) ### Task 4: Inverted bits task4_pos = (64 * 26, 48 * 18) b = boulder.Boulder(self, task4_pos[0] - 64, task4_pos[1] - 48 * 3, direction=(1, 0)) self.objects.append(b) self.objects.append(lever.Lever(self, task4_pos[0] - 64 * 3, task4_pos[1] - 48 * 3, [b.activate])) risingblocks = [block.RisingBlock(self, task4_pos[0] + 64 * i, task4_pos[1] - 48 * 3, is_up = False) for i in range(8)] for i in range(8): r = range(8) r.remove(i) self.objects.append(risingblocks[i]) n = random.choice(r) self.objects.append(lever.Lever(self, task4_pos[0] + 64 * i, task4_pos[1] - 48 * 2, [risingblocks[i].activate, risingblocks[n].activate], anim='lever_updown', toggling=True, signal=[0, 1])) for k in range(random.randint(0, 1)): self.objects[-1].use(self) self.objects[-1].set_init_pos() risingblocks[i].set_init_pos() risingblocks[n].set_init_pos() n = random.choice(r) self.objects.append(lever.Lever(self, task4_pos[0] + 64 * i, task4_pos[1], [risingblocks[i].activate, risingblocks[n].activate], anim='lever_updown', toggling=True, signal=[2, 3])) for k in range(random.randint(0, 1)): self.objects[-1].use(self) self.objects[-1].set_init_pos() risingblocks[i].set_init_pos() risingblocks[n].set_init_pos() self.objects.append(trigger.Trigger(self, task4_pos[0] + 64 * 8, task4_pos[1] - 48 * 3, [self.complete_task, b.fall], self.imgs['hole'], [b], signal=[0, 4])) # Moat self.add_tile(task4_pos[0] - 64 * 2, task4_pos[1] - 48 * 4, 'moat_corner_north') self.add_tile(task4_pos[0] - 64 * 2, task4_pos[1] - 48 * 3, 'moat_vertical') self.add_tile(task4_pos[0] - 64 * 2, task4_pos[1] - 48 * 2, 'moat_corner_south') self.add_tile(task4_pos[0] - 64, task4_pos[1] - 48 * 2, 'moat_end_horizontal_flip') for i in range(10): self.add_tile(task4_pos[0] + 64 * (i - 1), task4_pos[1] - 48 * 4, 'moat_horizontal') self.add_tile(task4_pos[0] + 64 * 9, task4_pos[1] - 48 * 4, 'moat_corner_north_flip') self.add_tile(task4_pos[0] + 64 * 9, task4_pos[1] - 48 * 3, 'moat_vertical') self.add_tile(task4_pos[0] + 64 * 9, task4_pos[1] - 48 * 2, 'moat_corner_south_flip') self.add_tile(task4_pos[0] + 64 * 8, task4_pos[1] - 48 * 2, 'moat_end_horizontal') self.draw_background() def add_tile(self, x, y, img, blocking=True): self.tiles.append(tile.Tile(self, x, y, self.imgs[img])) if blocking: self.objects.append(block.InvisBlock(self, x, y)) def load(self): """Load all resources used in the level.""" l = ['ground1', 'ground2'] for o in l: self.imgs[o] = pygame.image.load(os.path.join( self.graphics_dir, 'tiles', '%s.png' % o)) for o in range(1, 7): self.imgs['indoor%d' % o] = pygame.image.load(os.path.join( self.graphics_dir, 'tiles', 'indoor', 'ground%02d.png' % o)) l = ['block1', 'block1_lifted'] for o in l: self.imgs[o] = pygame.image.load(os.path.join( self.graphics_dir, 'blocks', '%s.png' % o)) l = ['hole', 'well'] for o in l: self.imgs[o] = pygame.image.load(os.path.join( self.graphics_dir, '%s.png' % o)) l = ['moat_corner_north', 'moat_corner_south', 'moat_corner_north_flip', 'moat_corner_south_flip', 'moat_end_horizontal', 'moat_horizontal', 'moat_vertical'] for o in l: self.imgs[o] = pygame.image.load(os.path.join( self.graphics_dir, 'moat', '%s.png' % o)) # Special treatment self.imgs['moat_end_horizontal_flip'] = pygame.transform.flip( self.imgs['moat_end_horizontal'], 1, 0) # Load animations for anim, directory in ( [('boulder_up', os.path.join('boulder', 'up')), ('boulder_down', os.path.join('boulder', 'down')), ('boulder_right', os.path.join('boulder', 'right')), ('boulder_left', os.path.join('boulder', 'right')), ('boulder_falling', os.path.join('boulder_fall')), ('lever_updown', os.path.join('lever', 'down-up')), ('lever_leftright', os.path.join('lever', 'left-right')), ('arrow_up', os.path.join('matt', 'up')), ('arrow_right', os.path.join('matt', 'right')), ('arrow_down', os.path.join('matt', 'down')), ('arrow_left', os.path.join('matt', 'right')),] ): self.imgs[anim] = [] # Find all image files for the given animation anim_files = [] for root, dirs, files in os.walk(os.path.join( self.graphics_dir, directory)): for f in files: if re.match(r"^.*\.(png)$", '/'.join([root, f])): anim_files.append('/'.join([root, f])) # Sort and load the files for f in sorted(anim_files): img = pygame.image.load(f) # Special treatment: if anim == 'arrow_left': img = pygame.transform.flip(img, 1, 0) self.imgs[anim].append(img) def complete_task(self, task): if task == 0: return self.task_completions.append(task) if len(self.task_completions) > 3: self.task_completions.remove(self.task_completions[0]) print(self.task_completions) def restart(self): for obj in self.objects: obj.reset_pos()