Mercurial > boomslang
comparison pyntnclick/scenewidgets.py @ 854:79b5c1be9a5e default tip
Remove pyntnclick, it's its own library, now
author | Stefano Rivera <stefano@rivera.za.net> |
---|---|
date | Sat, 21 Jun 2014 22:06:09 +0200 |
parents | f95830b58336 |
children |
comparison
equal
deleted
inserted
replaced
852:f95830b58336 | 854:79b5c1be9a5e |
---|---|
1 """Interactive elements within a Scene.""" | |
2 | |
3 | |
4 from pygame import Rect | |
5 from pygame.color import Color | |
6 from pygame.colordict import THECOLORS | |
7 from pygame.surface import Surface | |
8 | |
9 from pyntnclick.state import Thing | |
10 from pyntnclick.utils import convert_color, render_text | |
11 from pyntnclick.widgets.text import LabelWidget | |
12 | |
13 | |
14 class Interact(object): | |
15 | |
16 def __init__(self, image, rect, interact_rect): | |
17 self.image = image | |
18 self.rect = rect | |
19 self.interact_rect = interact_rect | |
20 | |
21 def set_thing(self, thing): | |
22 pass | |
23 | |
24 def draw(self, surface): | |
25 if self.image is not None: | |
26 surface.blit(self.image, self.rect, None) | |
27 | |
28 def animate(self): | |
29 return False | |
30 | |
31 | |
32 class InteractNoImage(Interact): | |
33 | |
34 def __init__(self, x, y, w, h): | |
35 super(InteractNoImage, self).__init__(None, None, Rect(x, y, w, h)) | |
36 | |
37 | |
38 class InteractDebugText(Interact): | |
39 """Display box with text to interact with -- mostly for debugging.""" | |
40 | |
41 def __init__(self, x, y, text, bg_color=None): | |
42 if bg_color is None: | |
43 bg_color = (127, 127, 127) | |
44 label = LabelWidget((0, 0), text) | |
45 # label.set_margin(5) | |
46 # label.border_width = 1 | |
47 # label.border_color = (0, 0, 0) | |
48 # label.bg_color = bg_color | |
49 # label.fg_color = (0, 0, 0) | |
50 image = Surface(label.size) | |
51 rect = Rect((x, y), label.size) | |
52 label.draw_all(image) | |
53 super(InteractDebugText, self).__init__(image, rect, rect) | |
54 | |
55 | |
56 class InteractText(Interact): | |
57 """Display a text string on a transparent background. | |
58 | |
59 Used so we can easily include translatable strings in the scenes""" | |
60 | |
61 def __init__(self, x, y, w, h, text, color, max_font_size, font=None, | |
62 centre=True): | |
63 self._text = text | |
64 self._color = convert_color(color) | |
65 self._max_font_size = max_font_size | |
66 self._font = font | |
67 self._centre = centre | |
68 rect = Rect((x, y), (w, h)) | |
69 super(InteractText, self).__init__(None, rect, rect) | |
70 | |
71 def set_thing(self, thing): | |
72 font_size = self._max_font_size | |
73 if not self._font: | |
74 # Pull the default font out of constants | |
75 self._font = thing.gd.constants.font | |
76 bg_color = Color(0, 0, 0, 0) # transparent background | |
77 self.image = render_text(self._text, self._font, font_size, | |
78 self._color, bg_color, thing.resource, self.rect.size, | |
79 self._centre) | |
80 | |
81 | |
82 class InteractRectUnion(Interact): | |
83 | |
84 def __init__(self, rect_list): | |
85 super(InteractRectUnion, self).__init__(None, None, None) | |
86 rect_list = [Rect(x) for x in rect_list] | |
87 self.interact_rect = rect_list | |
88 | |
89 | |
90 class InteractUnion(Interact): | |
91 """An interact made out of other interacts""" | |
92 | |
93 def __init__(self, interact_list): | |
94 super(InteractUnion, self).__init__(None, None, None) | |
95 self._interact_list = interact_list | |
96 | |
97 def set_thing(self, thing): | |
98 interact_list = [] | |
99 for sub_interact in self._interact_list: | |
100 sub_interact.set_thing(thing) | |
101 sub_rect = sub_interact.interact_rect | |
102 if hasattr(sub_rect, 'collidepoint'): | |
103 interact_list.append(sub_interact.interact_rect) | |
104 else: | |
105 interact_list.extend(sub_interact.interact_rect) | |
106 self.interact_rect = interact_list | |
107 | |
108 def draw(self, surface): | |
109 for sub_interact in self._interact_list: | |
110 sub_interact.draw(surface) | |
111 | |
112 def animate(self): | |
113 for sub_interact in self._interact_list: | |
114 sub_interact.animate() | |
115 | |
116 | |
117 class InteractImage(Interact): | |
118 | |
119 def __init__(self, x, y, image_name): | |
120 super(InteractImage, self).__init__(None, None, None) | |
121 self._pos = (x, y) | |
122 self._image_name = image_name | |
123 | |
124 def set_thing(self, thing): | |
125 self.image = thing.resource.get_image(thing.folder, self._image_name) | |
126 self.rect = Rect(self._pos, self.image.get_size()) | |
127 self.interact_rect = self.rect | |
128 | |
129 def __repr__(self): | |
130 return '<InteractImage: %s>' % self._image_name | |
131 | |
132 | |
133 class InteractImageRect(InteractImage): | |
134 def __init__(self, x, y, image_name, r_x, r_y, r_w, r_h): | |
135 super(InteractImageRect, self).__init__(x, y, image_name) | |
136 self._r_pos = (r_x, r_y) | |
137 self._r_size = (r_w, r_h) | |
138 | |
139 def set_thing(self, thing): | |
140 super(InteractImageRect, self).set_thing(thing) | |
141 self.interact_rect = Rect(self._r_pos, self._r_size) | |
142 | |
143 | |
144 class InteractAnimated(Interact): | |
145 """Interactive with an animation rather than an image""" | |
146 | |
147 # anim_seq - sequence of image names | |
148 # delay - number of frames to wait between changing images | |
149 | |
150 def __init__(self, x, y, anim_seq, delay): | |
151 self._pos = (x, y) | |
152 self._anim_pos = 0 | |
153 self._names = anim_seq | |
154 self._frame_count = 0 | |
155 self._anim_seq = None | |
156 self._delay = delay | |
157 | |
158 def set_thing(self, thing): | |
159 self._anim_seq = [thing.resource.get_image(thing.folder, x) | |
160 for x in self._names] | |
161 self.image = self._anim_seq[0] | |
162 self.rect = Rect(self._pos, self.image.get_size()) | |
163 for image in self._anim_seq: | |
164 assert image.get_size() == self.rect.size | |
165 self.interact_rect = self.rect | |
166 | |
167 def animate(self): | |
168 if self._anim_seq: | |
169 self._frame_count += 1 | |
170 if self._frame_count > self._delay: | |
171 self._frame_count = 0 | |
172 self._anim_pos += 1 | |
173 if self._anim_pos >= len(self._anim_seq): | |
174 self._anim_pos = 0 | |
175 self.image = self._anim_seq[self._anim_pos] | |
176 # queue redraw | |
177 return True | |
178 return False | |
179 | |
180 | |
181 class TakeableThing(Thing): | |
182 "Thing that can be taken." | |
183 | |
184 INITIAL_DATA = { | |
185 'taken': False, | |
186 } | |
187 | |
188 ITEM = None | |
189 | |
190 def __init__(self): | |
191 # In case a subclass replaces INITIAL_DATA and breaks 'taken'. | |
192 assert self.INITIAL_DATA['taken'] in (True, False) | |
193 super(TakeableThing, self).__init__() | |
194 | |
195 def should_add(self): | |
196 return not self.get_data('taken') | |
197 | |
198 def take(self): | |
199 self.set_data('taken', True) | |
200 self.game.add_inventory_item(self.ITEM) | |
201 self.scene.remove_thing(self) | |
202 | |
203 | |
204 class GenericDescThing(Thing): | |
205 "Thing with an InteractiveUnionRect and a description" | |
206 | |
207 INITIAL = "description" | |
208 | |
209 def __init__(self, prefix, number, description, areas): | |
210 super(GenericDescThing, self).__init__() | |
211 self.description = description | |
212 self.name = '%s.%s' % (prefix, number) | |
213 self.interacts = { | |
214 'description': InteractRectUnion(areas) | |
215 } | |
216 # Individual colors to make debugging easier | |
217 self._interact_hilight_color = Color(THECOLORS.keys()[number]) | |
218 | |
219 def get_description(self): | |
220 return self.description | |
221 | |
222 def is_interactive(self, tool=None): | |
223 return False |