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):
window.blit(self.background, (0 - self.camera_x, 0 - self.camera_y))
def _sorted_objs(self):
return sorted(self.objects, key=lambda obj: (obj.y + obj.z))
def _sorted_objs(self, objs=None):
return sorted(self.objects if objs is None else objs,
key=lambda obj: (obj.y + obj.z))
def draw(self, window):
self._blit_background(window)

View File

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

View File

@ -34,14 +34,14 @@ import level
import player
import tile
import block
import boulder
import lever
import mirror
import trigger
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):
@ -62,6 +62,9 @@ class Level4(level.Level):
for (x, y), t in self.playfield.items():
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 f(x, y):
def g(setting):
@ -105,17 +108,12 @@ class Level4(level.Level):
obj.reset_pos()
def generate_lasers(self):
lml = lm.generate_lasers(self.playfield)
self.lasers_orig = lm.generate_lasers(self.playfield)
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):
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)
for ((x0, y0), (x1, y1)), direc in self.lasers_orig:
self.lasers.append(laser.Laser(
self, (x0 * 64, y0 * 48),
(x1 * 64, y1 * 48)))
def draw(self, window):
self._blit_background(window)
@ -123,15 +121,27 @@ class Level4(level.Level):
objs = self._sorted_objs()
for obj in objs:
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:
# obj.draw(window)
for obj in objs:
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)

View File

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

View File

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