Mercurial > nagslang
annotate nagslang/puzzle.py @ 671:09c76e7ce675
Icon generation in Makefile
author | Stefano Rivera <stefano@rivera.za.net> |
---|---|
date | Sun, 08 Sep 2013 18:12:44 +0200 |
parents | 427d4a3c53d7 |
children |
rev | line source |
---|---|
201
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
1 from nagslang.constants import COLLISION_TYPE_PLAYER |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
2 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
3 |
235
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
4 def get_editable_puzzlers(): |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
5 classes = [] |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
6 for cls_name, cls in globals().iteritems(): |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
7 if isinstance(cls, type) and hasattr(cls, 'requires'): |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
8 classes.append((cls_name, cls)) |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
9 return classes |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
10 |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
11 |
201
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
12 class PuzzleGlue(object): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
13 """Glue that holds bits of a puzzle together. |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
14 """ |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
15 def __init__(self): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
16 self._components = {} |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
17 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
18 def add_component(self, name, puzzler): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
19 if not isinstance(puzzler, Puzzler): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
20 puzzler = puzzler.puzzler |
328
14339d2d46bc
Only add objects with actual puzzlers to the glue
Neil Muller <drnlmuller@gmail.com>
parents:
282
diff
changeset
|
21 if puzzler is None: |
14339d2d46bc
Only add objects with actual puzzlers to the glue
Neil Muller <drnlmuller@gmail.com>
parents:
282
diff
changeset
|
22 # We've got a name, but no puzzler, |
14339d2d46bc
Only add objects with actual puzzlers to the glue
Neil Muller <drnlmuller@gmail.com>
parents:
282
diff
changeset
|
23 # so we shouldn't actually be stuck |
14339d2d46bc
Only add objects with actual puzzlers to the glue
Neil Muller <drnlmuller@gmail.com>
parents:
282
diff
changeset
|
24 # in here |
14339d2d46bc
Only add objects with actual puzzlers to the glue
Neil Muller <drnlmuller@gmail.com>
parents:
282
diff
changeset
|
25 return |
201
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
26 self._components[name] = puzzler |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
27 puzzler.set_glue(self) |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
28 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
29 def get_state_of(self, name): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
30 return self._components[name].get_state() |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
31 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
32 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
33 class Puzzler(object): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
34 """Behaviour specific to a puzzle component. |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
35 """ |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
36 def set_glue(self, glue): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
37 self.glue = glue |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
38 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
39 def set_game_object(self, game_object): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
40 self.game_object = game_object |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
41 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
42 def get_state(self): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
43 raise NotImplementedError() |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
44 |
235
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
45 @classmethod |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
46 def requires(cls): |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
47 """Tell the level editor the arguments we require |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
48 |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
49 Format is a list of name: type hint tuples""" |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
50 return [("name", "string")] |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
51 |
201
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
52 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
53 class YesPuzzler(Puzzler): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
54 """Yes sir, I'm always on. |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
55 """ |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
56 def get_state(self): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
57 return True |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
58 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
59 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
60 class NoPuzzler(Puzzler): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
61 """No sir, I'm always off. |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
62 """ |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
63 def get_state(self): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
64 return False |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
65 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
66 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
67 class CollidePuzzler(Puzzler): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
68 def __init__(self, *collision_types): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
69 if not collision_types: |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
70 collision_types = (COLLISION_TYPE_PLAYER,) |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
71 self._collision_types = collision_types |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
72 |
456
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
73 def get_interior_colliders(self): |
201
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
74 space = self.game_object.get_space() |
444 | 75 my_shape = self.game_object.get_shape() |
76 shapes = [shape for shape in space.shapes | |
77 if shape.collision_type in self._collision_types] | |
456
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
78 return set(shape for shape in shapes |
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
79 if my_shape in space.point_query(shape.body.position)) |
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
80 |
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
81 def get_colliders(self): |
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
82 space = self.game_object.get_space() |
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
83 my_shape = self.game_object.get_shape() |
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
84 shapes = set(shape for shape in space.shape_query(my_shape) |
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
85 if shape.collision_type in self._collision_types) |
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
86 shapes.update(self.get_interior_colliders()) |
427d4a3c53d7
Better CollidePuzzler behaviour.
Jeremy Thurgood <firxen@gmail.com>
parents:
444
diff
changeset
|
87 return shapes |
444 | 88 |
89 def get_state(self): | |
90 return bool(self.get_colliders()) | |
201
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
91 |
235
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
92 @classmethod |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
93 def requires(cls): |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
94 return [("name", "string"), ("collision_types", "list of ints")] |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
95 |
201
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
96 |
444 | 97 class MultiCollidePuzzler(CollidePuzzler): |
98 def __init__(self, min_count, *collision_types): | |
99 self._min_count = min_count | |
100 super(MultiCollidePuzzler, self).__init__(*collision_types) | |
101 | |
102 def get_state(self): | |
103 return len(self.get_colliders()) >= self._min_count | |
104 | |
105 @classmethod | |
106 def requires(cls): | |
107 return [("name", "string"), ("min_count", "int"), | |
108 ("collision_types", "list of ints")] | |
109 | |
110 | |
282
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
111 class ParentAttrPuzzler(Puzzler): |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
112 def __init__(self, attr_name): |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
113 self._attr_name = attr_name |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
114 |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
115 def get_state(self): |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
116 return getattr(self.game_object, self._attr_name) |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
117 |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
118 @classmethod |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
119 def requires(cls): |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
120 return [("name", "string"), ("attr_name", "string")] |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
121 |
9d186b897d82
Toggle switch, sans art.
Jeremy Thurgood <firxen@gmail.com>
parents:
235
diff
changeset
|
122 |
201
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
123 class StateProxyPuzzler(Puzzler): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
124 def __init__(self, state_source): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
125 self._state_source = state_source |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
126 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
127 def get_state(self): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
128 return self.glue.get_state_of(self._state_source) |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
129 |
235
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
130 @classmethod |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
131 def requires(cls): |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
132 return [("name", "string"), ("sources", "list of names")] |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
133 |
201
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
134 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
135 class StateLogicalAndPuzzler(Puzzler): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
136 def __init__(self, *state_sources): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
137 self._state_sources = state_sources |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
138 |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
139 def get_state(self): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
140 for state_source in self._state_sources: |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
141 if not self.glue.get_state_of(state_source): |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
142 return False |
3495a2025bc6
Break puzzlers out of game_object.py
Stefano Rivera <stefano@rivera.za.net>
parents:
diff
changeset
|
143 return True |
235
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
144 |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
145 @classmethod |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
146 def requires(cls): |
831e4f6b3d18
Add hints for the level editor
Neil Muller <drnlmuller@gmail.com>
parents:
201
diff
changeset
|
147 return [("name", "string"), ("sources", "list of names")] |