Added lasers. Lasers not pretty yet.
This commit is contained in:
parent
1b439a400c
commit
13465f02ae
|
@ -58,19 +58,30 @@ class Level4(level.Level):
|
||||||
|
|
||||||
self.draw_background()
|
self.draw_background()
|
||||||
|
|
||||||
playfield = lm.generate_simple_playfield(16)
|
self.playfield = lm.generate_simple_playfield(16)
|
||||||
|
|
||||||
for (x, y), t in playfield.items():
|
for (x, y), t in self.playfield.items():
|
||||||
x, y = 64 * x, 48 * (y + 1)
|
x1, y1 = 64 * x, 48 * (y + 1)
|
||||||
|
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.Mirror(self, x1, y1, b, links=[f(x, y)])
|
||||||
self.objects.append({
|
self.objects.append({
|
||||||
lm.Mirror: mirror.Mirror(self, x, y, random.choice((True, False))),
|
lm.MirrorLeft: mir(True, x1, y1),
|
||||||
|
lm.MirrorRight: mir(False, x1, y1),
|
||||||
lm.Lever: lever.Lever(
|
lm.Lever: lever.Lever(
|
||||||
self, x, y, [lambda setting: self.generate_lasers], toggling=True,
|
self, x1, y1, [lambda setting: self.generate_lasers],
|
||||||
anim='lever_leftright' if x == 0 or x == 15 * 64
|
toggling=True,
|
||||||
|
anim='lever_leftright' if x in (0, 15)
|
||||||
else 'lever_updown'),
|
else 'lever_updown'),
|
||||||
lm.Target: block.Block(self, x, y, self.imgs['block3'],
|
lm.Target: block.Block(self, x1, y1, self.imgs['block3'],
|
||||||
movable=False),
|
movable=False),
|
||||||
lm.Blocker: block.Block(self, x, y, self.imgs['block1'],
|
lm.Blocker: block.Block(self, x1, y1, self.imgs['block1'],
|
||||||
movable=False)
|
movable=False)
|
||||||
}[t])
|
}[t])
|
||||||
mirrors = list(filter(lambda obj: isinstance(obj, mirror.Mirror),
|
mirrors = list(filter(lambda obj: isinstance(obj, mirror.Mirror),
|
||||||
|
@ -94,26 +105,33 @@ class Level4(level.Level):
|
||||||
obj.reset_pos()
|
obj.reset_pos()
|
||||||
|
|
||||||
def generate_lasers(self):
|
def generate_lasers(self):
|
||||||
|
lml = lm.generate_lasers(self.playfield)
|
||||||
self.lasers = []
|
self.lasers = []
|
||||||
|
for (x0, y0), (x1, y1) in lml:
|
||||||
|
self.lasers.append(((x0 * 64 + 32, y0 * 48 + 32),
|
||||||
|
(x1 * 64 + 32, y1 * 48 + 32)))
|
||||||
|
|
||||||
def draw_lasers(self, window):
|
def draw_lasers(self, window):
|
||||||
for p0, p1 in self.lasers:
|
for (x0, y0), (x1, y1) in self.lasers:
|
||||||
pygame.draw.line(p0, p1, (255, 0, 0))
|
pygame.draw.line(window, (255, 0, 0),
|
||||||
|
(x0 - self.camera_x, y0 - 28 - self.camera_y),
|
||||||
|
(x1 - self.camera_x, y1 - 28 - self.camera_y), 4)
|
||||||
|
|
||||||
def draw(self, window):
|
def draw(self, window):
|
||||||
self._blit_background(window)
|
self._blit_background(window)
|
||||||
|
|
||||||
objs = self._sorted_objs()
|
objs = self._sorted_objs()
|
||||||
nonmirrors = filter(lambda obj: not isinstance(obj, mirror.Mirror),
|
for obj in objs:
|
||||||
objs)
|
|
||||||
mirrors = filter(lambda obj: isinstance(obj, mirror.Mirror), objs)
|
|
||||||
for obj in nonmirrors:
|
|
||||||
obj.draw(window)
|
obj.draw(window)
|
||||||
|
# nonmirrors = filter(lambda obj: not isinstance(obj, mirror.Mirror),
|
||||||
|
# objs)
|
||||||
|
# mirrors = filter(lambda obj: isinstance(obj, mirror.Mirror), objs)
|
||||||
|
# for obj in nonmirrors:
|
||||||
|
# obj.draw(window)
|
||||||
|
|
||||||
self.draw_lasers(window)
|
self.draw_lasers(window)
|
||||||
|
|
||||||
for obj in mirrors:
|
# for obj in mirrors:
|
||||||
obj.draw(window)
|
# obj.draw(window)
|
||||||
|
|
||||||
self.darkness.draw(window)
|
self.darkness.draw(window)
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
#
|
#
|
||||||
# lasermirror.py
|
# lasermirror.py
|
||||||
# --------------------
|
# --------------------
|
||||||
# date created : Tue Aug 7 2016
|
# date created : Tue Aug 7 2012
|
||||||
# copyright : (C) 2016 Niels G. W. Serup
|
# copyright : (C) 2012 Niels G. W. Serup
|
||||||
# maintained by : Niels G. W. Serup <ns@metanohi.name>
|
# maintained by : Niels G. W. Serup <ns@metanohi.name>
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -36,7 +36,10 @@ import robotgame.logic.rollingstone as rstone
|
||||||
from robotgame.logic.rollingstone import Blocker
|
from robotgame.logic.rollingstone import Blocker
|
||||||
import robotgame.misc as misc
|
import robotgame.misc as misc
|
||||||
|
|
||||||
class Mirror(object):
|
class MirrorLeft(object):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MirrorRight(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Lever(object):
|
class Lever(object):
|
||||||
|
@ -58,7 +61,8 @@ def generate_simple_playfield(nmirrors):
|
||||||
* there are nmirrors levers
|
* there are nmirrors levers
|
||||||
* all levers are at the wall
|
* all levers are at the wall
|
||||||
|
|
||||||
Return playfield : {(x, y): Target | Mirror | rstone.Blocker | Lever}
|
Return playfield : {(x, y):
|
||||||
|
Target | MirrorLeft | MirrorRight | rstone.Blocker | Lever}
|
||||||
"""
|
"""
|
||||||
playfield = {(6, 6): Target,
|
playfield = {(6, 6): Target,
|
||||||
(9, 6): Target,
|
(9, 6): Target,
|
||||||
|
@ -69,6 +73,8 @@ def generate_simple_playfield(nmirrors):
|
||||||
(8, 7): rstone.Blocker,
|
(8, 7): rstone.Blocker,
|
||||||
(8, 8): rstone.Blocker,
|
(8, 8): rstone.Blocker,
|
||||||
}
|
}
|
||||||
|
width, height = 16, 16
|
||||||
|
|
||||||
succs = lambda d: d
|
succs = lambda d: d
|
||||||
source_direc = Up
|
source_direc = Up
|
||||||
nlevers = nmirrors
|
nlevers = nmirrors
|
||||||
|
@ -78,22 +84,54 @@ def generate_simple_playfield(nmirrors):
|
||||||
stone_playfield, _ = rstone.generate_simple_playfield(
|
stone_playfield, _ = rstone.generate_simple_playfield(
|
||||||
7, 7, nm, 0, False, False)
|
7, 7, nm, 0, False, False)
|
||||||
for pos, direc in stone_playfield.items():
|
for pos, direc in stone_playfield.items():
|
||||||
playfield[_adjust(source_direc, 16 - 1, 16 - 1, *pos)] = Mirror
|
playfield[_adjust(source_direc, 16 - 1, 16 - 1, *pos)] \
|
||||||
|
= random.choice((MirrorLeft, MirrorRight))
|
||||||
succs = (lambda s: lambda d: succ(s(d)))(succs)
|
succs = (lambda s: lambda d: succ(s(d)))(succs)
|
||||||
source_direc = succ(source_direc)
|
source_direc = succ(source_direc)
|
||||||
|
|
||||||
for _ in range(nlevers):
|
|
||||||
# This needs to be optimized...
|
|
||||||
occup = set(playfield.keys())
|
occup = set(playfield.keys())
|
||||||
emptys = list(
|
|
||||||
set([(0, y) for y in filter(lambda y: (1, y) not in occup, range(16))]
|
is_empty = lambda x, y: (x, y) not in occup
|
||||||
+ [(15, y) for y in filter(lambda y: (10, y) not in occup, range(16))]
|
|
||||||
+ [(x, 0) for x in filter(lambda x: (x, 1) not in occup, range(16))]
|
ok_a = lambda y: is_empty(1, y)
|
||||||
+ [(x, 15) for x in filter(lambda x: (x, 10) not in occup, range(16))]) - occup)
|
ok_b = lambda y: is_empty(width - 2, y)
|
||||||
pos = emptys[random.randrange(len(emptys))]
|
ok_c = lambda x: is_empty(x, 1)
|
||||||
|
ok_d = lambda x: is_empty(x, height - 2)
|
||||||
|
no_block = lambda x, y: \
|
||||||
|
all((ok_a(y) if x == 0 else True,
|
||||||
|
ok_b(y) if x == width - 1 else True,
|
||||||
|
ok_c(x) if y == 0 else True,
|
||||||
|
ok_d(x) if y == height - 1 else True))
|
||||||
|
|
||||||
|
emptys = set([(0, y) for y in filter(ok_a, range(height))]
|
||||||
|
+ [(width - 1, y) for y in filter(ok_b, range(height))]
|
||||||
|
+ [(x, 0) for x in filter(ok_c, range(width))]
|
||||||
|
+ [(x, height - 1) for x in filter(ok_d, range(width))]) - occup
|
||||||
|
emptys_full = set(itertools.product(range(width), range(height))) - occup
|
||||||
|
|
||||||
|
emptys = list(emptys)
|
||||||
|
random.shuffle(emptys)
|
||||||
|
emptys = set(emptys)
|
||||||
|
|
||||||
|
is_empty = lambda x, y: (x, y) in emptys_full
|
||||||
|
|
||||||
|
levers = []
|
||||||
|
for _ in range(nlevers):
|
||||||
|
while True:
|
||||||
|
pos = next(iter(emptys))
|
||||||
|
emptys.remove(pos)
|
||||||
|
emptys_full.remove(pos)
|
||||||
|
if no_block(*pos):
|
||||||
playfield[pos] = Lever
|
playfield[pos] = Lever
|
||||||
|
if not all(no_block(*pos) for pos in levers):
|
||||||
|
del playfield[pos]
|
||||||
|
else:
|
||||||
|
levers.append(pos)
|
||||||
|
break
|
||||||
|
|
||||||
return playfield
|
return playfield
|
||||||
|
|
||||||
|
|
||||||
def _adjust(source_direc, w, h, x, y):
|
def _adjust(source_direc, w, h, x, y):
|
||||||
return {
|
return {
|
||||||
Up: lambda x, y: (x, y),
|
Up: lambda x, y: (x, y),
|
||||||
|
@ -102,6 +140,44 @@ def _adjust(source_direc, w, h, x, y):
|
||||||
Left: lambda x, y: (y, h - x),
|
Left: lambda x, y: (y, h - x),
|
||||||
}[source_direc](x, y)
|
}[source_direc](x, y)
|
||||||
|
|
||||||
|
def generate_lasers(playfield):
|
||||||
|
width, height = 16, 16
|
||||||
|
sources = (((0, -1), Down),
|
||||||
|
((width, 0), Left),
|
||||||
|
((width - 1, height), Up),
|
||||||
|
((-1, height - 1), Right))
|
||||||
|
lasers = []
|
||||||
|
for start, direc in sources:
|
||||||
|
end = start
|
||||||
|
while True:
|
||||||
|
cur = playfield.get(end)
|
||||||
|
if cur is Target:
|
||||||
|
lasers.append((start, end))
|
||||||
|
break
|
||||||
|
if cur is Blocker:
|
||||||
|
lasers.append((start, end))
|
||||||
|
break
|
||||||
|
if cur in (MirrorLeft, MirrorRight):
|
||||||
|
if (start, end) in lasers:
|
||||||
|
break
|
||||||
|
lasers.append((start, end))
|
||||||
|
direc = _mirror_new_direc(cur, direc)
|
||||||
|
start = end
|
||||||
|
new_end = direc.next_pos(end)
|
||||||
|
if new_end[0] < 0 or new_end[1] < 0 or new_end[0] >= width or new_end[1] >= height:
|
||||||
|
if (start, end) not in lasers:
|
||||||
|
lasers.append((start, new_end))
|
||||||
|
break
|
||||||
|
end = new_end
|
||||||
|
return lasers
|
||||||
|
|
||||||
|
def _mirror_new_direc(mirror_type, old_direc):
|
||||||
|
return {Down: (Left, Right),
|
||||||
|
Left: (Down, Up),
|
||||||
|
Up: (Right, Left),
|
||||||
|
Right: (Up, Down)}[old_direc][
|
||||||
|
0 if mirror_type is MirrorLeft else 1]
|
||||||
|
|
||||||
def print_playfield(playfield, width, height, hide_directions=False):
|
def print_playfield(playfield, width, height, hide_directions=False):
|
||||||
text = [['·' for _ in range(width)] for _ in range(height)]
|
text = [['·' for _ in range(width)] for _ in range(height)]
|
||||||
for (x, y), val in playfield.items():
|
for (x, y), val in playfield.items():
|
||||||
|
|
|
@ -29,7 +29,7 @@ import pygame
|
||||||
import worldobject
|
import worldobject
|
||||||
|
|
||||||
class Mirror(worldobject.WorldObject):
|
class Mirror(worldobject.WorldObject):
|
||||||
def __init__(self, level, x, y, left_up=True):
|
def __init__(self, level, x, y, left_up=True, links=[]):
|
||||||
self.__dict__.update(locals())
|
self.__dict__.update(locals())
|
||||||
worldobject.WorldObject.__init__(self, level, x, y)
|
worldobject.WorldObject.__init__(self, level, x, y)
|
||||||
|
|
||||||
|
@ -54,6 +54,8 @@ class Mirror(worldobject.WorldObject):
|
||||||
if self.frame == top:
|
if self.frame == top:
|
||||||
self.in_rotation = False
|
self.in_rotation = False
|
||||||
self.left_up = not self.left_up
|
self.left_up = not self.left_up
|
||||||
|
for link in self.links:
|
||||||
|
link(self.left_up)
|
||||||
|
|
||||||
worldobject.WorldObject.update(self, e, t, dt)
|
worldobject.WorldObject.update(self, e, t, dt)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue