Merge branch 'master' of hongabar.org:robotgame

This commit is contained in:
Sakse Dalum 2012-08-12 17:37:06 +02:00
commit 3bd735788f
6 changed files with 109 additions and 35 deletions

45
robotgame/laser.py Normal file
View File

@ -0,0 +1,45 @@
# 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 <http://www.gnu.org/licenses/>.
#
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
#
# laser.py
# --------------------
# date created : Sun Aug 12 2012
# copyright : (C) 2012 Niels G. W. Serup
# maintained by : Niels G. W. Serup <ns@metanohi.name>
"""
A laser for drawing.
"""
import pygame
import worldobject
class Laser(worldobject.WorldObject):
def __init__(self, level, p0, p1):
self.__dict__.update(locals())
worldobject.WorldObject.__init__(self, level, p0[0], p0[1])
def update(self, e, t, dt):
worldobject.WorldObject.update(self, e, t, dt)
def draw(self, window):
(x0, y0), (x1, y1) = self.p0, self.p1
pygame.draw.line(window, (255, 0, 0),
(x0 - self.level.camera_x + 32, y0 + 4 - self.level.camera_y),
(x1 - self.level.camera_x + 32, y1 + 4 - self.level.camera_y), 4)

View File

@ -75,8 +75,9 @@ class Level(object):
def _blit_background(self, window): def _blit_background(self, window):
window.blit(self.background, (0 - self.camera_x, 0 - self.camera_y)) window.blit(self.background, (0 - self.camera_x, 0 - self.camera_y))
def _sorted_objs(self): def _sorted_objs(self, objs=None):
return sorted(self.objects, key=lambda obj: (obj.y + obj.z)) return sorted(self.objects if objs is None else objs,
key=lambda obj: (obj.y + obj.z))
def draw(self, window): def draw(self, window):
self._blit_background(window) self._blit_background(window)

View File

@ -38,7 +38,6 @@ import level
import player import player
import tile import tile
import block import block
import boulder
import lever import lever
import logic.colourboxes import logic.colourboxes

View File

@ -34,14 +34,14 @@ import level
import player import player
import tile import tile
import block import block
import boulder
import lever import lever
import mirror import mirror
import trigger import laser
import misc import misc
import worldobject import worldobject
import logic.lasermirror as lm import logic.lasermirror as lm
from logic.direction import *
class Level4(level.Level): class Level4(level.Level):
def __init__(self, game, graphics_dir, paused=False): def __init__(self, game, graphics_dir, paused=False):
@ -62,6 +62,9 @@ class Level4(level.Level):
for (x, y), t in self.playfield.items(): for (x, y), t in self.playfield.items():
x1, y1 = 64 * x, 48 * (y + 1) x1, y1 = 64 * x, 48 * (y + 1)
if isinstance(t, lm.Source):
self.objects.append(block.Block(self, x1, y1, self.imgs['block3'], movable=False))
continue
def mir(b, x1, y1): def mir(b, x1, y1):
def f(x, y): def f(x, y):
def g(setting): def g(setting):
@ -105,17 +108,12 @@ 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_orig = lm.generate_lasers(self.playfield)
self.lasers = [] self.lasers = []
for (x0, y0), (x1, y1) in lml: for ((x0, y0), (x1, y1)), direc in self.lasers_orig:
self.lasers.append(((x0 * 64 + 32, y0 * 48 + 32), self.lasers.append(laser.Laser(
(x1 * 64 + 32, y1 * 48 + 32))) self, (x0 * 64, y0 * 48),
(x1 * 64, y1 * 48)))
def draw_lasers(self, window):
for (x0, y0), (x1, y1) in self.lasers:
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)
@ -123,15 +121,27 @@ class Level4(level.Level):
objs = self._sorted_objs() objs = self._sorted_objs()
for obj in objs: for obj in objs:
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) for obj in self.lasers:
obj.draw(window)
# for obj in mirrors: for obj in objs:
# obj.draw(window) x0, y0 = obj.x / 64, obj.y / 48 - 1
if isinstance(obj, mirror.Mirror):
for (p0, p1), laser_direc in self.lasers_orig:
if p0 == (x0, y0):
mirror_direc = Left if obj.left_up else Right
do_redraw = {
(Left, Up): True,
(Left, Left): True,
(Left, Down): False,
(Left, Right): False,
(Right, Up): True,
(Right, Right): True,
(Right, Down): False,
(Right, Left): False
}[(mirror_direc, laser_direc)]
if do_redraw:
obj.draw(window)
self.darkness.draw(window) self.darkness.draw(window)

View File

@ -29,6 +29,13 @@ class Direction(object):
def next_pos(pos): def next_pos(pos):
raise NotImplementedError raise NotImplementedError
@staticmethod
def from_sakse(p):
return {(0, -1): Up,
(0, 1): Down,
(-1, 0): Left,
(1, 0): Right}[p]
class Up(Direction): class Up(Direction):
@staticmethod @staticmethod
def next_pos(pos): def next_pos(pos):

View File

@ -48,6 +48,10 @@ class Lever(object):
class Target(object): class Target(object):
pass pass
class Source(object):
def __init__(self, direction):
self.__dict__.update(locals())
def generate_simple_playfield(nmirrors): def generate_simple_playfield(nmirrors):
""" """
Generate a completable 16x16 playfield where: Generate a completable 16x16 playfield where:
@ -64,7 +68,14 @@ def generate_simple_playfield(nmirrors):
Return playfield : {(x, y): Return playfield : {(x, y):
Target | MirrorLeft | MirrorRight | rstone.Blocker | Lever} Target | MirrorLeft | MirrorRight | rstone.Blocker | Lever}
""" """
playfield = {(6, 6): Target,
width, height = 16, 16
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, (9, 6): Target,
(6, 9): Target, (6, 9): Target,
(9, 9): Target, (9, 9): Target,
@ -73,7 +84,6 @@ 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
@ -84,7 +94,7 @@ 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)] \ playfield[_adjust(source_direc, width - 1, height - 1, *pos)] \
= random.choice((MirrorLeft, MirrorRight)) = 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)
@ -141,32 +151,34 @@ def _adjust(source_direc, w, h, x, y):
}[source_direc](x, y) }[source_direc](x, y)
def generate_lasers(playfield): def generate_lasers(playfield):
"""
Generate laser paths.
Return [((x, y), direction), ...]
"""
width, height = 16, 16 width, height = 16, 16
sources = (((0, -1), Down), sources = ((pos, obj.direction) for pos, obj in filter(lambda posobj: isinstance(posobj[1], Source), playfield.items()))
((width, 0), Left),
((width - 1, height), Up),
((-1, height - 1), Right))
lasers = [] lasers = []
for start, direc in sources: for start, direc in sources:
end = start end = start
while True: while True:
cur = playfield.get(end) cur = playfield.get(end)
if cur is Target: if cur is Target:
lasers.append((start, end)) lasers.append(((start, end), direc))
break break
if cur is Blocker: if cur is Blocker:
lasers.append((start, end)) lasers.append(((start, end), direc))
break break
if cur in (MirrorLeft, MirrorRight): if cur in (MirrorLeft, MirrorRight):
if (start, end) in lasers: if (start, end) in ((start, end) for (start, end), direc in lasers):
break break
lasers.append((start, end)) lasers.append(((start, end), direc))
direc = _mirror_new_direc(cur, direc) direc = _mirror_new_direc(cur, direc)
start = end start = end
new_end = direc.next_pos(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 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: if (start, end) not in lasers:
lasers.append((start, new_end)) lasers.append(((start, new_end), direc))
break break
end = new_end end = new_end
return lasers return lasers