Author Topic: [fixed! OHBOY!]Collision bug, this is now driving me utterly insane.  (Read 2433 times)

zez

  • Active Member
  • ***
  • Posts: 203
  • Karma: +0/-0
    • View Profile
    • Devlog
So, the bug, is that during collisions, sometimes objects are forced into walls, then hurled off screen well overlapping the wall (its on the far walls, they either fly straight up and off the map, or straight down, every once in a blue moon they fly straight through the colliding tile and out the other side as well...) It generally occurs well the object against the wall is facing away from it, and happens more often (although not exclusively,) during collisions where the colliding object (not the one being forced through the wall,) is above the other. Its also pretty much driving me insane. It happens pretty much regardless of what sprite is being collided as well, so Im fairly sure it isnt something to do with the object itself. Im using flixel 2.34, and making the collide calls the usual way (I think,) right before the update, I basically have group.collide(other group) a few times (sprites, objects, walls, basically all colliding with each other, although objects and sprites dont collide...)
Im not really sure whats going on with this, and its driving me friggin nuts.
Should I just upgrade to 2.35? Is this a known bug? Am I just doing something friggin wonky? A lot of my sprites have velocity.x = speed, or = -speed, as apposed to += speed *flxg.elapsed or -= speed * flxg.elapsed, mostly because I want them to go from not moving to full speed instantly as apposed to easing into it and sliding around, could that be related? ???
Ima pull out my hair now. KTHNX bye.
« Last Edit: Sun, May 9, 2010 by zez »

Beppo5

  • Member
  • **
  • Posts: 37
  • Karma: +0/-0
    • View Profile
Re: Collision bug, this is now driving me utterly insane.
« Reply #1 on: Sun, May 9, 2010 »
I've had this problem too.  So that I can easily talk about this, let's say we have the player and a baddie, where the baddie is running into the player and forcing the player through the wall.  The way I solved this was to set the velocity of the baddie to 0 whenever it collided with the player or another baddie.  I don't think this is the most eligant soluton it was the best I could come up with. 

I'd like to know A better way of doing this too.  Does anyone else have any ideas?

Bjorgen

  • Member
  • **
  • Posts: 59
  • Karma: +0/-0
  • Party hats ftw!
    • View Profile
    • Project Morsel
Re: Collision bug, this is now driving me utterly insane.
« Reply #2 on: Sun, May 9, 2010 »
As per a suggestion from Adam, I ended up doing fake collision resolution for players vs enemies. I do a push-back along the axis of there centers, it seems to work pretty well.

I have 3 collision/overlap calls.

overlap entities vs triggers
overlap enemies vs. player
collide things vs world

Beppo5

  • Member
  • **
  • Posts: 37
  • Karma: +0/-0
    • View Profile
Re: Collision bug, this is now driving me utterly insane.
« Reply #3 on: Sun, May 9, 2010 »
so you check for overlap and then push back?  Can you link to Adams post or paste some code pls?

Bjorgen

  • Member
  • **
  • Posts: 59
  • Karma: +0/-0
  • Party hats ftw!
    • View Profile
    • Project Morsel
Re: Collision bug, this is now driving me utterly insane.
« Reply #4 on: Sun, May 9, 2010 »
Here is the example code from my project.

This is the relevent code from the states update function.
Code: [Select]
override public function update():void
{

...

super.update();

...

// Hot actor on actor action.
FlxU.overlap(EntityManager.ActorList, EntityManager.ActorList, FakeColide);
FlxU.collide(map, collidesVsMap);

...

}

Here is our onOverlap Function. Just tweek the force until the results are desirable.
Code: [Select]
public function FakeColide(Object1:FlxObject, Object2:FlxObject):void
{
var tmpVel:FlxPoint = new FlxPoint();
tmpVel.x = (Object1.x + Object1.width/2) - (Object2.x + Object2.width/2);
tmpVel.y = (Object1.y + Object1.height/2) - (Object2.y + Object2.height/2);

(Object1 as Actor).ApplyKnockback(tmpVel, 15);
tmpVel.x *= -1;
tmpVel.y *= -1;
(Object2 as Actor).ApplyKnockback(tmpVel, 15);

if (Object2 is Entity)
{
(Object2 as Entity).OnOverlap(Object1);
}
}


In the Actor Class we have this function.
Code: [Select]
public function ApplyKnockback(direction:FlxPoint, force:Number = 0):void
{
        // Special cases go here.
...

if (force != 0)
UtilsG.NormalizeVector(direction,force);

this.velocity.x += direction.x;
this.velocity.y += direction.y;
}


zez

  • Active Member
  • ***
  • Posts: 203
  • Karma: +0/-0
    • View Profile
    • Devlog
Re: Collision bug, this is now driving me utterly insane.
« Reply #5 on: Sun, May 9, 2010 »
Well, that seemed to work, but I have a few questions about it.
1.What is an Entity in this case? I commented out that bit, mostly because I wasnt sure what it was referring to or how to implement, but didnt want to totally get rid of it encase it was important. I just used flxu.overlap(group1, group2, FakeColide) is that about right?
2.Whats UtilsG? Should I worry about it? It SEEMS to be working without it, but I havent done toooo extensive of research.

Once again, right now its mostly working, Ill probably have to tweak some values, and maybe throw in a flag that turns off the players movement (You can now force enemys onto your head instead of through walls, its an improvement for sure, and I think I could get around it by having a switch that flips itself well you are colliding to prevent you from moving (thus setting your velocity instantly back to what it was on collision, and letting you keep pushing enemys) but before I play with it to much I want to make sure Im not omitting something that already accomplishes what Im going for.

Bjorgen

  • Member
  • **
  • Posts: 59
  • Karma: +0/-0
  • Party hats ftw!
    • View Profile
    • Project Morsel
Re: Collision bug, this is now driving me utterly insane.
« Reply #6 on: Sun, May 9, 2010 »
The UtilsG is some helper functions that I have. You would replace that call with your own vector normalization code. without that it uses the distance between the objects as the force.

The entity.OnOverlap is just a function that we could override to give special behaviors to things on overlaps, like status effects and whatnot.

Here are is my normalization code. if you are concerned about speed you might want to copy past the contents of these functions inline instead.

Code: [Select]
static public function NormalizeVector(pnt:FlxPoint, length:Number = 1):void
{
var oldLength:Number = Math.sqrt( (pnt.x * pnt.x) + (pnt.y * pnt.y) );
pnt.x = (pnt.x / oldLength) * length;
pnt.y = (pnt.y / oldLength) * length;
}

zez

  • Active Member
  • ***
  • Posts: 203
  • Karma: +0/-0
    • View Profile
    • Devlog
Re: Collision bug, this is now driving me utterly insane.
« Reply #7 on: Sun, May 9, 2010 »
Awesome, thats about what I thought, but I figured I would check just to make sure I wasnt missing something crucial. This bug has been driving me nuts for about a week now so I super appreciate the help with it. XD<3XD

cjdaniel

  • Guest
Thanks for this. Makes a lot of sense!

BTM

  • Guest
Damnation. It seams I've run into the same problem.

I've got an Actor wandering the level turning the other way around when he hits the FlxTilemap. When the Player walks to him he can push him in either the direction the Actor is moving or the oposite (head-on collision). But - as soon as the Actor is at the wall, facing away from it, and the Player pushesh at him the Actor gets proppeled into the air and lands on top of the Player.

I've tried to implement your fix but no success here. In addition the NormalizeVector function you've supplied - looks like it takes two params, does some math on them (;)) and ... doesn't return them?

All my code aside from Player vs Actor vs Wall works great - Actor vs Wall, Actor vs Actor - all works :(

huafeihua116

  • Guest
Great!!I have 3 collision/overlap calls. :P

zez

  • Active Member
  • ***
  • Posts: 203
  • Karma: +0/-0
    • View Profile
    • Devlog
@BTM, I got around it with an override in hitbottom that moves both the object and the colliding object in opposite directions on the X axis, based on what there X cords are (so, if (this.x > Object.x){this.velocity.x = something positive; Object.velocity.x = something negative;}), and then the opposite for <)
Its kind of a redundant call, in that it will lead to firing the overlap event multiple times, but it also kinda fixes the jump up thing (kinda) and prevents actors from standing on each others heads (the real reason I put it in, standing on an enemy's head is kind of tacky)
You may want to throw something in your overlap event that looks like if(your_map.getTile(actor1.right + something/tilesize,actor1.bottom/tilesize) < your maps collide value && actor2.x < actor1.x){do the overlap check on actor1} else if (your_map.getTile(actor1.left - something/tilesize,actor1.bottom/tilesize) < your maps collide value && actor2.x > actor1.x){do the overlap check on actor1} and then do the same for actor2, that should solve the problem, although it will prevent the fake collide event from firing if both actors have there back to a wall. You are probably going to have to jiggle the tile you are testing as well a little bit. Using bottom may or may not give you the tile under them, as if you trace the coordinates of something standing on a colliding tile, you will notice bottom is actually fluctuating constantly. The reason I would advice bottom as apposed to y, is because if the actor is taller then the tile size, and they collide with one tile, with an open space above it, Y will probably check at the open space. (bottom - 2 or 3, for example, would probably work fine)

Mind you, I havent tested this at all, as I had a totally different solution, that was REALLY a solution to another problem altogether, but doubled as one to this.

BTM

  • Guest
Ok, bear with me ... I've fixed the behaviour by ... setting the enemy entity height to one less pixel - and lo and behold - it f*cking works ... no more jumping, no need to do a fake overlap, enemies can push player etc...