variablesmit-scratch

Variable increasing by 3 instead of 1


In Scratch, I have a variable that is supposed to change by one every time a broadcast is received, however, in testing it changes by three per broadcast and I can't find why. The button used to send the broadcast has 3 clones but each has a different function and sending the broadcast depends on the "button selected" variable being set to "fight" so don't think that would affect the outcome.

I looked through all my code and it's not duplicated, there's nothing else changing the variable, and the broadcast is only being sent once at a time. It even works perfectly fine if I click the blocks to run them myself, but when it does it as the function in-game it changes it by three and I can't understand why.

The code for changing the variable is:

When I receive "attack"
Change "attacktimes" by 1

The code for sending the broadcast is this:

When key "z" pressed
if "enemy turn" = "0"
if "button type" = "fight"
broadcast "fight"

Does anybody know a solution?
Also here is the shared project, it is incomplete though. My project
Steps for recreating the bug are listed in the instructions


Solution

  • Broadcasts are a powerful mechanism, but they can be hard to control, especially in a project that uses clones.

    I looked through all my code and it's not duplicated

    That's irrelevant. It's all in the name: broadcasts go everywhere. What may seem like a single action when looking at the (static) code, may explode in all directions at runtime.

    In general, be very careful when cloning a sprite that has a 'when I receive' message handler. The message handler will be triggered for every clone, as well as the original sprite.

    In your case, sprite 'Error404 Sans' has two clones. Together with the original sprite, that's a total of three objects. When message 'Attack' comes in, the 'when I receive Attack' script will be executed for each of the three objects. Since variable 'AttackTimes' is a global variable, it will be incremented three times.

    So how to fix this? In this case, the easiest way is to move the whole 'when I receive Attack' script to the stage, to a dummy sprite or any other sprite that is not cloned. It's cute to have a Sans sprite made up of three parts, giving him that 'breathing' look. But that is already a big responsibility for a sprite; better implement the 'attacking' part elsewhere. Otherwise, you'll find yourself being attacked independently by Sans's head, torso and legs.

    A more clumsy solution would be use an 'if-then' block to ensure only one specific clone will proceed with the attack. For the 'if' condition, you will need a 'for this sprite only' variable or anything else that is clone-specific (e.g. position, costume name).