a-robots-conundrum/arobotsconundrum/level3.py

174 lines
6.9 KiB
Python

#!/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 <http://www.gnu.org/licenses/>.
#
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
#
# level3.py
# --------------------
# date created : Wed Aug 8 2012
# copyright : (C) 2012 Niels G. W. Serup
# maintained by : Niels G. W. Serup <ngws@metanohi.name>
"""
The third 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
import logic.colourboxes
class Level3(level.Level):
def __init__(self, game, graphics_dir, paused=False):
level.Level.__init__(self, game, graphics_dir, size=(64*11, 48*20),
paused=paused)
self.dimensions = 11, 20
# 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.task_start = (1, 6)
# Abstract "boxes", actually colour fields
boxes = []
for i in range(4):
boxes.extend([(0, 0, 0)] * i + box + [(0, 0, 0)] * (3 - i)
for box in logic.colourboxes.generate_colour_boxes(1, 3))
boxes.extend(logic.colourboxes.generate_random_box(4, 2) for _ in range(20))
boxes.extend([(0, 0, 0)] * 4 for _ in range(10))
random.shuffle(boxes)
pos_colour = {}
for i, j in self._positions():
self.tiles.append(
tile.Tile(self, i * 64, (j + 4) * 48, self.imgs['indoor%d' % random.randint(1, 6)]))
for box, (x, y) in zip(boxes, itertools.product(range(7), range(6))):
# self.tiles.append(tile.Tile(self, 64 * (x + self.task_start[0] + 1),
# 48 * (y + self.task_start[1] + 1),
# self.imgs['indoor%d' % random.randint(1, 6)]))
pos_colour[(x, y)] = box
self.draw_background()
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))
action_blocks = list(itertools.chain(*
[(block.ActionBlock(self, 64 * self.task_start[0],
48 * (i + 1 + self.task_start[1]),
movable=True),
block.ActionBlock(self, 64 * (self.task_start[0] + 8),
48 * (i + 1 + self.task_start[1]),
movable=True))
for i in range(6)]))
self.objects.extend(action_blocks)
wells = [block.ColorWell(self, self.task_start[0] * 64, self.task_start[1] * 48),
block.ColorWell(self, (self.task_start[0] + 8) * 64, self.task_start[1] * 48),
block.ColorWell(self, self.task_start[0] * 64, (self.task_start[1] + 7) * 48),
block.ColorWell(self, (self.task_start[0] + 8) * 64, (self.task_start[1] + 7) * 48),
]
self.objects.extend(wells)
self.wells = wells
self.bottom_objects.append(worldobject.WithBackground(
self, self.imgs['elevator_top'], 64 * (self.task_start[0] + 3), 48 * (self.task_start[1] + 10)))
self.elevator = worldobject.WithBackground(
self, self.imgs['elevator'], 64 * (self.task_start[0] + 3), 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] + 4), 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] + 3), 48 * (self.task_start[1] + 12)))
def update_wells(block):
cur_boxes = []
for block in action_blocks:
box = pos_colour.get((block.x / 64 - self.task_start[0] - 1,
block.y / 48 - self.task_start[1] - 1))
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 well, color in zip(wells, well_colours):
well.set_colour(*color)
for b in action_blocks:
b.action = update_wells
self.player.set_pos(64 * 5, 48 * 4)
self.player.set_init_pos()
def try_goto_next_level(self):
# if not all(well.well_colour == (255, 255, 255)
# for well in self.wells):
# 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(4)
def restart(self):
for obj in self.objects:
obj.reset_pos()