This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

Is there a way for "2.5D" advanced collision?

I overwrote the following from `entity.js` in a different file.

```ig.Entity.checkPair = function( a, b ) {

// Do these entities want checks?
if( a.checkAgainst & b.type ) {
a.check( b );
}

if( b.checkAgainst & a.type ) {
b.check( a );
}

// If this pair allows collision, solve it! At least one entity must
// collide ACTIVE or FIXED, while the other one must not collide NEVER.
if (a.collides && b.collides) {
ig.Entity.solveCollision( a, b );
}
};

ig.Entity.solveCollision = function( a, b ) {

// If one entity is FIXED, or the other entity is LITE, the weak
// (FIXED/NON-LITE) entity won't move in collision response
var weak = null;

if (-1 * a.collides == b.collides) {
weak = "none";
} else if (a.collides == 9 || Math.abs(a.collides) > Math.abs(b.collides)) {
weak = b;
} else if (b.collides == 9 || Math.abs(a.collides) < Math.abs(b.collides)) {
weak = a;
}

// Did they already overlap on the X-axis in the last frame? If so,
// this must be a vertical collision!
if(
a.last.x + a.size.x > b.last.x &&
a.last.x < b.last.x + b.size.x
) {
// Which one is on top?
if( a.last.y < b.last.y ) {
if (weak != "none") {
ig.Entity.seperateOnYAxis( a, b, weak );
}
}
else {
if (weak != "none") {
ig.Entity.seperateOnYAxis( b, a, weak );
}
}
a.collideWith( b, 'y' );
b.collideWith( a, 'y' );
}

// Horizontal collision
else if(
a.last.y + a.size.y > b.last.y &&
a.last.y < b.last.y + b.size.y
){
// Which one is on the left?
if( a.last.x < b.last.x ) {
if (weak != "none") {
ig.Entity.seperateOnXAxis( a, b, weak );
}
}
else {
if (weak != "none") {
ig.Entity.seperateOnXAxis( b, a, weak );
}
}
a.collideWith( b, 'x' );
b.collideWith( a, 'x' );
}
};

ig.Entity.seperateOnXAxis = function( left, right, weak ) {
var nudge = (left.pos.x + left.size.x - right.pos.x);

// We have a weak entity, so just move this one
if( weak ) {
var strong = left === weak ? right : left;
weak.vel.x = -weak.vel.x * weak.bounciness + strong.vel.x;

var resWeak = ig.game.collisionMap.trace(
weak.pos.x, weak.pos.y, weak == left ? -nudge : nudge, 0, weak.size.x, weak.size.y
);
weak.pos.x = resWeak.pos.x;
}

// Normal collision - both move
else {
/*var v2 = (left.vel.x - right.vel.x)/2;
left.vel.x = -v2;
right.vel.x = v2;

var resLeft = ig.game.collisionMap.trace(
left.pos.x, left.pos.y, -nudge/2, 0, left.size.x, left.size.y
);
left.pos.x = Math.floor(resLeft.pos.x);

var resRight = ig.game.collisionMap.trace(
right.pos.x, right.pos.y, nudge/2, 0, right.size.x, right.size.y
);
right.pos.x = Math.ceil(resRight.pos.x);*/

var vel = 0;

if (Math.abs(left.vel.x) > Math.abs(right.vel.x)) {
vel = left.vel.x
}

if (Math.abs(left.vel.x) < Math.abs(right.vel.x)) {
vel = right.vel.x
}

left.vel.x = vel;
right.vel.x = vel;
}
};

ig.Entity.seperateOnYAxis = function( top, bottom, weak ) {
var nudge = (top.pos.y + top.size.y - bottom.pos.y);

// We have a weak entity, so just move this one
if( weak ) {
var strong = top === weak ? bottom : top;
weak.vel.y = -weak.vel.y * weak.bounciness + strong.vel.y;

// Riding on a platform?
var nudgeX = 0;
if( weak == top && Math.abs(weak.vel.y - strong.vel.y) < weak.minBounceVelocity ) {
weak.standing = true;
nudgeX = strong.vel.x * ig.system.tick;
}

var resWeak = ig.game.collisionMap.trace(
weak.pos.x, weak.pos.y, nudgeX, weak == top ? -nudge : nudge, weak.size.x, weak.size.y
);
weak.pos.y = resWeak.pos.y;
weak.pos.x = resWeak.pos.x;
}

// Bottom entity is standing - just bounce the top one
else if( ig.game.gravity && (bottom.standing || top.vel.y > 0) ) {
var resTop = ig.game.collisionMap.trace(
top.pos.x, top.pos.y, 0, -(top.pos.y + top.size.y - bottom.pos.y), top.size.x, top.size.y
);
top.pos.y = resTop.pos.y;

if( top.bounciness > 0 && top.vel.y > top.minBounceVelocity ) {
top.vel.y *= -top.bounciness;
}
else {
top.standing = true;
top.vel.y = 0;
}
}

// Normal collision - both move
else {
/*var v2 = (top.vel.y - bottom.vel.y)/2;
top.vel.y = -v2;
bottom.vel.y = v2;

var nudgeX = bottom.vel.x * ig.system.tick;
var resTop = ig.game.collisionMap.trace(
top.pos.x, top.pos.y, nudgeX, -nudge/2, top.size.x, top.size.y
);
top.pos.y = resTop.pos.y;

var resBottom = ig.game.collisionMap.trace(
bottom.pos.x, bottom.pos.y, 0, nudge/2, bottom.size.x, bottom.size.y
);
bottom.pos.y = resBottom.pos.y;*/

var vel = 0;

if (Math.abs(top.vel.x) > Math.abs(bottom.vel.x)) {
vel = top.vel.x
}

if (Math.abs(top.vel.x) < Math.abs(bottom.vel.x)) {
vel = bottom.vel.x
}

top.vel.x = vel;
bottom.vel.x = vel;
}
};
```

I use 0-9 for the `entity.collides`. (Player is 5, Cattle are 4, Cabin is 9).

As you can see in the following gif, the collision works, but the cattle won't effect each other.

You shouldn't need to modify any of those core Impact functions.

Take a look at ig.Entity.collides. By setting your player to `ig.Entity.COLLIDES.FIXED` and cows to `ig.Entity.COLLIDES.ACTIVE`, the player should be able to push cows, and the cows should be able to push each other too.
Quote from Joncom
You shouldn't need to modify any of those core Impact functions.

Take a look at ig.Entity.collides. By setting your player to `ig.Entity.COLLIDES.FIXED` and cows to `ig.Entity.COLLIDES.ACTIVE`, the player should be able to push cows, and the cows should be able to push each other too.

Yes, but when you push a cow in to a solid object (cabin) it is pushed to the side, and doesn't stop the player from pushing it.

EDIT:
Would it be best if I use Box2D?

-Andrew
Is there a plugin that makes it so the player can't move if another entity is in the way? (Not push it to one side?)

-Andrew
Quote from AndrewMast
Would it be best if I use Box2D?
Probably not necessary.

Quote from AndrewMast
Is there a plugin that makes it so the player can't move if another entity is in the way? (Not push it to one side?)
I think I'm not not clear on what you're trying to accomplish...

1) Is the player supposed to be able to move cows?
2) Are cows supposed to be able to move the player?
3) Are cows supposed to be able to move cows?

How come your building is an entity instead of using the collision map?
Quote from Joncom
Probably not necessary.I think I'm not not clear on what you're trying to accomplish...

1) Is the player supposed to be able to move cows?
2) Are cows supposed to be able to move the player?
3) Are cows supposed to be able to move cows?

How come your building is an entity instead of using the collision map?

1). Yes
2). No
3). Yes

In the generation it would be easier to have the cabin as an entity.

Right now, this is my `ig.Entity.solveCollision` function: (It's the best I've got so far)
```ig.Entity.solveCollision = function( a, b ) {
var velA = {x: a.pos.x - a.last.x, y: a.pos.y - a.last.y};
var velB = {x: b.pos.x - b.last.x, y: b.pos.y - b.last.y};

var max = function (a, b) {
return Math.max(Math.abs(a), Math.abs(b)) == Math.abs(a) ? a : b;
};

var getSign = function (a) {
return a / Math.abs(a);
};

var velX = max(velA.x, velB.x);
var velY = max(velA.y, velB.y);

var strongX = velX == velA.x ? a : b;
var strongY = velY == velA.y ? a : b;

var weakX = velX == velA.x ? b : a;
var weakY = velY == velA.y ? b : a;

if (weakX.collides == 9) {
var v = strongX;
strongX = weakX;
weakX = v;
velX *= -1;
}

if (weakY.collides == 9) {
var n = strongY;
strongY = weakY;
weakY = n;
velY *= -1;
}

if (getSign(velX) === -1) {//LEFT
weakX.pos.x = strongX.pos.x - weakX.size.x;
} else if (getSign(velX) === 1) {//RIGHT
weakX.pos.x = strongX.pos.x + strongX.size.x;
}

if (getSign(velY) === -1) {//UP
weakY.pos.y = strongY.pos.y - weakY.size.y;
} else if (getSign(velY) === 1) {//DOWN
weakY.pos.y = strongY.pos.y + strongY.size.y;
}
}
```

I think I know why this is not 100% working. It&`039;s because of the order of the "#solveCollision`"s.
I can now move the cabin, because both the player and cabin are FIXED
First things first. Why is your cabin an entity? Perhaps try using the collision map for that instead. In other words, create a collision map in Weltmeister, and define what areas of the cabin are not walkable.

http://impactjs.com/documentation/video-tutorial-weltmeister
AndrewMast: Basically, the collision system in Impact is not very advanced. As you've noticed, many entities colliding with each other won't "line up" and push each other, they will stack, which is seldom what you want. Using Box2D would fix this particular problem, but I imagine it would introduce a host of others which you don't want to deal with. I realize that I never really found a great way to solve this problem, I used Box2D for one of my projects and it worked out rather well, but I wouldn't recommend it in your case.

I think you're probably on the right track with doing some modifications to the way Impact handles collisions, hope you figure it out!
Page 1 of 1
« first « previous next › last »