pyscratch-pysc 1.0.3__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.
Files changed (101) hide show
  1. assets/bullet_hell/enemy.py +130 -0
  2. assets/bullet_hell/enemy_bullets.py +230 -0
  3. assets/bullet_hell/main.py +11 -0
  4. assets/bullet_hell/old_verisons/bullet_hell.py +379 -0
  5. assets/bullet_hell/old_verisons/enemy.py +226 -0
  6. assets/bullet_hell/old_verisons/game_start.py +6 -0
  7. assets/bullet_hell/old_verisons/main.py +50 -0
  8. assets/bullet_hell/old_verisons/player.py +76 -0
  9. assets/bullet_hell/player.py +89 -0
  10. assets/bullet_hell/player_bullets.py +34 -0
  11. assets/bullet_hell/setting.py +33 -0
  12. examples/animated_sprite/main.py +7 -0
  13. examples/animated_sprite/my_sprite.py +79 -0
  14. examples/bullet_hell/enemy.py +152 -0
  15. examples/bullet_hell/enemy_bullet.py +88 -0
  16. examples/bullet_hell/main.py +17 -0
  17. examples/bullet_hell/player.py +39 -0
  18. examples/bullet_hell/player_bullet.py +31 -0
  19. examples/doodle_jump/main.py +9 -0
  20. examples/doodle_jump/platforms.py +51 -0
  21. examples/doodle_jump/player.py +52 -0
  22. examples/fish/assets/bullet_hell/enemy.py +130 -0
  23. examples/fish/assets/bullet_hell/enemy_bullets.py +230 -0
  24. examples/fish/assets/bullet_hell/main.py +11 -0
  25. examples/fish/assets/bullet_hell/old_verisons/bullet_hell.py +379 -0
  26. examples/fish/assets/bullet_hell/old_verisons/enemy.py +226 -0
  27. examples/fish/assets/bullet_hell/old_verisons/game_start.py +6 -0
  28. examples/fish/assets/bullet_hell/old_verisons/main.py +50 -0
  29. examples/fish/assets/bullet_hell/old_verisons/player.py +76 -0
  30. examples/fish/assets/bullet_hell/player.py +89 -0
  31. examples/fish/assets/bullet_hell/player_bullets.py +34 -0
  32. examples/fish/assets/bullet_hell/setting.py +33 -0
  33. examples/fish/fish.py +67 -0
  34. examples/fish/main.py +4 -0
  35. examples/getting-started/step 1 - create a sprite/main.py +11 -0
  36. examples/getting-started/step 1 - create a sprite/player.py +5 -0
  37. examples/getting-started/step 2 - control a sprite/main.py +11 -0
  38. examples/getting-started/step 2 - control a sprite/player.py +42 -0
  39. examples/getting-started/step 3 - backdrops/main.py +17 -0
  40. examples/getting-started/step 3 - backdrops/player.py +33 -0
  41. examples/getting-started/step 4 - clone a sprite/enemy.py +53 -0
  42. examples/getting-started/step 4 - clone a sprite/main.py +17 -0
  43. examples/getting-started/step 4 - clone a sprite/player.py +32 -0
  44. examples/getting-started/step 4 - clone a sprite (simple)/enemy.py +42 -0
  45. examples/getting-started/step 4 - clone a sprite (simple)/main.py +17 -0
  46. examples/getting-started/step 4 - clone a sprite (simple)/player.py +32 -0
  47. examples/getting-started/step 5 - local variables/enemy.py +52 -0
  48. examples/getting-started/step 5 - local variables/main.py +17 -0
  49. examples/getting-started/step 5 - local variables/player.py +49 -0
  50. examples/getting-started/step 6 - shared variables/enemy.py +64 -0
  51. examples/getting-started/step 6 - shared variables/main.py +17 -0
  52. examples/getting-started/step 6 - shared variables/player.py +80 -0
  53. examples/getting-started/step 7 - Referencing other sprites/enemy.py +83 -0
  54. examples/getting-started/step 7 - Referencing other sprites/hearts.py +39 -0
  55. examples/getting-started/step 7 - Referencing other sprites/main.py +23 -0
  56. examples/getting-started/step 7 - Referencing other sprites/player.py +59 -0
  57. examples/getting-started/step 8 - sprite variables/enemy.py +98 -0
  58. examples/getting-started/step 8 - sprite variables/hearts.py +39 -0
  59. examples/getting-started/step 8 - sprite variables/main.py +22 -0
  60. examples/getting-started/step 8 - sprite variables/player.py +63 -0
  61. examples/getting-started/step 9 - messages/enemy.py +98 -0
  62. examples/getting-started/step 9 - messages/hearts.py +39 -0
  63. examples/getting-started/step 9 - messages/main.py +23 -0
  64. examples/getting-started/step 9 - messages/player.py +78 -0
  65. examples/perspective_background/main.py +14 -0
  66. examples/perspective_background/player.py +52 -0
  67. examples/perspective_background/trees.py +39 -0
  68. examples/simple_pong/ball.py +72 -0
  69. examples/simple_pong/left_paddle.py +36 -0
  70. examples/simple_pong/main.py +21 -0
  71. examples/simple_pong/right_paddle.py +37 -0
  72. examples/simple_pong/score_display.py +54 -0
  73. pyscratch/__init__.py +48 -0
  74. pyscratch/event.py +263 -0
  75. pyscratch/game_module.py +1589 -0
  76. pyscratch/helper.py +561 -0
  77. pyscratch/sprite.py +1920 -0
  78. pyscratch/tools/sprite_preview/left_panel/frame_preview_card.py +238 -0
  79. pyscratch/tools/sprite_preview/left_panel/frame_preview_panel.py +42 -0
  80. pyscratch/tools/sprite_preview/main.py +18 -0
  81. pyscratch/tools/sprite_preview/main_panel/animation_display.py +77 -0
  82. pyscratch/tools/sprite_preview/main_panel/frame_bin.py +33 -0
  83. pyscratch/tools/sprite_preview/main_panel/play_edit_ui.py +64 -0
  84. pyscratch/tools/sprite_preview/main_panel/set_as_sprite_folder.py +22 -0
  85. pyscratch/tools/sprite_preview/main_panel/sprite_edit_ui.py +174 -0
  86. pyscratch/tools/sprite_preview/main_panel/warning_message.py +25 -0
  87. pyscratch/tools/sprite_preview/right_panel/back_button.py +35 -0
  88. pyscratch/tools/sprite_preview/right_panel/cut_button.py +32 -0
  89. pyscratch/tools/sprite_preview/right_panel/cut_parameter_fitting.py +152 -0
  90. pyscratch/tools/sprite_preview/right_panel/cut_parameters.py +42 -0
  91. pyscratch/tools/sprite_preview/right_panel/file_display.py +84 -0
  92. pyscratch/tools/sprite_preview/right_panel/file_display_area.py +57 -0
  93. pyscratch/tools/sprite_preview/right_panel/spritesheet_view.py +262 -0
  94. pyscratch/tools/sprite_preview/right_panel/ss_select_corner.py +208 -0
  95. pyscratch/tools/sprite_preview/settings.py +14 -0
  96. pyscratch/tools/sprite_preview/utils/input_box.py +235 -0
  97. pyscratch/tools/sprite_preview/utils/render_wrapped_file_name.py +86 -0
  98. pyscratch_pysc-1.0.3.dist-info/METADATA +37 -0
  99. pyscratch_pysc-1.0.3.dist-info/RECORD +101 -0
  100. pyscratch_pysc-1.0.3.dist-info/WHEEL +5 -0
  101. pyscratch_pysc-1.0.3.dist-info/top_level.txt +3 -0
pyscratch/event.py ADDED
@@ -0,0 +1,263 @@
1
+ """
2
+ Everything in this module is directly under the pyscratch namespace.
3
+ For example, instead of doing `pysc.event.Timer`,
4
+ you can also directly do `pysc.Timer`.
5
+ """
6
+
7
+ from __future__ import annotations
8
+ from typing import Any, Callable, Dict, Generator, Generic, List, ParamSpec, Set, Tuple, TypeVar, Union, override
9
+ from types import GeneratorType, NoneType
10
+
11
+ import pygame
12
+ import pymunk
13
+ import numpy as np
14
+
15
+ P = ParamSpec('P')
16
+ """@private"""
17
+ T = TypeVar('T')
18
+ """@private"""
19
+
20
+
21
+ def _declare_callback_type(obj: Event, func: Callable[P, Union[NoneType, Generator[float, None, None]]]) -> Event[P]:
22
+ return obj
23
+
24
+
25
+ class Event(Generic[P]):
26
+ """
27
+ A low level Event class.
28
+ You **do not** need to create the Event object yourself.
29
+ They are instead returned by functions like `sprite.when_game_started()`
30
+
31
+ In no circumstances will you need to create your custom event. Always use the message event instead.
32
+ """
33
+
34
+ def __init__(self):
35
+ """@private"""
36
+
37
+ self.__triggers: List = []
38
+ self.__callbacks: List[Callable[P, Union[NoneType, Generator[float, None, None]]]] = []
39
+ self.__stay_active = True
40
+ self.__to_soft_remove = False
41
+ self.__generators: Dict[GeneratorType, float] = {}
42
+
43
+
44
+ #def add_handler(self, func: Callable[P, Union[NoneType, Generator[float, None, None]]]):
45
+ # use Any for the simplicity in the doc
46
+ def add_handler(self, func: Callable[P, Any]):
47
+ """
48
+ Add a handler function to this event.
49
+ When the event is triggered, the handler functions are called, taking in the parameters passed on by the triggers.
50
+ """
51
+ self.__callbacks.append(func)
52
+ return self
53
+
54
+
55
+ def remove(self):
56
+ """Schedule this event to be removed."""
57
+ self.__stay_active = False
58
+
59
+ def soft_remove(self):
60
+ """Schedule this event to be removed when all the generators (yield functions) finish"""
61
+ self.__to_soft_remove = True
62
+
63
+ @property
64
+ def stay_active(self) -> bool:
65
+ """Shows whether this event is removed or scheduled to be removed."""
66
+ return self.__stay_active
67
+
68
+
69
+
70
+ def trigger(self, *args: P.args, **kwargs: P.kwargs):
71
+ """
72
+ @private
73
+ Trigger the event. The parameters will be passed on to the event handlers.
74
+
75
+ You will not need to run this method ever.
76
+ """
77
+ self.__triggers.append((args, kwargs))
78
+
79
+ def _handle_all(self, current_t_ms):
80
+ while self._handle_one(current_t_ms):
81
+ pass
82
+
83
+ def _handle_one(self, current_t_ms):
84
+
85
+ if not len(self.__triggers):
86
+ return False
87
+
88
+ args, kwargs = self.__triggers.pop(0)
89
+
90
+ for cb in self.__callbacks:
91
+ ret = cb(*args, **kwargs) # type: ignore
92
+ if isinstance(ret, GeneratorType):
93
+
94
+ # just to schedule to run immediately
95
+ # actually run when self.generators_proceed is called
96
+ self.__generators[ret] = current_t_ms
97
+
98
+ return True
99
+
100
+ def _generators_proceed(self, current_t_ms):
101
+ to_remove = []
102
+
103
+ for g, t in self.__generators.items():
104
+ next_t = t
105
+ while next_t<=current_t_ms:
106
+ try:
107
+ next_t = next_t+next(g)*1000
108
+ self.__generators[g] = next_t
109
+ except StopIteration:
110
+ next_t = np.inf
111
+ to_remove.append(g)
112
+
113
+ self.__generators = {g:t for g, t in self.__generators.items() if not g in to_remove}
114
+ if not len(self.__generators) and self.__to_soft_remove:
115
+ self.remove()
116
+
117
+
118
+
119
+
120
+ class _ConditionInterface:
121
+ """
122
+ A low level Condition class.
123
+ You **do not** need to create the Condition object yourself.
124
+ """
125
+ def _check(self):
126
+ pass
127
+
128
+ def add_handler(self, callback: Callable[[int], Any]):
129
+ """
130
+ Add a handler function to this event.
131
+ When the event is triggered, the handler functions are called, taking in the parameters passed on by the triggers.
132
+ """
133
+ return self
134
+
135
+ def remove(self):
136
+ """Schedule this event to be removed."""
137
+ pass
138
+
139
+ def soft_remove(self):
140
+ """Schedule this event to be removed when all the generators (yield functions) finish"""
141
+ pass
142
+
143
+ @property
144
+ def stay_active(self) -> bool:
145
+ """Shows whether this event is removed or scheduled to be removed."""
146
+ return True
147
+
148
+ class Condition(_ConditionInterface):
149
+ def __init__(self, checker: Callable[[], bool] = lambda: False, repeats: Union[float, int]=1):
150
+ """@private"""
151
+ self.trigger = Event()
152
+ self.repeat_remains = repeats
153
+ self.checker = checker
154
+ self.__stay_active = True
155
+
156
+ def add_handler(self, callback: Callable[[int], Any]):
157
+ self.trigger.add_handler(callback)
158
+ return self
159
+
160
+ def remove(self):
161
+ self.__stay_active = False
162
+ self.trigger.remove()
163
+
164
+ def soft_remove(self):
165
+ self.__stay_active = False
166
+ self.trigger.soft_remove()
167
+
168
+ @property
169
+ def stay_active(self):
170
+ return self.__stay_active
171
+
172
+ def _check(self):
173
+ if self.checker() and self.repeat_remains:
174
+ self.repeat_remains -= 1
175
+ self.trigger.trigger(self.repeat_remains)
176
+
177
+ if not self.repeat_remains:
178
+ self.soft_remove()
179
+
180
+ def change_checker(self, checker= lambda: False):
181
+ """@private"""
182
+ self.checker = checker
183
+
184
+
185
+
186
+ class TimerCondition(_ConditionInterface):
187
+ def __init__(self, reset_period=np.inf, repeats=np.inf):
188
+ """
189
+ @private
190
+ """
191
+ self.trigger = Event()
192
+ self.repeat_remains = repeats
193
+ self.timer = Timer(reset_period=reset_period)
194
+ self.period = 0
195
+ self.__stay_active = True
196
+
197
+ def add_handler(self, callback: Callable[[int], Any]):
198
+ self.trigger.add_handler(callback)
199
+ return self
200
+
201
+ def remove(self):
202
+ self.__stay_active = False
203
+ self.trigger.remove()
204
+
205
+ def soft_remove(self):
206
+ self.__stay_active = False
207
+ self.trigger.soft_remove()
208
+
209
+ @property
210
+ def stay_active(self):
211
+ return self.__stay_active
212
+
213
+ def _check(self):
214
+ self.timer.read()
215
+ while (self.timer.n_period > self.period) and self.repeat_remains:
216
+ self.period += 1
217
+ self.repeat_remains -= 1
218
+ self.trigger.trigger(self.repeat_remains)
219
+
220
+ if not self.repeat_remains:
221
+ self.soft_remove()
222
+
223
+
224
+
225
+ class Timer:
226
+ """
227
+ Create a timer that resets every `reset_period` seconds.
228
+ """
229
+ def __init__(self, reset_period=np.inf):
230
+ """
231
+ Parameters
232
+ ---
233
+ reset_period: float
234
+ The reset period. Pass in np.inf for no reset
235
+ """
236
+ self._t0 = pygame.time.get_ticks()/1000
237
+ self.reset_period = reset_period
238
+ self.n_period = 0
239
+ """How many times the `reset_period` have passed"""
240
+
241
+ def read(self):
242
+ """
243
+ Read the timer.
244
+ """
245
+ dt = pygame.time.get_ticks()/1000 - self._t0
246
+ self.n_period = int(dt // self.reset_period)
247
+ return dt % self.reset_period
248
+
249
+ def full_reset(self):
250
+ """
251
+ Reset the timer and the `n_period`.
252
+ """
253
+ self.n_period = 0
254
+ self._t0 = pygame.time.get_ticks()/1000
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+