pgzero-plus 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pgzero-plus might be problematic. Click here for more details.
- pgzero/__init__.py +41 -0
- pgzero/__main__.py +3 -0
- pgzero/actor.py +597 -0
- pgzero/animation.py +244 -0
- pgzero/builtins.py +45 -0
- pgzero/clock.py +200 -0
- pgzero/constants.py +33 -0
- pgzero/data/icon.png +0 -0
- pgzero/data/joypad.png +0 -0
- pgzero/game.py +573 -0
- pgzero/keyboard.py +67 -0
- pgzero/loaders.py +308 -0
- pgzero/music.py +180 -0
- pgzero/ptext.py +500 -0
- pgzero/rect.py +523 -0
- pgzero/runner.py +233 -0
- pgzero/screen.py +210 -0
- pgzero/soundfmt.py +105 -0
- pgzero/spellcheck.py +173 -0
- pgzero/sprites.py +182 -0
- pgzero/storage.py +191 -0
- pgzero/tilemaps.py +307 -0
- pgzero/tone.py +132 -0
- pgzero_plus-0.1.0.dist-info/METADATA +259 -0
- pgzero_plus-0.1.0.dist-info/RECORD +30 -0
- pgzero_plus-0.1.0.dist-info/WHEEL +5 -0
- pgzero_plus-0.1.0.dist-info/entry_points.txt +2 -0
- pgzero_plus-0.1.0.dist-info/licenses/COPYING +165 -0
- pgzero_plus-0.1.0.dist-info/top_level.txt +2 -0
- pgzrun.py +34 -0
pgzero/rect.py
ADDED
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import pygame.rect
|
|
3
|
+
import operator
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Rect(pygame.rect.Rect):
|
|
7
|
+
__slots__ = ()
|
|
8
|
+
|
|
9
|
+
# From Pygame docs
|
|
10
|
+
VALID_ATTRIBUTES = """
|
|
11
|
+
x y
|
|
12
|
+
top left bottom right
|
|
13
|
+
topleft bottomleft topright bottomright
|
|
14
|
+
midtop midleft midbottom midright
|
|
15
|
+
center centerx centery
|
|
16
|
+
size width height
|
|
17
|
+
w h
|
|
18
|
+
""".split()
|
|
19
|
+
|
|
20
|
+
def __setattr__(self, key, value):
|
|
21
|
+
try:
|
|
22
|
+
pygame.rect.Rect.__setattr__(self, key, value)
|
|
23
|
+
except AttributeError as e:
|
|
24
|
+
from .spellcheck import suggest
|
|
25
|
+
suggestions = suggest(key, self.VALID_ATTRIBUTES)
|
|
26
|
+
msg = e.args[0]
|
|
27
|
+
if suggestions:
|
|
28
|
+
msg += "; did you mean {!r}?".format(suggestions[0])
|
|
29
|
+
raise AttributeError(msg) from None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Rect.__doc__ = pygame.rect.Rect.__doc__
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class NoIntersect(Exception):
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ZRect:
|
|
40
|
+
"""ZRect
|
|
41
|
+
|
|
42
|
+
This is a Python implementation of the pygame Rect class. Its raison
|
|
43
|
+
d'être is to allow the coordinates to be floating point. All pygame
|
|
44
|
+
functions which require a rect allow for an object with a "rect"
|
|
45
|
+
attribute and whose coordinates will be converted to integers implictly.
|
|
46
|
+
|
|
47
|
+
All functions which require a dict will use the flexible constructor
|
|
48
|
+
to convert from: this (or a subclass); a Pygame Rect; a 4-tuple or a
|
|
49
|
+
pair of 2-tuples. In addition, they'll recognise any object which has
|
|
50
|
+
an (optionally callable) .rect attribute whose value will be used instead.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
_item_mapping = dict(enumerate("xywh"))
|
|
54
|
+
|
|
55
|
+
def __init__(self, *args):
|
|
56
|
+
|
|
57
|
+
if len(args) == 1:
|
|
58
|
+
args = tuple(self._handle_one_arg(args[0]))
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# At this point we have one of:
|
|
62
|
+
#
|
|
63
|
+
# x, y, w, h
|
|
64
|
+
# (x, y), (w, h)
|
|
65
|
+
# (x, y, w, h),
|
|
66
|
+
#
|
|
67
|
+
if len(args) == 4:
|
|
68
|
+
self.x, self.y, self.w, self.h = args
|
|
69
|
+
elif len(args) == 2:
|
|
70
|
+
(self.x, self.y), (self.w, self.h) = args
|
|
71
|
+
elif len(args) == 1:
|
|
72
|
+
self.x, self.y, self.w, self.h = args[0]
|
|
73
|
+
else:
|
|
74
|
+
raise TypeError(
|
|
75
|
+
"%s should be called with one, two or four arguments"
|
|
76
|
+
% (self.__class__.__name__)
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
self.rect = self
|
|
80
|
+
|
|
81
|
+
def _handle_one_arg(self, arg):
|
|
82
|
+
"""Handle -- possibly recursively -- the case of one parameter
|
|
83
|
+
|
|
84
|
+
Pygame -- and consequently pgzero -- is very accommodating when constructing
|
|
85
|
+
a rect. You can pass four integers, two pairs of 2-tuples, or one 4-tuple.
|
|
86
|
+
|
|
87
|
+
Also, you can pass an existing Rect-like object, or an object with a .rect
|
|
88
|
+
attribute. The object named by the .rect attribute is either one of the above,
|
|
89
|
+
or it's a callable object which returns one of the above.
|
|
90
|
+
|
|
91
|
+
This is evidently a recursive solution where an object with a .rect
|
|
92
|
+
attribute can yield an object with a .rect attribute, and so ad infinitum.
|
|
93
|
+
"""
|
|
94
|
+
#
|
|
95
|
+
# If the arg is an existing rect, return its elements
|
|
96
|
+
#
|
|
97
|
+
if isinstance(arg, RECT_CLASSES):
|
|
98
|
+
return arg.x, arg.y, arg.w, arg.h
|
|
99
|
+
|
|
100
|
+
#
|
|
101
|
+
# If it's something with a .rect attribute, start again with
|
|
102
|
+
# that attribute, calling it first if it's callable
|
|
103
|
+
#
|
|
104
|
+
if hasattr(arg, "rect"):
|
|
105
|
+
rectobj = arg.rect
|
|
106
|
+
if callable(rectobj):
|
|
107
|
+
rectobj = rectobj()
|
|
108
|
+
return self._handle_one_arg(rectobj)
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Otherwise, we assume it's an iterable of four elements
|
|
112
|
+
#
|
|
113
|
+
return arg
|
|
114
|
+
|
|
115
|
+
def __repr__(self):
|
|
116
|
+
return "<%s (x: %s, y: %s, w: %s, h: %s)>" % (
|
|
117
|
+
self.__class__.__name__, self.x, self.y, self.w, self.h)
|
|
118
|
+
|
|
119
|
+
def __reduce__(self):
|
|
120
|
+
return self.__class__, (self.x, self.y, self.w, self.h)
|
|
121
|
+
|
|
122
|
+
def copy(self):
|
|
123
|
+
return self.__class__(self.x, self.y, self.w, self.h)
|
|
124
|
+
__copy__ = copy
|
|
125
|
+
|
|
126
|
+
def __len__(self):
|
|
127
|
+
return 4
|
|
128
|
+
|
|
129
|
+
def __getitem__(self, item):
|
|
130
|
+
try:
|
|
131
|
+
return getattr(self, self._item_mapping[item])
|
|
132
|
+
except KeyError:
|
|
133
|
+
raise IndexError
|
|
134
|
+
|
|
135
|
+
def __setitem__(self, item, value):
|
|
136
|
+
try:
|
|
137
|
+
attribute = self._item_mapping[item]
|
|
138
|
+
except KeyError:
|
|
139
|
+
raise IndexError
|
|
140
|
+
else:
|
|
141
|
+
setattr(attribute, value)
|
|
142
|
+
|
|
143
|
+
def __bool__(self):
|
|
144
|
+
return self.w != 0 and self.h != 0
|
|
145
|
+
|
|
146
|
+
def __iter__(self):
|
|
147
|
+
yield self.x
|
|
148
|
+
yield self.y
|
|
149
|
+
yield self.w
|
|
150
|
+
yield self.h
|
|
151
|
+
|
|
152
|
+
def __hash__(self):
|
|
153
|
+
raise TypeError("ZRect instances may not be used as dictionary keys")
|
|
154
|
+
|
|
155
|
+
def __eq__(self, *other):
|
|
156
|
+
rect = self.__class__(*other)
|
|
157
|
+
return (self.x, self.y, self.w, self.h) == (rect.x, rect.y, rect.w, rect.h)
|
|
158
|
+
|
|
159
|
+
def __ne__(self, *other):
|
|
160
|
+
rect = self.__class__(*other)
|
|
161
|
+
return (self.x, self.y, self.w, self.h) != (rect.x, rect.y, rect.w, rect.h)
|
|
162
|
+
|
|
163
|
+
def __lt__(self, *other):
|
|
164
|
+
rect = self.__class__(*other)
|
|
165
|
+
return (self.x, self.y, self.w, self.h) < (rect.x, rect.y, rect.w, rect.h)
|
|
166
|
+
|
|
167
|
+
def __gt__(self, *other):
|
|
168
|
+
rect = self.__class__(*other)
|
|
169
|
+
return (self.x, self.y, self.w, self.h) > (rect.x, rect.y, rect.w, rect.h)
|
|
170
|
+
|
|
171
|
+
def __le__(self, *other):
|
|
172
|
+
rect = self.__class__(*other)
|
|
173
|
+
return (self.x, self.y, self.w, self.h) <= (rect.x, rect.y, rect.w, rect.h)
|
|
174
|
+
|
|
175
|
+
def __ge__(self, *other):
|
|
176
|
+
rect = self.__class__(*other)
|
|
177
|
+
return (self.x, self.y, self.w, self.h) >= (rect.x, rect.y, rect.w, rect.h)
|
|
178
|
+
|
|
179
|
+
def __contains__(self, other):
|
|
180
|
+
"""Test whether a point (x, y) or another rectangle
|
|
181
|
+
(anything accepted by ZRect) is contained within this ZRect
|
|
182
|
+
"""
|
|
183
|
+
if len(other) == 2:
|
|
184
|
+
return self.collidepoint(*other)
|
|
185
|
+
else:
|
|
186
|
+
return self.contains(*other)
|
|
187
|
+
|
|
188
|
+
def _get_width(self):
|
|
189
|
+
return self.w
|
|
190
|
+
|
|
191
|
+
def _set_width(self, width):
|
|
192
|
+
self.w = width
|
|
193
|
+
width = property(_get_width, _set_width)
|
|
194
|
+
|
|
195
|
+
def _get_height(self):
|
|
196
|
+
return self.h
|
|
197
|
+
|
|
198
|
+
def _set_height(self, height):
|
|
199
|
+
self.h = height
|
|
200
|
+
height = property(_get_height, _set_height)
|
|
201
|
+
|
|
202
|
+
def _get_top(self):
|
|
203
|
+
return self.y
|
|
204
|
+
|
|
205
|
+
def _set_top(self, top):
|
|
206
|
+
self.y = top
|
|
207
|
+
top = property(_get_top, _set_top)
|
|
208
|
+
|
|
209
|
+
def _get_left(self):
|
|
210
|
+
return self.x
|
|
211
|
+
|
|
212
|
+
def _set_left(self, left):
|
|
213
|
+
self.x = left
|
|
214
|
+
left = property(_get_left, _set_left)
|
|
215
|
+
|
|
216
|
+
def _get_right(self):
|
|
217
|
+
return self.x + self.w
|
|
218
|
+
|
|
219
|
+
def _set_right(self, right):
|
|
220
|
+
self.x = right - self.w
|
|
221
|
+
right = property(_get_right, _set_right)
|
|
222
|
+
|
|
223
|
+
def _get_bottom(self):
|
|
224
|
+
return self.y + self.h
|
|
225
|
+
|
|
226
|
+
def _set_bottom(self, bottom):
|
|
227
|
+
self.y = bottom - self.h
|
|
228
|
+
bottom = property(_get_bottom, _set_bottom)
|
|
229
|
+
|
|
230
|
+
def _get_centerx(self):
|
|
231
|
+
return self.x + (self.w / 2)
|
|
232
|
+
|
|
233
|
+
def _set_centerx(self, centerx):
|
|
234
|
+
self.x = centerx - (self.w / 2)
|
|
235
|
+
centerx = property(_get_centerx, _set_centerx)
|
|
236
|
+
|
|
237
|
+
def _get_centery(self):
|
|
238
|
+
return self.y + (self.h / 2)
|
|
239
|
+
|
|
240
|
+
def _set_centery(self, centery):
|
|
241
|
+
self.y = centery - (self.h / 2)
|
|
242
|
+
centery = property(_get_centery, _set_centery)
|
|
243
|
+
|
|
244
|
+
def _get_topleft(self):
|
|
245
|
+
return self.x, self.y
|
|
246
|
+
|
|
247
|
+
def _set_topleft(self, topleft):
|
|
248
|
+
self.x, self.y = topleft
|
|
249
|
+
topleft = property(_get_topleft, _set_topleft)
|
|
250
|
+
|
|
251
|
+
def _get_topright(self):
|
|
252
|
+
return self.x + self.w, self.y
|
|
253
|
+
|
|
254
|
+
def _set_topright(self, topright):
|
|
255
|
+
x, y = topright
|
|
256
|
+
self.x = x - self.w
|
|
257
|
+
self.y = y
|
|
258
|
+
topright = property(_get_topright, _set_topright)
|
|
259
|
+
|
|
260
|
+
def _get_bottomleft(self):
|
|
261
|
+
return self.x, self.y + self.h
|
|
262
|
+
|
|
263
|
+
def _set_bottomleft(self, bottomleft):
|
|
264
|
+
x, y = bottomleft
|
|
265
|
+
self.x = x
|
|
266
|
+
self.y = y - self.h
|
|
267
|
+
bottomleft = property(_get_bottomleft, _set_bottomleft)
|
|
268
|
+
|
|
269
|
+
def _get_bottomright(self):
|
|
270
|
+
return self.x + self.w, self.y + self.h
|
|
271
|
+
|
|
272
|
+
def _set_bottomright(self, bottomright):
|
|
273
|
+
x, y = bottomright
|
|
274
|
+
self.x = x - self.w
|
|
275
|
+
self.y = y - self.h
|
|
276
|
+
bottomright = property(_get_bottomright, _set_bottomright)
|
|
277
|
+
|
|
278
|
+
def _get_midtop(self):
|
|
279
|
+
return self.x + self.w / 2, self.y
|
|
280
|
+
|
|
281
|
+
def _set_midtop(self, midtop):
|
|
282
|
+
x, y = midtop
|
|
283
|
+
self.x = x - self.w / 2
|
|
284
|
+
self.y = y
|
|
285
|
+
midtop = property(_get_midtop, _set_midtop)
|
|
286
|
+
|
|
287
|
+
def _get_midleft(self):
|
|
288
|
+
return self.x, self.y + self.h / 2
|
|
289
|
+
|
|
290
|
+
def _set_midleft(self, midleft):
|
|
291
|
+
x, y = midleft
|
|
292
|
+
self.x = x
|
|
293
|
+
self.y = y - self.h / 2
|
|
294
|
+
midleft = property(_get_midleft, _set_midleft)
|
|
295
|
+
|
|
296
|
+
def _get_midbottom(self):
|
|
297
|
+
return self.x + self.w / 2, self.y + self.h
|
|
298
|
+
|
|
299
|
+
def _set_midbottom(self, midbottom):
|
|
300
|
+
x, y = midbottom
|
|
301
|
+
self.x = x - self.w / 2
|
|
302
|
+
self.y = y - self.h
|
|
303
|
+
midbottom = property(_get_midbottom, _set_midbottom)
|
|
304
|
+
|
|
305
|
+
def _get_midright(self):
|
|
306
|
+
return self.x + self.w, self.y + self.h / 2
|
|
307
|
+
|
|
308
|
+
def _set_midright(self, midright):
|
|
309
|
+
x, y = midright
|
|
310
|
+
self.x = x - self.w
|
|
311
|
+
self.y = y - self.h / 2
|
|
312
|
+
midright = property(_get_midright, _set_midright)
|
|
313
|
+
|
|
314
|
+
def _get_center(self):
|
|
315
|
+
return self.x + self.w / 2, self.y + self.h / 2
|
|
316
|
+
|
|
317
|
+
def _set_center(self, center):
|
|
318
|
+
x, y = center
|
|
319
|
+
self.x = x - self.w / 2
|
|
320
|
+
self.y = y - self.h / 2
|
|
321
|
+
center = property(_get_center, _set_center)
|
|
322
|
+
|
|
323
|
+
def _get_size(self):
|
|
324
|
+
return self.w, self.h
|
|
325
|
+
|
|
326
|
+
def _set_size(self, size):
|
|
327
|
+
self.w, self.h = size
|
|
328
|
+
size = property(_get_size, _set_size)
|
|
329
|
+
|
|
330
|
+
def move(self, x, y):
|
|
331
|
+
return self.__class__(self.x + x, self.y + y, self.w, self.h)
|
|
332
|
+
|
|
333
|
+
def move_ip(self, x, y):
|
|
334
|
+
self.x += x
|
|
335
|
+
self.y += y
|
|
336
|
+
|
|
337
|
+
def _inflated(self, x, y):
|
|
338
|
+
return self.x - x / 2, self.y - y / 2, self.w + x, self.h + y
|
|
339
|
+
|
|
340
|
+
def inflate(self, x, y):
|
|
341
|
+
return self.__class__(*self._inflated(x, y))
|
|
342
|
+
|
|
343
|
+
def inflate_ip(self, x, y):
|
|
344
|
+
self.x, self.y, self.w, self.h = self._inflated(x, y)
|
|
345
|
+
|
|
346
|
+
def _clamped(self, *other):
|
|
347
|
+
rect = self.__class__(*other)
|
|
348
|
+
|
|
349
|
+
if self.w >= rect.w:
|
|
350
|
+
x = rect.x + rect.w / 2 - self.w / 2
|
|
351
|
+
elif self.x < rect.x:
|
|
352
|
+
x = rect.x
|
|
353
|
+
elif self.x + self.w > rect.x + rect.w:
|
|
354
|
+
x = rect.x + rect.w - self.w
|
|
355
|
+
else:
|
|
356
|
+
x = self.x
|
|
357
|
+
|
|
358
|
+
if self.h >= rect.h:
|
|
359
|
+
y = rect.y + rect.h / 2 - self.h / 2
|
|
360
|
+
elif self.y < rect.y:
|
|
361
|
+
y = rect.y
|
|
362
|
+
elif self.y + self.h > rect.y + rect.h:
|
|
363
|
+
y = rect.y + rect.h - self.h
|
|
364
|
+
else:
|
|
365
|
+
y = self.y
|
|
366
|
+
|
|
367
|
+
return x, y
|
|
368
|
+
|
|
369
|
+
def clamp(self, *other):
|
|
370
|
+
rect = self.__class__(*other)
|
|
371
|
+
x, y = self._clamped(rect)
|
|
372
|
+
return self.__class__(x, y, self.w, self.h)
|
|
373
|
+
|
|
374
|
+
def clamp_ip(self, *other):
|
|
375
|
+
rect = self.__class__(*other)
|
|
376
|
+
self.x, self.y = self._clamped(rect)
|
|
377
|
+
|
|
378
|
+
def _clipped(self, *other):
|
|
379
|
+
rect = self.__class__(*other)
|
|
380
|
+
|
|
381
|
+
if self.x >= rect.x and self.x < (rect.x + rect.w):
|
|
382
|
+
x = self.x
|
|
383
|
+
elif rect.x >= self.x and rect.x < (self.x + self.w):
|
|
384
|
+
x = rect.x
|
|
385
|
+
else:
|
|
386
|
+
raise NoIntersect
|
|
387
|
+
|
|
388
|
+
if (self.x + self.w) > rect.x and (self.x + self.w) <= (rect.x + rect.w):
|
|
389
|
+
w = self.x + self.w - x
|
|
390
|
+
elif (rect.x + rect.w) > self.x and (rect.x + rect.w) <= (self.x + self.w):
|
|
391
|
+
w = rect.x + rect.w - x
|
|
392
|
+
else:
|
|
393
|
+
raise NoIntersect
|
|
394
|
+
|
|
395
|
+
if self.y >= rect.y and self.y < (rect.y + rect.h):
|
|
396
|
+
y = self.y
|
|
397
|
+
elif rect.y >= self.y and rect.y < (self.y + self.h):
|
|
398
|
+
y = rect.y
|
|
399
|
+
else:
|
|
400
|
+
raise NoIntersect
|
|
401
|
+
|
|
402
|
+
if (self.y + self.h) > rect.y and (self.y + self.h) <= (rect.y + rect.h):
|
|
403
|
+
h = self.y + self.h - y
|
|
404
|
+
elif (rect.y + rect.h) > self.y and (rect.y + rect.h) <= (self.y + self.h):
|
|
405
|
+
h = rect.y + rect.h - y
|
|
406
|
+
else:
|
|
407
|
+
raise NoIntersect
|
|
408
|
+
|
|
409
|
+
return x, y, w, h
|
|
410
|
+
|
|
411
|
+
def clip(self, *other):
|
|
412
|
+
rect = self.__class__(*other)
|
|
413
|
+
try:
|
|
414
|
+
x, y, w, h = self._clipped(rect)
|
|
415
|
+
except NoIntersect:
|
|
416
|
+
x, y, w, h = self.x, self.y, 0, 0
|
|
417
|
+
return self.__class__(x, y, w, h)
|
|
418
|
+
|
|
419
|
+
def clip_ip(self, *other):
|
|
420
|
+
rect = self.__class__(*other)
|
|
421
|
+
try:
|
|
422
|
+
self.x, self.y, self.w, self.h = self._clipped(rect)
|
|
423
|
+
except NoIntersect:
|
|
424
|
+
self.x, self.y, self.w, self.h = self.x, self.y, 0, 0
|
|
425
|
+
|
|
426
|
+
def _unioned(self, *other):
|
|
427
|
+
rect = self.__class__(*other)
|
|
428
|
+
x = min(self.x, rect.x)
|
|
429
|
+
y = min(self.y, rect.y)
|
|
430
|
+
w = max(self.x + self.w, rect.x + rect.w) - x
|
|
431
|
+
h = max(self.y + self.h, rect.y + rect.h) - y
|
|
432
|
+
return x, y, w, h
|
|
433
|
+
|
|
434
|
+
def union(self, *other):
|
|
435
|
+
rect = self.__class__(*other)
|
|
436
|
+
return self.__class__(*self._unioned(rect))
|
|
437
|
+
|
|
438
|
+
def union_ip(self, *other):
|
|
439
|
+
rect = self.__class__(*other)
|
|
440
|
+
self.x, self.y, self.w, self.h = self._unioned(rect)
|
|
441
|
+
|
|
442
|
+
def _unionalled(self, others):
|
|
443
|
+
allrects = [self] + [self.__class__(other) for other in others]
|
|
444
|
+
x = min(r.x for r in allrects)
|
|
445
|
+
y = min(r.y for r in allrects)
|
|
446
|
+
w = max(r.x + r.w for r in allrects) - x
|
|
447
|
+
h = max(r.y + r.h for r in allrects) - y
|
|
448
|
+
return x, y, w, h
|
|
449
|
+
|
|
450
|
+
def unionall(self, others):
|
|
451
|
+
return self.__class__(*self._unionalled(others))
|
|
452
|
+
|
|
453
|
+
def unionall_ip(self, others):
|
|
454
|
+
self.x, self.y, self.w, self.h = self._unionalled(others)
|
|
455
|
+
|
|
456
|
+
def fit(self, *other):
|
|
457
|
+
rect = self.__class__(*other)
|
|
458
|
+
ratio = max(self.w / rect.w, self.h / rect.h)
|
|
459
|
+
w = self.w / ratio
|
|
460
|
+
h = self.h / ratio
|
|
461
|
+
x = rect.x + (rect.w - w) / 2
|
|
462
|
+
y = rect.y + (rect.h - h) / 2
|
|
463
|
+
return self.__class__(x, y, w, h)
|
|
464
|
+
|
|
465
|
+
def normalize(self):
|
|
466
|
+
if self.w < 0:
|
|
467
|
+
self.x += self.w
|
|
468
|
+
self.w = abs(self.w)
|
|
469
|
+
if self.h < 0:
|
|
470
|
+
self.y += self.h
|
|
471
|
+
self.h = abs(self.h)
|
|
472
|
+
|
|
473
|
+
def contains(self, *other):
|
|
474
|
+
rect = self.__class__(*other)
|
|
475
|
+
return (
|
|
476
|
+
self.x <= rect.x and
|
|
477
|
+
self.y <= rect.y and
|
|
478
|
+
self.x + self.w >= rect.x + rect.w and
|
|
479
|
+
self.y + self.h >= rect.y + rect.h and
|
|
480
|
+
self.x + self.w > rect.x and
|
|
481
|
+
self.y + self.h > rect.y
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
def collidepoint(self, *args):
|
|
485
|
+
if len(args) == 1:
|
|
486
|
+
x, y = args[0]
|
|
487
|
+
else:
|
|
488
|
+
x, y = args
|
|
489
|
+
return (
|
|
490
|
+
self.x <= x < (self.x + self.w) and
|
|
491
|
+
self.y <= y < (self.y + self.h)
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
def colliderect(self, *other):
|
|
495
|
+
rect = self.__class__(*other)
|
|
496
|
+
return (
|
|
497
|
+
self.x < rect.x + rect.w and
|
|
498
|
+
self.y < rect.y + rect.h and
|
|
499
|
+
self.x + self.w > rect.x and
|
|
500
|
+
self.y + self.h > rect.y
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
def collidelist(self, others):
|
|
504
|
+
for n, other in enumerate(others):
|
|
505
|
+
if self.colliderect(other):
|
|
506
|
+
return n
|
|
507
|
+
else:
|
|
508
|
+
return -1
|
|
509
|
+
|
|
510
|
+
def collidelistall(self, others):
|
|
511
|
+
return [n for n, other in enumerate(others) if self.colliderect(other)]
|
|
512
|
+
|
|
513
|
+
def collidedict(self, dict, use_values=True):
|
|
514
|
+
for k, v in dict.items():
|
|
515
|
+
if self.colliderect(v if use_values else k):
|
|
516
|
+
return k, v
|
|
517
|
+
|
|
518
|
+
def collidedictall(self, dict, use_values=True):
|
|
519
|
+
val = operator.itemgetter(1 if use_values else 0)
|
|
520
|
+
return [i for i in dict.items() if self.colliderect(val(i))]
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
RECT_CLASSES = (pygame.rect.Rect, ZRect)
|