9 years ago by AndrewMast
Is there a way for "2.5D" advanced collision?
I overwrote the following from
I use 0-9 for the
As you can see in the following gif, the collision works, but the cattle won't effect each other.
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.
9 years ago by 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
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. 9 years ago by AndrewMast
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 toig.Entity.COLLIDES.FIXED
and cows toig.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:
9 years ago by AndrewMast
Would it be best if I use Box2D?
-Andrew
-Andrew
9 years ago by 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?)
-Andrew
-Andrew
9 years ago by Joncom
Quote from AndrewMastProbably not necessary.
Would it be best if I use Box2D?
Quote from AndrewMastI think I'm not not clear on what you're trying to accomplish...
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?)
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?
9 years ago by AndrewMast
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. 9 years ago by Joncom
I can now move the cabin, because both the player and cabin are FIXEDFirst 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
9 years ago by Krisjet
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!
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 »