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.
- assets/bullet_hell/enemy.py +130 -0
- assets/bullet_hell/enemy_bullets.py +230 -0
- assets/bullet_hell/main.py +11 -0
- assets/bullet_hell/old_verisons/bullet_hell.py +379 -0
- assets/bullet_hell/old_verisons/enemy.py +226 -0
- assets/bullet_hell/old_verisons/game_start.py +6 -0
- assets/bullet_hell/old_verisons/main.py +50 -0
- assets/bullet_hell/old_verisons/player.py +76 -0
- assets/bullet_hell/player.py +89 -0
- assets/bullet_hell/player_bullets.py +34 -0
- assets/bullet_hell/setting.py +33 -0
- examples/animated_sprite/main.py +7 -0
- examples/animated_sprite/my_sprite.py +79 -0
- examples/bullet_hell/enemy.py +152 -0
- examples/bullet_hell/enemy_bullet.py +88 -0
- examples/bullet_hell/main.py +17 -0
- examples/bullet_hell/player.py +39 -0
- examples/bullet_hell/player_bullet.py +31 -0
- examples/doodle_jump/main.py +9 -0
- examples/doodle_jump/platforms.py +51 -0
- examples/doodle_jump/player.py +52 -0
- examples/fish/assets/bullet_hell/enemy.py +130 -0
- examples/fish/assets/bullet_hell/enemy_bullets.py +230 -0
- examples/fish/assets/bullet_hell/main.py +11 -0
- examples/fish/assets/bullet_hell/old_verisons/bullet_hell.py +379 -0
- examples/fish/assets/bullet_hell/old_verisons/enemy.py +226 -0
- examples/fish/assets/bullet_hell/old_verisons/game_start.py +6 -0
- examples/fish/assets/bullet_hell/old_verisons/main.py +50 -0
- examples/fish/assets/bullet_hell/old_verisons/player.py +76 -0
- examples/fish/assets/bullet_hell/player.py +89 -0
- examples/fish/assets/bullet_hell/player_bullets.py +34 -0
- examples/fish/assets/bullet_hell/setting.py +33 -0
- examples/fish/fish.py +67 -0
- examples/fish/main.py +4 -0
- examples/getting-started/step 1 - create a sprite/main.py +11 -0
- examples/getting-started/step 1 - create a sprite/player.py +5 -0
- examples/getting-started/step 2 - control a sprite/main.py +11 -0
- examples/getting-started/step 2 - control a sprite/player.py +42 -0
- examples/getting-started/step 3 - backdrops/main.py +17 -0
- examples/getting-started/step 3 - backdrops/player.py +33 -0
- examples/getting-started/step 4 - clone a sprite/enemy.py +53 -0
- examples/getting-started/step 4 - clone a sprite/main.py +17 -0
- examples/getting-started/step 4 - clone a sprite/player.py +32 -0
- examples/getting-started/step 4 - clone a sprite (simple)/enemy.py +42 -0
- examples/getting-started/step 4 - clone a sprite (simple)/main.py +17 -0
- examples/getting-started/step 4 - clone a sprite (simple)/player.py +32 -0
- examples/getting-started/step 5 - local variables/enemy.py +52 -0
- examples/getting-started/step 5 - local variables/main.py +17 -0
- examples/getting-started/step 5 - local variables/player.py +49 -0
- examples/getting-started/step 6 - shared variables/enemy.py +64 -0
- examples/getting-started/step 6 - shared variables/main.py +17 -0
- examples/getting-started/step 6 - shared variables/player.py +80 -0
- examples/getting-started/step 7 - Referencing other sprites/enemy.py +83 -0
- examples/getting-started/step 7 - Referencing other sprites/hearts.py +39 -0
- examples/getting-started/step 7 - Referencing other sprites/main.py +23 -0
- examples/getting-started/step 7 - Referencing other sprites/player.py +59 -0
- examples/getting-started/step 8 - sprite variables/enemy.py +98 -0
- examples/getting-started/step 8 - sprite variables/hearts.py +39 -0
- examples/getting-started/step 8 - sprite variables/main.py +22 -0
- examples/getting-started/step 8 - sprite variables/player.py +63 -0
- examples/getting-started/step 9 - messages/enemy.py +98 -0
- examples/getting-started/step 9 - messages/hearts.py +39 -0
- examples/getting-started/step 9 - messages/main.py +23 -0
- examples/getting-started/step 9 - messages/player.py +78 -0
- examples/perspective_background/main.py +14 -0
- examples/perspective_background/player.py +52 -0
- examples/perspective_background/trees.py +39 -0
- examples/simple_pong/ball.py +72 -0
- examples/simple_pong/left_paddle.py +36 -0
- examples/simple_pong/main.py +21 -0
- examples/simple_pong/right_paddle.py +37 -0
- examples/simple_pong/score_display.py +54 -0
- pyscratch/__init__.py +48 -0
- pyscratch/event.py +263 -0
- pyscratch/game_module.py +1589 -0
- pyscratch/helper.py +561 -0
- pyscratch/sprite.py +1920 -0
- pyscratch/tools/sprite_preview/left_panel/frame_preview_card.py +238 -0
- pyscratch/tools/sprite_preview/left_panel/frame_preview_panel.py +42 -0
- pyscratch/tools/sprite_preview/main.py +18 -0
- pyscratch/tools/sprite_preview/main_panel/animation_display.py +77 -0
- pyscratch/tools/sprite_preview/main_panel/frame_bin.py +33 -0
- pyscratch/tools/sprite_preview/main_panel/play_edit_ui.py +64 -0
- pyscratch/tools/sprite_preview/main_panel/set_as_sprite_folder.py +22 -0
- pyscratch/tools/sprite_preview/main_panel/sprite_edit_ui.py +174 -0
- pyscratch/tools/sprite_preview/main_panel/warning_message.py +25 -0
- pyscratch/tools/sprite_preview/right_panel/back_button.py +35 -0
- pyscratch/tools/sprite_preview/right_panel/cut_button.py +32 -0
- pyscratch/tools/sprite_preview/right_panel/cut_parameter_fitting.py +152 -0
- pyscratch/tools/sprite_preview/right_panel/cut_parameters.py +42 -0
- pyscratch/tools/sprite_preview/right_panel/file_display.py +84 -0
- pyscratch/tools/sprite_preview/right_panel/file_display_area.py +57 -0
- pyscratch/tools/sprite_preview/right_panel/spritesheet_view.py +262 -0
- pyscratch/tools/sprite_preview/right_panel/ss_select_corner.py +208 -0
- pyscratch/tools/sprite_preview/settings.py +14 -0
- pyscratch/tools/sprite_preview/utils/input_box.py +235 -0
- pyscratch/tools/sprite_preview/utils/render_wrapped_file_name.py +86 -0
- pyscratch_pysc-1.0.3.dist-info/METADATA +37 -0
- pyscratch_pysc-1.0.3.dist-info/RECORD +101 -0
- pyscratch_pysc-1.0.3.dist-info/WHEEL +5 -0
- pyscratch_pysc-1.0.3.dist-info/top_level.txt +3 -0
@@ -0,0 +1,238 @@
|
|
1
|
+
"""
|
2
|
+
broadcast messages:
|
3
|
+
order_change ((old, new))
|
4
|
+
preview_click(dict(surface=surface, order=order))
|
5
|
+
change_animation_done (frames: List)
|
6
|
+
|
7
|
+
|
8
|
+
receice messages:
|
9
|
+
change_animation
|
10
|
+
reload the animation from the animation path
|
11
|
+
remove and create the frame cards for this animation
|
12
|
+
|
13
|
+
shared_data:
|
14
|
+
scrolling_offset (read only)
|
15
|
+
animation_path
|
16
|
+
frame_card_list
|
17
|
+
"""
|
18
|
+
|
19
|
+
from typing import Dict, List
|
20
|
+
|
21
|
+
import numpy as np
|
22
|
+
import pyscratch as pysc
|
23
|
+
from pyscratch.sprite import Sprite
|
24
|
+
from settings import *
|
25
|
+
from pygame import Surface
|
26
|
+
from math import floor
|
27
|
+
from pathlib import Path
|
28
|
+
|
29
|
+
|
30
|
+
# Sprite Function: the frame preview card
|
31
|
+
FRAME_PREVIEW_MARGIN = 10
|
32
|
+
preview_width = LEFT_PANEL_WIDTH-FRAME_PREVIEW_MARGIN*2
|
33
|
+
preview_height = preview_width
|
34
|
+
|
35
|
+
def FramePreviewCard(surface:Surface, order):
|
36
|
+
|
37
|
+
preview_bg = pysc.create_rect_sprite(
|
38
|
+
(255, 255, 255),
|
39
|
+
preview_width,
|
40
|
+
preview_height
|
41
|
+
)
|
42
|
+
preview_bg['surface'] = surface
|
43
|
+
preview_bg['order'] = order
|
44
|
+
preview_bg.oob_limit = np.inf
|
45
|
+
|
46
|
+
preview_bg.set_draggable(True)
|
47
|
+
|
48
|
+
|
49
|
+
# set xy
|
50
|
+
ypos = FRAME_PREVIEW_MARGIN + order*(preview_height+FRAME_PREVIEW_MARGIN) + preview_height/2
|
51
|
+
|
52
|
+
xpos = LEFT_PANEL_WIDTH/2
|
53
|
+
preview_bg.set_xy((xpos, ypos))
|
54
|
+
preview_bg.y += pysc.game['scrolling_offset']
|
55
|
+
|
56
|
+
# display preview
|
57
|
+
image_margin = 20
|
58
|
+
fit = "horizontal" if surface.get_width() >= surface.get_height() else "vertical"
|
59
|
+
pv_surface = pysc.scale_to_fit_aspect(surface, (preview_width-image_margin, preview_height-image_margin ), fit)
|
60
|
+
preview_bg.draw(pv_surface, (preview_width/2, preview_height/2))
|
61
|
+
|
62
|
+
|
63
|
+
# send message on click
|
64
|
+
def on_click():
|
65
|
+
|
66
|
+
|
67
|
+
pysc.game.broadcast_message('preview_click', dict(surface=surface, order=order))
|
68
|
+
pysc.game.broadcast_message('show_bin', None)
|
69
|
+
|
70
|
+
|
71
|
+
preview_bg.when_this_sprite_clicked().add_handler(on_click)
|
72
|
+
|
73
|
+
|
74
|
+
# scrolling
|
75
|
+
def on_scrolling(offset):
|
76
|
+
preview_bg.y = ypos + offset
|
77
|
+
preview_bg.when_receive_message('scrolling').add_handler(on_scrolling)
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
# dragging
|
83
|
+
def on_mouse_release():
|
84
|
+
pysc.game.broadcast_message('hide_bin', None)
|
85
|
+
|
86
|
+
left_panel: pysc.Sprite = pysc.game['left_panel']
|
87
|
+
|
88
|
+
frame_card_list = pysc.game['frame_card_list']
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
new_order = ((preview_bg.y-pysc.game['scrolling_offset'])-preview_height/2-FRAME_PREVIEW_MARGIN)/(preview_height+FRAME_PREVIEW_MARGIN)
|
93
|
+
new_order = floor(new_order+0.5)
|
94
|
+
|
95
|
+
|
96
|
+
preview_bg.x = xpos
|
97
|
+
|
98
|
+
preview_bg.y = ypos + pysc.game['scrolling_offset']
|
99
|
+
|
100
|
+
new_order = min(max(new_order, 0), len(frame_card_list)-1)
|
101
|
+
|
102
|
+
if not (to_remove := pysc.game['frame_bin'].is_touching_mouse()):
|
103
|
+
if not left_panel.is_touching(preview_bg): return
|
104
|
+
if new_order == order: return
|
105
|
+
|
106
|
+
|
107
|
+
print(f"{order} -> {new_order}")
|
108
|
+
|
109
|
+
first_half = frame_card_list[:order]
|
110
|
+
second_half = frame_card_list[order+1:] if (order+1)<len(frame_card_list) else []
|
111
|
+
|
112
|
+
temp = first_half + second_half
|
113
|
+
|
114
|
+
#print([c['order'] for c in temp] )
|
115
|
+
|
116
|
+
if not to_remove:
|
117
|
+
temp = temp[:new_order] + [preview_bg] + (temp[new_order:] if (new_order)<len(temp) else [])
|
118
|
+
|
119
|
+
#print([c['order'] for c in temp] )
|
120
|
+
|
121
|
+
write_new_frame_list([f['surface'] for f in temp])
|
122
|
+
|
123
|
+
# update
|
124
|
+
pysc.game.broadcast_message('change_animation', pysc.game['animation_path'])
|
125
|
+
|
126
|
+
pysc.game.when_this_sprite_click_released(preview_bg).add_handler(on_mouse_release)
|
127
|
+
|
128
|
+
return preview_bg
|
129
|
+
|
130
|
+
|
131
|
+
def on_cut_sprite_frame_drop(data):
|
132
|
+
if not 'animation_path' in pysc.game.shared_data:
|
133
|
+
pysc.game.broadcast_message('warning', "Animation not selected yet.")
|
134
|
+
return
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
sprite: pysc.Sprite = data['sprite']
|
139
|
+
surface: Surface = data['surface']
|
140
|
+
mos_x, mos_y = data['position']
|
141
|
+
frame_card_list = pysc.game['frame_card_list']
|
142
|
+
|
143
|
+
|
144
|
+
left_panel: pysc.Sprite = pysc.game['left_panel']
|
145
|
+
|
146
|
+
if not left_panel.is_touching_mouse(): return
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
order = ((mos_y-pysc.game['scrolling_offset'])-preview_height/2-FRAME_PREVIEW_MARGIN)/(preview_height+FRAME_PREVIEW_MARGIN)
|
151
|
+
order = floor(order+0.5)
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
frame_card_list = pysc.game['frame_card_list']
|
156
|
+
|
157
|
+
first_half = frame_card_list[:order]
|
158
|
+
second_half = frame_card_list[order:] if (order)<len(frame_card_list) else []
|
159
|
+
|
160
|
+
frame_list = [f['surface'] for f in first_half] +[surface]+ [f['surface'] for f in second_half]
|
161
|
+
|
162
|
+
write_new_frame_list(frame_list)
|
163
|
+
|
164
|
+
# update
|
165
|
+
pysc.game.broadcast_message('change_animation', pysc.game['animation_path'])
|
166
|
+
|
167
|
+
sprite.x = sprite['x']
|
168
|
+
sprite.y = sprite['y']
|
169
|
+
|
170
|
+
|
171
|
+
pysc.game.when_receive_message('cut_sprite_frame_drop').add_handler(on_cut_sprite_frame_drop)
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
# helper function
|
177
|
+
import shutil
|
178
|
+
def write_new_frame_list(frame_list: List[Surface]):
|
179
|
+
# TODO: frame quality degrade over time?
|
180
|
+
temp_folder = Path('temp')
|
181
|
+
temp_folder.mkdir(exist_ok=True)
|
182
|
+
shutil.rmtree(temp_folder)
|
183
|
+
temp_folder.mkdir()
|
184
|
+
|
185
|
+
suffix = 'png' # TODO: allow changing suffix
|
186
|
+
for i, f in enumerate(frame_list):
|
187
|
+
pygame.image.save(f, temp_folder/f"{i}.{suffix}")
|
188
|
+
|
189
|
+
shutil.rmtree(pysc.game['animation_path'])
|
190
|
+
shutil.copytree(temp_folder, pysc.game['animation_path'])
|
191
|
+
shutil.rmtree(temp_folder)
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
# event: when there is a change to the animation
|
196
|
+
# reload the animation from the animation path
|
197
|
+
pysc.game['frame_card_list'] = []
|
198
|
+
def on_change_animation(path: Path):
|
199
|
+
|
200
|
+
#pysc.game['scrolling_offset'] = 0
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
pysc.game['animation_path'] = path
|
205
|
+
for c in pysc.game['frame_card_list']:
|
206
|
+
c.remove()
|
207
|
+
pysc.game['frame_card_list'] = []
|
208
|
+
|
209
|
+
def extract_images(path: Path):
|
210
|
+
index2image: Dict[int, pygame.Surface] = {}
|
211
|
+
|
212
|
+
for f in path.iterdir():
|
213
|
+
if f.is_dir():
|
214
|
+
continue
|
215
|
+
|
216
|
+
if not f.stem.isdigit():
|
217
|
+
print(f'skipping: {f.name}')
|
218
|
+
continue
|
219
|
+
index2image[int(f.stem)] = pygame.image.load(f).convert_alpha()
|
220
|
+
|
221
|
+
return [index2image[i] for i in sorted(index2image.keys())]
|
222
|
+
|
223
|
+
try:
|
224
|
+
frames = extract_images(path)
|
225
|
+
except:
|
226
|
+
print('invalid folder structure.')
|
227
|
+
return
|
228
|
+
|
229
|
+
|
230
|
+
for i, f in enumerate(frames):
|
231
|
+
pysc.game.shared_data['frame_card_list'].append(
|
232
|
+
FramePreviewCard(f, i)
|
233
|
+
)
|
234
|
+
|
235
|
+
pysc.game.broadcast_message("change_animation_done", frames)
|
236
|
+
|
237
|
+
|
238
|
+
pysc.game.when_receive_message('change_animation').add_handler(on_change_animation)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
"""
|
2
|
+
broadcast messages:
|
3
|
+
scrolling (scrolling_offset)
|
4
|
+
|
5
|
+
shared_data:
|
6
|
+
scrolling_offset
|
7
|
+
"""
|
8
|
+
|
9
|
+
|
10
|
+
from pathlib import Path
|
11
|
+
from typing import Dict
|
12
|
+
|
13
|
+
from pygame import Surface
|
14
|
+
import pyscratch as pysc
|
15
|
+
from settings import *
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
# Sprite: the panel (the background of the preview frames)
|
20
|
+
PANEL_BG_COLOUR = 199, 207, 224
|
21
|
+
panel = pysc.create_rect_sprite(
|
22
|
+
PANEL_BG_COLOUR,
|
23
|
+
LEFT_PANEL_WIDTH,
|
24
|
+
SCREEN_HEIGHT# - PANEL_MARGIN*2
|
25
|
+
)
|
26
|
+
panel.set_xy((LEFT_PANEL_WIDTH/2, SCREEN_HEIGHT/2))
|
27
|
+
|
28
|
+
# event: scrolling
|
29
|
+
pysc.game['scrolling_offset'] = 0
|
30
|
+
def on_mouse_scroll(updown):
|
31
|
+
if not panel.is_touching_mouse(): return
|
32
|
+
if updown == 'up':
|
33
|
+
pysc.game['scrolling_offset'] += 10
|
34
|
+
else:
|
35
|
+
|
36
|
+
pysc.game['scrolling_offset'] -= 10
|
37
|
+
|
38
|
+
pysc.game.broadcast_message("scrolling", pysc.game['scrolling_offset'])
|
39
|
+
|
40
|
+
pysc.game.when_mouse_scroll().add_handler(on_mouse_scroll)
|
41
|
+
pysc.game['left_panel'] = panel
|
42
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
import pyscratch as pysc
|
3
|
+
from settings import *
|
4
|
+
|
5
|
+
from right_panel import file_display_area, spritesheet_view, cut_parameters, back_button, cut_button, ss_select_corner, cut_parameter_fitting
|
6
|
+
from main_panel import sprite_edit_ui, play_edit_ui, animation_display, frame_bin, set_as_sprite_folder, warning_message
|
7
|
+
from left_panel import frame_preview_card, frame_preview_panel
|
8
|
+
|
9
|
+
bg = pysc.create_rect((221, 221, 221), SCREEN_WIDTH, SCREEN_HEIGHT)
|
10
|
+
pysc.game.update_screen_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
|
11
|
+
pysc.game.set_backdrops([bg])
|
12
|
+
pysc.game.switch_backdrop(0)
|
13
|
+
|
14
|
+
pysc.game.broadcast_message('folder_update', Path('assets'))
|
15
|
+
pysc.game.broadcast_message('cut_or_nav_mode_change', 'nav')
|
16
|
+
#pysc.game.broadcast_message('change_sprite_selection', Path('./testing_assets/cat'))
|
17
|
+
|
18
|
+
pysc.game.start(30)
|
@@ -0,0 +1,77 @@
|
|
1
|
+
"""
|
2
|
+
shared_data:
|
3
|
+
display_sprite
|
4
|
+
scale_factor
|
5
|
+
frame_interval
|
6
|
+
is_playing
|
7
|
+
|
8
|
+
receive messages:
|
9
|
+
preview_click
|
10
|
+
change the frame of the display sprite when the preview is clicked
|
11
|
+
|
12
|
+
scale_factor_change
|
13
|
+
change the scale of the display sprite
|
14
|
+
|
15
|
+
change_animation_done
|
16
|
+
destory and create the display sprite for a new animation
|
17
|
+
"""
|
18
|
+
|
19
|
+
from pathlib import Path
|
20
|
+
from typing import Dict
|
21
|
+
|
22
|
+
from pygame import Surface
|
23
|
+
import pyscratch as pysc
|
24
|
+
from settings import *
|
25
|
+
|
26
|
+
|
27
|
+
pysc.game['display_sprite'] = None
|
28
|
+
|
29
|
+
|
30
|
+
def create_display_sprite(frames):
|
31
|
+
|
32
|
+
#frame_list = [c['surface'] for c in pysc.game['frame_card_list']]
|
33
|
+
#print(frames)
|
34
|
+
if display_sprite:=pysc.game['display_sprite']:
|
35
|
+
display_sprite.remove()
|
36
|
+
x, y = display_sprite.x, display_sprite.y
|
37
|
+
else:
|
38
|
+
x, y = 350, 200
|
39
|
+
|
40
|
+
if not len(frames):
|
41
|
+
pysc.game['display_sprite'] = None
|
42
|
+
return
|
43
|
+
|
44
|
+
|
45
|
+
sprite = pysc.Sprite({'always':frames})
|
46
|
+
sprite.set_xy((x, y))
|
47
|
+
|
48
|
+
sprite.set_draggable(True)
|
49
|
+
|
50
|
+
if pysc.game['scale_factor']:
|
51
|
+
sprite.set_scale(pysc.game['scale_factor'])
|
52
|
+
|
53
|
+
pysc.game['display_sprite'] = sprite
|
54
|
+
|
55
|
+
def play(_):
|
56
|
+
#TODO: if the user put a big value in frame_interval, and change it back to a small one
|
57
|
+
# the animation will wait for the big frame_interval until it comes back again
|
58
|
+
while True:
|
59
|
+
itv = pysc.game['frame_interval']
|
60
|
+
if pysc.game['is_playing'] and itv:
|
61
|
+
sprite.next_frame()
|
62
|
+
yield itv if itv else 0.1
|
63
|
+
|
64
|
+
sprite.when_timer_above(0).add_handler(play)
|
65
|
+
|
66
|
+
|
67
|
+
def on_scale_factor_change(scale):
|
68
|
+
print(scale)
|
69
|
+
if scale:
|
70
|
+
sprite.set_scale(scale)
|
71
|
+
|
72
|
+
sprite.when_receive_message("scale_factor_change").add_handler(on_scale_factor_change)
|
73
|
+
sprite.when_receive_message('preview_click').add_handler(lambda d: sprite.set_frame(d['order']))
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
pysc.game.when_receive_message("change_animation_done").add_handler(create_display_sprite)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
"""
|
2
|
+
msg in:
|
3
|
+
show_bin
|
4
|
+
hide_bin
|
5
|
+
|
6
|
+
shared data
|
7
|
+
frame_bin
|
8
|
+
"""
|
9
|
+
|
10
|
+
|
11
|
+
import pyscratch as pysc
|
12
|
+
from settings import *
|
13
|
+
|
14
|
+
|
15
|
+
frame_bin = pysc.create_rect_sprite((255, 127, 127), 100, 100)
|
16
|
+
frame_bin.write_text("bin", DEFAULT_FONT48, offset=(50, 50))
|
17
|
+
|
18
|
+
def set_xy():
|
19
|
+
|
20
|
+
container = pysc.game['main_bottom_panel']
|
21
|
+
|
22
|
+
frame_bin.hide()
|
23
|
+
frame_bin.lock_to(container, (0,0))
|
24
|
+
frame_bin.x = 0
|
25
|
+
frame_bin.y = 0
|
26
|
+
|
27
|
+
frame_bin.when_game_start().add_handler(set_xy)
|
28
|
+
|
29
|
+
|
30
|
+
frame_bin.when_receive_message('show_bin').add_handler(lambda d: frame_bin.show())
|
31
|
+
frame_bin.when_receive_message('hide_bin').add_handler(lambda d: frame_bin.hide())
|
32
|
+
|
33
|
+
pysc.game['frame_bin'] = frame_bin
|
@@ -0,0 +1,64 @@
|
|
1
|
+
from utils.input_box import IntegerInputBox, FloatInputBoxVerticallyLabel
|
2
|
+
import pyscratch as pysc
|
3
|
+
from settings import *
|
4
|
+
frame_itv = FloatInputBoxVerticallyLabel("frame_interval", default_value="0.2")
|
5
|
+
|
6
|
+
def set_xy():
|
7
|
+
container = pysc.game['main_bottom_panel']
|
8
|
+
frame_itv.lock_to(container, (0,0))
|
9
|
+
frame_itv.set_xy((200, 30))
|
10
|
+
|
11
|
+
frame_itv.when_game_start().add_handler(
|
12
|
+
set_xy
|
13
|
+
)
|
14
|
+
|
15
|
+
def new_switch(text0, text1, data_key):
|
16
|
+
container = pysc.game.shared_data['main_bottom_panel']
|
17
|
+
container_width, container_height = pysc.game.shared_data['main_bottom_size']
|
18
|
+
|
19
|
+
button_w, button_h = 80, 50
|
20
|
+
button = pysc.create_rect_sprite((221, 221, 221), button_w, button_h)
|
21
|
+
|
22
|
+
pysc.game.shared_data[data_key] = False
|
23
|
+
button.write_text(text0, DEFAULT_FONT48, colour=(0,0,0), offset=(button_w/2, button_h/2))
|
24
|
+
|
25
|
+
def on_click():
|
26
|
+
pysc.game.shared_data[data_key] = not pysc.game.shared_data[data_key]
|
27
|
+
|
28
|
+
if pysc.game.shared_data[data_key]:
|
29
|
+
button.write_text(text1, DEFAULT_FONT48, colour=(0,0,0), offset=(button_w/2, button_h/2))
|
30
|
+
else:
|
31
|
+
button.write_text(text0, DEFAULT_FONT48, colour=(0,0,0), offset=(button_w/2, button_h/2))
|
32
|
+
|
33
|
+
button.when_this_sprite_clicked().add_handler(on_click)
|
34
|
+
|
35
|
+
|
36
|
+
button.lock_to(container, (-(container_width-button_w)/2, -(container_height-button_h)/2), reset_xy=True)
|
37
|
+
return button
|
38
|
+
|
39
|
+
|
40
|
+
def create_play_button():
|
41
|
+
container = pysc.game.shared_data['main_bottom_panel']
|
42
|
+
|
43
|
+
play_button = new_switch('Play','Pause', 'is_playing')
|
44
|
+
play_button.lock_to(container, (0,0))
|
45
|
+
|
46
|
+
play_button.set_xy((0, 70))
|
47
|
+
|
48
|
+
pysc.game.when_game_start().add_handler(create_play_button)
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
scale_factor_input = FloatInputBoxVerticallyLabel("scale_factor", "scale_factor_change", default_value="1")
|
55
|
+
|
56
|
+
def set_xy2():
|
57
|
+
container = pysc.game.shared_data['main_bottom_panel']
|
58
|
+
scale_factor_input.lock_to(container, (0,0))
|
59
|
+
scale_factor_input.set_xy((200, 120))
|
60
|
+
|
61
|
+
scale_factor_input.when_game_start().add_handler(
|
62
|
+
set_xy2
|
63
|
+
)
|
64
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from utils.input_box import IntegerInputBox, FloatInputBoxVerticallyLabel
|
2
|
+
import pyscratch as pysc
|
3
|
+
from settings import *
|
4
|
+
|
5
|
+
button = pysc.create_rect_sprite((150, 150, 150), 220, 50)
|
6
|
+
button.write_text('Set current folder as sprite', DEFAULT_FONT24, offset=(110, 25))
|
7
|
+
|
8
|
+
def set_xy():
|
9
|
+
container = pysc.game['main_bottom_panel']
|
10
|
+
button.lock_to(container, (0,0))
|
11
|
+
button.x = 0
|
12
|
+
button.y = 0
|
13
|
+
|
14
|
+
button.when_game_start().add_handler(set_xy)
|
15
|
+
|
16
|
+
|
17
|
+
def on_click():
|
18
|
+
pysc.game.broadcast_message('change_sprite_selection', pysc.game['path'])
|
19
|
+
pass
|
20
|
+
|
21
|
+
|
22
|
+
button.when_this_sprite_clicked().add_handler(on_click)
|
@@ -0,0 +1,174 @@
|
|
1
|
+
"""
|
2
|
+
shared_data
|
3
|
+
animation_dict (order -> animation selection button)
|
4
|
+
sprite_folder_path
|
5
|
+
path (read): navigation path
|
6
|
+
main_bottom_size (read)
|
7
|
+
main_bottom_panel (read)
|
8
|
+
|
9
|
+
broadcast messages:
|
10
|
+
folder_update (navigation path)
|
11
|
+
change_sprite_selection (path of the sprite folder)
|
12
|
+
change_animation (path of the animation folder)
|
13
|
+
|
14
|
+
|
15
|
+
receive messages:
|
16
|
+
change_sprite_selection
|
17
|
+
change the animation panel when another sprite is selected
|
18
|
+
"""
|
19
|
+
|
20
|
+
|
21
|
+
from pathlib import Path
|
22
|
+
from typing import cast
|
23
|
+
import pyscratch as pysc
|
24
|
+
from settings import *
|
25
|
+
|
26
|
+
container_width = SCREEN_WIDTH - LEFT_PANEL_WIDTH - RIGHT_PANEL_WIDTH - PANEL_MARGIN*3
|
27
|
+
container_height = 300
|
28
|
+
|
29
|
+
# container
|
30
|
+
container = pysc.create_rect_sprite((230, 230, 230), container_width, container_height)
|
31
|
+
container.x = container_width/2+LEFT_PANEL_WIDTH+PANEL_MARGIN
|
32
|
+
container.y = SCREEN_HEIGHT-container_height/2-PANEL_MARGIN
|
33
|
+
pysc.game['main_bottom_panel'] = container
|
34
|
+
pysc.game['main_bottom_size'] = container_width, container_height
|
35
|
+
|
36
|
+
# sprite function
|
37
|
+
def NewButton(text):
|
38
|
+
button_w, button_h = 150, 50
|
39
|
+
button = pysc.create_rect_sprite((221, 221, 221), button_w, button_h)
|
40
|
+
button.write_text(text, DEFAULT_FONT48, colour=(0,0,0), offset=(button_w/2, button_h/2))
|
41
|
+
button.lock_to(container, (-(container_width-button_w)/2, -(container_height-button_h)/2), reset_xy=True)
|
42
|
+
return button
|
43
|
+
|
44
|
+
|
45
|
+
# sprite: add sprite button
|
46
|
+
add_sprite_button = NewButton("New Sprite")
|
47
|
+
add_sprite_button.y=10
|
48
|
+
add_sprite_button.x=200
|
49
|
+
|
50
|
+
# event: the click of the add sprite button
|
51
|
+
def on_click1():
|
52
|
+
folder_path: Path = pysc.game.shared_data['path']
|
53
|
+
|
54
|
+
c = 0
|
55
|
+
while True:
|
56
|
+
|
57
|
+
new_folder = (folder_path / f"unnamed_sprite_{c}")
|
58
|
+
if not new_folder.exists():
|
59
|
+
new_folder.mkdir()
|
60
|
+
break
|
61
|
+
else:
|
62
|
+
c+=1
|
63
|
+
pysc.game.broadcast_message('folder_update', folder_path)
|
64
|
+
pysc.game.broadcast_message('cut_or_nav_mode_change', 'nav')
|
65
|
+
pysc.game.broadcast_message('change_sprite_selection', new_folder)
|
66
|
+
|
67
|
+
add_sprite_button.when_this_sprite_clicked().add_handler(on_click1)
|
68
|
+
|
69
|
+
|
70
|
+
# sprite function: animation selection
|
71
|
+
def AnimationSelection(order, path):
|
72
|
+
|
73
|
+
|
74
|
+
w, h = 120, 30
|
75
|
+
on_select = pysc.create_rect((150,150, 150), w, h)
|
76
|
+
not_on_select = pysc.create_rect((127, 127, 127), w, h)
|
77
|
+
sprite = pysc.Sprite(dict(on_select=[on_select], not_on_select=[not_on_select]))
|
78
|
+
|
79
|
+
sprite.lock_to(container, (-(container_width-w)/2, -(container_height-h)/2))
|
80
|
+
sprite.x = 3
|
81
|
+
sprite.y = order*(h+3)+3
|
82
|
+
|
83
|
+
sprite.set_animation('on_select')
|
84
|
+
sprite.write_text(path.stem, DEFAULT_FONT24, offset=(w/2, h/2))
|
85
|
+
|
86
|
+
sprite.set_animation('not_on_select')
|
87
|
+
sprite.write_text(path.stem, DEFAULT_FONT24, offset=(w/2, h/2))
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
def on_click():
|
92
|
+
sprite.set_animation('on_select')
|
93
|
+
|
94
|
+
pysc.game.broadcast_message('change_animation', path)
|
95
|
+
pysc.game.broadcast_message('deselect', sprite)
|
96
|
+
|
97
|
+
|
98
|
+
sprite.when_this_sprite_clicked().add_handler(on_click)
|
99
|
+
|
100
|
+
|
101
|
+
def on_deselect(s):
|
102
|
+
if not sprite is s:
|
103
|
+
sprite.set_animation('not_on_select')
|
104
|
+
|
105
|
+
sprite.when_receive_message('deselect').add_handler(on_deselect)
|
106
|
+
|
107
|
+
return sprite
|
108
|
+
|
109
|
+
# event: msg: change_sprite_selection:
|
110
|
+
# remove and create the animation buttons when sprite change
|
111
|
+
pysc.game['animation_dict'] = {}
|
112
|
+
def on_msg_change_sprite_selection(sprite_folder:Path):
|
113
|
+
"""
|
114
|
+
change the animation selection buttons
|
115
|
+
"""
|
116
|
+
|
117
|
+
pysc.game['sprite_folder_path'] = sprite_folder
|
118
|
+
|
119
|
+
#pysc.game['frame_dict'] =
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
# remove all the old buttons
|
124
|
+
for k, v in pysc.game['animation_dict'].items():
|
125
|
+
v.remove()
|
126
|
+
pysc.game['animation_dict'] = {}
|
127
|
+
|
128
|
+
animation_dict = pysc.game['animation_dict']
|
129
|
+
|
130
|
+
|
131
|
+
# add the new buttons
|
132
|
+
c = 0
|
133
|
+
for f in sprite_folder.iterdir():
|
134
|
+
if f.is_dir():
|
135
|
+
animation_dict[c] = AnimationSelection(c, f)
|
136
|
+
c+=1
|
137
|
+
|
138
|
+
pysc.game.when_receive_message("change_sprite_selection").add_handler(on_msg_change_sprite_selection)
|
139
|
+
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
# sprite: add animation button
|
144
|
+
add_animation_button = NewButton("New Animation")
|
145
|
+
add_animation_button.x = 370
|
146
|
+
add_animation_button.y = 10
|
147
|
+
|
148
|
+
# event: click of the add animation button
|
149
|
+
def on_click2():
|
150
|
+
|
151
|
+
|
152
|
+
if not (folder_path:= pysc.game.shared_data.get('sprite_folder_path')):
|
153
|
+
pysc.game.broadcast_message('warning', "Sprite folder not selected yet")
|
154
|
+
return
|
155
|
+
|
156
|
+
folder_path = cast(Path, folder_path)
|
157
|
+
c = 0
|
158
|
+
while True:
|
159
|
+
|
160
|
+
|
161
|
+
new_folder = (folder_path / f"animation_{c}")
|
162
|
+
if not new_folder.exists():
|
163
|
+
new_folder.mkdir()
|
164
|
+
break
|
165
|
+
else:
|
166
|
+
c+=1
|
167
|
+
|
168
|
+
pysc.game.broadcast_message('folder_update', pysc.game.shared_data['path'])
|
169
|
+
|
170
|
+
# no actual change. just to trigger the update
|
171
|
+
pysc.game.broadcast_message('change_sprite_selection', folder_path)
|
172
|
+
|
173
|
+
|
174
|
+
add_animation_button.when_this_sprite_clicked().add_handler(on_click2)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from utils.render_wrapped_file_name import render_wrapped_file_name
|
2
|
+
import pyscratch as pysc
|
3
|
+
from settings import *
|
4
|
+
|
5
|
+
w, h = 400, 100
|
6
|
+
message_display = pysc.create_rect_sprite((255, 255, 255), w, h)
|
7
|
+
message_display.hide()
|
8
|
+
ori_xy = 200, 200
|
9
|
+
message_display.set_draggable(True)
|
10
|
+
|
11
|
+
def on_warning_message(message):
|
12
|
+
|
13
|
+
message_display.show()
|
14
|
+
message_display.set_xy(ori_xy)
|
15
|
+
txt = render_wrapped_file_name(message, 200, DEFAULT_FONT24, color=(255,0,0))
|
16
|
+
message_display.draw(txt, offset=(w/2, h/2))
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
message_display.when_receive_message('warning').add_handler(on_warning_message)
|
21
|
+
|
22
|
+
def on_click():
|
23
|
+
message_display.hide()
|
24
|
+
|
25
|
+
message_display.when_this_sprite_clicked().add_handler(on_click)
|