Added elevator and minor other things to level 3 and 4. Added link from level 3
to level 4.
This commit is contained in:
parent
e7745a6f60
commit
ca7fea1916
|
@ -96,6 +96,7 @@ class Block(worldobject.WorldObject):
|
|||
self.y - self.img.get_size()[1] + 24
|
||||
- self.level.camera_y), self.blit_area)
|
||||
|
||||
|
||||
class InvisBlock(Block):
|
||||
def __init__(self, level, x, y):
|
||||
self.__dict__.update(locals())
|
||||
|
|
|
@ -28,26 +28,26 @@ import os
|
|||
import pygame
|
||||
|
||||
class Fadeout(object):
|
||||
def __init__(self, game, function):
|
||||
def __init__(self, game, function, duration=500):
|
||||
self.__dict__.update(locals())
|
||||
self.game.objs.append(self)
|
||||
self.img = pygame.Surface(self.game.window.get_size())
|
||||
self._start_time = pygame.time.get_ticks()
|
||||
self._middle_time = self._start_time + 500
|
||||
self._end_time = self._middle_time + 500
|
||||
self._middle_time = self._start_time + duration
|
||||
self._end_time = self._middle_time + duration
|
||||
self.img.set_alpha(0)
|
||||
self.img.fill((0, 0, 0))
|
||||
self._has_run = False
|
||||
|
||||
def update(self, e, t, dt):
|
||||
if t < self._middle_time:
|
||||
self.img.set_alpha(255 * (t - self._start_time) / 500)
|
||||
self.img.set_alpha(255 * (t - self._start_time) / self.duration)
|
||||
else:
|
||||
if not self._has_run:
|
||||
self.function()
|
||||
self._has_run = True
|
||||
if t < self._end_time:
|
||||
self.img.set_alpha(255 * (500 - (t - self._middle_time)) / 500)
|
||||
self.img.set_alpha(255 * (self.duration - (t - self._middle_time)) / self.duration)
|
||||
else:
|
||||
self.game.objs.remove(self)
|
||||
self.update = lambda *xs: None
|
||||
|
|
|
@ -96,7 +96,7 @@ class Game(object):
|
|||
exec 'from level%d import Level%d as level' % (level, level)
|
||||
|
||||
self.level = level(self, graphics_dir)
|
||||
self.objs.append(self.level)
|
||||
self.objs.insert(0, self.level)
|
||||
|
||||
def restart_level(self):
|
||||
self.goto_level(self.level_num)
|
||||
|
|
|
@ -25,6 +25,7 @@ A generic level.
|
|||
"""
|
||||
|
||||
import pygame
|
||||
import itertools
|
||||
|
||||
import player
|
||||
import fadeout
|
||||
|
@ -35,6 +36,7 @@ class Level(object):
|
|||
|
||||
self.tiles = []
|
||||
self.objects = []
|
||||
self.bottom_objects = [] # Special tiles
|
||||
self.imgs = game.loader.imgs
|
||||
|
||||
self.reverse_imgs = (
|
||||
|
@ -78,6 +80,10 @@ class Level(object):
|
|||
self.camera_y = max(0, min(self.size[1] - screen_size[1] - 48,
|
||||
(self.player.y - screen_size[1] / 2 - 24)))
|
||||
|
||||
def _positions(self):
|
||||
return ((x, y) for (y, x) in itertools.product(xrange(self.dimensions[1]),
|
||||
xrange(self.dimensions[0])))
|
||||
|
||||
def _blit_background(self, window):
|
||||
window.blit(self.background, (0 - self.camera_x, 0 - self.camera_y))
|
||||
|
||||
|
@ -88,6 +94,12 @@ class Level(object):
|
|||
def draw(self, window):
|
||||
self._blit_background(window)
|
||||
|
||||
for obj in self._sorted_objs(self.bottom_objects):
|
||||
try:
|
||||
obj.draw(window)
|
||||
except IndexError:
|
||||
print("Skipping frames ...")
|
||||
|
||||
for obj in self._sorted_objs():
|
||||
try:
|
||||
obj.draw(window)
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
The third level.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import pygame
|
||||
import random
|
||||
|
@ -36,26 +38,28 @@ 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*20, 48*20),
|
||||
level.Level.__init__(self, game, graphics_dir, size=(64*11, 48*20),
|
||||
paused=paused)
|
||||
|
||||
self.dimensions = 10, 10
|
||||
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']))
|
||||
|
||||
task_start = (2, 2)
|
||||
self.task_start = (1, 6)
|
||||
|
||||
# Abstract "boxes", actually colour fields
|
||||
boxes = []
|
||||
|
@ -66,36 +70,68 @@ class Level3(level.Level):
|
|||
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 + task_start[0] + 1),
|
||||
48 * (y + task_start[1] + 1),
|
||||
self.imgs['indoor%d' % random.randint(1, 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 * task_start[0],
|
||||
48 * (i + 1 + task_start[1]),
|
||||
[(block.ActionBlock(self, 64 * self.task_start[0],
|
||||
48 * (i + 1 + self.task_start[1]),
|
||||
movable=True),
|
||||
block.ActionBlock(self, 64 * (task_start[0] + 8),
|
||||
48 * (i + 1 + task_start[1]),
|
||||
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, task_start[0] * 64, task_start[1] * 48),
|
||||
block.ColorWell(self, (task_start[0] + 8) * 64, task_start[1] * 48),
|
||||
block.ColorWell(self, task_start[0] * 64, (task_start[1] + 7) * 48),
|
||||
block.ColorWell(self, (task_start[0] + 8) * 64, (task_start[1] + 7) * 48),
|
||||
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 - task_start[0] - 1,
|
||||
block.y / 48 - task_start[1] - 1))
|
||||
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)
|
||||
|
||||
|
@ -109,9 +145,29 @@ class Level3(level.Level):
|
|||
for b in action_blocks:
|
||||
b.action = update_wells
|
||||
|
||||
self.player.set_pos(64 * 4, 48 * 3)
|
||||
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()
|
||||
|
|
|
@ -48,15 +48,16 @@ from logic.direction import *
|
|||
class Level4(level.Level):
|
||||
def __init__(self, game, graphics_dir, paused=False):
|
||||
level.Level.__init__(self, game, graphics_dir,
|
||||
size=(64 * 16, 48 * 20), paused=paused)
|
||||
size=(64 * 17, 48 * 21), paused=paused)
|
||||
|
||||
self.dimensions = 16, 16
|
||||
self.dimensions = 17, 17
|
||||
|
||||
for i in range(self.dimensions[0]):
|
||||
for j in range(self.dimensions[1]):
|
||||
not_ok_pos = set(itertools.product(range(7, 10), range(1, 4)))
|
||||
for i, j in filter(lambda p: p not in not_ok_pos, self._positions()):
|
||||
self.tiles.append(
|
||||
tile.Tile(self, i*64, (j+4)*48,
|
||||
self.imgs['indoor%d' % random.randint(1, 6)]))
|
||||
tile.Tile(self, i * 64, (j + 4) * 48, self.imgs[
|
||||
('indoor%d' % random.randint(1, 6))
|
||||
if random.randrange(6) != 0 else 'ground1']))
|
||||
|
||||
self.draw_background()
|
||||
|
||||
|
@ -106,7 +107,7 @@ class Level4(level.Level):
|
|||
mirrors.remove(m)
|
||||
l.links.insert(0, (lambda m: lambda setting: m.rotate())(m))
|
||||
|
||||
top = self.size[0] / 64
|
||||
top = self.dimensions[0]
|
||||
for i in range(top):
|
||||
if not i % 3:
|
||||
self.objects.append(block.Block(
|
||||
|
@ -116,16 +117,27 @@ class Level4(level.Level):
|
|||
blit_area=(0, 0, 96, 192) if i == top - 1 else None))
|
||||
self.objects.append(block.InvisBlock(self, i * 64,
|
||||
self.size[1]))
|
||||
for i in range(self.size[1] / 48):
|
||||
self.objects.append(block.InvisBlock(self, - 64,
|
||||
i * 48))
|
||||
self.objects.append(block.InvisBlock(self, self.size[0],
|
||||
i * 48))
|
||||
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.generate_lasers()
|
||||
|
||||
self.player.set_pos(64 * 7, 48 * 5)
|
||||
self.bottom_objects.append(worldobject.WithBackground(
|
||||
self, self.imgs['elevator_top'], 64 * 7, 48 * 5))
|
||||
self.elevator = worldobject.WithBackground(
|
||||
self, self.imgs['elevator'], 64 * 7, 48 * 6, 48 * 3,
|
||||
(0, 0, 256, 192 - 24 - 48 * 2))
|
||||
self.bottom_objects.append(self.elevator)
|
||||
self.bottom_objects.append(worldobject.WithBackground(
|
||||
self, self.imgs['elevator_bottom'], 64 * 7, 48 * 7))
|
||||
|
||||
self.player.set_pos(64 * 8, 48 * 5)
|
||||
self.player.set_init_pos()
|
||||
self._old_player_update = self.player.update
|
||||
self.player.update = lambda e, t, dt: self._old_player_update([], t, dt)
|
||||
|
||||
self._start_time = pygame.time.get_ticks()
|
||||
|
||||
def on_completion(self):
|
||||
# End game here.
|
||||
|
@ -149,6 +161,18 @@ class Level4(level.Level):
|
|||
self.on_completion()
|
||||
|
||||
def update(self, e, t, dt):
|
||||
self.update2(e, t, dt)
|
||||
start_offset = (t - self._start_time) / 25
|
||||
if start_offset >= 96:
|
||||
start_offset = 96
|
||||
self.player.y = 48 * 7 - start_offset
|
||||
self.elevator.z_px = 48 * 3 - start_offset
|
||||
self.elevator.blit_area = (0, 0, 256, 192 - 24 - 48 * 2 + start_offset)
|
||||
if start_offset == 96:
|
||||
self.update = self.update2
|
||||
self.player.update = self._old_player_update
|
||||
|
||||
def update2(self, e, t, dt):
|
||||
level.Level.update(self, e, t, dt)
|
||||
for laser in self.lasers:
|
||||
laser.update(e, t, dt)
|
||||
|
@ -156,6 +180,12 @@ class Level4(level.Level):
|
|||
def draw(self, window):
|
||||
self._blit_background(window)
|
||||
|
||||
for obj in self._sorted_objs(self.bottom_objects):
|
||||
try:
|
||||
obj.draw(window)
|
||||
except IndexError:
|
||||
print("Skipping frames ...")
|
||||
|
||||
objs = self._sorted_objs(self.objects + self.lasers)
|
||||
objs = self._after_sort(itertools.groupby(
|
||||
objs, lambda obj: obj.y + obj.z))
|
||||
|
|
|
@ -54,12 +54,12 @@ class Source(object):
|
|||
|
||||
def generate_simple_playfield(nmirrors):
|
||||
"""
|
||||
Generate a completable 16x16 playfield where:
|
||||
Generate a completable 17x17 playfield where:
|
||||
* there are four laser sources, one in each corner
|
||||
+ the one in the upper left corner (0, 0) starts in (0, -1) heading down
|
||||
+ the one in the upper right corner (15, 0) starts in (16, 0), heading left
|
||||
+ the one in the lower right corner (15, 15) starts in (15, 16), heading up
|
||||
+ the one in the lower left corner (0, 15) starts in (-1, 15), heading right
|
||||
+ the one in the upper right corner (16, 0) starts in (17, 0), heading left
|
||||
+ the one in the lower right corner (16, 16) starts in (16, 17), heading up
|
||||
+ the one in the lower left corner (0, 16) starts in (-1, 16), heading right
|
||||
* there are four laser targets
|
||||
* there are nmirrors mirrors
|
||||
* there are nmirrors levers
|
||||
|
@ -69,20 +69,25 @@ def generate_simple_playfield(nmirrors):
|
|||
Target | MirrorLeft | MirrorRight | rstone.Blocker | Lever}
|
||||
"""
|
||||
|
||||
width, height = 16, 16
|
||||
width, height = 17, 17
|
||||
|
||||
playfield = {(0, 0): Source(Down),
|
||||
(width - 1, 0): Source(Left),
|
||||
(width - 1, height - 1): Source(Up),
|
||||
(0, height - 1): Source(Right),
|
||||
(6, 6): Target,
|
||||
(9, 6): Target,
|
||||
(6, 9): Target,
|
||||
(9, 9): Target,
|
||||
(10, 6): Target,
|
||||
(6, 10): Target,
|
||||
(10, 10): Target,
|
||||
(7, 7): rstone.Blocker,
|
||||
(7, 8): rstone.Blocker,
|
||||
(7, 9): rstone.Blocker,
|
||||
(8, 7): rstone.Blocker,
|
||||
(8, 8): rstone.Blocker,
|
||||
(8, 9): rstone.Blocker,
|
||||
(9, 7): rstone.Blocker,
|
||||
(9, 8): rstone.Blocker,
|
||||
(9, 9): rstone.Blocker,
|
||||
}
|
||||
|
||||
succs = lambda d: d
|
||||
|
@ -156,7 +161,7 @@ def generate_lasers(playfield):
|
|||
|
||||
Return [((x, y), direction), ...]
|
||||
"""
|
||||
width, height = 16, 16
|
||||
width, height = 17, 17
|
||||
sources = ((pos, obj.direction) for pos, obj
|
||||
in filter(lambda posobj: isinstance(posobj[1], Source),
|
||||
playfield.items()))
|
||||
|
|
|
@ -35,3 +35,12 @@ class Tile(worldobject.WorldObject):
|
|||
window.blit(self.img, (self.x - 32 - self.level.camera_x,
|
||||
self.y - self.img.get_size()[1] + 24
|
||||
- self.level.camera_y))
|
||||
|
||||
class NaiveTile(object):
|
||||
def __init__(self, x, y, img):
|
||||
self.__dict__.update(locals())
|
||||
|
||||
def draw(self, window):
|
||||
window.blit(self.img, (self.x - 32,
|
||||
self.y - self.img.get_size()[1] + 24))
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ import numpy
|
|||
import copy
|
||||
|
||||
class WorldObject(object):
|
||||
def __init__(self, level, x, y, z=0, direction=(1, 0), speed=4,
|
||||
def __init__(self, level, x, y, z=0, z_px=0, direction=(1, 0), speed=4,
|
||||
tile_x=64, tile_y=48,
|
||||
movable=False, blocking=True, is_moving=False, visible=True,
|
||||
blit_area=None):
|
||||
|
@ -42,7 +42,7 @@ class WorldObject(object):
|
|||
self.holding = None
|
||||
self.holder = None
|
||||
|
||||
self.ignore_list = []
|
||||
self.ignore_list = [WithBackground]
|
||||
|
||||
self.is_currently_opaque = True
|
||||
|
||||
|
@ -137,3 +137,17 @@ class WorldObject(object):
|
|||
self.is_moving = self.x != self.move_x or self.y != self.move_y
|
||||
|
||||
self.x, self.y = int(self.x), int(self.y)
|
||||
|
||||
|
||||
|
||||
|
||||
class WithBackground(WorldObject):
|
||||
def __init__(self, level, img, x, y, z_px=0, blit_area=None):
|
||||
self.__dict__.update(locals())
|
||||
WorldObject.__init__(self, level, x, y, z_px=z_px, blit_area=blit_area)
|
||||
|
||||
def draw(self, window):
|
||||
window.blit(self.img, (self.x - 32 - self.level.camera_x,
|
||||
self.y - self.img.get_size()[1] + 24
|
||||
- self.level.camera_y + self.z_px),
|
||||
self.blit_area)
|
||||
|
|
Loading…
Reference in New Issue