Hello scratchers!
I come to you with a request for some help with collision techniques. I have this project where I have my main character that flies around, my objective and my method of death. I also have a hoop. The hoop is meant to be an obstacle that the player has to pass through the centre of. The player should not be able to pass through the sides of the hoop.
The method I have at the moment is extremely poor and involves moving the player upwards (when they have hit into the hoop) until they are not touching it any more. This has two disadvantages: one, the player is still able to go through it if they have enough momentum and two, as the player is repeatedly moved up by the change y position block, they are moved down by gravity. This creates a bouncing effect and does not look very good.
Thanks in advance!
Rook.
Offline
Lovely graphics! Now to the issue. You may be able to do something involving Y position of the hoop subtract the Y position of the player. This will give you the relative y value distance between them. I would then advice making this value always positive. You'd get an equation like this:
Set Relative distance to : √((Ypos of hoop - Ypos of player)^2)
or for ease in scatch: √ ( (Ypos of hoop - Ypos of player) x (Ypos of hoop - Ypos of player) ). You then need to decide what value of this you want to accept the player passing through to have. A script with an IF statement should check the value of this variable and then decide if it can get through.
Eg. if Relative distance < 20 then allow player to pass through, ELSE don't allow.
You'll have to see what value works best and fits the size of the hoop (20 just came of the top of my head)
I hope this helps in some way!
Offline
Here's an idea: Store the positions of the top and bottom of the hoop in a few lists (where item number corresponds to level number). Then, use these scripts. You will not be able to move through the top or bottom of the hoop. This'll make a pretty nice-looking physics interaction (it's the same script that's used for corners in Music Marathon). The scripts are big, but it should work. Anyway, I hope you'll consider it.
Since comments don't work in massive Scratchblocks scripts, here's the description:
Store the locations of the top/bottom x/y positions of the hoop in variables for easy access.
Check the distance to these locations.
If the distance is less than the radius of the player, project the velocity onto the perpendicular to the vector formed between the point and the character.
And that's it! One word of caution, though: make sure that the distance between the top and bottom points is no less than two times the radius, otherwise you'll never be able to get through the hoop.
These scripts use Velocity.X and Velocity.Y to represent X and Y velocities. Those are the only two variables that you have already, all the others won't interfere.
when I receive [Play v] set [Radius v] to [20] // Or however many pixels it actually is. set [Hoop.Bottom.X v] to (item (LevelNumber) of [Hoop.Bottom.X's v]) set [Hoop.Bottom.X v] to (item (LevelNumber) of [Hoop.Bottom.Y's v]) set [Hoop.Top.X v] to (item (LevelNumber) of [Hoop.Top.X's v]) set [Hoop.Top.Y v] to (item (LevelNumber) of [Hoop.Top.Y's v]) repeat until <not <(Playing?) = [true]> > update position, velocity, etc. set [DistanceToHoopBottom v] to ([sqrt v] of ((((x position)-(Hoop.Bottom.X))*((x position)-(Hoop.Bottom.X))) + (((y position)-(Hoop.Bottom.Y))*((y position)-(Hoop.Bottom.Y))))) if <(DistanceToHoopBottom) < (Radius)> set x to (( ( ((x position) - (Hoop.Bottom.X)) * (Radius) ) / (DistanceToHoopBottom)) + (Hoop.Bottom.X)) set y to (( ( ((y position) - (Hoop.Bottom.Y)) * (Radius) ) / (DistanceToHoopBottom)) + (Hoop.Bottom.Y)) set [Surface.X v] to ((y position) - (Hoop.Bottom.Y)) // The perpendicular to vector <x, y> is set [Surface.Y v] to ([-1] * ((x position) - (Hoop.Bottom.X))) // vector <y, -x>. set [Surface.MagnitudeSquared v] to (((Surface.X) * (Surface.X)) + ((Surface.Y) * (Surface.Y))) set [Surface.Scalar v] to ((((Velocity.X) * (Surface.X)) + ((Velocity.Y) * (Surface.Y))) / (Surface.MagnitudeSquared)) set [Velocity.X v] to ((Surface.X) * (Surface.Scalar)) set [Velocity.Y v] to ((Surface.Y) * (Surface.Scalar)) end set [DistanceToHoopTop v] to ([sqrt v] of ((((x position)-(Hoop.Top.X))*((x position)-(Hoop.Top.X))) + (((y position)-(Hoop.Top.Y))*((y position)-(Hoop.Top.Y))))) if <(DistanceToHoopTop) < (Radius)> set x to (( ( ((x position) - (Hoop.Top.X)) * (Radius) ) / (DistanceToHoopTop)) + (Hoop.Top.X)) set y to (( ( ((y position) - (Hoop.Top.Y)) * (Radius) ) / (DistanceToHoopTop)) + (Hoop.Top.Y)) set [Surface.X v] to ((y position) - (Hoop.Top.Y)) // The perpendicular to vector <x, y> is set [Surface.Y v] to ([-1] * ((x position) - (Hoop.Top.X))) // vector <y, -x>. set [Surface.MagnitudeSquared v] to (((Surface.X) * (Surface.X)) + ((Surface.Y) * (Surface.Y))) set [Surface.Scalar v] to ((((Velocity.X) * (Surface.X)) + ((Velocity.Y) * (Surface.Y))) / (Surface.MagnitudeSquared)) set [Velocity.X v] to ((Surface.X) * (Surface.Scalar)) set [Velocity.Y v] to ((Surface.Y) * (Surface.Scalar)) end end
Last edited by amcerbu (2012-04-26 20:17:15)
Offline
^ Oh... my... gosh...
Offline
amcerbu wrote:
Here's an idea: Store the positions of the top and bottom of the hoop in a few lists (where item number corresponds to level number). Then, use these scripts. You will not be able to move through the top or bottom of the hoop. This'll make a pretty nice-looking physics interaction (it's the same script that's used for corners in Music Marathon). The scripts are big, but it should work. Anyway, I hope you'll consider it.
Since comments don't work in massive Scratchblocks scripts, here's the description:
Store the locations of the top/bottom x/y positions of the hoop in variables for easy access.
Check the distance to these locations.
If the distance is less than the radius of the player, project the velocity onto the perpendicular to the vector formed between the point and the character.
And that's it! One word of caution, though: make sure that the distance between the top and bottom points is no less than two times the radius, otherwise you'll never be able to get through the hoop.
These scripts use Velocity.X and Velocity.Y to represent X and Y velocities. Those are the only two variables that you have already, all the others won't interfere.lots of scripts
Thanks! That works great!
And for anyone interested in seeing how it worked out:
http://scratch.mit.edu/projects/rookwood101/2499554
Last edited by rookwood101 (2012-04-27 11:43:37)
Offline
I'm glad it worked! If you don't want the player to stick to the hoop, put the right/left/up sensing scripts after the scripts for hoop collision.
EDIT: Oh, never mind. I keep thinking in terms of 1s1s. It seems you have separate scripts for motion and collision.
Last edited by amcerbu (2012-04-27 13:21:40)
Offline