Merge branch 'master' of hongabar.org:robotgame

Conflicts:
	resources/graphics/TODO.txt
This commit is contained in:
Lasse 2012-08-12 18:05:00 +02:00
commit b3c871292a
10 changed files with 188 additions and 47 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -11,6 +11,10 @@ DONE /door/ gate
widen block03.png widen block03.png
dummy spacecraft.png spaceship dummy spacecraft.png spaceship
elevating_platform elevating_platform
<<<<<<< HEAD
dummy wall.png walls (in-door) dummy wall.png walls (in-door)
teleportation effect (Tænker evt. at det bare skal være en cirkel på jorden, der lyser op.) teleportation effect (Tænker evt. at det bare skal være en cirkel på jorden, der lyser op.)
water/lava/to be discussed water/lava/to be discussed
=======
tiles for level 1, matte and shining (green light)
>>>>>>> debca3bab2cc711d7acdfe349ad41a2810b5d165

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

@ -59,7 +59,7 @@ class Level1(level.Level):
self.tiles.append( self.tiles.append(
tile.Tile(self, i*64, j*48, self.imgs['ground1'])) tile.Tile(self, i*64, j*48, self.imgs['ground1']))
self.player.set_pos(64 * 15, 48 * 15) self.player.set_pos(64 * 15, 48 * 30)
self.player.set_init_pos() self.player.set_init_pos()
for i in range(self.dimensions[0]): for i in range(self.dimensions[0]):
@ -122,7 +122,7 @@ class Level1(level.Level):
'moat_corner_south') 'moat_corner_south')
self.add_tile(task1_pos[0] - 64 * 2, self.add_tile(task1_pos[0] - 64 * 2,
task1_pos[1] + 48, task1_pos[1] + 48,
'moat_end_horizontal') 'moat_horizontal')
self.add_tile(task1_pos[0] + 64 * 6, self.add_tile(task1_pos[0] + 64 * 6,
task1_pos[1] + 48, task1_pos[1] + 48,
'moat_end_horizontal_flip') 'moat_end_horizontal_flip')
@ -269,7 +269,7 @@ class Level1(level.Level):
### Task 3: Colour blocks ### Task 3: Colour blocks
task3_pos = (64 * 15, 48 * 18) task3_pos = (64 * 15, 48 * 20)
# Abstract "boxes", actually colour fields # Abstract "boxes", actually colour fields
boxes = logic.colourboxes.generate_colour_boxes(1, 3) boxes = logic.colourboxes.generate_colour_boxes(1, 3)
@ -405,7 +405,68 @@ class Level1(level.Level):
'moat_end_horizontal') 'moat_end_horizontal')
### Task 5: The bridge. ### Task 5: Teleporters
task5_size = 5, 8 # y, x -- Note, inverted.
task5_pos = (64 * 12, 48 * 19)
task5_nturns = random.randint(2, 4) * 2 - 1
playfield, nsteps, directions = (
logic.rollingstone.generate_simple_unsolved_solvable_extra(
task5_size[0], task5_size[1], task5_nturns,
task5_size[0]*task5_size[1]))
for x in range(task5_size[1]):
for y in range(task5_size[0]):
self.add_tile(task5_pos[0] - 64 * (x - 1),
task5_pos[1] - 48 * y,
'indoor%d' % random.randint(1, 6), blocking=False)
for i, j in playfield:
self.objects.append(
trigger.Trigger(self,
task5_pos[0] - 64 * (j - 1),
task5_pos[1] - 48 * i,
[lambda x: self.player.set_pos(
task5_pos[0] + 2 * 64,
(task5_pos[1]
- random.randint(0, task5_size[0] - 1) * 48))],
self.imgs['hole'],
[self.player],
visible=False))
for i in range(task5_size[1] + 1):
self.add_tile(task5_pos[0] - 64 * i,
task5_pos[1] + 48,
'moat_horizontal')
self.add_tile(task5_pos[0] - 64 * i,
task5_pos[1] - task5_size[0] * 48,
'moat_horizontal')
self.add_tile(task5_pos[0] + 64,
task5_pos[1] + 48,
'moat_end_horizontal_flip')
# self.add_tile(task5_pos[0] + 64,
# task5_pos[1] - task5_size[0] * 48,
# 'moat_end_horizontal_flip')
self.add_tile(task5_pos[0] - 64 * (task5_size[1] + 1),
task5_pos[1] + 48,
'moat_corner_south')
self.add_tile(task5_pos[0] - 64 * (task5_size[1] + 1),
task5_pos[1] - task5_size[0] * 48,
'moat_corner_north')
for i in range(task5_size[0]):
self.add_tile(task5_pos[0] - 64 * (task5_size[1] + 1),
task5_pos[1] - 48 * i,
'moat_vertical')
self.objects.append(
lever.Lever(self,
task5_pos[0] - 64 * (task5_size[1]),
task5_pos[1] - (task5_size[0] / 2) * 48,
[lambda *x: self.complete_task(5)]))
# DRAW THE BACKGROUND
self.draw_background() self.draw_background()

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

View File

@ -31,15 +31,16 @@ import worldobject
class Trigger(worldobject.WorldObject): class Trigger(worldobject.WorldObject):
def __init__(self, level, x, y, links, img, trigger_objs, def __init__(self, level, x, y, links, img, trigger_objs,
toggling=False, signal=[0, 1], toggling=False, signal=[0, 1],
setting=False): setting=False, blocking=False,
visible=True):
self.__dict__.update(locals()) self.__dict__.update(locals())
worldobject.WorldObject.__init__(self, level, x, y, z=-48, worldobject.WorldObject.__init__(self, level, x, y, z=-48,
blocking=False) blocking=blocking, visible=visible)
self.frame = 0 self.frame = 0
self.anim_speed = 15 self.anim_speed = 15
def trigger(self, setting): def trigger(self, setting, obj):
if self.setting != setting: if self.setting != setting:
self.setting = setting self.setting = setting
@ -49,13 +50,14 @@ class Trigger(worldobject.WorldObject):
def update(self, e, t, dt): def update(self, e, t, dt):
for obj in self.trigger_objs: for obj in self.trigger_objs:
if self.x == obj.x and self.y == obj.y: if self.x == obj.x and self.y == obj.y:
self.trigger(True) self.trigger(True, obj)
break break
self.trigger(False) self.trigger(False, None)
worldobject.WorldObject.update(self, e, t, dt) worldobject.WorldObject.update(self, e, t, dt)
def draw(self, window): def draw(self, window):
window.blit(self.img, (self.x - 32 - self.level.camera_x, if self.visible:
self.y - self.img.get_size()[1] + 24 window.blit(self.img, (self.x - 32 - self.level.camera_x,
- self.level.camera_y)) self.y - self.img.get_size()[1] + 24
- self.level.camera_y))