Skip to content

Commit 5bc153e

Browse files
authored
Merge pull request #50 from Secret-chest/conditions
2 parents 56efce9 + 9659baa commit 5bc153e

File tree

7 files changed

+52
-20
lines changed

7 files changed

+52
-20
lines changed

assets/project.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"targets":[{"isStage":true,"name":"Stage","variables":{"`jEk@4|i[#Fk?(8x)AV.-my variable":["variabila mea",0]},"lists":{},"broadcasts":{},"blocks":{},"comments":{},"currentCostume":0,"costumes":[{"assetId":"cd21514d0531fdffb22204e0ec5ed84a","name":"decor1","md5ext":"cd21514d0531fdffb22204e0ec5ed84a.svg","dataFormat":"svg","rotationCenterX":240,"rotationCenterY":180}],"sounds":[{"assetId":"83a9787d4cb6f3b7632b4ddfebf74367","name":"pop","dataFormat":"wav","format":"","rate":44100,"sampleCount":1032,"md5ext":"83a9787d4cb6f3b7632b4ddfebf74367.wav"}],"volume":100,"layerOrder":0,"tempo":60,"videoTransparency":50,"videoState":"on","textToSpeechLanguage":null},{"isStage":false,"name":"Personaj1","variables":{},"lists":{},"broadcasts":{},"blocks":{"2gXe00(^=5?jAV4GO65H":{"opcode":"event_whenkeypressed","next":"[6l:dI8V6DP/46FRvqWF","parent":null,"inputs":{},"fields":{"KEY_OPTION":["up arrow",null]},"shadow":false,"topLevel":true,"x":221,"y":482},"[6l:dI8V6DP/46FRvqWF":{"opcode":"control_repeat","next":"66+5V9OT]aVmQ~an[lHS","parent":"2gXe00(^=5?jAV4GO65H","inputs":{"TIMES":[1,[6,"10"]],"SUBSTACK":[2,"!5m_j*V4@%-:ZJk_u8BM"]},"fields":{},"shadow":false,"topLevel":false},"66+5V9OT]aVmQ~an[lHS":{"opcode":"control_repeat","next":null,"parent":"[6l:dI8V6DP/46FRvqWF","inputs":{"TIMES":[1,[6,"10"]],"SUBSTACK":[2,"0w,.oaq;Me*YJldkC8F."]},"fields":{},"shadow":false,"topLevel":false},"!5m_j*V4@%-:ZJk_u8BM":{"opcode":"motion_changeyby","next":null,"parent":"[6l:dI8V6DP/46FRvqWF","inputs":{"DY":[1,[4,"10"]]},"fields":{},"shadow":false,"topLevel":false},"0w,.oaq;Me*YJldkC8F.":{"opcode":"motion_changeyby","next":null,"parent":"66+5V9OT]aVmQ~an[lHS","inputs":{"DY":[1,[4,"-10"]]},"fields":{},"shadow":false,"topLevel":false}},"comments":{},"currentCostume":0,"costumes":[{"assetId":"b7853f557e4426412e64bb3da6531a99","name":"costum1","bitmapResolution":1,"md5ext":"b7853f557e4426412e64bb3da6531a99.svg","dataFormat":"svg","rotationCenterX":48,"rotationCenterY":50},{"assetId":"e6ddc55a6ddd9cc9d84fe0b4c21e016f","name":"costum2","bitmapResolution":1,"md5ext":"e6ddc55a6ddd9cc9d84fe0b4c21e016f.svg","dataFormat":"svg","rotationCenterX":46,"rotationCenterY":53}],"sounds":[{"assetId":"83c36d806dc92327b9e7049a565c6bff","name":"Miau","dataFormat":"wav","format":"","rate":44100,"sampleCount":37376,"md5ext":"83c36d806dc92327b9e7049a565c6bff.wav"}],"volume":100,"layerOrder":1,"visible":true,"x":0,"y":0,"size":100,"direction":90,"draggable":false,"rotationStyle":"all around"}],"monitors":[],"extensions":[],"meta":{"semver":"3.0.0","vm":"0.2.0-prerelease.20201016122132","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Scratch/3.18.1 Chrome/80.0.3987.165 Electron/8.2.5 Safari/537.36"}}
1+
{"targets":[{"isStage":true,"name":"Stage","variables":{"`jEk@4|i[#Fk?(8x)AV.-my variable":["variabila mea",0]},"lists":{},"broadcasts":{},"blocks":{},"comments":{},"currentCostume":0,"costumes":[{"name":"decor1","dataFormat":"svg","assetId":"cd21514d0531fdffb22204e0ec5ed84a","md5ext":"cd21514d0531fdffb22204e0ec5ed84a.svg","rotationCenterX":240,"rotationCenterY":180}],"sounds":[{"name":"pop","assetId":"83a9787d4cb6f3b7632b4ddfebf74367","dataFormat":"wav","format":"","rate":44100,"sampleCount":1032,"md5ext":"83a9787d4cb6f3b7632b4ddfebf74367.wav"}],"volume":100,"layerOrder":0,"tempo":60,"videoTransparency":50,"videoState":"on","textToSpeechLanguage":"ro"},{"isStage":false,"name":"Personaj1","variables":{},"lists":{},"broadcasts":{},"blocks":{"i0sF-x|[yQ-#%j@rU%f,":{"opcode":"event_whenflagclicked","next":")u+B7H(M9g25%Em.w=5;","parent":null,"inputs":{},"fields":{},"shadow":false,"topLevel":true,"x":360,"y":168},")u+B7H(M9g25%Em.w=5;":{"opcode":"control_forever","next":null,"parent":"i0sF-x|[yQ-#%j@rU%f,","inputs":{"SUBSTACK":[2,"/B0dn4qYH?K,.K9rc;A`"]},"fields":{},"shadow":false,"topLevel":false},"/B0dn4qYH?K,.K9rc;A`":{"opcode":"control_if","next":"|LMd9D?RO[2$-2d9tSaH","parent":")u+B7H(M9g25%Em.w=5;","inputs":{"CONDITION":[2,"#Uk8A~y8%JVMqn}NHx[`"],"SUBSTACK":[2,"oh,d/q]c)nT*MAUu,[S@"]},"fields":{},"shadow":false,"topLevel":false},"#Uk8A~y8%JVMqn}NHx[`":{"opcode":"sensing_keypressed","next":null,"parent":"/B0dn4qYH?K,.K9rc;A`","inputs":{"KEY_OPTION":[1,"DNHO5a8nfKM+34^x:43}"]},"fields":{},"shadow":false,"topLevel":false},"DNHO5a8nfKM+34^x:43}":{"opcode":"sensing_keyoptions","next":null,"parent":"#Uk8A~y8%JVMqn}NHx[`","inputs":{},"fields":{"KEY_OPTION":["space",null]},"shadow":true,"topLevel":false},"oh,d/q]c)nT*MAUu,[S@":{"opcode":"looks_switchcostumeto","next":null,"parent":"/B0dn4qYH?K,.K9rc;A`","inputs":{"COSTUME":[1,"R^t{wX)}j(l,vXrOTX(g"]},"fields":{},"shadow":false,"topLevel":false},"R^t{wX)}j(l,vXrOTX(g":{"opcode":"looks_costume","next":null,"parent":"oh,d/q]c)nT*MAUu,[S@","inputs":{},"fields":{"COSTUME":["costum2",null]},"shadow":true,"topLevel":false},"|LMd9D?RO[2$-2d9tSaH":{"opcode":"control_if","next":null,"parent":"/B0dn4qYH?K,.K9rc;A`","inputs":{"CONDITION":[2,"46_hm$E}C?N}KA=/3@`u"],"SUBSTACK":[2,"[+(oxNIM5(qM,kq~)/=K"]},"fields":{},"shadow":false,"topLevel":false},"w!`lxu[+VTbb!a@:2IFM":{"opcode":"sensing_keypressed","next":null,"parent":"46_hm$E}C?N}KA=/3@`u","inputs":{"KEY_OPTION":[1,"@`Y@ky)Etn+{XJ-{4Vsb"]},"fields":{},"shadow":false,"topLevel":false},"@`Y@ky)Etn+{XJ-{4Vsb":{"opcode":"sensing_keyoptions","next":null,"parent":"w!`lxu[+VTbb!a@:2IFM","inputs":{},"fields":{"KEY_OPTION":["space",null]},"shadow":true,"topLevel":false},"[+(oxNIM5(qM,kq~)/=K":{"opcode":"looks_switchcostumeto","next":null,"parent":"|LMd9D?RO[2$-2d9tSaH","inputs":{"COSTUME":[1,"laZz,h-Z/Z?46wV,!;C*"]},"fields":{},"shadow":false,"topLevel":false},"laZz,h-Z/Z?46wV,!;C*":{"opcode":"looks_costume","next":null,"parent":"[+(oxNIM5(qM,kq~)/=K","inputs":{},"fields":{"COSTUME":["costum1",null]},"shadow":true,"topLevel":false},"46_hm$E}C?N}KA=/3@`u":{"opcode":"operator_not","next":null,"parent":"|LMd9D?RO[2$-2d9tSaH","inputs":{"OPERAND":[2,"w!`lxu[+VTbb!a@:2IFM"]},"fields":{},"shadow":false,"topLevel":false}},"comments":{},"currentCostume":0,"costumes":[{"name":"costum1","bitmapResolution":1,"dataFormat":"svg","assetId":"5b8a85774c8c983b993b7d1549b46082","md5ext":"5b8a85774c8c983b993b7d1549b46082.svg","rotationCenterX":47.678985050489445,"rotationCenterY":49.499230353205405},{"name":"costum2","bitmapResolution":1,"dataFormat":"svg","assetId":"1bf03016126b8879eb6228066a9a28a2","md5ext":"1bf03016126b8879eb6228066a9a28a2.svg","rotationCenterX":47.67898252524472,"rotationCenterY":49.49923017660271}],"sounds":[{"name":"Miau","assetId":"83c36d806dc92327b9e7049a565c6bff","dataFormat":"wav","format":"","rate":44100,"sampleCount":37376,"md5ext":"83c36d806dc92327b9e7049a565c6bff.wav"}],"volume":100,"layerOrder":1,"visible":true,"x":0,"y":0,"size":100,"direction":90,"draggable":false,"rotationStyle":"all around"}],"monitors":[],"extensions":[],"meta":{"semver":"3.0.0","vm":"1.2.52","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"}}

block.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import config
1212
import math
1313
import pygame
14+
import eventContainer
15+
from scratch import KEY_MAPPING
1416

1517
i18n.set("locale", config.language)
1618
i18n.set("filename_format", "{locale}.{format}")
@@ -40,9 +42,10 @@ def __init__(self):
4042
self.inEventLoop = False
4143
self.value = None # reported value
4244
self.repeatCounter = None # for repeat block
45+
self.canRun = None # for if then / if then else
4346

4447
# Evaluates block value (for reporters)
45-
def evaluateBlockValue(self):
48+
def evaluateBlockValue(self, eventContainer=eventContainer.EventContainer):
4649
if self.opcode == "operator_add": # () + ()
4750
self.value = float(self.getInputValue("num1")) + float(self.getInputValue("num2"))
4851
return self.value
@@ -83,18 +86,22 @@ def evaluateBlockValue(self):
8386
newY = newY - config.screenWidth // 2
8487
self.value = newY
8588
return newY
89+
elif self.opcode == "sensing_keypressed": # key pressed?
90+
return KEY_MAPPING[self.getMenuValue("key_option")] in eventContainer.keys
91+
elif self.opcode == "operator_not": # not <>
92+
return not self.target.blocks[self.getBlockInputValue("operand")].evaluateBlockValue(eventContainer)
8693

8794
# Returns block input value
8895
def getBlockInputValue(self, inputId):
8996
return self.inputs[inputId.upper()][1]
9097

9198
# Returns block input value
92-
def getInputValue(self, inputId, lookIn=(1, 1)):
99+
def getInputValue(self, inputId, lookIn=(1, 1), eventContainer=eventContainer.EventContainer()):
93100
if self.inputs[inputId.upper()][lookIn[0]][0] in {4, 0, 5, 6}:
94101
return self.inputs[inputId.upper()][lookIn[0]][1] or 0
95102
elif self.inputs[inputId.upper()][0] == 3:
96103
blockLink = self.inputs[inputId.upper()][1]
97-
return self.target.blocks[blockLink].evaluateBlockValue()
104+
return self.target.blocks[blockLink].evaluateBlockValue(eventContainer)
98105
else:
99106
pass
100107

@@ -104,7 +111,7 @@ def getCustomInputValue(self, number, lookIn=(1, 1)):
104111

105112
# Returns dropdown menu value (menus are separate blocks)
106113
def getMenuValue(self, menuId):
107-
return self.inputs[menuId.upper()][1].fields[menuId.upper()][0]
114+
return self.target.blocks[self.inputs[menuId.upper()][1]].fields[menuId.upper()][0]
108115

109116
# Returns field value (menus are separate blocks)
110117
def getFieldValue(self, fieldId, lookIn=0):

config.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
# Project file name
2626
# If in test mode, set the Scratch project file to load.
27-
projectFileName: str = "projects/KeyJump.sb3"
27+
projectFileName: str = "projects/ChangeColour.sb3"
2828

2929
# Download cache size
3030
# Number of recent downloaded projects stored. 0 means infinity.
@@ -40,14 +40,13 @@
4040

4141
# Enable debug messages
4242
# Set whether debug messages (messages to stderr) should be allowed.
43-
enableDebugMessages: bool = False
43+
enableDebugMessages: bool = True
4444

4545
# Enable pygame welcome message
4646
# Enable or disable the "
4747
# pygame X.Y.Z (SDL X.Y.Z, Python 3.Y.Z)
4848
# Hello from the pygame community. https://www.pygame.org/contribute.html"
4949
# message.
50-
5150
pygameWelcomeMessage: bool = True
5251

5352
# Enable Scratch Addons debugger logs

projects/ChangeColour.sb3

40.9 KB
Binary file not shown.

projects/NotKeyPressed.sb3

40.8 KB
Binary file not shown.

scratch.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def execute(block, s, events=eventContainer.EventContainer()):
166166
keyEvents = events.keyEvents
167167

168168
if opcode == "motion_gotoxy": # go to x: () y: ()
169-
s.setXy(float(block.getInputValue("x")), float(block.getInputValue("y")))
169+
s.setXy(float(block.getInputValue("x", eventContainer=events)), float(block.getInputValue("y", eventContainer=events)))
170170

171171
elif opcode == "motion_goto":
172172
nextBlock = block.getBlockInputValue("to")
@@ -194,28 +194,28 @@ def execute(block, s, events=eventContainer.EventContainer()):
194194
return
195195

196196
elif opcode == "motion_setx": # set x to ()
197-
s.setXy(float(block.getInputValue("x")), s.y)
197+
s.setXy(float(block.getInputValue("x", eventContainer=events)), s.y)
198198

199199
elif opcode == "motion_changexby": # change x by ( )
200-
s.setXyDelta(float(block.getInputValue("dx")), 0)
200+
s.setXyDelta(float(block.getInputValue("dx", eventContainer=events)), 0)
201201

202202
elif opcode == "motion_sety": # set y to ()
203-
s.setXy(s.x, float(block.getInputValue("y")))
203+
s.setXy(s.x, float(block.getInputValue("y", eventContainer=events)))
204204

205205
elif opcode == "motion_changeyby": # change y by ()
206-
s.setXyDelta(0, float(block.getInputValue("dy")))
206+
s.setXyDelta(0, float(block.getInputValue("dy", eventContainer=events)))
207207

208208
elif opcode == "motion_turnleft": # turn ccw () degrees
209-
s.setRotDelta(0 - float(block.getInputValue("degrees")))
209+
s.setRotDelta(0 - float(block.getInputValue("degrees", eventContainer=events)))
210210

211211
elif opcode == "motion_turnright": # turn cw () degrees
212-
s.setRotDelta(float(block.getInputValue("degrees")))
212+
s.setRotDelta(float(block.getInputValue("degrees", eventContainer=events)))
213213

214214
elif opcode == "control_wait": # wait () seconds
215215
block.screenRefresh = True
216216
if not block.waiting:
217217
# Get time delay and convert it to milliseconds
218-
block.timeDelay = int(round(float(float(block.getInputValue("duration"))) * 1000))
218+
block.timeDelay = int(round(float(float(block.getInputValue("duration", eventContainer=events))) * 1000))
219219
block.waiting = True
220220
block.executionTime = 0
221221
print(_("debug-prefix"), _("block-waiting", time=block.timeDelay), file=sys.stderr)
@@ -332,7 +332,7 @@ def execute(block, s, events=eventContainer.EventContainer()):
332332

333333
elif opcode == "control_repeat": # repeat (10) {...}
334334
if block.repeatCounter is None:
335-
block.repeatCounter = int(block.getInputValue("times"))
335+
block.repeatCounter = int(block.getInputValue("times", eventContainer=events))
336336
# Don't mark the loop as ran until done, and do a screen refresh
337337
if block.repeatCounter > 0:
338338
block.blockRan = False
@@ -366,6 +366,32 @@ def execute(block, s, events=eventContainer.EventContainer()):
366366
nb.next = block.blockID
367367
return nextBlock
368368

369+
elif opcode == "control_if": # if <> then {...}
370+
if block.target.blocks[inputs["CONDITION"][1]].evaluateBlockValue(events):
371+
# If there are blocks, get them
372+
if inputs["SUBSTACK"][1]:
373+
# No blocks will be flagged as ran inside a forever loop
374+
for b in block.substack:
375+
s.target.blocks[b].blockRan = False
376+
nextBlock = s.target.blocks[inputs["SUBSTACK"][1]]
377+
nb = s.target.blocks[inputs["SUBSTACK"][1]]
378+
block.substack.add(nb.blockID)
379+
while nb.next and nb.next not in block.substack:
380+
nb.blockRan = False
381+
nb.waiting = False
382+
nb.timeDelay = 0
383+
nb.executionTime = 0
384+
nb = s.target.blocks[nb.next]
385+
block.substack.add(nb.blockID)
386+
nb.next = block.next
387+
block.blockRan = True
388+
return nextBlock
389+
block.blockRan = True
390+
# TODO why does it hang???
391+
else:
392+
block.blockRan = True
393+
return s.target.blocks[block.next]
394+
369395
elif opcode == "looks_switchcostumeto": # switch costume to [... v]
370396
nextBlock = block.getBlockInputValue("costume")
371397
return s.target.blocks[nextBlock]
@@ -429,9 +455,9 @@ def execute(block, s, events=eventContainer.EventContainer()):
429455
if block.proccode == "​​log​​ %s": # Scratch Addons log ()
430456
print("[", datetime.now().strftime("%H:%M:%S:%f"), "]", _("project-log"), block.getCustomInputValue(0), file=sys.stderr)
431457
elif block.proccode == "​​warn​​ %s": # Scratch Addons warn ()
432-
print(_("project-warn"), block.getCustomInputValue(0), file=sys.stderr)
458+
print("[", datetime.now().strftime("%H:%M:%S:%f"), "]", _("project-warn"), block.getCustomInputValue(0), file=sys.stderr)
433459
elif block.proccode == "​​error​​ %s": # Scratch Addons error ()
434-
print(_("project-error"), block.getCustomInputValue(0), file=sys.stderr)
460+
print("[", datetime.now().strftime("%H:%M:%S:%f"), "]", _("project-error"), block.getCustomInputValue(0), file=sys.stderr)
435461

436462
else:
437463
print(_("unknown-opcode"), opcode)

targetSprite.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def setXy(self, x, y):
8181
# Set X and Y
8282
self.x = x
8383
self.y = y
84-
print(_("debug-prefix"), _("new-sprite-position", x=x, y=y, name=self.name), file=sys.stderr)
84+
# print(_("debug-prefix"), _("new-sprite-position", x=x, y=y, name=self.name), file=sys.stderr)
8585
# Scratch really is weird.
8686
if self.isBitmap:
8787
self.rect.x = self.x + scratch.WIDTH // 2 - round(self.target.costumes[self.target.currentCostume].rotationCenterX) + round(self.imageSize[0] / 2)

0 commit comments

Comments
 (0)