Browse Source

Improved lasers, implemented the weight indicator, created a level 2 with the symbol blocks, deleted the much too difficult level 3 and the no-content level 2, made proper links between the levels, created an end screen.

master
Niels G. W. Serup 9 years ago
parent
commit
a3aeb127af
  1. 2
      arobotsconundrum/block.py
  2. 3
      arobotsconundrum/game.py
  3. 58
      arobotsconundrum/laser.py
  4. 44
      arobotsconundrum/level1.py
  5. 165
      arobotsconundrum/level2.py
  6. 330
      arobotsconundrum/level3.py
  7. 276
      arobotsconundrum/level4.py
  8. 42
      arobotsconundrum/level_bonus.py
  9. 14
      arobotsconundrum/loader.py
  10. 71
      arobotsconundrum/weight_indicator.py
  11. 0
      resources/graphics/blocks/block1-lifted.png
  12. 0
      resources/graphics/laser_beam_horizontal.png
  13. 0
      resources/graphics/symbols/blocks/symbolblock01-down.png
  14. 0
      resources/graphics/symbols/blocks/symbolblock01-lifted.png
  15. 0
      resources/graphics/symbols/blocks/symbolblock01.png
  16. 0
      resources/graphics/symbols/blocks/symbolblock02-down.png
  17. 0
      resources/graphics/symbols/blocks/symbolblock02-lifted.png
  18. 0
      resources/graphics/symbols/blocks/symbolblock02.png
  19. 0
      resources/graphics/symbols/blocks/symbolblock03-down.png
  20. 0
      resources/graphics/symbols/blocks/symbolblock03-lifted.png
  21. 0
      resources/graphics/symbols/blocks/symbolblock03.png
  22. 0
      resources/graphics/symbols/blocks/symbolblock04-down.png
  23. 0
      resources/graphics/symbols/blocks/symbolblock04-lifted.png
  24. 0
      resources/graphics/symbols/blocks/symbolblock04.png
  25. 0
      resources/graphics/symbols/blocks/symbolblock05-down.png
  26. 0
      resources/graphics/symbols/blocks/symbolblock05-lifted.png
  27. 0
      resources/graphics/symbols/blocks/symbolblock05.png
  28. 0
      resources/graphics/symbols/blocks/symbolblock06-down.png
  29. 0
      resources/graphics/symbols/blocks/symbolblock06-lifted.png
  30. 0
      resources/graphics/symbols/blocks/symbolblock06.png
  31. 0
      resources/graphics/symbols/blocks/symbolblock07-down.png
  32. 0
      resources/graphics/symbols/blocks/symbolblock07-lifted.png
  33. 0
      resources/graphics/symbols/blocks/symbolblock07.png
  34. 0
      resources/graphics/symbols/blocks/symbolblock08-down.png
  35. 0
      resources/graphics/symbols/blocks/symbolblock08-lifted.png
  36. 0
      resources/graphics/symbols/blocks/symbolblock08.png
  37. 0
      resources/graphics/symbols/blocks/symbolblock09-down.png
  38. 0
      resources/graphics/symbols/blocks/symbolblock09-lifted.png
  39. 0
      resources/graphics/symbols/blocks/symbolblock09.png
  40. 0
      resources/graphics/symbols/blocks/symbolblock10-down.png
  41. 0
      resources/graphics/symbols/blocks/symbolblock10-lifted.png
  42. 0
      resources/graphics/symbols/blocks/symbolblock10.png
  43. 0
      resources/graphics/symbols/blocks/symbolblock11-down.png
  44. 0
      resources/graphics/symbols/blocks/symbolblock11-lifted.png
  45. 0
      resources/graphics/symbols/blocks/symbolblock11.png
  46. 0
      resources/graphics/symbols/blocks/symbolblock12-down.png
  47. 0
      resources/graphics/symbols/blocks/symbolblock12-lifted.png
  48. 0
      resources/graphics/symbols/blocks/symbolblock12.png

2
arobotsconundrum/block.py

@ -88,7 +88,7 @@ class Block(worldobject.WorldObject):
obj.holding = self
self.holder = obj
if hasattr(self, 'img_str'):
self.img = self.level.imgs[self.img_str + '_lifted']
self.img = self.level.imgs[self.img_str + '-lifted']
# self.orig_alpha = self.orig_alphas['lifted']
def draw(self, window):

3
arobotsconundrum/game.py

@ -138,3 +138,6 @@ class Game(object):
self.menu.draw(self.window)
pygame.display.flip()
def quit(self):
self.running = False

58
arobotsconundrum/laser.py

@ -65,39 +65,53 @@ class Laser(worldobject.WorldObject):
self.x1d += x1de
self.y1d += y1de
self.start_dark = 0
# self.start_dark = 0
self.surf = pygame.Surface(self.level.game.window.get_size(),
pygame.SRCALPHA)
# self.surf = pygame.Surface(self.level.game.window.get_size(),
# pygame.SRCALPHA)
self.load()
def update(self, e, t, dt):
self.start_dark = (t % 200) / 100
# self.start_dark = (t % 200) / 100
worldobject.WorldObject.update(self, e, t, dt)
def load(self):
self.img_horizontal = self.level.imgs['laser_beam_horizontal']
self.img_vertical = self.level.imgs['laser_beam_vertical']
def draw(self, window):
self.surf.fill((0, 0, 0, 0))
# self.surf.fill((0, 0, 0, 0))
colors = [(155, 0, 0), (255, 0, 0)]
c = self.start_dark
# colors = [(155, 0, 0), (255, 0, 0)]
# c = self.start_dark
if self.x0d != self.x1d:
length = self.x1d - self.x0d
for i in range(0, length, 8):
x0d = self.x0d + i
pygame.draw.line(self.surf, colors[c],
(x0d - self.level.camera_x,
self.y0d - self.level.camera_y),
(x0d + min(8, length - i) - self.level.camera_x,
self.y1d - self.level.camera_y), 2)
c ^= 1
x0d = self.x0d + i + 2
window.blit(self.img_horizontal,
(x0d - self.level.camera_x,
self.y0d - self.level.camera_y),
self.blit_area)
# pygame.draw.line(self.surf, colors[c],
# (x0d - self.level.camera_x,
# self.y0d - self.level.camera_y),
# (x0d + min(8, length - i) - self.level.camera_x,
# self.y1d - self.level.camera_y), 2)
# c ^= 1
else:
length = self.y1d - self.y0d
for i in range(0, length, 8):
y0d = self.y0d + i
pygame.draw.line(self.surf, colors[c],
(self.x0d - self.level.camera_x,
y0d - self.level.camera_y),
(self.x0d - self.level.camera_x,
y0d + min(8, length - i) - self.level.camera_y), 2)
c ^= 1
y0d = self.y0d + i + 2
window.blit(self.img_vertical,
(self.x0d - self.level.camera_x,
y0d - self.level.camera_y),
self.blit_area)
# pygame.draw.line(self.surf, colors[c],
# (self.x0d - self.level.camera_x,
# y0d - self.level.camera_y),
# (self.x0d - self.level.camera_x,
# y0d + min(8, length - i) - self.level.camera_y), 2)
# c ^= 1
window.blit(self.surf, (0, 0))
# window.blit(self.surf, (0, 0))

44
arobotsconundrum/level1.py

@ -39,6 +39,8 @@ import boulder
import lever
import trigger
import worldobject
import level_bonus
import fadeout
import logic.teleportermap
import logic.rollingstone
@ -516,12 +518,17 @@ class Level1(level.Level):
if self.task_completions == self.solution
else lambda *v: None],
anim='lever_updown', toggling=False))
self.objects.append(
trigger.Trigger(self, 64 * door_x, 48 * 4,
[self.game.goto_level],
self.imgs['indoor1'],
[self.player]))
door.activate(1)
self._next_level_trigger = trigger.Trigger(
self,
64 * door_x, 48 * 4,
[lambda setting: self.goto_next_level()],
self.imgs['hole'],
[self.player],
visible=False)
self.objects.append(self._next_level_trigger)
if random.randint(0, 1):
for i in range(3):
self.objects.append(
@ -533,6 +540,26 @@ class Level1(level.Level):
CompletionBlock(self, 64 * (door_x - 3 - i), 48 * 4,
self.solution[i], i + 1))
### Link to bonus level
bonus = level_bonus.Level(self.game, self.graphics_dir)
def goto_bonus():
self._update = self.update
self.update = lambda *args: None
def g():
self.update = self._update
bonus.enter(self)
fadeout.Fadeout(self.game, g)
self.objects.append(
lever.Lever(
self, 64 * 39, 48 * 39,
[lambda setting: goto_bonus()],
toggling=False,
anim='lever_updown'))
# DRAW THE BACKGROUND
self.draw_background()
@ -553,6 +580,13 @@ class Level1(level.Level):
for obj in self.objects:
obj.reset_pos()
def goto_next_level(self):
print(333)
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)
fadeout.Fadeout(self.game, lambda: self.game.goto_level(2), duration=1500)
class CompletionBlock(block.Block):
def __init__(self, level, x, y, task, number):
self.__dict__.update(locals())

165
arobotsconundrum/level2.py

@ -1,53 +1,168 @@
#!/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/>.
#
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
#
# level2.py
# --------------------
# date created : Fri Oct 12 2012
# copyright : (C) 2012 Niels G. W. Serup
# maintained by : Niels G. W. Serup <ngws@metanohi.name>
"""
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 boulder
import lever
import level_bonus
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*5, 48*5),
level.Level.__init__(self, game, graphics_dir, size=(64*21, 48*20),
paused=paused)
self.dimensions = 5, 5
self.dimensions = 21, 20
for i in range(self.dimensions[0]):
for j in range(self.dimensions[1]):
self.tiles.append(
tile.Tile(self, i*64, (j + 1)*48,
self.imgs['indoor%d' % random.randint(1, 6)]))
self.task_start = (1, 6)
self.draw_background()
for i, j in self._positions():
self.tiles.append(
tile.Tile(self, i * 64, (j + 4) * 48, self.imgs['ground1']))
bonus = level_bonus.Level(self.game, self.graphics_dir)
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)
def f():
self._update = self.update
self.update = lambda *args: None
def g():
self.update = self._update
bonus.enter(self)
fadeout.Fadeout(self.game, g)
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.objects.append(
lever.Lever(
self, 64 * 2, 48 * 3,
[lambda setting: f()],
toggling=False,
anim='lever_updown'))
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 * 2, 48 * 1)
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:

330
arobotsconundrum/level3.py

@ -1,25 +1,23 @@
#!/usr/bin/env python.
# -*- coding: utf-8 -*-
# This file is part of A Robot's Conundrum
# 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.
# 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
# level3.py
# --------------------
# date created : Wed Aug 8 2012
# date created : Fri Aug 10 2012
# copyright : (C) 2012 Niels G. W. Serup
# maintained by : Niels G. W. Serup <ngws@metanohi.name>
@ -35,53 +33,82 @@ import random
import re
import itertools
import worldobject
import level
import player
import trigger
import tile
import block
import lever
from mirror import Mirror
from laser import Laser
import misc
import worldobject
import fadeout
import logic.colourboxes
import logic.lasermirror as lm
from logic.direction import *
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)]))
level.Level.__init__(self, game, graphics_dir,
size=(64 * 17, 48 * 21), paused=paused)
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.dimensions = 17, 17
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))
if random.randrange(6) != 0 else 'ground1']))
self.draw_background()
self.playfield = lm.generate_simple_playfield(16)
self.target_blocks = []
for (x, y), t in self.playfield.items():
x1, y1 = 64 * x, 48 * (y + 4)
if isinstance(t, lm.Source):
self.objects.append(
block.LaserSource(self, x1, y1, t.direction))
continue
def mir(b, x1, y1):
def f(x, y):
def g(setting):
self.playfield[(x, y)] = lm.MirrorLeft \
if self.playfield[(x, y)] is lm.MirrorRight \
else lm.MirrorRight
self.generate_lasers()
return g
return Mirror(self, x, y, b, links=[f(x, y)])
def targ():
b = block.LaserTarget(self, x, y)
self.target_blocks.append(b)
return b
self.objects.append({
lm.MirrorLeft: lambda: mir(True, x1, y1),
lm.MirrorRight: lambda: mir(False, x1, y1),
lm.Lever: lambda: lever.Lever(
self, x1, y1, [lambda setting: self.generate_lasers],
toggling=True,
anim='lever_leftright' if x in (0, 15)
else 'lever_updown'),
lm.Target: targ,
lm.Blocker: lambda: block.Block(self, x1, y1,
self.imgs['block1'],
movable=False)
}[t]())
mirrors = list(filter(lambda obj: isinstance(obj, Mirror),
self.objects))
levers = list(filter(lambda obj: isinstance(obj, lever.Lever),
self.objects))
random.shuffle(levers)
for l in levers:
m = min(mirrors, key=lambda m: misc.manhattan_dist(
(m.x, m.y), (l.x, l.y)))
mirrors.remove(m)
l.links.insert(0, (lambda m: lambda setting: m.rotate())(m))
top = self.dimensions[0]
for i in range(top):
if i % 3 == 0:
@ -93,81 +120,172 @@ class Level3(level.Level):
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.objects.append(block.InvisBlock(self, - 64, (i + 4) * 48))
self.objects.append(block.InvisBlock(self, self.size[0], (i + 4) * 48))
self.generate_lasers()
self.bottom_objects.append(worldobject.WithBackground(
self, self.imgs['elevator_top'], 64 * (self.task_start[0] + 3), 48 * (self.task_start[1] + 10)))
self, self.imgs['elevator_top'], 64 * 7, 48 * 5))
self.elevator = worldobject.WithBackground(
self, self.imgs['elevator'], 64 * (self.task_start[0] + 3), 48 * (self.task_start[1] + 11), 48)
self, self.imgs['elevator'], 64 * 7, 48 * 6, 48 * 3,
(0, 0, 256, 192 - 24 - 48 * 2))
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()
self, self.imgs['elevator_bottom'], 64 * 7, 48 * 7))
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.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.update = self.update2
self._start_time = pygame.time.get_ticks()
fadeout.Fadeout(self.game, self.goto_next_level, duration=1500)
self.on_completion()
def on_completion(self):
# End game here.
fadeout.Fadeout(self.game, lambda: self.game.goto_level(4), duration=5000)
def restart(self):
for obj in self.objects:
obj.reset_pos()
def generate_lasers(self):
lasers = lm.generate_lasers(self.playfield)
self.lasers_orig = list(itertools.chain(*lasers))
self.lasers = []
for laser in lasers:
laser = iter(laser)
self.lasers.append(Laser(self, next(laser), first_laser=True))
self.lasers.extend(Laser(self, line) for line in laser)
for b in self.target_blocks:
b.new_playfield_update()
if all(b.glows for b in self.target_blocks):
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)
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
for laser in self.lasers:
laser.update(e, t, dt)
def draw(self, window):
self._blit_background(window)
def goto_next_level(self):
self.game.goto_level(4)
for obj in self._sorted_objs(self.bottom_objects):
try:
obj.draw(window)
except IndexError:
print("Skipping frames ...")
def restart(self):
for obj in self.objects:
obj.reset_pos()
objs = self._sorted_objs(self.objects + self.lasers)
objs = self._after_sort(itertools.groupby(
objs, lambda obj: obj.y + obj.z))
for obj in objs:
obj.draw(window)
self.darkness.draw(window)
def _after_sort(self, objss):
n_objs = []
for c, objs in objss:
n_objs.extend(self._after_sort_line(list(objs)))
return n_objs
def _after_sort_line(self, objs):
is_special = lambda obj: type(obj) in \
(Mirror, Laser, block.LaserSource, block.LaserTarget)
specials, nonspecials = (filter(is_special, objs),
filter(lambda obj: not is_special(obj), objs))
return nonspecials + self._sort_line_specials(specials)
def _sort_line_specials(self, objs):
mirrors = filter(lambda obj: isinstance(obj, Mirror), objs)
lasers = filter(lambda obj: isinstance(obj, Laser), objs)
sources = filter(lambda obj: isinstance(obj, block.LaserSource), objs)
targets = filter(lambda obj: isinstance(obj, block.LaserTarget), objs)
lasers_back = set(lasers)
sep_ords = []
for obj in itertools.chain(mirrors, targets):
before, after = [], []
for laser in _hit_lasers(obj, lasers):
lasers_back.discard(laser)
if _obj_is_behind_laser(obj, laser):
after.append(laser)
else:
before.append(laser)
sep_ords.append(before + [obj] + after)
points = set((obj.x0, obj.y0) for obj in itertools.chain(mirrors, targets))
for laser in filter(lambda laser: (laser.x0, laser.y0) in points
and (laser.x1, laser.y1) in points, lasers):
# print(laser)
xs, ys = filter(lambda sep_ord: laser in sep_ord, sep_ords)
sep_ords.remove(xs)
sep_ords.remove(ys)
xs, ys, nobjs = iter(xs), iter(ys), []
while True:
x = next(xs)
if x is laser:
break
nobjs.append(x)
while True:
x = next(ys)
if x is laser:
break
nobjs.append(x)
nobjs.append(laser)
nobjs.extend(xs)
nobjs.extend(ys)
sep_ords.append(nobjs)
objs = list(itertools.chain(*sep_ords)) + list(lasers_back) \
+ sources
return objs
def _hit_lasers(obj, lasers):
p = (obj.x0, obj.y0)
return filter(lambda laser: (laser.x0, laser.y0) == p
or (laser.x1, laser.y1) == p, lasers)
def _obj_is_behind_laser(obj, laser):
return (_mirror_is_behind_laser
if isinstance(obj, Mirror)
else _target_is_behind_laser)(obj, laser)
def _mirror_is_behind_laser(mirror, laser):
return \
laser.y0 == laser.y1 \
and (
(mirror.left_up
and (
(laser.x0 == mirror.x0 and laser.x1 > mirror.x0)
or
(laser.x1 == mirror.x0 and laser.x0 > mirror.x0)
)
) \
or \
(not mirror.left_up
and (
(laser.x0 == mirror.x0 and laser.x1 < mirror.x0)
or
(laser.x1 == mirror.x0 and laser.x0 < mirror.x0)
)
)
)
def _target_is_behind_laser(target, laser):
return laser.x0 != laser.x1

276
arobotsconundrum/level4.py

@ -15,275 +15,37 @@
#
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
#
# level1.py
# level4.py
# --------------------
# date created : Fri Aug 10 2012
# copyright : (C) 2012 Niels G. W. Serup
# maintained by : Niels G. W. Serup <ngws@metanohi.name>
# date created : Thu Nov 15 2012
# copyright : (C) 2012 Sakse Dalum
# maintained by : Sakse Dalum <don_s@hongabar.org>
"""
The fourth level.
The final level.
"""
from __future__ import print_function
import os
import pygame
import random
import re
import itertools
import os.path
import level
import player
import tile
import block
import lever
from mirror import Mirror
from laser import Laser
import misc
import worldobject
import logic.lasermirror as lm
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 * 17, 48 * 21), paused=paused)
self.dimensions = 17, 17
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))
if random.randrange(6) != 0 else 'ground1']))
self.draw_background()
self.playfield = lm.generate_simple_playfield(16)
self.target_blocks = []
for (x, y), t in self.playfield.items():
x1, y1 = 64 * x, 48 * (y + 4)
if isinstance(t, lm.Source):
self.objects.append(
block.LaserSource(self, x1, y1, t.direction))
continue
def mir(b, x1, y1):
def f(x, y):
def g(setting):
self.playfield[(x, y)] = lm.MirrorLeft \
if self.playfield[(x, y)] is lm.MirrorRight \
else lm.MirrorRight
self.generate_lasers()
return g
return Mirror(self, x, y, b, links=[f(x, y)])
def targ():
b = block.LaserTarget(self, x, y)
self.target_blocks.append(b)
return b
self.objects.append({
lm.MirrorLeft: lambda: mir(True, x1, y1),
lm.MirrorRight: lambda: mir(False, x1, y1),
lm.Lever: lambda: lever.Lever(
self, x1, y1, [lambda setting: self.generate_lasers],
toggling=True,
anim='lever_leftright' if x in (0, 15)
else 'lever_updown'),
lm.Target: targ,
lm.Blocker: lambda: block.Block(self, x1, y1,
self.imgs['block1'],
movable=False)
}[t]())
mirrors = list(filter(lambda obj: isinstance(obj, Mirror),
self.objects))
levers = list(filter(lambda obj: isinstance(obj, lever.Lever),
self.objects))
random.shuffle(levers)
for l in levers:
m = min(mirrors, key=lambda m: misc.manhattan_dist(
(m.x, m.y), (l.x, l.y)))
mirrors.remove(m)
l.links.insert(0, (lambda m: lambda setting: m.rotate())(m))
top = self.dimensions[0]
for i in range(top):
if not i % 3:
self.objects.append(block.Block(
self, i * 64, 48 * 3,
self.imgs['wall'],
width=1 if i == top - 1 else 3,
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.dimensions[1]):
self.objects.append(block.InvisBlock(self, - 64, (i + 4) * 48))
self.objects.append(block.InvisBlock(self, self.size[0], (i + 4) * 48))
self.generate_lasers()
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.
print('Well done.')
def restart(self):
for obj in self.objects:
obj.reset_pos()
def generate_lasers(self):
lasers = lm.generate_lasers(self.playfield)
self.lasers_orig = list(itertools.chain(*lasers))
self.lasers = []
for laser in lasers:
laser = iter(laser)
self.lasers.append(Laser(self, next(laser), first_laser=True))
self.lasers.extend(Laser(self, line) for line in laser)
for b in self.target_blocks:
b.new_playfield_update()
if all(b.glows for b in self.target_blocks):
self.on_completion()
self.background_img = pygame.image.load(os.path.join(self.graphics_dir,
'main_menu.png'))
self.background_img = pygame.transform.smoothscale(
self.background_img, self.game.window.get_size())
self.background_img = pygame.transform.rotate(
self.background_img, 180)
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)
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))
for obj in objs:
obj.draw(window)
self.darkness.draw(window)
def _after_sort(self, objss):
n_objs = []
for c, objs in objss:
n_objs.extend(self._after_sort_line(list(objs)))
return n_objs
def _after_sort_line(self, objs):
is_special = lambda obj: type(obj) in \
(Mirror, Laser, block.LaserSource, block.LaserTarget)
specials, nonspecials = (filter(is_special, objs),
filter(lambda obj: not is_special(obj), objs))
return nonspecials + self._sort_line_specials(specials)
def _sort_line_specials(self, objs):
mirrors = filter(lambda obj: isinstance(obj, Mirror), objs)
lasers = filter(lambda obj: isinstance(obj, Laser), objs)
sources = filter(lambda obj: isinstance(obj, block.LaserSource), objs)
targets = filter(lambda obj: isinstance(obj, block.LaserTarget), objs)
lasers_back = set(lasers)
sep_ords = []
for obj in itertools.chain(mirrors, targets):
before, after = [], []
for laser in _hit_lasers(obj, lasers):
lasers_back.discard(laser)
if _obj_is_behind_laser(obj, laser):
after.append(laser)
else:
before.append(laser)
sep_ords.append(before + [obj] + after)
points = set((obj.x0, obj.y0) for obj in itertools.chain(mirrors, targets))
for laser in filter(lambda laser: (laser.x0, laser.y0) in points
and (laser.x1, laser.y1) in points, lasers):
# print(laser)
xs, ys = filter(lambda sep_ord: laser in sep_ord, sep_ords)
sep_ords.remove(xs)
sep_ords.remove(ys)
if not self.paused:
for event in e:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
self.game.quit()
xs, ys, nobjs = iter(xs), iter(ys), []
while True:
x = next(xs)
if x is laser:
break
nobjs.append(x)
while True:
x = next(ys)
if x is laser:
break
nobjs.append(x)
nobjs.append(laser)
nobjs.extend(xs)
nobjs.extend(ys)
sep_ords.append(nobjs)
objs = list(itertools.chain(*sep_ords)) + list(lasers_back) \
+ sources
return objs
def _hit_lasers(obj, lasers):
p = (obj.x0, obj.y0)
return filter(lambda laser: (laser.x0, laser.y0) == p
or (laser.x1, laser.y1) == p, lasers)
def _obj_is_behind_laser(obj, laser):
return (_mirror_is_behind_laser
if isinstance(obj, Mirror)
else _target_is_behind_laser)(obj, laser)
def _mirror_is_behind_laser(mirror, laser):
return \
laser.y0 == laser.y1 \
and (
(mirror.left_up
and (
(laser.x0 == mirror.x0 and laser.x1 > mirror.x0)
or
(laser.x1 == mirror.x0 and laser.x0 > mirror.x0)
)
) \
or \
(not mirror.left_up
and (
(laser.x0 == mirror.x0 and laser.x1 < mirror.x0)
or
(laser.x1 == mirror.x0 and laser.x0 < mirror.x0)
)
)
)
def _target_is_behind_laser(target, laser):
return laser.x0 != laser.x1
def draw(self, window):
window.blit(self.background_img, (0, 0))

42
arobotsconundrum/level_bonus.py

@ -42,24 +42,33 @@ import fadeout
class Level(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*21, 48*20),
paused=paused)
self.dimensions = 20, 20
self.dimensions = 21, 20
for i in range(self.dimensions[0]):
for j in range(self.dimensions[1]):
self.tiles.append(
tile.Tile(self, (i+1)*64, j*48, self.imgs['indoor%d' % random.randint(1, 6)]))
for i, j in self._positions():
self.tiles.append(
tile.Tile(self, i * 64, (j + 4) * 48, self.imgs['ground1']))
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))
for x, y in misc.pick_random_elements(
list(itertools.product(range(2, 20), range(2, 20))), 150):
self.objects.append(block.Block(self, 64 * x, 48 * y,
self.imgs['block1'], movable=True))
def f():
def go_back():
self._update = self.update
self.update = lambda *args: None
def g():
@ -69,12 +78,17 @@ class Level(level.Level):
self.objects.append(
lever.Lever(
self, 64, 48,
[lambda setting: f()],
self, 0, 48 * 4,
[lambda setting: go_back()],
toggling=False,
anim='lever_updown'))
self.player.set_pos(64 * 1, 48 * 2)
for x, y in misc.pick_random_elements(
list(itertools.product(range(2, 19), range(2, 14))), 150):
self.objects.append(block.Block(self, 64 * x, 48 * (4 + y),
self.imgs['block1'], movable=True))
self.player.set_pos(0, 48 * 5)
self.player.set_init_pos()
def enter(self, root_level):

14
arobotsconundrum/loader.py

@ -42,11 +42,11 @@ class Loader(object):
self.directory, 'tiles', '%s.png' % o))
for o in range(1, 13):
for i in range(16, 19):
self.imgs['symbol%02d-%04d' % (o, i)] = (
for i in ('', '-lifted', '-down'):
s = 'symbolblock%02d%s' % (o, i)
self.imgs[s] = (
pygame.image.load(os.path.join(
self.directory, 'symbols', 'blocks',
'block%02d-%04d.png' % (o, i))))
self.directory, 'symbols', 'blocks', s + '.png')))
for o in range(13, 18):
for i in range(16, 20):
self.imgs['symbol%02d-%04d' % (o, i)] = (
@ -58,9 +58,10 @@ class Loader(object):
self.imgs['indoor%d' % o] = pygame.image.load(os.path.join(
self.directory, 'tiles', 'indoor', 'ground%02d.png' % o))
l = ['block1', 'block1_lifted', 'block3', '../lasertarget',
l = ['block1', 'block1-lifted', 'block3', '../lasertarget',
'../lasersource_up', '../lasersource_down', '../lasersource_right',
'../lasertarget_glow']
'../lasertarget_glow', '../laser_beam_horizontal',
'../laser_beam_vertical']
for o in l:
self.imgs[os.path.basename(o)] = pygame.image.load(os.path.join(
self.directory, 'blocks', '%s.png' % o))
@ -127,6 +128,7 @@ class Loader(object):
('elevating_column', 'elevating_column'),
('mirror', 'mirror'),
('weight_indicator', 'weight_indicator'),
('door', 'door')]
):

71
arobotsconundrum/weight_indicator.py

@ -0,0 +1,71 @@
# 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/>.
#
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
#
# weight_indicator.py
# --------------------
# date created : Thu Nov 15 2012
# copyright : (C) 2012 Niels G. W. Serup
# maintained by : Niels G. W. Serup <ngws@metanohi.name>
"""
A weight indicator for drawing.
"""
import pygame
import worldobject
class WeightIndicator(worldobject.WorldObject):
def __init__(self, level, x0, y0, state=0, links=[]):
self.__dict__.update(locals())
self.xd, self.yd = self.x0 * 64, (self.y0 + 4) * 48
worldobject.WorldObject.__init__(self, level, self.xd, self.yd)
self.in_rotation = False
self.frame = self.state_to_frame(self.state)
def state_to_frame(self, state):
return state * 9 + 9
def change_state(self, new_state):
if self.in_rotation or new_state == self.state:
return
self.in_rotation = True
self.start_frame = self.frame
self.goal_state = new_state
self.goal_frame = self.state_to_frame(new_state)
self.start_time = pygame.time.get_ticks()
def update(self, e, t, dt):
if self.in_rotation:
d = (t - self.start_time) / 1000.0
self.frame = min(18, int(self.start_frame
+ (self.goal_frame - self.start_frame)
* d))
if self.frame == self.goal_frame:
self.in_rotation = False
self.state = self.goal_state
for link in self.links:
link(self.state)
worldobject.WorldObject.update(self, e, t, dt)
def draw(self, window):
self.img = self.level.imgs['weight_indicator'][self.frame]
window.blit(self.img, (self.xd - 32 - self.level.camera_x,
self.yd - self.img.get_size()[1] + 24
- self.level.camera_y))

0
resources/graphics/blocks/block1_lifted.png → resources/graphics/blocks/block1-lifted.png

Before

Width: 128  |  Height: 128  |  Size: 12 KiB

After

Width: 128  |  Height: 128  |  Size: 12 KiB

0
resources/graphics/laser_beam_horisontal.png → resources/graphics/laser_beam_horizontal.png

Before

Width: 8  |  Height: 5  |  Size: 210 B

After

Width: 8  |  Height: 5  |  Size: 210 B

0
resources/graphics/symbols/blocks/block01-0018.png → resources/graphics/symbols/blocks/symbolblock01-down.png

Before

Width: 128  |  Height: 128  |  Size: 6.9 KiB

After

Width: 128  |  Height: 128  |  Size: 6.9 KiB

0
resources/graphics/symbols/blocks/block01-0017.png → resources/graphics/symbols/blocks/symbolblock01-lifted.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block01-0016.png → resources/graphics/symbols/blocks/symbolblock01.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block02-0018.png → resources/graphics/symbols/blocks/symbolblock02-down.png

Before

Width: 128  |  Height: 128  |  Size: 7.0 KiB

After

Width: 128  |  Height: 128  |  Size: 7.0 KiB

0
resources/graphics/symbols/blocks/block02-0017.png → resources/graphics/symbols/blocks/symbolblock02-lifted.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block02-0016.png → resources/graphics/symbols/blocks/symbolblock02.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block03-0018.png → resources/graphics/symbols/blocks/symbolblock03-down.png

Before

Width: 128  |  Height: 128  |  Size: 7.0 KiB

After

Width: 128  |  Height: 128  |  Size: 7.0 KiB

0
resources/graphics/symbols/blocks/block03-0017.png → resources/graphics/symbols/blocks/symbolblock03-lifted.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block03-0016.png → resources/graphics/symbols/blocks/symbolblock03.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block04-0018.png → resources/graphics/symbols/blocks/symbolblock04-down.png

Before

Width: 128  |  Height: 128  |  Size: 6.9 KiB

After

Width: 128  |  Height: 128  |  Size: 6.9 KiB

0
resources/graphics/symbols/blocks/block04-0017.png → resources/graphics/symbols/blocks/symbolblock04-lifted.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block04-0016.png → resources/graphics/symbols/blocks/symbolblock04.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block05-0018.png → resources/graphics/symbols/blocks/symbolblock05-down.png

Before

Width: 128  |  Height: 128  |  Size: 6.9 KiB

After

Width: 128  |  Height: 128  |  Size: 6.9 KiB

0
resources/graphics/symbols/blocks/block05-0017.png → resources/graphics/symbols/blocks/symbolblock05-lifted.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block05-0016.png → resources/graphics/symbols/blocks/symbolblock05.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block06-0018.png → resources/graphics/symbols/blocks/symbolblock06-down.png

Before

Width: 128  |  Height: 128  |  Size: 6.9 KiB

After

Width: 128  |  Height: 128  |  Size: 6.9 KiB

0
resources/graphics/symbols/blocks/block06-0017.png → resources/graphics/symbols/blocks/symbolblock06-lifted.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block06-0016.png → resources/graphics/symbols/blocks/symbolblock06.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block07-0018.png → resources/graphics/symbols/blocks/symbolblock07-down.png

Before

Width: 128  |  Height: 128  |  Size: 7.0 KiB

After

Width: 128  |  Height: 128  |  Size: 7.0 KiB

0
resources/graphics/symbols/blocks/block07-0017.png → resources/graphics/symbols/blocks/symbolblock07-lifted.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block07-0016.png → resources/graphics/symbols/blocks/symbolblock07.png

Before

Width: 128  |  Height: 128  |  Size: 11 KiB

After

Width: 128  |  Height: 128  |  Size: 11 KiB

0
resources/graphics/symbols/blocks/block08-0018.png → resources/graphics/symbols/blocks/symbolblock08-down.png