Discuss Scratch

Chillout5
Scratcher
6 posts

How do I make a sprite go to a random position, but not overlapping another sprite?

Like this, but better. This code keeps forcing the sprite to spawn. I want the sprite to spawn anywhere but on Sprite 6.
go to x: (300) y: (pick random (-100) to (100))
if <touching [Sprite 6] ?> then
go to x: (300) y: (pick random (-100) to (100))
end
deck26
Scratcher
1000+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

Sharing what you have might help us understand better what you're doing. By fixing x you'll have limited options for y which will work. You could try using the y-position of sprite6 as a baseline figure and add a random value of 50 to 100 (for example) to that. You could multiply the adjustment by a random value -1 or 1 as well to allow the clone to be above or below.
FiveCubed
Scratcher
100+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

This should work:
go to x: (300) y: (pick random (-100) to (100))
repeat until <not<touching [Sprite 6] ?>>
go to x: (300) y: (pick random (-100) to (100))
end
deenfoxx
Scratcher
100+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

Just a note… do that (what FiveCubed said) inside a custom block set to “Run Without Screen Refresh”, otherwise it will be drawing it every time it re-calls the “go to x/y” block, causing flickers of the sprite in the wrong spot.



define spawn (x)(y1)(y2)
go to x: (x) y: (pick random (y1) to (y2))
repeat until <not<touching [Sprite 6] ?>>
go to x: (x) y: (pick random (y1) to (y2))
end
deenfoxx
Scratcher
100+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

Also note, it must be visible even though it is in the custom block executing without screen refresh. So, I threw the “show” block in there to make sure it is visible. Hidden sprites cannot detect collisions with other sprites.

define spawn (x)(y1)(y2)
go to x: (x) y: (pick random (y1) to (y2))
show
repeat until <not<touching [Sprite 6] ?>>
go to x: (x) y: (pick random (y1) to (y2))
end

Last edited by deenfoxx (March 22, 2017 19:23:13)

dvargasews
Scratcher
500+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

deenfoxx wrote:

Just a note… do that (what FiveCubed said) inside a custom block set to “Run Without Screen Refresh”, otherwise it will be drawing it every time it re-calls the “go to x/y” block, causing flickers of the sprite in the wrong spot.

define spawn (x)(y1)(y2)
go to x: (x) y: (pick random (y1) to (y2))
show
repeat until <not<touching [Sprite 6] ?>>
go to x: (x) y: (pick random (y1) to (y2))
end
Wouldn't it be better to have the show block after the repeat until block for that purpose?
deenfoxx
Scratcher
100+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

dvargasews wrote:

Wouldn't it be better to have the show block after the repeat until block for that purpose?

No, a hidden sprite cannot detect collisions with other sprites.
asivi
Scratcher
1000+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

dvargasews wrote:

deenfoxx wrote:

Just a note… do that (what FiveCubed said) inside a custom block set to “Run Without Screen Refresh”, otherwise it will be drawing it every time it re-calls the “go to x/y” block, causing flickers of the sprite in the wrong spot.

define spawn (x)(y1)(y2)
go to x: (x) y: (pick random (y1) to (y2))
show
repeat until <not<touching [Sprite 6] ?>>
go to x: (x) y: (pick random (y1) to (y2))
end
Wouldn't it be better to have the show block after the repeat until block for that purpose?
Please re-read the @deenfoxx response.
asivi
Scratcher
1000+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

Ooops! Too late (one more time)
Sorry.
deenfoxx
Scratcher
100+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

asivi wrote:

Please re-read the @deenfoxx response.

It's not dvargasews' fault. I was editing the message when he was responding to the un-edited version. haha.
DadOfMrLog
Scratcher
1000+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

deenfoxx wrote:

dvargasews wrote:

Wouldn't it be better to have the show block after the repeat until block for that purpose?
No, a hidden sprite cannot detect collisions with other sprites.
And yet it *can* detect touching everything else (mouse-pointer, edge, colour)…


Here's a slightly bizarre (but interesting) alternative idea:

go to x: (300) y: (([y position v] of [sprite 6 v])+((((pick random (0) to (1))*(2))-(1))*(pick random (50) to (150))))

The 50 and 150 above are the min & max distances you want it(s centre) to spawn from (centre of) sprite6.

Note that it does end up ‘skewing’ the possible positions to be centred around wherever sprite6 happens to be, but it's just a thought that's a bit different, and might give some ideas…



Last edited by DadOfMrLog (March 22, 2017 21:09:38)

deck26
Scratcher
1000+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

DadOfMrLog wrote:

deenfoxx wrote:

dvargasews wrote:

Wouldn't it be better to have the show block after the repeat until block for that purpose?
No, a hidden sprite cannot detect collisions with other sprites.
And yet it *can* detect touching everything else (mouse-pointer, edge, colour)…


Here's a slightly bizarre (but interesting) alternative idea:

go to x: (300) y: (([y position v] of [sprite 6 v])+((((pick random (0) to (1))*(2))-(1))*(pick random (50) to (150))))

The 50 and 150 above are the min & max distances you want it(s centre) to spawn from (centre of) sprite6.

Note that it does end up ‘skewing’ the possible positions to be centred around wherever sprite6 happens to be, but it's just a thought that's a bit different, and might give some ideas…



That's what I suggested!
deenfoxx
Scratcher
100+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

DadOfMrLog wrote:

Here's a slightly bizarre (but interesting) alternative idea:

go to x: (300) y: (([y position v] of [sprite 6 v])+((((pick random (0) to (1))*(2))-(1))*(pick random (50) to (150))))

The 50 and 150 above are the min & max distances you want it(s centre) to spawn from (centre of) sprite6.




Hahah… only a mathematician is going to love that way of choosing a positive 1 or negative 1.

I love it.

The only problem is it doesn't stay within the -100 and +100… you could literally end up anywhere that is NOT within the 100 pixels centered at sprite 6, even off the screen (pushed back on of course, which could then potentially STILL collide with sprite 6 if it were on the edge also.

So, even though it is an interesting attempt at a one-liner… it is not going to work well in this situation.

Last edited by deenfoxx (March 22, 2017 21:16:57)

deck26
Scratcher
1000+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

deenfoxx wrote:

DadOfMrLog wrote:

Here's a slightly bizarre (but interesting) alternative idea:

go to x: (300) y: (([y position v] of [sprite 6 v])+((((pick random (0) to (1))*(2))-(1))*(pick random (50) to (150))))

The 50 and 150 above are the min & max distances you want it(s centre) to spawn from (centre of) sprite6.




Hahah… only a mathematician is going to love that way of choosing a positive 1 or negative 1.

I love it.

The only problem is it doesn't stay within the -100 and +100… you could literally end up anywhere that is NOT within the 100 pixels centered at sprite 6, even off the screen (pushed back on of course, which could then potentially STILL collide with sprite 6 if it were on the edge also.

So, even though it is an interesting attempt at a one-liner… it is going to work well in this situation.
You'd still need to check for touching for that reason but the chances of having it touch are greatly reduced.
deenfoxx
Scratcher
100+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

deck26 wrote:

You'd still need to check for touching for that reason but the chances of having it touch are greatly reduced.

If you really want something that is simple that will just WORK, and be inclusively between -100 to +100 on the y…

go to x: (300) y: ((([y position v] of [OtherPlayer v]) mod (200)) - (100))

BUT, this is not a random placement, it is exactly 100 points away from the OtherPlayer, either up or down.

P.S. I don't know why we are choosing x as 300, since that is off the stage max of 240 anyway. But, going with the flow.

Last edited by deenfoxx (March 22, 2017 21:43:23)

TheLogFather
Scratcher
1000+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

deck26 wrote:

That's what I suggested!
Ah, wow, so you did – missed that!

deenfoxx wrote:

[The only problem is it doesn't stay within the -100 and +100… you could literally end up anywhere that is NOT within the 100 pixels centered at sprite 6, even off the screen (pushed back on of course, which could then potentially STILL collide with sprite 6 if it were on the edge also.

Yeah, indeed it's not exactly the same as the OP, but just some food for thought.


On a slightly more general note, there are a couple of tricks that I use to place a bunch of clones in random-looking positions, but without overlap.

One is used in here to place the arrows (see the “clones” custom block, and note the slight ‘jitter’ in position in the “when I start as a clone” script):


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

The other is used here to place the piles at the start (and it does it slowly so you can actually see what it does):
[EDIT: oops, this is maybe not quite what I was thinking – see my next post, apologies!]


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


Maybe those ideas (somewhat related to this topic) could prove useful at some point…?

Last edited by TheLogFather (March 22, 2017 22:22:50)

deenfoxx
Scratcher
100+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

I just tested it… this also works if you want some randomness…

set [distance v] to (pick random (50) to (100))
go to x: (300) y: ((([y position v] of [OtherPlayer v]) mod ((distance) * (2))) - (distance))

Guaranteed not to touch the OtherPlayer if you pick the minimum (50) correctly. The maximum can be up to 180. Leaving it at 100 keeps it between the -100 and +100.
TheLogFather
Scratcher
1000+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

Hmmm… it's been a while since I did those two project that I mentioned in the previous post. And looking at the second one, I see it's not what I was thinking – it's actually doing the same sort of thing as the first, and just gliding them outwards into position as an animation at the start.


Perhaps the one I had in mind was this one:


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

But in that one it's just doing the outward motion of the turrets (while invisible) to get them placed around the edge of the screen (and they are at fixed positions, not random).

Still, maybe it's enough to give some vague idea of the technique I had in mind…?


Anyway, I'm starting to get somewhat off-topic…

Last edited by TheLogFather (March 22, 2017 22:24:41)

asivi
Scratcher
1000+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

TheLogFather wrote:

Hmmm… it's been a while since I did those two project that I mentioned in the previous post. And looking at the second one, I see it's not what I was thinking – it's actually doing the same sort of thing as the first, and just gliding them outwards into position as an animation at the start.


Perhaps the one I had in mind was this one:


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

But in that one it's just doing the outward motion (while invisible) to get them placed around the edge of the screen (and they are at fixed positions, not random).

Still, maybe it's enough to give some vague idea of the technique I had in mind…?


Anyway, I'm starting to get somewhat off-topic

Please don't spam.
deenfoxx
Scratcher
100+ posts

How do I make a sprite go to a random position, but not overlapping another sprite?

asivi wrote:

Please don't spam.

Yeah, you're making my nice easy solution disappear… I'll repeat it so it doesn't get lost. ;-)

Had to fix the “distance” variable anyway, so it would show up as a user variable it is now “my_distance”.

set [my_distance v] to (pick random (50) to (100))
go to x: (300) y: ((([y position v] of [OtherPlayer v]) mod ((my_distance) * (2))) - (my_distance))

Powered by DjangoBB