Reputation: 31
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
Upvotes: 3
Views: 2534
Reputation: 61
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.
Upvotes: 0
Reputation: 391
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.
Upvotes: 0
Reputation: 21
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
Upvotes: -1
Reputation: 897
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]>>
Upvotes: 3
Reputation: 33409
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
Upvotes: 0
Reputation: 770
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.
Upvotes: 0