Discuss Scratch

awesome5185
Scratcher
1000+ posts

Clone number block

jromagnoli wrote:

awesome5185 wrote:

ScratchMatrix wrote:

awesome5185 wrote:

ScratchMatrix wrote:

awesome5185 wrote:

Workaround:

when green flag clicked
set [ID v] to [1] // This is a local variable
repeat (Clone Amount)
change [ID v] by (1)
create clone of [myself v]
end

when I start as a clone
if <(ID) = [5]> then
say [my ID is 5!] for (2) secs
end

Did, that help..?
I tried that before, but it isn't a permanent ID. Thanks though!
What do you mean my permanent? Will the clone delete itself? This is “permanent” until deleted.
Well, this method is pretty hard for me to make use of, its really hard to explain Sorry.
It's ok!
It is permanent as long as the variable is set “for this sprite only”. You can't use global vars.
That's what I said ^ (-_-)
kenny2scratch
Scratcher
500+ posts

Clone number block

I know there is a workaround:
when gf clicked
set [id v] to (0) // "for this sprite only"
set [pubid v] to (0) // "for all sprites"
repeat (...)
change [pubid v] by (1)
create clone of [myself v]
end
when I start as a clone
set [id v] to (pubid)
if <(id) = (...)> then
...
end
However that adds two extra variables and is annoying to set up. So I would support that a) the "create clone of []" block changes the id of the target sprite's clone and b) there be a new block,
(id :: control)
So basically,
create clone of [myself v]
=
create clone of [myself v]
change [pubid v] by (1)
and
when I start as a clone
=
when I start as a clone
set (id :: control) to (pubid)

Last edited by kenny2scratch (Feb. 26, 2020 18:06:57)

DadOfMrLog
Scratcher
1000+ posts

Clone number block

No, you don't need two extra variables, you only need the single local variable “id”:

set [id v] to [7] // Temporarily set the value. Seven means something to the project
create clone of [myself v] // new clone will have the ID 7, no need to set it in "when I start as a clone"
set [id v] to [0] // Revert back to whatever the ID is for *this* sprite/clone

I don't see how a special “id” block is any different to a single extra “id” variable (except that you can potentially do whatever you like with the variable).

Last edited by DadOfMrLog (March 14, 2017 07:34:15)

awesome5185
Scratcher
1000+ posts

Clone number block

DadOfMrLog wrote:

No, you don't need two extra variables, you only need the single local variable “id”:

set [id v] to [7] // Temporarily set the value. Seven means something to the project
create clone of [myself v] // new clone will have the ID 7, no need to set it in "when I start as a clone"
set [id v] to [0] // Revert back to whatever the ID is for *this* sprite/clone

I don't see how a special “id” block is any different to a single extra “id” variable (except that you can potentially do whatever you like with the variable).

This is basically a simplified version of what i made ^

However, I don't get what the revert does, and won't this script make all clone ids 7?

Last edited by awesome5185 (March 14, 2017 07:38:46)

DadOfMrLog
Scratcher
1000+ posts

Clone number block

awesome5185 wrote:

This is basically a simplified version of what i made
Yeah… it seems hard to get through, for some reason…

awesome5185 wrote:

However, I don't get what the revert does, and won't this script make all clone ids 7?
I'm assuming that you'd set whatever value you need for the clone that you're creating, and then you set it back to the value that the creating sprite had.

There are all sorts of different scenarios – for example, it doesn't have to be a numerical identifier, and you might not care about being able to identify specific clones, only a specific *type* (e.g. a bullet rather than an enemy ship, since the easiest way to make a clone fire a clone is to have both as clones of the same sprite – see example project here: https://scratch-mit-edu.ezproxyberklee.flo.org/projects/22222215/ )

So, in that case you might have something like:
when GF clicked
hide
create (10) ship clones // probably want this to run without screen refresh
define create (N) ship clones
set [clone type v] to [ship]
repeat (N)
create clone of [myself v]
end
set [clone type v] to [none] // 'cos original sprite isn't a 'ship', but only creates clones
when I start as a clone
if <(clone type)=[ship]> then
do ship stuff :: custom block // sets ship costume, moves it around, makes it shoot, etc.
else
if <(clone type)=[missile]> then
do missile stuff :: custom block // this sets missile costume and moves it, etc.
end
end

At some point the ship would want to shoot, and would do something like:

define do ship stuff
initialise the ship, move it to its starting position, show it, etc... :: grey
repeat until <some condition for ship to end :: operators> // whatever that may be
make ship do some stuff, move around, etc... :: grey
if <time for ship to fire :: operators> then // however that may be decided
set [clone type v] to [missile] // want to make new clone act as missile
create clone of [myself v] // new clone will have 'clone type' set to "missile"
set [clone type v] to [ship] // set this back to what it should be for *this* ship clone
end
end

The great thing about the above system is that the missile will start at the same location as the ship that's firing it, and will point in the right direction, etc. – since the new clone ‘inherits’ everything from the parent clone.

You can then use the ‘clone type’ to respond to broadcasts in some appropriate way, for example:
when I receive [EMP v] // player used an EMP which blows up all missiles
if <(clone type)=[missile]> then
make it blow up with an explosion, etc... :: grey
delete this clone
end

Does that help explain what's going on?

Last edited by DadOfMrLog (March 14, 2017 08:03:32)

awesome5185
Scratcher
1000+ posts

Clone number block

DadOfMrLog wrote:

<Snip>

Does that help explain what's going on?

Yup! Thanks for your time to explain!
~
So to clarify, this script could merge two sprites into one with the “ID” right? Saving up clutter etc.
miniepicness
Scratcher
1000+ posts

Clone number block

ScratchMatrix wrote:

awesome5185 wrote:

ScratchMatrix wrote:

awesome5185 wrote:

Workaround:

when green flag clicked
set [ID v] to [1] // This is a local variable
repeat (Clone Amount)
change [ID v] by (1)
create clone of [myself v]
end

when I start as a clone
if <(ID) = [5]> then
say [my ID is 5!] for (2) secs
end

Did, that help..?
I tried that before, but it isn't a permanent ID. Thanks though!
What do you mean my permanent? Will the clone delete itself? This is “permanent” until deleted.
Well, this method is pretty hard for me to make use of, its really hard to explain Sorry.
How else would you use it?
braxbroscratcher
Scratcher
1000+ posts

Clone number block

ScratchMatrix wrote:

awesome5185 wrote:

ScratchMatrix wrote:

awesome5185 wrote:

Workaround:

when green flag clicked
set [ID v] to [1] // This is a local variable
repeat (Clone Amount)
change [ID v] by (1)
create clone of [myself v]
end

when I start as a clone
if <(ID) = [5]> then
say [my ID is 5!] for (2) secs
end

Did, that help..?
I tried that before, but it isn't a permanent ID. Thanks though!
What do you mean my permanent? Will the clone delete itself? This is “permanent” until deleted.
Well, this method is pretty hard for me to make use of, its really hard to explain Sorry.
You'll want a second variable that is set from the initial ID variable (sprite-only ofc, whereas the ID var is global) to minimize it, as I've seen that when you clone a sprite, sometimes var values are reset.
DadOfMrLog
Scratcher
1000+ posts

Clone number block

braxbroscratcher wrote:

You'll want a second variable that is set from the initial ID variable (sprite-only ofc, whereas the ID var is global) to minimize it, as I've seen that when you clone a sprite, sometimes var values are reset.
Hmmm, no, don't think so… They inherit their values from the parent (i.e. whatever created the clone). You shouldn't necessarily need to use a global var at all (I certainly didn't in my examples above, and it's rare I've done it that way in one of my projects, unless I'm actually keeping a global tally of the number of clones used, and I want every new clone to use that number for its ID).

If it was a clone that created the clone (i.e. it did “create clone of myself”) then the new clone will inherit everything from the creator clone (its local vars, its costume, direction, size, effects, etc.)

If it was the original sprite that made the clone (or another sprite that made a clone of this sprite) then the clone inherits everything from the original sprite.

Note that “create clone of SPRITE” will always make it inherit from the original sprite, even if a clone uses that block like that – in that case the clone is NOT creating a clone of itself, but of the original sprite. To ensure a clone passes its values on to a new clone it creates, you must use “create clone of MYSELF”.

I've never seen a clone fail to get its values from the parent – but if you can point to a demo project, I'd be interested…

(One slight caveat to above is if the size of the parent is beyond what Scratch would normally allow – i.e. larger than screen, or smaller than a couple of pixels. In that case, Scratch will act as if you've used the “set size” block on the clone, which bounds the size, so it'll not end up the same as the parent. Conversely, though, Scratch doesn't move a newly created clone that's offscreen to make it on-screen. Inconsistency much… )

awesome5185 wrote:

So to clarify, this script could merge two sprites into one with the “ID” right? Saving up clutter etc.
Yes. Not only saving clutter, but making it much easier in certain cases – such as a projectile firing from a clone, because it inherits everything straight away from the parent (in particular for a projectile: its position & direction).

I'm kinda tempted to think of it in terms of that projectile being an ‘extension’ of that particular ‘ship’, hence why it's the same sprite.

Last edited by DadOfMrLog (March 14, 2017 13:44:07)

braxbroscratcher
Scratcher
1000+ posts

Clone number block

DadOfMrLog wrote:

braxbroscratcher wrote:

You'll want a second variable that is set from the initial ID variable (sprite-only ofc, whereas the ID var is global) to minimize it, as I've seen that when you clone a sprite, sometimes var values are reset.
Hmmm, no, don't think so… They inherit their values from the parent (i.e. whatever created the clone). You shouldn't necessarily need to use a global var at all (I certainly didn't in my examples above, and it's rare I've done it that way in one of my projects, unless I'm actually keeping a global tally of the number of clones used, and I want every new clone to use that number for its ID).

If it was a clone that created the clone (i.e. it did “create clone of myself”) then the new clone will inherit everything from the creator clone (its local vars, its costume, direction, size, effects, etc.)

If it was the original sprite that made the clone (or another sprite that made a clone of this sprite) then the clone inherits everything from the original sprite.

Note that “create clone of SPRITE” will always make it inherit from the original sprite, even if a clone uses that block like that – in that case the clone is NOT creating a clone of itself, but of the original sprite. To ensure a clone passes its values on to a new clone it creates, you must use “create clone of MYSELF”.

I've never seen a clone fail to get its values from the parent – but if you can point to a demo project, I'd be interested…

(One slight caveat to above is if the size of the parent is beyond what Scratch would normally allow – i.e. larger than screen, or smaller than a couple of pixels. In that case, Scratch will act as if you've used the “set size” block on the clone, which bounds the size, so it'll not end up the same as the parent. Conversely, though, Scratch doesn't move a newly created clone that's offscreen to make it on-screen. Inconsistency much… )

awesome5185 wrote:

So to clarify, this script could merge two sprites into one with the “ID” right? Saving up clutter etc.
Yes. Not only saving clutter, but making it much easier in certain cases – such as a projectile firing from a clone, because it inherits everything straight away from the parent (in particular for a projectile: its position & direction).

I'm kinda tempted to think of it in terms of that projectile being an ‘extension’ of that particular ‘ship’, hence why it's the same sprite.

I do it to be safe, as well as to reference number of clones I have when I need it.

It's happened before when I had a var quickly updating with a clone referencing it (e.g. forever increase var by one, forever clone, different scripts) It's nice to have a safeguard from such things - I don't do those type of shenanigans outside of messing with the editor, but better safe than sorry.

Last edited by braxbroscratcher (March 14, 2017 14:35:23)

DadOfMrLog
Scratcher
1000+ posts

Clone number block

Yes, it's usual for the script after a ‘create clone’ block to continue running *before* the clone actually starts up its own “when I start as a clone” script.

It means the following may *not* do what you want:
some stuff before... :: grey
set [global id v] to [5] // you expect the clone to set its local id to 5
create clone of [myself v]
change [global id v] by (1) // but this will probably change global id before clone sets its local id below
more stuff after... :: grey
when I start as a clone
set [local id v] to (global id) // so it ends up set to 6 (or even something else, if you continue changing global id)
etc... :: grey

A good way to check the sequence of events is by adding to a list (ensure it's global):
when GF clicked
delete (all v) of [events v] // global list
add [creating clone...] to [events v]
create clone of [myself v]
add [after create clone] to [events v]
when I start as a clone
add [clone started script] to [events v]

Looking at the list after running will show exactly what order Scratch does everything, and it might surprise you!

I think that's another reason to avoid using a global var…



While on the subject, I'll note that the only reason *this* works:

set [global id v] to [0]
repeat (10)
change [global id v] by (1) // increase *before* creating clone
create clone of [myself v] // note that nothing else happens to global id during this pass of the loop
end
when I start as a clone
set [local id v] to (global id)
etc... :: grey
…is because Scratch causes the top script to yield when it reaches the end of each pass of the loop (assuming it's running with refresh enabled). And that gives the chance for the clone script to start up *before* Scratch goes back to run the next pass of the loop (i.e. before it then increases global id by one).


Now, if it had the blocks in a different order (with the increase after creating the clone):

set [global id v] to [1]
repeat (10)
create clone of [myself v]
change [global id v] by (1) // this is now *after* the create clone block
end
when I start as a clone
set [local id v] to (global id)
etc... :: grey
…then the clone ids will be offset by one (i.e. they will start at 2) because global id got increased by 1 before the clone script started.


Yeah… Scratch may be ‘for kids’, but it can be quite tricky sometimes…

Last edited by DadOfMrLog (March 14, 2017 17:26:02)

BLOKBUSTR_GD
Scratcher
38 posts

Clone number block

This may sound pretty tedious, but it would be pretty useful if there was some kind of Clone ID block.
(Clone ID)
When a new clone is created, it would get a unique ID. That ID stays with the clone until it is deleted. It would be useful for circumstances where a sprite would have to go to a specific clone.
chexbox
Scratcher
100+ posts

Clone number block

You can actually do that. Make a variable called “clone ID” and make sure you select “for this sprite only”. Now change the clone id by one before each clone is created:
when green flag clicked
set [clone id v] to (0)
repeat (10)
create clone of [myself v]
change [clone id v] by (1)
end
when I start as a clone
...
BLOKBUSTR_GD
Scratcher
38 posts

Clone number block

Well, you won't be able to do things like this:

when green flag clicked
point towards [Clone 15]
repeat until <touching [Clone 15] ?>
move (5) steps
end
ScratchDiogoh
Scratcher
1000+ posts

Clone number block

BLOKBUSTR_GD wrote:

Well, you won't be able to do things like this:

when green flag clicked
point towards [Clone 15]
repeat until <touching [Clone 15] ?>
move (5) steps
end
Workaround:
create clone of [me v]
change [ID Number v] by (1)
set [Clone ID v] to (join [Clone] (ID Number)

Last edited by ScratchDiogoh (June 18, 2018 19:49:51)

-ShadowOfTheFuture-
Scratcher
1000+ posts

Clone number block

BLOKBUSTR_GD wrote:

Well, you won't be able to do things like this:

when green flag clicked
point towards [Clone 15]
repeat until <touching [Clone 15] ?>
move (5) steps
end

Instead of putting the touching block in the sprite detecting the clone, you could put it in the clone and make it detect the sprite.

You can also use lists.
MDCCCLXVII
Scratcher
1000+ posts

Clone number block

bump
TopicBumper
New Scratcher
100+ posts

Clone number block

MDCCCLXVII wrote:

bump
Ditto.
the2000
Scratcher
1000+ posts

Clone number block

This seems harmless and could be kind of useful, but I'm not sure if I would actually use this very much when working with clones. I don't know, I guess not all Scratch blocks have to be particularly useful in most situations…
Art-and-more
Scratcher
28 posts

Clone number block

Thats an awesome idea, but as stated, there are many workarounds. That would be a cool block, though, if it tracked the clone id or something, which is a bit harder to workaround.

Powered by DjangoBB