Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var TIMESLICE_EPSILON = .0001;
- var MAX_TIMESLICE_SUBDIVISIONS = 32;
- var timesliceRemaining;
- function step(e:Event) {
- // controls - spring, keys
- var k = .1;
- var d = .2;
- if (mDown) {
- pl.vx += k*(mouseX-pl.x)-d*pl.vx;
- pl.vy += k*(mouseY-pl.y)-d*pl.vy;
- }
- if (kLeft && !kRight) {
- pl.vx -= pl.speed;
- } else if (kRight && !kLeft) {
- pl.vx += pl.speed;
- }
- if (kUp && !kDown) {
- pl.vy -= pl.speed;
- } else if (kDown && !kUp) {
- pl.vy += pl.speed;
- }
- pl.vx *= .85;
- pl.vy *= .85;
- // collisions + integration
- resolveCollisions();
- pl.x += pl.vx*timesliceRemaining;
- pl.y += pl.vy*timesliceRemaining;
- }
- // comparison vars as opposed to a struct at the moment
- var testTime:Number;
- var testNx:Number;
- var testNy:Number;
- var testSurfaceArea:Number;
- function resolveCollisions() {
- var bestCollision:Collision = new Collision();
- timesliceRemaining = 1;
- var numberOfTimesSubdivided = 0;
- while (timesliceRemaining > TIMESLICE_EPSILON) {
- bestCollision.time = 1+TIMESLICE_EPSILON;
- var collided = false;
- var collisions = 0;
- for (var i = 0; i < rects.length; ++i) {
- // broadphase check
- var bpx = pl.vx > 0 ? pl.x : pl.x + pl.vx;
- var bpy = pl.vy > 0 ? pl.y : pl.y + pl.vy;
- var bpw = pl.vx > 0 ? pl.vx + pl.width : pl.width - pl.vx;
- var bph = pl.vy > 0 ? pl.vy + pl.height : pl.height - pl.vy;
- var left = rects[i].x-(bpx+bpw);
- var right = (rects[i].x+rects[i].width)-bpx;
- var top = rects[i].y-(bpy+bph);
- var bottom = (rects[i].y+rects[i].height)-bpy;
- if (left > 0 || right < 0 || top > 0 || bottom < 0) continue;
- if (intersectionTest(rects[i])) {
- if (testTime < bestCollision.time ||
- (testTime < bestCollision.time+TIMESLICE_EPSILON/* && testSurfaceArea > bestCollision.surfaceArea*/)) {
- collided = true;
- bestCollision.time = testTime;
- bestCollision.nx = testNx;
- bestCollision.ny = testNy;
- bestCollision.surfaceArea = testSurfaceArea;
- }
- }
- }
- if (!collided) break;
- resolveCollision(bestCollision, timesliceRemaining);
- timesliceRemaining = (1-bestCollision.time)*timesliceRemaining;
- numberOfTimesSubdivided++;
- if (numberOfTimesSubdivided > MAX_TIMESLICE_SUBDIVISIONS) {
- trace("max subdivisions reached!");
- break;
- }
- }
- }
- function resolveCollision(collision, dt) {
- // setting position to old position with corrected velocity
- pl.x = pl.x+pl.vx*collision.time;
- pl.y = pl.y+pl.vy*collision.time;
- var nx = collision.nx;
- var ny = collision.ny;
- pl.vx *= dt;
- pl.vy *= dt;
- // inelastic vector 'reflection' for velocity, essentially zeroing it out on the correct axis
- var ndv = nx*pl.vx+ny*pl.vy;
- var rfmag = -1*ndv;
- pl.vx += rfmag*nx;
- pl.vy += rfmag*ny;
- }
- function intersectionTest(rect:Object):Boolean {
- var xInvEntry, yInvEntry;
- var xInvExit, yInvExit;
- if (pl.vx > 0) {
- xInvEntry = rect.x - (pl.x + pl.width);
- xInvExit = (rect.x + rect.width) - pl.x;
- } else {
- xInvEntry = (rect.x + rect.width) - pl.x;
- xInvExit = rect.x - (pl.x + pl.width);
- }
- if (pl.vy > 0) {
- yInvEntry = rect.y - (pl.y + pl.height);
- yInvExit = (rect.y + rect.height) - pl.y;
- } else {
- yInvEntry = (rect.y + rect.height) - pl.y;
- yInvExit = rect.y - (pl.y + pl.height);
- }
- var xEntry, yEntry;
- var xExit, yExit;
- if (pl.vx == 0) {
- xEntry = Number.NEGATIVE_INFINITY;
- xExit = Number.POSITIVE_INFINITY;
- } else {
- xEntry = xInvEntry/pl.vx;
- xExit = xInvExit/pl.vx;
- }
- if (pl.vy == 0) {
- yEntry = Number.NEGATIVE_INFINITY;
- yExit = Number.POSITIVE_INFINITY;
- } else {
- yEntry = yInvEntry/pl.vy;
- yExit = yInvExit/pl.vy;
- }
- var entryTime = Math.max(xEntry, yEntry);
- var exitTime = Math.min(xExit, yExit);
- var mtd;
- // calculating mtd as difference between new position and 'incorrect' overlapping position-to-be
- if (entryTime > exitTime || xEntry < 0 && yEntry < 0 || xEntry > 1 && yEntry > 1) {
- return false;
- } else {
- var normalx, normaly;
- // calculate normal of collided surface
- if (xEntry > yEntry) {
- if (xInvEntry < 0) {
- normalx = 1;
- normaly = 0;
- } else {
- normalx = -1;
- normaly = 0;
- }
- var newx = pl.x+pl.vx*entryTime;
- mtd = Math.abs(newx-pl.x);
- } else {
- if (yInvEntry < 0) {
- normalx = 0;
- normaly = 1;
- } else {
- normalx = 0;
- normaly = -1;
- }
- var newy = pl.y+pl.vy*entryTime;
- mtd = Math.abs(newy-pl.y);
- }
- if (entryTime > 1) return false;
- testTime = entryTime;
- testNx = normalx;
- testNy = normaly;
- testSurfaceArea = mtd;
- return true;
- }
- return false;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement