Scratch game scoring bug

1.8k views Asked by At

I'm making a paddle ball game on Scratch (just for fun), and I'm running into a problem with my scoring. If you want to look at the code I already wrote, the link to the game is https://scratch.mit.edu/projects/66541388/ . For some reason, when the game is played the score variable does not actually always change by one. It changes by a different number every time I test it. Any ideas on what the problem is or how to fix it?

Here's the core of the code:

when green flag clicked
set [Score v] to [0]
set x to (0)
set y to (0)
point in direction (pick random (-90) to (90))
forever
    if <(y position) < [-146]> then
        broadcast [gameOver v]
        stop [all v]
    end
    if <touching [Paddle v]?> then
        change [color v] effect by (pick random (1) to (1000))
        change [Score v] by (1)
        point in direction (pick random (-90) to (90))
    end
    move (10) steps
    if on edge, bounce
end
6

There are 6 answers

0
Scimonster On

urnotsam's answer is technically correct, but i'd like to give some reasoning behind it and an alternate solution.

The problem lies in the fact that a penguin is not a square. When you hit the paddle, it turns to a random direction, and moves 10 steps. Now, if it started out facing sideways, and the random direction is also pretty much sideways, it can escape with those 10 steps. Same if both are straight up. But if it starts sideways and ends straight up, it's now further below the line than it had been, and even after moving 10 steps, part of it is still touching the paddle. It seems to me that giving it a head start of another ten or twenty steps should let it escape, and not mess up your scoring.

if <touching [Paddle v]?> then
    change [color v] effect by (pick random (1) to (1000))
    change [Score v] by (1)
    point in direction (pick random (-90) to (90))
    move (20) steps
end
0
urnotsam On

Your problem is that you are dealing with a race condition. When you test for collision between your paddle and penguin the penguin does not leave the paddle as quick as the detection is getting called again causing it to add more than one to the score. You can add some timing code so that it can only increment score by 1 if a timer is greater than lets say one second. Then reset the timer after every "legal" hit.

There are other ways to deal with these conditions, but you have to be creative.

0
Peter B. On

The easiest way to avoid scoring multiple touches at the paddle is to count only touches of a ball that is going downwards, not upwards. Once a ball touches the paddle going downwards, its direction is changed to go upwards, so it would not be recounted.

To achieve this in your code, extend the line

if <touching [Paddle v]?> then

by

if <<touching [Paddle v] ?> and <([abs v] of (direction)) > [90]>> then

This works without additional variables or wait functions.

0
UnsignedByte On

Though both answers are correct, you can simply put the scoring in a different block of code, with a wait until <not<touching [Paddle v]>>, like this:

when green flag clicked
forever
    if <touching [Paddle v]> {
        change [color v] effect by (pick random (1) to (1000))
        change [Score v] by (1)
        wait until <not<touching [Paddle v]>>
2
Account_2 On

The first thing you can do is to add a short delay for the scoring, so that the delay would let the penguin move away from the paddle. Then it will not be counted as a score.

However, another idea is to respawn the penguin whenever they score. You will still need a short delay, though. In this way, the penguin would not be in the way of the paddle.

0
TheLittleCoder On

When you change your score by 1 it may count it a few times because it is touching the paddle so you have to add a wait block right after the point in random direction block. It would look like this:

    if <touching [Paddle v]?> then
    change [color v] effect by (pick random (1) to (1000))
    change [Score v] by (1)
    point in direction (pick random (-90) to (90))
    wait [0.1] sec
end