Discuss Scratch

Wasupcuz
Scratcher
10 posts

Recognising clone costumes

I need help because I'm not exactly sure how to have sprites recognize if the clone they're touching has a certain costume activated. Something like
iftouchingCloned Sprite?andcostume #ofCloned Sprite=2thenbroadcastsuccess

Last edited by Wasupcuz (Jan. 17, 2017 01:38:43)

stickfiregames
Scratcher
1000+ posts

Recognising clone costumes

I don't think there is a way to do it directly, but you might be able to send a broadcast to the clone and have the clone do the checking, like this:
iftouchingcloned spritethenbroadcastcheck costumeandwait this also detects the original sprite, you could use a clone ID system if you don't want it towhenIreceivecheck costume this script goes in the cloned spriteiftouchingsprite?andcostume#=2thenbroadcastsuccess

Last edited by stickfiregames (Jan. 17, 2017 02:16:48)

Wasupcuz
Scratcher
10 posts

Recognising clone costumes

stickfiregames wrote:

I don't think there is a way to do it directly, but you might be able to send a broadcast to the clone and have the clone do the checking, like this:
iftouchingcloned spritethenbroadcastcheck costume this also detects the original sprite, you could use a clone ID system if you don't want it towhenIreceivecheck costume this script goes in the cloned spriteiftouchingsprite?andcostume#=2thenbroadcastsuccess
thank ya. I'll try it out
Despicable_Dad
Scratcher
500+ posts

Recognising clone costumes

That way (OP) doesn't work, because it's the parent sprite that's tested.
You could try to work around it by having a global list containing up-to-date costume numbers of all your clones.
For this example, I'm assuming you have a PLAYER sprite and a bunch of GHOST clones.
Each ghost clone would have its own ID number as a local variable, which would correspond to a position in the list.
When a ghost clone detects a collision with PLAYER, it updates a global variable (e.g. “clone just hit”) with its ID number, and broadcasts “Player hit a ghost”.
PLAYER sprite responds to that broadcast by checking the value of “clone just hit” and looking up the costume number at that position in the list.

Here's a demo: https://scratch.mit.edu/projects/140319410/

There may be a more efficient way… this is just off the top of my head.

Last edited by Despicable_Dad (Jan. 17, 2017 03:14:55)

Wasupcuz
Scratcher
10 posts

Recognising clone costumes

Despicable_Dad wrote:

That way (OP) doesn't work, because it's the parent sprite that's tested.
You could try to work around it by having a global list containing up-to-date costume numbers of all your clones.
For this example, I'm assuming you have a PLAYER sprite and a bunch of GHOST clones.
Each ghost clone would have its own ID number as a local variable, which would correspond to a position in the list.
When a ghost clone detects a collision with PLAYER, it updates a global variable (e.g. “clone just hit”) with its ID number, and broadcasts “Player hit a ghost”.
PLAYER sprite responds to that broadcast by checking the value of “clone just hit” and looking up the costume number at that position in the list.

There may be a more efficient way… this is just off the top of my head.
Thank you very much but I just got it working.

stickfiregames wrote:

I don't think there is a way to do it directly, but you might be able to send a broadcast to the clone and have the clone do the checking, like this:
iftouchingcloned spritethenbroadcastcheck costumeandwait this also detects the original sprite, you could use a clone ID system if you don't want it towhenIreceivecheck costume this script goes in the cloned spriteiftouchingsprite?andcostume#=2thenbroadcastsuccess
Finally got it. I had to make tweaks because the project is a lot more complicated than I let on

Last edited by Wasupcuz (Jan. 17, 2017 03:08:37)

TheLogFather
Scratcher
1000+ posts

Recognising clone costumes

stickfiregames wrote:

I don't think there is a way to do it directly, but you might be able to send a broadcast to the clone and have the clone do the checking, like this:
iftouchingcloned spritethenbroadcastcheck costumeandwait this also detects the original sprite, you could use a clone ID system if you don't want it towhenIreceivecheck costume this script goes in the cloned spriteiftouchingsprite?andcostume#=2thenbroadcastsuccess
The method above will probably work *most* of the time, but it's possible it won't really be 100% reliable (depending on what else you're doing in the first sprite).

The reason is because all sorts of things can happen between the two touching tests (the one in the first sprite and the one in the clone), which can mean that the second test ends up not being true, even though the first one was. (Though it's possible that will actually end up not making any difference in practice, if the first sprite never does anything else when it discovers it is touching the clone.)

For a demo of such things (and an explanation of why it can happen), see this project:


https://scratch.mit.edu/projects/125830858/


I'd suggest a more reliable way to do it would be all from within the clone itself – i.e. have the clone do the touching test, and send the broadcast to the other sprite, along with its own costume number/name in a global var. (You may not even need to send a broadcast, if you can make any appropriate changes to health and/or score variable, or whatever, from within the clone, simply by having those as global vars instead.)

Doing it that way ensures there is only a single touching test, so there cannot be a mismatch between what the sprite and clone think they are touching.


The caveat to all of above would be if your first sprite is actually one of several clones itself.

In that case, you can't easily avoid having two touching tests, and you have to use a “wait 0 secs” block to pause the first clone for a frame, as well as making sure you don't do anything else in the first clone until the second clone has done its test, and making sure you don't move or change the second clone in any way before it does its test, so that you can ensure the two touching tests will agree reliably.


Hope that kinda makes some sense!

Last edited by TheLogFather (Jan. 17, 2017 10:59:17)

stickfiregames
Scratcher
1000+ posts

Recognising clone costumes

TheLogFather wrote:

stickfiregames wrote:

I don't think there is a way to do it directly, but you might be able to send a broadcast to the clone and have the clone do the checking, like this:
iftouchingcloned spritethenbroadcastcheck costumeandwait this also detects the original sprite, you could use a clone ID system if you don't want it towhenIreceivecheck costume this script goes in the cloned spriteiftouchingsprite?andcostume#=2thenbroadcastsuccess
The method above will probably work *most* of the time, but it's possible it won't really be 100% reliable (depending on what else you're doing in the first sprite).

The reason is because all sorts of things can happen between the two touching tests (the one in the first sprite and the one in the clone), which can mean that the second test ends up not being true, even though the first one was. (Though it's possible that will actually end up not making any difference in practice, if the first sprite never does anything else when it discovers it is touching the clone.)

-snip-

You're right about things happening in between colour tests - I didn't think of that because I normally run one script at a time from a central loop. Would it affect my example though? As far as I can tell it will do the first collision test, broadcast “check costume”, and immediately do the second collision test in all the clones. Or does broadcasting have a frame delay?
TheLogFather
Scratcher
1000+ posts

Recognising clone costumes

stickfiregames wrote:

You're right about things happening in between colour tests - I didn't think of that because I normally run one script at a time from a central loop. Would it affect my example though? As far as I can tell it will do the first collision test, broadcast “check costume”, and immediately do the second collision test in all the clones. Or does broadcasting have a frame delay?
The answer is that it all depends on what else is happening, and, in particular, in what order.

If the test with the broadcast-and-wait is the *last* (or only) script that sprite executes within a pass of all its scripts/loops, then what you have above should work fine. (That's one reason I would advocate having a single main loop in a project, which controls pretty much everything else in all sprites, etc. It helps to remove such uncertainties.)


Here's a very simplified example (with two loops in the player-controlled sprite that would obviously be better joined together – but it demonstrates the point, and it's even not uncommon to see things done like this)…

In the player-controlled sprite:
whenclickedforeverifkeyright arrowpressed?thenchangexby5ifkeyleft arrowpressed?thenchangexby-5whenclicked most sensible thing is to put contents of this loop into loop above...foreveriftouchingenemy?thenbroadcasttouched enemyandwait find the touched clone(s), and return its infodosomethingwithEnemyCostume&EnemyID... global variables ...but this is just demonstrating the point in as simple a way as I can make it

In the enemy clones:
whenIstartasacloneforevermovethisenemyaround,etc...whenIreceivetouched enemyiftouchingplayer?thensetEnemy Costumetocostume# if you want to know all of those clones that were touched...setEnemy IDtocloneID ...then you could add these to some lists, or something. only a clone that is touching the player should respond

If the first script (detecting left/right) is executed first, then the above scripting will work reliably. But if the first script gets executed after the second script has sent its broadcast (but before the enemy has started up its corresponding receiver script), then that second script might have moved the player sprite so that it is no longer touching the enemy sprite, so the touching clone global vars will not get set at all. (They may then contain some ‘old’ values from a previous touch, and that may cause it all to go badly wrong…)

And what determines the order that scripts get run is the layer order of the scripts in the sprite. Lower scripts get started first.

That means if the first script (for player movement) is ‘below’ the second script (touching test and broadcast), all will be fine, since it will always run a pass through its loop, and do any movement, before the second script has a chance to send its broadcast.


But now imagine that at some point you want to tidy up your scripts… So you grab that first script, and drag it into a different place in the editor – but that means you have just relayered that script so it is above the second script. Consequently, the next time you run the project, the movement script will run *after* the touching test script. And that means there's the chance that key presses will move the player sprite away from touching the enemy after the broadcast was sent (but before the enemy receiver script runs) – so the enemy clone will no longer know that it was touching the player…


In other words, the behaviour of the project is dependent not only upon the actual scripts it contains, but also on something that is really not at all obvious – just what layer order those two scripts have in the player sprite. (In fact, if those two scripts are not overlapping in some part, there's no way to tell for sure, just by looking at the scripts in the editor, what its behaviour will be! Imagine how many Scratch projects there are out there which fall into that category…)


Basically, you can break a working project simply by dragging a script.
(See this demo project for an example of how just moving a script can totally change the project's behaviour.)

And you thought Scratch was meant to be simple…?

Well, no, there can be some really tricky subtleties in some cases…

Last edited by TheLogFather (Jan. 17, 2017 18:29:03)

MrBeeGamerMakesGamez
New Scratcher
6 posts

Recognising clone costumes

Same problem in mod bee pokemon pls help!!!!
MrBeeGamerMakesGamez
New Scratcher
6 posts

Recognising clone costumes

My code
whenthisspriteclickedifclone=1thenifcostume=TacklethenbroadcastTackle
The problem is it thinks growl is tackle
Nezon
Scratcher
1000+ posts

Recognising clone costumes

Please do not Necropost

Powered by DjangoBB