I need help with a game I'm working on. ( http://scratch.mit.edu/projects/cds56/652703 )
It is a one sprite one-script game with a health bar, a player, and enemies.
right now the player is a green square, and the enemy is a little box, the as of now just sort of bounces back and forth.
Since It is a one sprite one script game, how do I get it to get the enemy to sense if hes touching the player? (they are the same sprite!)
and I already know how to make the health bar shorter.
http://scratch.mit.edu/projects/cds56/652703
Last edited by cds56 (2009-08-19 15:25:38)
Offline
You mean something like this:
http://scratch.mit.edu/projects/justtestingstickman/652852
In that, it repeats until your character's X and Y variables are within 10 of the opponent's X and Y variables (the boxes are 10x10) and then says it caught you and stops the script.
Offline
BoltBait wrote:
Have you tried "touching color"?
Won't work because it's pen not sprites.
Offline
Yeah, justtesting, I used ur hittest script with the rounding and such, so I luvd ur and faved ur project.
I released the next version of the TEST. with cwappy AI and REAL LIVE HELTH BAR!!!!
http://scratch.mit.edu/projects/cds56/652912
Last edited by cds56 (2009-08-19 18:08:05)
Offline
Here's a method I devised. I haven't tested it in Scratch, but go for it! (Maybe I'll *gasp* make a project out of it, as it's more advanced than the collision detection used in my Asteroids Renderer)
//Variables for the circle
private var circle.x=20
private var circle.y=20
private var circle.radius=10
private var circle.points=12
private var $circle.step=0
private var $circle.angle=0
//Variables for the square
private var square.x=-20
private var square.y=-20
//A square with a radius? No way!
private var square.radius=10
private var square.direction=0
//Handy dandy loop variable
private var $loop=0
//All-purpose collision variable
private var $collision="true"
//More collision variables
private var $distance=0
private var $distanceX=0
private var $distanceY=0
private var $direction=0
private var $pointX
private var $pointY
private var $greater
/*This flag click script continually broadcasts a render command. If you're adamant about keeping the project one-script as
well as one-sprite, you can combine the scripts, obviously, by placing the scripts from the "when I receive" hats in place of
the block that broadcasts them. For convenience, I break this up into several scripts.*/
when flag clicked{
forever{
broadcast "render" and wait
broadcast "collisions" and wait
}
}
when I receive "render"{
clear;
/*Let's draw the circle first. Circles are painful in this type of real-time rendering as they have to be drawn by the
individual points on the circle rather than with a "move 3 steps"/"turn 3 degrees" loop. I think we can get a decent circle
with 12 points. Technically, we're drawing a dodecagon.*/
pen up;
//In Scratch, I tend to put dollar signs in front of variables that go in loops or are kind of temporary. You just don't get it.
$circle.step=0
$circle.angle=360/circle.points
pen down;
go to x: circle.x , y: circle.y+circle.radius;
repeat (circle.points){
change $circle.step by 1
got to x: circle.x+(sin($circle.step*$circle.angle)*circle.radius) , y: circle.y+(cos($circle.step*$circle.angle)*circle.radius)
}
pen up;
//Now let's do the square. Squares are a bit simpler. Again, you're free to break it up into more broadcasts or combine them if you like.
$loop=0
go to x: square.x+(sin(45+square.direction)*square.radius) , y: square.y+(sin(45+square.direction)*square.radius);
pen down;
repeat (3){
change $loop by 90;
go to x: square.x+(sin(45+square.direction+$loop)*square.radius) , y: square.y+(sin(45+square.direction+$loop)*square.radius);
}
pen up;
}
when I receive "collisions"{
//Now let's check to see whether the two shapes are touching.
if(circle.radius>square.radius){
$greater=circle.radius
}else{
$greater=square.radius
}
if(sqrt(((square.x-circle.x)*(square.x-circle.x))+((square.y-circle.y)*(square.y-circle.y)))<$greater){
//If the center of one object falls within the circular bounds of another, our job gets a whole lot easier.
$collision=true
}else{
/*We're going to find the direction from the square to the circle.
Picture a triangle whose hypotenuse runs from the point in the center of the circle (circle.x,circle.y) to the point in the center of the square (square.x,square.y)
The $distanceX and $distanceY variables form the adjacent and opposite sides of the triangle and are the difference between the objects' x and y positions.*/
$distanceX=square.x-circle.x
$distanceY=square.y-circle.y
//The $distance variable is the distance between the centers the two objects.
$distance=sqrt(((square.x-circle.x)*(square.x-circle.x))+((square.y-circle.y)*(square.y-circle.y)));
$direction=(acos($distanceY/$distance))*($distanceX+0.001/(abs($distanceX)+0.001))
//If for some reason this doesn't work, try changing $direction by 180 at this point.
//Now that we know the direction, we can find the point on the circle that is closest to the square. If that falls within the square, we've got a collision.
$pointX=circle.x+(sin($direction)*$distance)
$pointY=circle.y+(cos($direction)*$distance)
//All that remains to do is determine whether the square's distance to ($pointX,$pointY) is less than or equal to its outer radius.
//I'm recycling the $distance variable, and it will now refer to the distance from (square.x,square.y) to ($pointX,$pointY)
$distance=sqrt(((square.x-$pointX)*(square.x-$pointX))+((square.y-$pointY)*(square.y-$pointY)))
if(not($distance>square.radius)){
$collision=true
say("Whoa, a collision!")
broadcast "collision"
}else{
$collision=false
say("")
}
}
}
when I receive "collision"{
//Do something interesting when the objects collide.
}Good luck and happy collisions!

Offline
Assuming you really want to restrict yourself to one-sprite/one-script, I would just compute the distance between the centers of the square and circle (using the standard distance formula), and check if it was less than about 5 pixels or so.
Offline