pyscratch-pysc 1.0.3__py3-none-any.whl → 2.0.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.
- assets/startup-assets/tutorial-steps/1-create-sprites/main.py +10 -0
- assets/startup-assets/tutorial-steps/1-create-sprites/player.py +5 -0
- assets/startup-assets/tutorial-steps/1-create-sprites-task/enemy.py +4 -0
- assets/startup-assets/tutorial-steps/1-create-sprites-task/main.py +11 -0
- assets/startup-assets/tutorial-steps/1-create-sprites-task/player.py +5 -0
- assets/startup-assets/tutorial-steps/2-basic-events/enemy.py +4 -0
- assets/startup-assets/tutorial-steps/2-basic-events/main.py +11 -0
- assets/startup-assets/tutorial-steps/2-basic-events/player.py +31 -0
- assets/startup-assets/tutorial-steps/2-basic-events-task1/enemy.py +4 -0
- assets/startup-assets/tutorial-steps/2-basic-events-task1/main.py +11 -0
- assets/startup-assets/tutorial-steps/2-basic-events-task1/player.py +23 -0
- assets/startup-assets/tutorial-steps/2-basic-events-task2/enemy.py +14 -0
- assets/startup-assets/tutorial-steps/2-basic-events-task2/main.py +11 -0
- assets/startup-assets/tutorial-steps/2-basic-events-task2/player.py +23 -0
- assets/startup-assets/tutorial-steps/3-loops-conditions/enemy.py +14 -0
- assets/startup-assets/tutorial-steps/3-loops-conditions/main.py +11 -0
- assets/startup-assets/tutorial-steps/3-loops-conditions/player.py +23 -0
- assets/startup-assets/tutorial-steps/3-loops-conditions-task1/enemy.py +14 -0
- assets/startup-assets/tutorial-steps/3-loops-conditions-task1/main.py +11 -0
- assets/startup-assets/tutorial-steps/3-loops-conditions-task1/player.py +34 -0
- assets/startup-assets/tutorial-steps/3-loops-conditions-task2/enemy.py +23 -0
- assets/startup-assets/tutorial-steps/3-loops-conditions-task2/main.py +11 -0
- assets/startup-assets/tutorial-steps/3-loops-conditions-task2/player.py +41 -0
- assets/startup-assets/tutorial-steps/4-variables/enemy.py +23 -0
- assets/startup-assets/tutorial-steps/4-variables/main.py +11 -0
- assets/startup-assets/tutorial-steps/4-variables/player.py +59 -0
- assets/startup-assets/tutorial-steps/5-sprite-object/enemy.py +19 -0
- assets/startup-assets/tutorial-steps/5-sprite-object/main.py +11 -0
- assets/startup-assets/tutorial-steps/5-sprite-object/player.py +20 -0
- assets/startup-assets/tutorial-steps/5-sprite-object-task1/enemy.py +19 -0
- assets/startup-assets/tutorial-steps/5-sprite-object-task1/main.py +11 -0
- assets/startup-assets/tutorial-steps/5-sprite-object-task1/player.py +38 -0
- assets/startup-assets/tutorial-steps/5-sprite-object-task2/enemy.py +20 -0
- assets/startup-assets/tutorial-steps/5-sprite-object-task2/main.py +11 -0
- assets/startup-assets/tutorial-steps/5-sprite-object-task2/player.py +58 -0
- assets/startup-assets/tutorial-steps/6-referencing-sprites/enemy.py +32 -0
- assets/startup-assets/tutorial-steps/6-referencing-sprites/main.py +11 -0
- assets/startup-assets/tutorial-steps/6-referencing-sprites/player.py +59 -0
- assets/startup-assets/tutorial-steps/6-referencing-sprites-task/enemy.py +37 -0
- assets/startup-assets/tutorial-steps/6-referencing-sprites-task/main.py +11 -0
- assets/startup-assets/tutorial-steps/6-referencing-sprites-task/player.py +60 -0
- assets/startup-assets/tutorial-steps/7-parameterised-events/enemy.py +37 -0
- assets/startup-assets/tutorial-steps/7-parameterised-events/main.py +11 -0
- assets/startup-assets/tutorial-steps/7-parameterised-events/player.py +83 -0
- assets/startup-assets/tutorial-steps/7-parameterised-events-msg/enemy.py +37 -0
- assets/startup-assets/tutorial-steps/7-parameterised-events-msg/main.py +11 -0
- assets/startup-assets/tutorial-steps/7-parameterised-events-msg/player.py +86 -0
- assets/startup-assets/tutorial-steps/7-parameterised-events-task/enemy.py +35 -0
- assets/startup-assets/tutorial-steps/7-parameterised-events-task/main.py +11 -0
- assets/startup-assets/tutorial-steps/7-parameterised-events-task/player.py +86 -0
- assets/startup-assets/tutorial-steps/8-backdrop-music/enemy.py +35 -0
- assets/startup-assets/tutorial-steps/8-backdrop-music/main.py +11 -0
- assets/startup-assets/tutorial-steps/8-backdrop-music/player.py +86 -0
- assets/startup-assets/tutorial-steps/9-polish/enemy.py +39 -0
- assets/startup-assets/tutorial-steps/9-polish/enemy_red.py +40 -0
- assets/startup-assets/tutorial-steps/9-polish/main.py +12 -0
- assets/startup-assets/tutorial-steps/9-polish/player.py +119 -0
- examples/fish/assets/startup-assets/tutorial-steps/1-create-sprites/main.py +10 -0
- examples/fish/assets/startup-assets/tutorial-steps/1-create-sprites/player.py +5 -0
- examples/fish/assets/startup-assets/tutorial-steps/1-create-sprites-task/enemy.py +4 -0
- examples/fish/assets/startup-assets/tutorial-steps/1-create-sprites-task/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/1-create-sprites-task/player.py +5 -0
- examples/fish/assets/startup-assets/tutorial-steps/2-basic-events/enemy.py +4 -0
- examples/fish/assets/startup-assets/tutorial-steps/2-basic-events/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/2-basic-events/player.py +31 -0
- examples/fish/assets/startup-assets/tutorial-steps/2-basic-events-task1/enemy.py +4 -0
- examples/fish/assets/startup-assets/tutorial-steps/2-basic-events-task1/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/2-basic-events-task1/player.py +23 -0
- examples/fish/assets/startup-assets/tutorial-steps/2-basic-events-task2/enemy.py +14 -0
- examples/fish/assets/startup-assets/tutorial-steps/2-basic-events-task2/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/2-basic-events-task2/player.py +23 -0
- examples/fish/assets/startup-assets/tutorial-steps/3-loops-conditions/enemy.py +14 -0
- examples/fish/assets/startup-assets/tutorial-steps/3-loops-conditions/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/3-loops-conditions/player.py +23 -0
- examples/fish/assets/startup-assets/tutorial-steps/3-loops-conditions-task1/enemy.py +14 -0
- examples/fish/assets/startup-assets/tutorial-steps/3-loops-conditions-task1/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/3-loops-conditions-task1/player.py +34 -0
- examples/fish/assets/startup-assets/tutorial-steps/3-loops-conditions-task2/enemy.py +23 -0
- examples/fish/assets/startup-assets/tutorial-steps/3-loops-conditions-task2/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/3-loops-conditions-task2/player.py +41 -0
- examples/fish/assets/startup-assets/tutorial-steps/4-variables/enemy.py +23 -0
- examples/fish/assets/startup-assets/tutorial-steps/4-variables/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/4-variables/player.py +59 -0
- examples/fish/assets/startup-assets/tutorial-steps/5-sprite-object/enemy.py +19 -0
- examples/fish/assets/startup-assets/tutorial-steps/5-sprite-object/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/5-sprite-object/player.py +20 -0
- examples/fish/assets/startup-assets/tutorial-steps/5-sprite-object-task1/enemy.py +19 -0
- examples/fish/assets/startup-assets/tutorial-steps/5-sprite-object-task1/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/5-sprite-object-task1/player.py +38 -0
- examples/fish/assets/startup-assets/tutorial-steps/5-sprite-object-task2/enemy.py +20 -0
- examples/fish/assets/startup-assets/tutorial-steps/5-sprite-object-task2/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/5-sprite-object-task2/player.py +58 -0
- examples/fish/assets/startup-assets/tutorial-steps/6-referencing-sprites/enemy.py +32 -0
- examples/fish/assets/startup-assets/tutorial-steps/6-referencing-sprites/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/6-referencing-sprites/player.py +59 -0
- examples/fish/assets/startup-assets/tutorial-steps/6-referencing-sprites-task/enemy.py +37 -0
- examples/fish/assets/startup-assets/tutorial-steps/6-referencing-sprites-task/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/6-referencing-sprites-task/player.py +60 -0
- examples/fish/assets/startup-assets/tutorial-steps/7-parameterised-events/enemy.py +37 -0
- examples/fish/assets/startup-assets/tutorial-steps/7-parameterised-events/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/7-parameterised-events/player.py +83 -0
- examples/fish/assets/startup-assets/tutorial-steps/7-parameterised-events-msg/enemy.py +37 -0
- examples/fish/assets/startup-assets/tutorial-steps/7-parameterised-events-msg/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/7-parameterised-events-msg/player.py +86 -0
- examples/fish/assets/startup-assets/tutorial-steps/7-parameterised-events-task/enemy.py +35 -0
- examples/fish/assets/startup-assets/tutorial-steps/7-parameterised-events-task/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/7-parameterised-events-task/player.py +86 -0
- examples/fish/assets/startup-assets/tutorial-steps/8-backdrop-music/enemy.py +35 -0
- examples/fish/assets/startup-assets/tutorial-steps/8-backdrop-music/main.py +11 -0
- examples/fish/assets/startup-assets/tutorial-steps/8-backdrop-music/player.py +86 -0
- examples/fish/assets/startup-assets/tutorial-steps/9-polish/enemy.py +39 -0
- examples/fish/assets/startup-assets/tutorial-steps/9-polish/enemy_red.py +40 -0
- examples/fish/assets/startup-assets/tutorial-steps/9-polish/main.py +12 -0
- examples/fish/assets/startup-assets/tutorial-steps/9-polish/player.py +119 -0
- examples/getting-started/step 7 - Referencing other sprites/enemy.py +1 -6
- examples/tutorial-day1/chest.py +21 -0
- examples/tutorial-day1/enemy.py +106 -0
- examples/tutorial-day1/friend.py +51 -0
- examples/tutorial-day1/in-steps/1-create-sprites/chest.py +5 -0
- examples/tutorial-day1/in-steps/1-create-sprites/enemy.py +5 -0
- examples/tutorial-day1/in-steps/1-create-sprites/main.py +9 -0
- examples/tutorial-day1/in-steps/2-basic-events/chest.py +24 -0
- examples/tutorial-day1/in-steps/2-basic-events/enemy.py +18 -0
- examples/tutorial-day1/in-steps/2-basic-events/main.py +9 -0
- examples/tutorial-day1/in-steps/3-flow/chest.py +25 -0
- examples/tutorial-day1/in-steps/3-flow/enemy.py +56 -0
- examples/tutorial-day1/in-steps/3-flow/friend.py +47 -0
- examples/tutorial-day1/in-steps/3-flow/main.py +9 -0
- examples/tutorial-day1/in-steps/4-variables/chest.py +37 -0
- examples/tutorial-day1/in-steps/4-variables/enemy.py +76 -0
- examples/tutorial-day1/in-steps/4-variables/friend.py +49 -0
- examples/tutorial-day1/in-steps/4-variables/main.py +9 -0
- examples/tutorial-day1/in-steps/5-backdrops/chest.py +37 -0
- examples/tutorial-day1/in-steps/5-backdrops/enemy.py +76 -0
- examples/tutorial-day1/in-steps/5-backdrops/friend.py +49 -0
- examples/tutorial-day1/in-steps/5-backdrops/main.py +26 -0
- examples/tutorial-day1/main.py +48 -0
- examples/tutorial-day1/target.py +14 -0
- examples/tutorial-day1/text.py +23 -0
- pyscratch/game_module.py +73 -32
- pyscratch/sprite.py +42 -10
- {pyscratch_pysc-1.0.3.dist-info → pyscratch_pysc-2.0.0.dist-info}/METADATA +8 -3
- pyscratch_pysc-2.0.0.dist-info/RECORD +239 -0
- pyscratch_pysc-1.0.3.dist-info/RECORD +0 -101
- {pyscratch_pysc-1.0.3.dist-info → pyscratch_pysc-2.0.0.dist-info}/WHEEL +0 -0
- {pyscratch_pysc-1.0.3.dist-info → pyscratch_pysc-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
import pyscratch as pysc
|
2
|
+
from pyscratch import game
|
3
|
+
|
4
|
+
enemy = pysc.create_single_costume_sprite("assets/fish_red_skeleton_outline.png")
|
5
|
+
|
6
|
+
|
7
|
+
def clicked():
|
8
|
+
"""
|
9
|
+
when the enemy is clicked:
|
10
|
+
change the enemy location with a fade out effect
|
11
|
+
"""
|
12
|
+
game['score'] += 10
|
13
|
+
|
14
|
+
|
15
|
+
for i in range(10):
|
16
|
+
yield 1/game.framerate
|
17
|
+
enemy.set_transparency(1-i/10) # print(1-i/10) if you find this confusing.
|
18
|
+
enemy.scale_by(0.9)
|
19
|
+
|
20
|
+
enemy.x = pysc.random_number(0, game.screen_width)
|
21
|
+
enemy.y = pysc.random_number(0, game.screen_height)
|
22
|
+
|
23
|
+
enemy.set_transparency(1)
|
24
|
+
enemy.set_scale(1)
|
25
|
+
|
26
|
+
enemy.when_this_sprite_clicked().add_handler(clicked)
|
27
|
+
|
28
|
+
|
29
|
+
def movement():
|
30
|
+
"""
|
31
|
+
when_game_start:
|
32
|
+
the movement of the enemy
|
33
|
+
"""
|
34
|
+
|
35
|
+
centre = (game.screen_width/2, game.screen_height/2)
|
36
|
+
|
37
|
+
while True:
|
38
|
+
yield 1/game.framerate
|
39
|
+
|
40
|
+
speed = 5+game['score']*0.1
|
41
|
+
speed = max(1, speed)
|
42
|
+
|
43
|
+
|
44
|
+
# get the distance to the mouse
|
45
|
+
mouse_x, mouse_y = pysc.get_mouse_pos()
|
46
|
+
distance_to_mouse = enemy.distance_to((mouse_x, mouse_y))
|
47
|
+
|
48
|
+
# enemy avoids the mouse when it is close to the mouse
|
49
|
+
if distance_to_mouse < 200:
|
50
|
+
enemy.point_towards_mouse()
|
51
|
+
enemy.direction += 180
|
52
|
+
enemy.move_indir(speed)
|
53
|
+
|
54
|
+
# otherwise, go to the centre of the screen
|
55
|
+
else:
|
56
|
+
enemy.point_towards(centre)
|
57
|
+
enemy.move_indir(speed)
|
58
|
+
|
59
|
+
|
60
|
+
enemy.when_game_start().add_handler(movement)
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
def reduce_score():
|
65
|
+
"""
|
66
|
+
reduce the score for every 0.1 second the enemy is in the centre
|
67
|
+
"""
|
68
|
+
centre = (game.screen_width/2, game.screen_height/2)
|
69
|
+
|
70
|
+
while True:
|
71
|
+
yield 0.1
|
72
|
+
|
73
|
+
if enemy.distance_to(centre) < 50:
|
74
|
+
game['score'] -= 1
|
75
|
+
|
76
|
+
enemy.when_game_start().add_handler(reduce_score)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import pyscratch as pysc
|
2
|
+
import pygame
|
3
|
+
game = pysc.game
|
4
|
+
|
5
|
+
friend = pysc.create_single_costume_sprite("assets/fish_orange_outline.png")
|
6
|
+
|
7
|
+
def movement():
|
8
|
+
"""
|
9
|
+
when_game_start:
|
10
|
+
the movement of the friend: always moving away from the curosr
|
11
|
+
"""
|
12
|
+
centre = game.screen_width/2, game.screen_height/2
|
13
|
+
while True:
|
14
|
+
yield 1/game.framerate
|
15
|
+
mouse_x, mouse_y = pysc.get_mouse_pos()
|
16
|
+
if friend.distance_to((mouse_x, mouse_y)) < 200:
|
17
|
+
friend.point_towards_mouse()
|
18
|
+
friend.direction += 180
|
19
|
+
friend.move_indir(2)
|
20
|
+
|
21
|
+
else:
|
22
|
+
friend.point_towards(centre)
|
23
|
+
friend.move_indir(2)
|
24
|
+
|
25
|
+
friend.when_game_start().add_handler(movement)
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
def check_if_centred():
|
30
|
+
"""
|
31
|
+
when_game_start:
|
32
|
+
move away when near the centre
|
33
|
+
"""
|
34
|
+
centre = game.screen_width/2, game.screen_height/2
|
35
|
+
while True:
|
36
|
+
yield 1/game.framerate
|
37
|
+
if friend.distance_to(centre) < 50:
|
38
|
+
game['score'] += 10
|
39
|
+
|
40
|
+
new_x = pysc.random_number(0, game.screen_width)
|
41
|
+
new_y = pysc.random_number(0, game.screen_height)
|
42
|
+
|
43
|
+
friend.x = new_x
|
44
|
+
friend.y = new_y
|
45
|
+
|
46
|
+
friend.when_game_start().add_handler(check_if_centred)
|
47
|
+
|
48
|
+
|
49
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import pyscratch as pysc
|
2
|
+
from pyscratch import game
|
3
|
+
import chest, enemy, friend
|
4
|
+
|
5
|
+
# background
|
6
|
+
bg0 = pysc.load_image("assets/undersea_bg.png")
|
7
|
+
bg0 = pysc.scale_to_fit_aspect(bg0, (1024, 576))
|
8
|
+
game.add_backdrop('bg0', bg0)
|
9
|
+
|
10
|
+
bg1 = pysc.load_image("assets/Cat In Space Wallpaper Hq.jpg")
|
11
|
+
bg1 = pysc.scale_to_fit_aspect(bg1, (1024, 576))
|
12
|
+
game.add_backdrop('bg1', bg1)
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
def on_game_start():
|
17
|
+
game.switch_backdrop('bg0')
|
18
|
+
|
19
|
+
game.when_game_start().add_handler(on_game_start)
|
20
|
+
|
21
|
+
|
22
|
+
# starting the game
|
23
|
+
game.update_screen_mode((1024, 576))
|
24
|
+
game.start(show_mouse_position=True)
|
25
|
+
|
26
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import pyscratch as pysc
|
2
|
+
import pygame
|
3
|
+
import target, enemy, chest, friend#, text
|
4
|
+
|
5
|
+
game = pysc.game
|
6
|
+
|
7
|
+
# mouse
|
8
|
+
pygame.mouse.set_visible(False)
|
9
|
+
|
10
|
+
|
11
|
+
# background
|
12
|
+
bg0 = pysc.load_image("assets/undersea_bg.png")
|
13
|
+
bg0 = pysc.scale_to_fit_aspect(bg0, (1024, 576))
|
14
|
+
game.add_backdrop('bg0', bg0)
|
15
|
+
|
16
|
+
bg1 = pysc.load_image("assets/Cat In Space Wallpaper Hq.jpg")
|
17
|
+
bg1 = pysc.scale_to_fit_aspect(bg1, (1024, 576))
|
18
|
+
game.add_backdrop('bg1', bg1)
|
19
|
+
|
20
|
+
game.switch_backdrop('bg0')
|
21
|
+
|
22
|
+
# sound
|
23
|
+
game.load_sound("hit", "assets/impactMetal_light_004.ogg")
|
24
|
+
game.load_sound("background", "assets/Circus-Theme-Entry-of-the-Gladiators-Ragtime-Version(chosic.com).mp3")
|
25
|
+
|
26
|
+
def play_loop():
|
27
|
+
while True:
|
28
|
+
game.play_sound("background", volume=0)
|
29
|
+
yield 2*60+33
|
30
|
+
game.when_game_start().add_handler(play_loop)
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
def background():
|
36
|
+
while True:
|
37
|
+
yield 1/game.framerate
|
38
|
+
if game['score'] < 0:
|
39
|
+
game.switch_backdrop('bg1')
|
40
|
+
|
41
|
+
|
42
|
+
game.when_game_start().add_handler(background)
|
43
|
+
|
44
|
+
|
45
|
+
game.update_screen_mode((1024, 576))
|
46
|
+
game.start(show_mouse_position=True)
|
47
|
+
|
48
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import pyscratch as pysc
|
2
|
+
game = pysc.game
|
3
|
+
target = pysc.create_single_costume_sprite("assets/target_b.png")
|
4
|
+
|
5
|
+
# 3. Flow control
|
6
|
+
def follow_mouse():
|
7
|
+
game.bring_to_front(target)
|
8
|
+
while True:
|
9
|
+
yield 1/game.framerate
|
10
|
+
mouse_x, mouse_y = pysc.get_mouse_pos()
|
11
|
+
target.x = mouse_x
|
12
|
+
target.y = mouse_y
|
13
|
+
|
14
|
+
target.when_game_start().add_handler(follow_mouse)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import pyscratch as pysc
|
2
|
+
import pygame
|
3
|
+
game = pysc.game
|
4
|
+
|
5
|
+
text_box = pysc.create_rect_sprite((200, 200, 200, 20), 700, 90)
|
6
|
+
font = pygame.font.Font('assets/Kenney Future.ttf', size=96)
|
7
|
+
|
8
|
+
text_box.write_text("YOU LOSE", font, offset=(350, 45))
|
9
|
+
|
10
|
+
|
11
|
+
text_box.hide()
|
12
|
+
|
13
|
+
text_box.set_draggable(True)
|
14
|
+
text_box.set_xy((260, 195))
|
15
|
+
text_box.direction = -35
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
def game_end():
|
20
|
+
text_box.show()
|
21
|
+
|
22
|
+
text_box.when_backdrop_switched(1).add_handler(game_end)
|
23
|
+
|
pyscratch/game_module.py
CHANGED
@@ -12,6 +12,7 @@ from pathlib import Path
|
|
12
12
|
import threading
|
13
13
|
import time
|
14
14
|
import json, inspect
|
15
|
+
from typing_extensions import deprecated
|
15
16
|
|
16
17
|
import numpy as np
|
17
18
|
import pygame
|
@@ -309,16 +310,23 @@ class Game:
|
|
309
310
|
self._mouse_drag_trigger = self.create_pygame_event([pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP, pygame.MOUSEMOTION])
|
310
311
|
self._mouse_drag_trigger.add_handler(self.__mouse_drag_handler)
|
311
312
|
|
312
|
-
|
313
|
-
self.
|
314
|
-
|
313
|
+
# Backdrops
|
314
|
+
self.backdrops_by_key: Dict[str, pygame.Surface] = {}
|
315
|
+
self.backdrop_indices_by_key: Dict[str, int] = {}
|
316
|
+
self.backdrop_keys: List[str] = []
|
317
|
+
|
318
|
+
# TODO: testing needed
|
315
319
|
|
316
320
|
self.__screen_width: int = 0
|
317
321
|
self.__screen_height: int = 0
|
318
322
|
self.__framerate: float = 0
|
319
323
|
|
320
|
-
|
324
|
+
# TODO index and key need to be changed together
|
325
|
+
# the index is remained for the next_backdrop function
|
321
326
|
self.__backdrop_index = None
|
327
|
+
self.__backdrop_key = None
|
328
|
+
|
329
|
+
# TODO: the event is now triggered by the name not the index
|
322
330
|
self._backdrop_change_triggers: List[Event] = []
|
323
331
|
|
324
332
|
self._top_edge: Sprite
|
@@ -627,8 +635,8 @@ class Game:
|
|
627
635
|
# Drawing
|
628
636
|
|
629
637
|
#self._screen.fill((30, 30, 30))
|
630
|
-
if not (self.
|
631
|
-
self._screen.blit(self.
|
638
|
+
if not (self.__backdrop_key is None):
|
639
|
+
self._screen.blit(self.backdrops_by_key[self.__backdrop_key], (0, 0))
|
632
640
|
else:
|
633
641
|
self._screen.fill((255,255,255))
|
634
642
|
helper._draw_guide_lines(self._screen, guide_lines_font, 100, 500)
|
@@ -724,6 +732,9 @@ class Game:
|
|
724
732
|
self._space.gravity = xy
|
725
733
|
|
726
734
|
def _new_sprite_of_file(self, caller_file):
|
735
|
+
"""
|
736
|
+
return a index of the sprite created in the file
|
737
|
+
"""
|
727
738
|
if not caller_file in self._sprite_count_per_file:
|
728
739
|
self._sprite_count_per_file[caller_file] = 0
|
729
740
|
else:
|
@@ -732,16 +743,17 @@ class Game:
|
|
732
743
|
return self._sprite_count_per_file[caller_file]
|
733
744
|
|
734
745
|
|
735
|
-
def _add_sprite(self, sprite: Sprite,
|
746
|
+
def _add_sprite(self, sprite: Sprite, caller_file=None):
|
736
747
|
|
737
748
|
self._all_sprites.add(sprite)
|
738
749
|
if len(self._all_sprites) > self.max_number_sprite:
|
739
750
|
raise RuntimeError('Reached the maximum number sprite. ')
|
740
751
|
#self._space.add(sprite.body, sprite.shape)
|
741
752
|
self._sprite_click_trigger[sprite] = []
|
742
|
-
if to_show:
|
743
|
-
|
744
|
-
|
753
|
+
# if to_show:
|
754
|
+
# sprite.show()
|
755
|
+
#self._all_sprites_to_show.add(sprite)
|
756
|
+
#sprite.update()
|
745
757
|
|
746
758
|
if self.__started_interactive:
|
747
759
|
sprite.set_draggable(True)
|
@@ -784,16 +796,12 @@ class Game:
|
|
784
796
|
def _show_sprite(self, sprite: Sprite):
|
785
797
|
"""
|
786
798
|
Show the sprite.
|
787
|
-
|
788
|
-
You can use the alias `sprite.show()` to do the same.
|
789
799
|
"""
|
790
800
|
self._all_sprites_to_show.add(sprite)
|
791
801
|
|
792
802
|
def _hide_sprite(self, sprite: Sprite):
|
793
803
|
"""
|
794
804
|
Hide the sprite.
|
795
|
-
|
796
|
-
You can use the alias `sprite.hide()` to do the same.
|
797
805
|
"""
|
798
806
|
self._all_sprites_to_show.remove(sprite)
|
799
807
|
|
@@ -831,6 +839,7 @@ class Game:
|
|
831
839
|
"""
|
832
840
|
self._all_sprites_to_show.get_layer_of_sprite(sprite)
|
833
841
|
|
842
|
+
@deprecated("use add_backdrop")
|
834
843
|
def set_backdrops(self, images: List[pygame.Surface]):
|
835
844
|
"""
|
836
845
|
Set the list of all available backdrops. This function is meant to be run before the game start.
|
@@ -849,32 +858,63 @@ class Game:
|
|
849
858
|
pysc.game.switch_backdrop(1)
|
850
859
|
```
|
851
860
|
"""
|
852
|
-
|
853
|
-
|
861
|
+
for idx, img in enumerate(images):
|
862
|
+
self.add_backdrop(str(idx), img)
|
863
|
+
|
864
|
+
def add_backdrop(self, key, image: pygame.Surface):
|
865
|
+
"""
|
866
|
+
Add the image as a backdrop, and index it with the key so it can be switched to using switch_backdrop
|
867
|
+
|
868
|
+
Example:
|
869
|
+
```python
|
870
|
+
bg0 = pysc.load_image("assets/undersea_bg.png")'
|
871
|
+
|
872
|
+
game.add_backdrop('background0', bg0)
|
873
|
+
game.switch_backdrop('background0')
|
874
|
+
```
|
875
|
+
|
876
|
+
"""
|
877
|
+
assert not key in self.backdrops_by_key, f"the name '{key}' is already in used"
|
878
|
+
self.backdrop_keys.append(key)
|
879
|
+
self.backdrops_by_key[key] = image
|
880
|
+
self.backdrop_indices_by_key[key] = len(self.backdrop_keys) - 1 # minus one since the new one is added in the previous line
|
881
|
+
|
882
|
+
|
854
883
|
@property
|
855
884
|
def backdrop_index(self):
|
856
885
|
"""
|
857
|
-
The index of the current backdrops.
|
886
|
+
The index of the current backdrops.
|
858
887
|
"""
|
859
888
|
return self.__backdrop_index
|
889
|
+
|
860
890
|
|
861
|
-
|
891
|
+
@property
|
892
|
+
def backdrop_key(self):
|
893
|
+
"""
|
894
|
+
The key (i.e. name) of the current backdrops.
|
895
|
+
"""
|
896
|
+
return self.__backdrop_key
|
897
|
+
|
898
|
+
def switch_backdrop(self, key:Optional[str]=None):
|
862
899
|
"""
|
863
900
|
Change the backdrop by specifying the index of the backdrop.
|
864
901
|
"""
|
865
902
|
|
866
|
-
if
|
867
|
-
self.
|
903
|
+
if key != self.__backdrop_key:
|
904
|
+
self.__backdrop_key = key
|
905
|
+
self.__backdrop_index = None if key is None else self.backdrop_indices_by_key[key]
|
868
906
|
for t in self._backdrop_change_triggers:
|
869
|
-
t.trigger(
|
870
|
-
self._specific_backdrop_event_emitter.on_event(
|
907
|
+
t.trigger(key)
|
908
|
+
self._specific_backdrop_event_emitter.on_event(key)
|
871
909
|
|
910
|
+
# TODO: testing needed
|
872
911
|
def next_backdrop(self):
|
873
912
|
"""
|
874
913
|
Switch to the next backdrop.
|
875
914
|
"""
|
876
915
|
if not self.__backdrop_index is None:
|
877
|
-
|
916
|
+
idx = (self.__backdrop_index+1) % len(self.backdrops_by_key)
|
917
|
+
self.switch_backdrop(self.backdrop_keys[idx])
|
878
918
|
|
879
919
|
# all events
|
880
920
|
|
@@ -1026,19 +1066,19 @@ class Game:
|
|
1026
1066
|
t = _declare_callback_type(t, sample_callback)
|
1027
1067
|
return t
|
1028
1068
|
|
1029
|
-
|
1030
|
-
def when_backdrop_switched(self,
|
1069
|
+
# TODO: testing needed
|
1070
|
+
def when_backdrop_switched(self, backdrop_key: str, associated_sprites : Iterable[Sprite]=[]) -> Event[[]]:
|
1031
1071
|
"""
|
1032
1072
|
It is recommended to use the `Sprite.when_backdrop_switched` alias instead of this method,
|
1033
1073
|
so you don't need to specify the `associated_sprites` in every event.
|
1034
1074
|
|
1035
|
-
Returns an `Event` that is triggered when the game is switched to a backdrop
|
1075
|
+
Returns an `Event` that is triggered when the game is switched to a backdrop with the key `backdrop_key`.
|
1036
1076
|
|
1037
1077
|
The event handler does not take in any parameter.
|
1038
1078
|
|
1039
1079
|
Parameters
|
1040
1080
|
---
|
1041
|
-
|
1081
|
+
backdrop_key: str
|
1042
1082
|
The index of the backdrop
|
1043
1083
|
|
1044
1084
|
associated_sprites: List[Sprite]
|
@@ -1053,10 +1093,11 @@ class Game:
|
|
1053
1093
|
return
|
1054
1094
|
t = _declare_callback_type(t, sample_callback)
|
1055
1095
|
|
1056
|
-
self._specific_backdrop_event_emitter.add_event(
|
1096
|
+
self._specific_backdrop_event_emitter.add_event(backdrop_key, t)
|
1057
1097
|
return t
|
1058
|
-
|
1059
|
-
|
1098
|
+
|
1099
|
+
# TODO: testing needed
|
1100
|
+
def when_any_backdrop_switched(self, associated_sprites : Iterable[Sprite]=[]) -> Event[[Union[str,None]]]:
|
1060
1101
|
"""
|
1061
1102
|
It is recommended to use the `Sprite.when_any_backdrop_switched` alias instead of this method,
|
1062
1103
|
so you don't need to specify the `associated_sprites` in every event.
|
@@ -1064,7 +1105,7 @@ class Game:
|
|
1064
1105
|
Returns an `Event` that is triggered when the backdrop is switched.
|
1065
1106
|
|
1066
1107
|
The event handler have to take one parameter:
|
1067
|
-
- **
|
1108
|
+
- **str** (str): The key of the new backdrop
|
1068
1109
|
|
1069
1110
|
Parameters
|
1070
1111
|
---
|
@@ -1075,7 +1116,7 @@ class Game:
|
|
1075
1116
|
t = self._create_event(associated_sprites)
|
1076
1117
|
self._backdrop_change_triggers.append(t)
|
1077
1118
|
if TYPE_CHECKING:
|
1078
|
-
def sample_callback(
|
1119
|
+
def sample_callback(key: Union[str, None])-> Any:
|
1079
1120
|
return
|
1080
1121
|
t = _declare_callback_type(t, sample_callback)
|
1081
1122
|
|
pyscratch/sprite.py
CHANGED
@@ -165,7 +165,7 @@ def create_single_costume_sprite(image_path, *args, **kwargs):
|
|
165
165
|
return Sprite(frame_dict, "always", *args, **kwargs)
|
166
166
|
|
167
167
|
|
168
|
-
def create_shared_data_display_sprite(key, font, size = (150, 50), bg_colour=(127, 127, 127), text_colour=(255,255,255), position: Optional[Tuple[float, float]]=None, update_period=0.1, **kwargs):
|
168
|
+
def create_shared_data_display_sprite(key, font:Optional[pygame.font.Font]=None, size = (150, 50), bg_colour=(127, 127, 127), text_colour=(255,255,255), position: Optional[Tuple[float, float]]=None, update_period=0.1, **kwargs):
|
169
169
|
"""
|
170
170
|
Create a display for a variable inside shared_data given the dictionary key (i.e. the name of the variable).
|
171
171
|
The variable display will update every `update_period` seconds.
|
@@ -191,8 +191,9 @@ def create_shared_data_display_sprite(key, font, size = (150, 50), bg_colour=(12
|
|
191
191
|
---
|
192
192
|
key: str
|
193
193
|
The dictionary key of the variable in `game.shared_data` that you want to display.
|
194
|
-
font: pygame.font.Font
|
194
|
+
font: None or pygame.font.Font
|
195
195
|
The pygame font object. Refer to the website of pygame for more details.
|
196
|
+
If None, a default font will be used.
|
196
197
|
size: Tuple[float, float]
|
197
198
|
The size of the display panel
|
198
199
|
bg_colour: Tuple[int, int, int] or Tuple[int, int, int, int]
|
@@ -207,6 +208,9 @@ def create_shared_data_display_sprite(key, font, size = (150, 50), bg_colour=(12
|
|
207
208
|
Whatever the `Sprite` constructor takes, except `frame_dict`,`starting_animation` & `position`
|
208
209
|
"""
|
209
210
|
|
211
|
+
if font is None:
|
212
|
+
font = pygame.font.Font(None, 36)
|
213
|
+
|
210
214
|
w, h = size
|
211
215
|
if position is None:
|
212
216
|
position = w/2+25, h/2+25
|
@@ -713,7 +717,17 @@ class Sprite(pygame.sprite.Sprite):
|
|
713
717
|
if not caller_file == this_file:
|
714
718
|
break
|
715
719
|
|
720
|
+
|
721
|
+
self._intend_to_show = True
|
722
|
+
self._shown = False
|
723
|
+
self.hide()
|
724
|
+
|
716
725
|
count = game._add_sprite(self, caller_file=caller_file)
|
726
|
+
|
727
|
+
self.update()
|
728
|
+
self.show()
|
729
|
+
|
730
|
+
|
717
731
|
self.identifier: str
|
718
732
|
"""
|
719
733
|
An identifier of the sprite for loading sprite states (position and direction).
|
@@ -760,8 +774,10 @@ class Sprite(pygame.sprite.Sprite):
|
|
760
774
|
|
761
775
|
x, y = self._body.position
|
762
776
|
self.image, self.rect, self.mask = self._drawing_manager.on_update(x, y, self.__direction.angle_degrees)
|
763
|
-
|
777
|
+
self._shown = self._intend_to_show
|
778
|
+
|
764
779
|
self._physics_manager.on_update(self.image)
|
780
|
+
|
765
781
|
|
766
782
|
if self.__is_dragging:
|
767
783
|
self._body.velocity=0,0
|
@@ -1364,12 +1380,17 @@ class Sprite(pygame.sprite.Sprite):
|
|
1364
1380
|
```
|
1365
1381
|
"""
|
1366
1382
|
|
1367
|
-
if not self in game._all_sprites_to_show:
|
1368
|
-
|
1383
|
+
# if not self in game._all_sprites_to_show:
|
1384
|
+
# return False
|
1385
|
+
|
1386
|
+
# if not other_sprite in game._all_sprites_to_show:
|
1387
|
+
# return False
|
1369
1388
|
|
1370
|
-
if not
|
1389
|
+
if not self._shown:
|
1390
|
+
return False
|
1391
|
+
|
1392
|
+
if not other_sprite._shown:
|
1371
1393
|
return False
|
1372
|
-
|
1373
1394
|
|
1374
1395
|
if not pygame.sprite.collide_rect(self, other_sprite):
|
1375
1396
|
return False
|
@@ -1380,6 +1401,9 @@ class Sprite(pygame.sprite.Sprite):
|
|
1380
1401
|
"""
|
1381
1402
|
Returns whether or not this sprite is touching the mouse
|
1382
1403
|
"""
|
1404
|
+
if not self._shown:
|
1405
|
+
return False
|
1406
|
+
|
1383
1407
|
mos_x, mos_y = pygame.mouse.get_pos()
|
1384
1408
|
|
1385
1409
|
if not self.rect.collidepoint((mos_x, mos_y)):
|
@@ -1411,12 +1435,17 @@ class Sprite(pygame.sprite.Sprite):
|
|
1411
1435
|
The hidden sprite is still in the space but it cannot touch another sprites
|
1412
1436
|
"""
|
1413
1437
|
game._hide_sprite(self)
|
1438
|
+
self._shown = False
|
1439
|
+
self._intend_to_show = False
|
1414
1440
|
|
1415
1441
|
def show(self):
|
1416
1442
|
"""
|
1417
1443
|
Shows the sprite.
|
1418
1444
|
"""
|
1419
1445
|
game._show_sprite(self)
|
1446
|
+
self._intend_to_show = True
|
1447
|
+
# self._shown is set to True only during the update
|
1448
|
+
|
1420
1449
|
|
1421
1450
|
@override
|
1422
1451
|
def remove(self, *_):
|
@@ -1430,7 +1459,8 @@ class Sprite(pygame.sprite.Sprite):
|
|
1430
1459
|
my_sprite.remove()
|
1431
1460
|
```
|
1432
1461
|
"""
|
1433
|
-
|
1462
|
+
self.hide() # prevent collision
|
1463
|
+
game._remove_sprite(self)
|
1434
1464
|
self.__removed = True
|
1435
1465
|
|
1436
1466
|
|
@@ -1455,8 +1485,10 @@ class Sprite(pygame.sprite.Sprite):
|
|
1455
1485
|
shape_size_factor = self._physics_manager.shape_size_factor,
|
1456
1486
|
body_type = self._body.body_type,
|
1457
1487
|
)
|
1458
|
-
if not self
|
1459
|
-
|
1488
|
+
if not self._intend_to_show:
|
1489
|
+
sprite.hide()
|
1490
|
+
else:
|
1491
|
+
sprite.show()
|
1460
1492
|
|
1461
1493
|
if self.__rotation_style == _RotationStyle.LEFTRIGHT:
|
1462
1494
|
sprite.set_rotation_style_left_right()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pyscratch-pysc
|
3
|
-
Version:
|
3
|
+
Version: 2.0.0
|
4
4
|
Summary: A Python game development framework designed to provide an easy transitioning from Scratch to Python
|
5
5
|
Author-email: Daniel Ka-Wa Chan <kwdaniel525@protonmail.com>
|
6
6
|
License: MIT
|
@@ -22,10 +22,15 @@ For more information, see: https://kwdchan.github.io/pyscratch/
|
|
22
22
|
|
23
23
|
|
24
24
|
|
25
|
+
## Change History
|
26
|
+
### 12 Oct 2025
|
27
|
+
**v2.0.0**
|
28
|
+
The backdrops are now indexed by keys instead of integers
|
25
29
|
|
26
30
|
|
27
|
-
|
28
|
-
|
31
|
+
### 12 Sep 2025
|
32
|
+
**v1.0.4**
|
33
|
+
Fixed the show/hide collision related problem due to the deferral of movement to the frame update.
|
29
34
|
|
30
35
|
### 07 Sep 2025
|
31
36
|
**v1.0.3**
|