Jump to content


Photo

Top down wall collisions?


  • Please log in to reply
34 replies to this topic

#21 creators124

creators124

    awesomeliciousmember

  • GMC Member
  • 866 posts
  • Version:GM8

Posted 06 May 2012 - 05:22 AM

so what should i do?

smooth collision is tough for GM to even think about!(alot of GML coding and possibly a external file that will make GM understand how to not put pixel with pixel.)
find something through the tutorials and extending Game maker forums to find good smooth movements.
but for now you could slap this Posted Image DnD action or the other one.Posted Image
and move on to your next problem.
  • 0

#22 Jack Indie Box

Jack Indie Box

    GMC Member

  • GMC Member
  • 1460 posts
  • Version:GM:Studio

Posted 06 May 2012 - 09:12 AM

its like you people dont even google it(or listen to me)

smooth collision engine

this was made yearrrrrrrrs ago and works great.
"The engine is intended primarily for top-down games, but it can be used for platformers as well. obj_player3 demonstrates how this functionality can be achieved."

im not sure what version of gm it was made in so may need some tweeking
  • 0

#23 Jobo

Jobo

    No neurons left today

  • GMC Member
  • 2405 posts
  • Version:GM:Studio

Posted 06 May 2012 - 07:36 PM

BBGaming that's absolutely, undoubtedly the most idiotic way of accomplishing this I have ever seen.

Here, I wrote your code for you.

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
}

Now, this may be choppy if you have to speed set under keyboard_check_pressed(); so I suggest setting speed under keyboard_check(); (This way it instantly restores horizontal/vertical movement when there no longer is a collision)

And here's the description of what you don't understand:
collision_circle(x, y, radius, object, precise, not this object);

Downloadable example of this: http://www.mediafire...9r1odr99uamtq45
(Proof that it works, you have no excuse now)

I know this helped you, and I know this works, so have fun.

Edited by Jobo, 06 May 2012 - 07:40 PM.

  • 0

#24 zehevi

zehevi

    GMC Member

  • GMC Member
  • 637 posts
  • Version:GM8

Posted 06 May 2012 - 08:03 PM

Jobo, no need for flaming.

There are two ways to achieve perfect collisions: Motion planning or moving within loops.

Motion planning is easy, before moving to a position you check for an instance in that position.
If no instance found - we can move.
For example:
//left arrow key event
if place_empty(x-4,y) then x-=4;


The second way is abit more advanced:

if !place_meeting(x,y,other) exit; //if theres no collision: exit;

a = point_direction(x,y,other.x,other.y); //find the direction to the instance we collide with
xoff = lengthdir_x(0.5,a); //hope you know what lengthdir is, if not google it
yoff = lengthdir_y(0.5,a);

while place_meeting(x,y,other) { //as long as we collide

x -= xoff; //move
y -= yoff;
}


Second code is much more advance and pretty much the most percise code I can think of. (also good for sliding against objects)
You can use what fits your needs the most.

P.S.
Jobo there's a problem with your code, there will be times when you cannot recover from colliding, you just won't be able to move once you hit a block.

Edited by zehevi, 06 May 2012 - 08:07 PM.

  • 0

#25 Jobo

Jobo

    No neurons left today

  • GMC Member
  • 2405 posts
  • Version:GM:Studio

Posted 06 May 2012 - 08:20 PM

Jobo there's a problem with your code, there will be times when you cannot recover from colliding, you just won't be able to move once you hit a block.

False.
Perhaps you should study my code block, and realize that I have put an offset to the collision circle.
collision_circle(x + offset + offset, y + offset - offset, 16, obj_block, 1, 1)
Here you go. I marked the offsets for you.

Edited by Jobo, 06 May 2012 - 08:24 PM.

  • 0

#26 zehevi

zehevi

    GMC Member

  • GMC Member
  • 637 posts
  • Version:GM8

Posted 06 May 2012 - 08:27 PM

Jobo there's a problem with your code, there will be times when you cannot recover from colliding, you just won't be able to move once you hit a block.

False.
Perhaps you should study my code block, and realize that I have put an offset to the collision circle.
collision_circle(x + offset + offset, y + offset - offset, 16, obj_block, 1, 1)
Here you go. I marked the offsets for you.


Your second offset is "speed", which can be equal to 0.
If you want to use accelerated speed with a sprite larger then 12 then you'll be stuck.
  • 0

#27 Jobo

Jobo

    No neurons left today

  • GMC Member
  • 2405 posts
  • Version:GM:Studio

Posted 06 May 2012 - 08:31 PM

Your second offset is "speed", which can be equal to 0.

I fail to understand your argument.
My second offset is either vspeed or hspeed.

Secondly, the size of the sprite in the example I created is 32.
Speed is set when key 'W' is held, and is always 3.
Set to 0 when released.

Just download my example and try for yourself, you're digging your own grave here.

Edited by Jobo, 06 May 2012 - 08:33 PM.

  • 0

#28 Jack Indie Box

Jack Indie Box

    GMC Member

  • GMC Member
  • 1460 posts
  • Version:GM:Studio

Posted 06 May 2012 - 08:37 PM

Here you go. I marked the offsets for you.

no need to be condescending jobo

and i may be wrong but i dont think "sliding" would work at a slant, as either hspeed or vspeed is 0 which means you cannot have a triangular vector. so although its probably great, there are better ones. Just looking at 3d games with sliding
  • 0

#29 zehevi

zehevi

    GMC Member

  • GMC Member
  • 637 posts
  • Version:GM8

Posted 06 May 2012 - 08:40 PM

Your second offset is "speed", which can be equal to 0.

I fail to understand your argument.
My second offset is either vspeed or hspeed.

Secondly, the size of the sprite in the example I created is 32.
Speed is set when key 'W' is held, and is always 3.
Set to 0 when released.

Just download my example and try for yourself, you're digging your own grave here.


You're right about 1 thing, sprite doesn't matter because you check for collision circle.
Looking at your example, it is far from beeing a "perfect collision".
Check my code with any sprite, any speed and against any wall, that is how perfect collision should look like.

There, I've uploaded an example.
Download smooth wall collisions.gm81 from Host-A

Edited by zehevi, 06 May 2012 - 08:48 PM.

  • 0

#30 creators124

creators124

    awesomeliciousmember

  • GMC Member
  • 866 posts
  • Version:GM8

Posted 06 May 2012 - 08:56 PM


Your second offset is "speed", which can be equal to 0.

I fail to understand your argument.
My second offset is either vspeed or hspeed.

Secondly, the size of the sprite in the example I created is 32.
Speed is set when key 'W' is held, and is always 3.
Set to 0 when released.

Just download my example and try for yourself, you're digging your own grave here.


You're right about 1 thing, sprite doesn't matter because you check for collision circle.
Looking at your example, it is far from beeing a "perfect collision".
Check my code with any sprite, any speed and against any wall, that is how perfect collision should look like.

There, I've uploaded an example.
Download smooth wall collisions.gm81 from Host-A

HOLY GUACAMOLE!
It excelled over JOBO'S example even on my slow computer(sucky performancePosted Image)
I love it!

EDIT:
I also went into debug mode and I set speed to 100 and it still excelled on this sucky computer!Posted Image

sincerely,
CREATORS124

Edited by creators124, 06 May 2012 - 08:58 PM.

  • 0

#31 Jobo

Jobo

    No neurons left today

  • GMC Member
  • 2405 posts
  • Version:GM:Studio

Posted 06 May 2012 - 09:11 PM

and i may be wrong but i dont think "sliding" would work at a slant, as either hspeed or vspeed is 0 which means you cannot have a triangular vector. so although its probably great, there are better ones. Just looking at 3d games with sliding

2D games don't need a third axis. No need to build functionality for one if you don't need it.
hspeed and vspeed can both have an applied speed, it's not one or the other.
My example uses point_direction(x, y, mouse_x, mouse_y); to set direction to obj_player.

no need to be condescending jobo

Jobo, no need for flaming.

He had it coming.

You're right about 1 thing, sprite doesn't matter because you check for collision circle.
Looking at your example, it is far from beeing a "perfect collision".
Check my code with any sprite, any speed and against any wall, that is how perfect collision should look like.

It is perfect if you adjust the values to fit your needs. My pre-set values will obviously not work with a 300x300 sprite.
You can use this code with any sprite, any speed and any and all objects in the room as wall.
  • 0

#32 Jack Indie Box

Jack Indie Box

    GMC Member

  • GMC Member
  • 1460 posts
  • Version:GM:Studio

Posted 06 May 2012 - 11:13 PM

2D games don't need a third axis

you understood me completely wrong... i meant 3d games as in on the xbox or ps3 or wateva with sliding wall collisions which has been popular in games without advance physics, which im pretty sure your code does not do(on slanted surfaces)

hspeed and vspeed can both have an applied speed, it's not one or the other.

i was only reading what your code says, hspeed=0 or vspeed=0 depending on the collision you even added the comment // Horizontal collision and // Vertical collision. which emplies either one would result with one axis speed being 0, which im pretty sure if for eg. hspeed=6 and vspeed=0 or vise versa there is no allowence for a slanted direction

It is perfect if you adjust the values to fit your needs


there is no need to flame anyone on the GMC even if YOU think they deserve it

I would never say any of my work was perfect an its a little egotistical to
  • 0

#33 BBGaming

BBGaming

    Programmer

  • GMC Member
  • 2455 posts
  • Version:GM7

Posted 07 May 2012 - 03:55 AM

BBGaming that's absolutely, undoubtedly the most idiotic way of accomplishing this I have ever seen.

Might be, it was first idea that popped into my head at the time; I'm used to 3D movement which I do in a similar way. I still think the ideal answer is missing though, since your example isn't pixel-perfect and doesn't maintain a constant speed during collision. Perhaps if we split it up more:
dir=point_direction(x,y,mouse_x,mouse_y);
spd=3*mouse_check_button(mb_left);
var xx,yy;
xx=lengthdir_x(spd,dir);
yy=lengthdir_y(spd,dir);
if (place_free(x+xx,y+yy))
{
  x+=xx;
  y+=yy;
}
else
{
  var nx,ny;
  nx=0;
  ny=0;
  if (!place_free(x+xx,y))
  {
    nx=x;
    move_contact_solid(180*(xx<0),spd);
    xx=nx-x;
    x=nx;
    yy=sign(yy)*sqrt(sqr(spd)-sqr(xx));
  }
  if (!place_free(x,y+yy))
  {
    ny=y;
    move_contact_solid(90+180*(yy>0),spd);
    yy=ny-y;
    y=ny;
    if (nx==0)
      xx=sign(xx)*sqrt(sqr(spd)-sqr(yy));
  }
  x+=xx;
  y+=yy;
}
I assumed 90 degree walls, and I don't like hspeed and vspeed so I didn't use them. Also might need a bit of tweaking, I typed it in the fast reply. Of course this is well past the beginner application we were aiming for in the first place; I wouldn't want to just copy and paste this into someone's topic.

By the way, calm down a little bit. No hard feelings, man; I'm not sure what I did to wrong you but I sure didn't mean it.
  • 0

#34 zehevi

zehevi

    GMC Member

  • GMC Member
  • 637 posts
  • Version:GM8

Posted 07 May 2012 - 07:58 AM

@BBgaming: the first part of your code is almost the same as the code I posted, the second part (after the else) is meant to keep the object close to the block?
Cause if so, it is suppose to happen anyways. And this code will work only with a solid walls, what will happen when you collide with a non solid object?
This is abit messy for me, can you explain it abit?

Edit:
I was curious so I tried your code, and as I said it worked only against solid objects.
So I modifyed it to collide with any object (place_empty, move_contact_all) and the results were... bad.
I gained random errors for negative numbers and the ball shaked when in contact.

Edited by zehevi, 07 May 2012 - 08:01 AM.

  • 0

#35 BBGaming

BBGaming

    Programmer

  • GMC Member
  • 2455 posts
  • Version:GM7

Posted 07 May 2012 - 12:41 PM

The goal was to keep the object moving at spd, that's the 'second part' of the code. I prefer this solution because it is more realistic to a computer-controlled character, the same way the player character will always keep the same moving speed even if it is moving around walls. It's also different in that I check for collision before moving and not after, which your example does.

Here's non-solid, although I'm not sure why it's important:

dir=point_direction(x,y,mouse_x,mouse_y);
spd=3*mouse_check_button(mb_left);
var xx,yy;
xx=lengthdir_x(spd,dir);
yy=lengthdir_y(spd,dir);
if (!place_meeting(x+xx,y+yy,o_wall))
{
  x+=xx;
  y+=yy;
}
else
{
  var nx,ny;
  nx=0;
  ny=0;
  if (place_meeting(x+xx,y,o_wall))
  {
    nx=x;
    move_contact_object(180*(xx<0),spd,o_wall);
    xx=nx-x;
    x=nx;
    yy=sign(yy)*sqrt(sqr(spd)-sqr(xx));
  }
  if (place_meeting(x,y+yy,o_wall))
  {
    ny=y;
    move_contact_object(90+180*(yy>0),spd,o_wall);
    yy=ny-y;
    y=ny;
    if (nx==0)
      xx=sign(xx)*sqrt(sqr(spd)-sqr(yy));
  }
  x+=xx;
  y+=yy;
}
This will work with non-solid o_wall or its children. move_contact_object() is a custom script which I don't have on me right now, but is trivial to write. You could conceivably replace it with move_contact_all(), but then you may get weird effects.
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users