- Title: Smooth top-down wall collisions.
- Description: This may be in the official tutorials. I don't know. Not many does. No new beginners ever look at those anyway. And if they do, they sure don't decide to learn from it.
- GM Version: GM8
- Registered: Only if collision_circle is pro.
- File Type: .gmk
- File Size: 9.86 kB
- File Link: http://www.mediafire...9r1odr99uamtq45
- Required Extensions: None.
- Required DLLs: None.
Attention: The attached GMK does not contain all of the collision scripts listed below.
This is a collection of collision scripts that can be used for any and all top-down games.
Some may suit your needs to perfection.
We encourage everybody to post their own collision scripts so that they may be added to the collection for everyone to enjoy.
#1 by Jobo:
This is generally for circular sprites, but can easily be adjusted to rectangular or whatever you want. Just change the collision_<shape> code.
Adjust arguments to fit your needs (below code was made for a 32x32 circular sprite). Use with a centered origin on sprite, or adjust to fit.
Place this in a Step event.
if(collision_circle(x + lengthdir_x(6, direction) + hspeed, y + lengthdir_y(6, direction) - vspeed, 16, obj_block, 1, 1)) { // Horizontal collision
hspeed = 0; // Stop horizontal movement
}
if(collision_circle(x + lengthdir_x(6, direction) - hspeed, y + lengthdir_y(6, direction) + vspeed, 16, obj_block, 1, 1)) { // Vertical collision
vspeed = 0; // Stop vertical movement
}#2 by Nocturne:
This works best with centered origin sprite.
Place this in a Collision event.
//This one is for 32x32 horizontal and vertical walls ONLY
var xDif, yDif;
xDif = x - other.x;
yDif = y - other.y;
if abs(xDif)>abs(yDif)
{
x = other.x + sign(xDif) * 32;
}
else
{
y = other.y + sign(yDif) * 32;
}#3 by Nocturne:
This works best with centered origin sprite.
Place this in a Collision event.
//This one is a similar concept as #2, but slightly more general... x += 0.1 * (x - (other.x)); y += 0.1 * (y - (other.y));
#4 by slayer 64:
This script checks all solid objects.
Place this in a Step event.
if hspeed!=0
if !place_free(x+hspeed,y)
{
if hspeed>0 move_contact_solid(0,hspeed)
if hspeed<0 move_contact_solid(180,-hspeed)
hspeed=0
}
if vspeed!=0
if !place_free(x+hspeed,y+vspeed)
{
if vspeed>0 move_contact_solid(270,vspeed)
if vspeed<0 move_contact_solid(90,-vspeed)
vspeed=0
}#5 by TheSnidr:
First script is used only to slide past circular shapes.
Second script is used only to slide past rectangular shapes.
Downloadable usage example: http://www.host-a.ne...voidshapes.gm81
//avoid_circle(player_radius,x,y,radius)
//(x,y) is the center of the circle
var d;
argument3+=argument0
d=point_distance(x,y,argument1,argument2)
if d>0 and d<argument3
{
xx=argument1+(x-argument1)*argument3/d
yy=argument2+(y-argument2)*argument3/d
return 1;
}
return 0;//avoid_rectangle(player_radius,x,y,width,height,angle)
//(x,y) is the center of the rectangle
var xto,yto,v,h,ah,vh,d;
argument3/=2
argument4/=2
if point_distance(x,y,argument1,argument2) < point_distance(0,0,argument3,argument4)+argument0
{
xto=cos(degtorad(argument5))
yto=sin(degtorad(argument5))
xx=x-argument1
yy=y-argument2
h=(xto*xx-yto*yy)
v=(xto*yy+yto*xx)
ah=abs(h/argument3)
av=abs(v/argument4)
if max(ah,av)<=1
{
//If the object is inside the rectangle
if ah>av{
h=(argument3+argument0)*sign(h)}
else{
v=(argument4+argument0)*sign(v)}
xx=argument1+xto*h+yto*v
yy=argument2+xto*v-yto*h
return 1;
}
else
{
//If the object is touching the rectangle
h=median(h,-argument3,argument3)
v=median(v,-argument4,argument4)
xx=argument1+xto*h+yto*v
yy=argument2+xto*v-yto*h
d=point_distance(xx,yy,x,y)/argument0
if d<1
{
xx+=(x-xx)/d
yy+=(y-yy)/d
return 1;
}
}
}
xx=x
yy=y
return 0;#6 by Nocturne:
Argument0 = target instance (for example obj_wall)
Argument1 = resolution (1-45, low integers are slow, 15 is default)
Place this in either End Step event or Collision event.
//THIS CAN GO IN THE END STEP OF THE INSTANCE
//OR THE COLLISION EVENT WITH AN INSTANCE
//
//scr_move_slide(inst, res);
//
//argument0 = instance to check for
//argument1 = resolution. Must be between 1 and 45 (low numbers are SLOW). 15 is a good default
var xmot, ymot;
x=xprevious;
y=yprevious;
for (i = 0; i < 90; i += argument1)
{
xmot = x + lengthdir_x(speed, direction + i);
ymot = y + lengthdir_y(speed, direction + i);
if !place_meeting(xmot, ymot,argument0) {x = xmot; y = ymot; exit;}
xmot = x + lengthdir_x(speed, direction - i);
ymot = y + lengthdir_y(speed, direction - i);
if !place_meeting(xmot, ymot, argument0) {x = xmot; y = ymot; exit;}
}On behalf of all the contributors to this collection, I gladly say: I hope we've helped you!
Edited by Jobo, 12 May 2012 - 10:13 AM.











