Discuss Scratch

_nix
Scratcher
1000+ posts

Scratch Workaround Guide VII

8to16 wrote:

May I suggest adding the
when (::obsolete) clicked :: events hat
workaround?
Of course, and the suggestion is appreciated! But a couple of people have suggested and discussed this before: here through here, and earlier back here. I don't think we ever actually replied directly, so we'll do that now…

The main part of this workaround guide excludes “when stop clicked” on purpose. It's not that the workarounds aren't creative uses of Scratch's blocks (which would normally totally fit this guide!). I also recognize that this is something that the Scratch programming language totally “allows”. Someone on the Scratch Team is probably aware and decided it didn't matter enough to find a way to make the workaround impossible.

However, the stop button isn't supposed to do stuff. It is rude and possibly scary if you make your project “refuse” to stop, because Scratchers expect the stop button to, you know, stop the project. Sometimes Scratchers stop a project because it turns out their computer's volume was up way too high, and they would be in trouble if stopping played more sound. Generally, if you take away the way that you're supposed to stop a project, people will feel startled and stuck!

It's not part of the workaround guide because we are worried that would give it a lot of exposure, to people who might not think about the consequences. It doesn't really fit the tone of the rest of the guide, either: this is pretty much the only “unsafe” block. A workaround that does work, ooo, but you should think before you use it, spooky!

But you might still have a good reason to use “when stop clicked”. Since anybody can use the workaround, it is up to you to decide if your reason is “good enough” to counter the concerns above. For example, animating in a silent and slow-moving splash screen 1) would not cause volume problems, and 2) probably would not cause visual (motion) problems either. Or you're making an arcade game and could ask if the player wants to submit their score to the leaderboard, even though they quit earlier than if they'd lost in-game.

If you feel that your own reason is good, then go for it—just think about it carefully!

We haven't carefully tested each of these workarounds to know which ones are most reliable. Sorry If someone wants to create projects demonstrating which workarounds work better and ideally why, we can fill in better details here. Until then, if one workaround doesn't quite work, just try another.

Method 1: always reset the timer, detect when it goes past zero (thanks, @1080GBA!)

when [timer v] > (0)
reset timer

when [timer v] > (0)
do something in response to stop being clicked :: grey

Method 2: reset the timer while running, detect when it goes past a small number (thanks, @k0d3rrr / Scratch wiki!)

when green flag clicked
forever
reset timer
end

when [timer v] > (0.1)
do something in response to stop being clicked :: grey

Method 3: set a variable to the timer while running, detect when timer goes past that variable (thanks, @8to16!)

when green flag clicked
forever
set [running timer v] to (timer)
end

when [timer v] > (running timer)
do something in response to stop being clicked :: grey

Method 4: detect when timer goes past a variable plus an offset (thanks, @-ErrorPurpl_157!)

when green flag clicked
forever
set [ahead of timer v] to ((timer) + (1))
end

when [timer v] > (ahead of timer)
do something in response to stop being clicked :: grey
_nix
Scratcher
1000+ posts

Scratch Workaround Guide VII

han614698 pointed us toward their very neat scratchblocks guide, and of course with the new 3.0 blocks on the forums, we're checking it out! Just for fun, here's a rework of a post from a while ago where we tried out a different format for tutorials. It's probably not a format we are going to really come back to, but maybe a neat demo of the new “+” and “-” syntax. Compare with the original post if you want!

_nix wrote:

⎯⎯⎯ WIP content, here be dragons ⎯⎯⎯

x position of clone, costume # of clone, etc

Scratch doesn't have any blocks for interacting with specific clones, but there are pretty simple workarounds for most blocks that might come in handy. They're all based on using a clone ID system. Every clone has its own ID, which is a “for this sprite only” variable that is a unique number for each clone. Clone data gets updated constantly in “for all sprites” lists, and accessed from those lists whenever needed.

This is a more complicated workaround, but once you learn how to use it, you'll have a very powerful tool for all kinds of projects involving clones!

The first step is to create “for all sprites” lists for each piece of information you'll want to track, like X position, Y position, direction, costume number, and so on. Make sure you delete all from each of these lists when the green flag is clicked, because restarting the project always deletes all clones, and you don't want any old data from the last time the project was run getting in the way.

when green flag clicked
delete all of [clone X v] :: list
delete all of [clone Y v] :: list
delete all of [clone direction v] :: list
delete all of [clone costume # v] :: list

Because the order Scratch evaluates blocks in the same frame can be hard to predict, you should use “wait 0 seconds” at the start of other “when flag pressed” scripts which are going to create clones.

Now you'll want to make a new custom block which replaces “create this clone”. Make a “for this sprite only” clone ID variable, too. The custom block will create a new clone, add the current information values to the list, and set the clone ID value to the length of the information lists.

when green flag clicked
set [clone ID v] to [0]

define create and track clone of myself
add (x position) to [clone X v]
add (y position) to [clone Y v]
add (direction) to [clone direction v]
add (costume [number v] :: looks) to [clone costume # v]
set [clone ID v] to (length of [clone X v])
create clone of [myself v]
set [clone ID v] to [0]

If you're going to have clones actually create clones of themselves, change the last part to restore the clone ID to its previous value instead of resetting it to zero. Use an additional “for this sprite only” variable:

define create and track clone of myself
... :: #c0c0c0
add (direction :: #8495dd) to [clone direction v] :: #d78c76
add (costume [number v] :: #a17edd) to [clone costume # v] :: #d78c76
+set [saved clone ID v] to (clone ID)
set [clone ID v] to (length of [clone X v] :: #d78c76) :: #ef8964
create clone of [myself v] :: #e7bd74
+set [clone ID v] to (saved clone ID)

Next, you'll want to have each clone update the information in the “for all sprites” lists. You want this to happen every frame, so the latest information is always in the lists. A simple way is with a forever loop:

when I start as a clone
forever
replace item (clone ID) of [clone X v] with (x position)
replace item (clone ID) of [clone Y v] with (y position)
replace item (clone ID) of [clone direction v] with (direction)
replace item (clone ID) of [clone costume # v] with (costume [number v] :: looks)
end

If your project uses an “update” broadcast loop (such as “forever: broadcast update and wait” or “forever: broadcast tick and wait”), you can skip the forever loop and just put the “replace item” blocks at the bottom of the “when I receive update” script.

Now your project is good to go! If you run it, and show the clone information lists, it should automatically fill up with the details for each clone.

If you know the ID for a clone, you can get information about it by getting it from the lists. For example, ID 3 means that the third item of clone X, the third item of clone Y, the third item of clone direction, and so on, all are the information for that clone. Here's an example script:

when green flag clicked
wait (0) seconds :: control
create and track clone of myself :: custom
forever
set x to ((50) + (item (1) of [clone X v])
set y to ((50) + (item (1) of [clone Y v])
end

when I start as a clone
forever
glide (1) secs to [random position v] :: motion
end

The clone glides somewhere random, and the original sprite follows it.

for each of my clones

You can use a “for this sprite only” list, called “my clones”, to keep track of the clone ID for each clone that a sprite or clone creates of itself. Change the “create and track clone of myself” block to add the new clone ID to that list.

when green flag clicked :: #d4a47a
+delete all of [my clones v]
delete all of [clone X v] :: #d78c76
delete all of [clone Y v] :: #d78c76
... :: #c0c0c0

define create and track clone of myself
... :: #c0c0c0
set [saved clone ID v] to (clone ID :: #ef8964) :: #ef8964
set [clone ID v] to (length of [clone X v] :: #d78c76) :: #ef8964
create clone of [myself v] :: #e7bd74
+add (clone ID) to [my clones v] // Keep track of the new clone ID before restoring it.
set [clone ID v] to (saved clone ID :: #ef8964) :: #ef8964

when I start as a clone :: #e7bd74
+delete all of [my clones v] // The clone gets its own list of clones!
... :: #c0c0c0

Now you can loop over each item in the “my clones” list. Use a repeat loop or a “for” loop. (Look at the workaround for “for each item of list”, in Variables & Lists, for more information.)

set [index v] to [1]
repeat (length of [my clones v])
set [my clone's ID v] to (item (index) of [my clones v])
set [my clone's X v] to (item (my clone's ID) of [clone X v])
set [my clone's Y v] to (item (my clone's ID) of [clone Y v])
... do something interesting ... :: grey
change [index v] by (1)
end

clone that created me, parent ID

You might want a clone to be able to get information about the clone which created it! Track that information in the “create and track clone of” block:

define create and track clone of myself
... :: #c0c0c0
+set [saved parent ID v] to (parent ID) // Like clone ID, we have to restore this when we're done.
set [saved clone ID v] to (clone ID :: #ef8964) :: #ef8964
+set [parent ID v] to (clone ID) // Set parent ID to our own ID before getting a new ID for the new clone!
set [clone ID v] to (length of [clone X v] :: #d78c76) :: #ef8964
create clone of [myself v] :: #e7bd74
+set [parent ID v] to (saved parent ID)
set [clone ID v] to (saved clone ID :: #ef8964) :: #ef8964

(Alternate variable tracking which cuts out the need for “saved clone ID”, shout me out if you like assembly code)

define create and track clone of myself
... :: #c0c0c0
-set [saved clone ID v] to (clone ID)
+set [saved parent ID v] to (parent ID)
+set [parent ID v] to (clone ID)
set [clone ID v] to (length of [clone X v] :: #d78c76) :: #ef8964
create clone of [myself v] :: #e7bd74
-set [clone ID v] to (saved clone ID)
+set [clone ID v] to (parent ID)
+set [parent ID v] to (saved parent ID)

Last edited by _nix (Nov. 7, 2024 02:51:26)

medians
Scratcher
1000+ posts

Scratch Workaround Guide VII

My eyes just died.. also I am now just gonna use images again for my blocks LOL
Edit: god signatures gone again
Edit 2: that edit fixed it

Last edited by medians (Nov. 7, 2024 03:31:35)

secretuch
Scratcher
100+ posts

Scratch Workaround Guide VII

2.0 block turned into 3.0 blocks?
abubriski
Scratcher
500+ posts

Scratch Workaround Guide VII

secretuch wrote:

2.0 block turned into 3.0 blocks?
What do you mean?
medians
Scratcher
1000+ posts

Scratch Workaround Guide VII

PaperMarioFan2022 wrote:

secretuch wrote:

TheCreatorOfUnTV wrote:

secretuch wrote:

-snip-
It actually does work due to how Scratch handles fencing.
I did not say snip
Keep the discussion on topic, please. This is about workarounds, not snipping posts.
Why didn't you literally just explain snipping posts LOL

That guy assumed that part meant what was said..

abubriski wrote:

secretuch wrote:

2.0 block turned into 3.0 blocks?
What do you mean?
That post was made when the forum blocks changed from 2.0 to 3.0

Last edited by medians (Dec. 9, 2024 01:44:29)

Catzcute4
Scratcher
500+ posts

Scratch Workaround Guide VII

about the point to x,y: what is the y of the sprite = the y you point to, because that’ division by zero
tbh this is why i think point to x,y or direction to x,y should be a dedicated block but there’s already suggustions for that

Last edited by Catzcute4 (Dec. 14, 2024 16:39:46)

nembence
Scratcher
100+ posts

Scratch Workaround Guide VII

mouse dragging this sprite? with set drag mode block
set [x v] to (x position)
set x to ((1) - (round (x))) // try to move
if<(x position)=(x)> then
... // failed to move: the mouse is dragging this sprite
else
set x to (x) // reset position
... // the mouse isn't dragging
end
WsDanzel
Scratcher
47 posts

Scratch Workaround Guide VII

medians wrote:

PaperMarioFan2022 wrote:

secretuch wrote:

TheCreatorOfUnTV wrote:

secretuch wrote:

-snip-
It actually does work due to how Scratch handles fencing.
I did not say snip
Keep the discussion on topic, please. This is about workarounds, not snipping posts.
Why didn't you literally just explain snipping posts LOL

That guy assumed that part meant what was said..

abubriski wrote:

secretuch wrote:

2.0 block turned into 3.0 blocks?
What do you mean?
That post was made when the forum blocks changed from 2.0 to 3.0
Why did you say this literally LOL

I can't use ideas and tutorials now K

Catzcute4 wrote:

about the point to x,y: what is the y of the sprite = the y you point to, because that’ division by zero
tbh this is why i think point to x,y or direction to x,y should be a dedicated block but there’s already suggustions for that
Hell I use not this

Last edited by WsDanzel (Dec. 18, 2024 13:55:26)

JelliBeens-2
New Scratcher
25 posts

Scratch Workaround Guide VII

nembence wrote:

mouse dragging this sprite? with set drag mode block
set [x v] to (x position)
set x to ((1) - (round (x))) // try to move
if<(x position)=(x)> then
... // failed to move: the mouse is dragging this sprite
else
set x to (x) // reset position
... // the mouse isn't dragging
end
This is definitely clever, but with flaws

Last edited by JelliBeens-2 (Dec. 21, 2024 03:54:34)

Sviat770
Scratcher
18 posts

Scratch Workaround Guide VII

And will it really be added?
medians
Scratcher
1000+ posts

Scratch Workaround Guide VII

WsDanzel wrote:

Why did you say this literally LOL

I can't use ideas and tutorials now K

Catzcute4 wrote:

about the point to x,y: what is the y of the sprite = the y you point to, because that’ division by zero
tbh this is why i think point to x,y or direction to x,y should be a dedicated block but there’s already suggustions for that
Hell I use not this
I said that because it was obvious they just did not know what snipping was, and because the other person that I quoted was asking what was meant
Also, what LOL
DidcotPrimaryAcademy
New Scratcher
43 posts

Scratch Workaround Guide VII

Got sent a simplified guide, it is very unsafe so fix it.

Last edited by DidcotPrimaryAcademy (Jan. 23, 2025 19:14:57)

secretuch
Scratcher
100+ posts

Scratch Workaround Guide VII

abubriski wrote:

secretuch wrote:

2.0 block turned into 3.0 blocks?
What do you mean?
This is now the move 10 steps block
move (10) steps
AmpElectrecuted
Scratcher
500+ posts

Scratch Workaround Guide VII

_nix wrote:

which uses variables and a “when stage clikced” block
typo
jmdzti_0-0
Scratcher
500+ posts

Scratch Workaround Guide VII

If the microphone or camera is off, the reporter blocks which need these permissions can only report «-1», and we can take advantage of that by making these blocks. These might be useful to make games which need camera or mic permissions.

Mic on?

<not <(loudness) = [-1]>>

Camera on?

<not <(video [motion v] on [Stage v]) = [-1]>>
WsDanzel
Scratcher
47 posts

Scratch Workaround Guide VII

secretuch wrote:

abubriski wrote:

secretuch wrote:

2.0 block turned into 3.0 blocks?
What do you mean?
This is now the move 10 steps block
move (10) steps
that's an image… or not

Last edited by WsDanzel (Feb. 5, 2025 12:40:03)

secretuch
Scratcher
100+ posts

Scratch Workaround Guide VII

WsDanzel wrote:

secretuch wrote:

abubriski wrote:

secretuch wrote:

2.0 block turned into 3.0 blocks?
What do you mean?
This is now the move 10 steps block
move (10) steps
that's an image… or not
Its not an image, its scratchblocks
secretuch
Scratcher
100+ posts

Scratch Workaround Guide VII

TheCreatorOfUnTV wrote:

secretuch wrote:

-snip-
It actually does work due to how Scratch handles fencing.
Why did you change it to -snip-?
Spaceandmoon1
Scratcher
100+ posts

Scratch Workaround Guide VII

Small question: Why does my ‘pen down’ block not work? I want my pen to be able to draw.

Powered by DjangoBB