Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on May 30th, 2013  |  syntax: ActionScript 3  |  size: 4.67 KB  |  views: 61  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. var TIMESLICE_EPSILON = .0001;
  2.  
  3. var MAX_TIMESLICE_SUBDIVISIONS = 32;
  4.  
  5. var timesliceRemaining;
  6.  
  7. function step(e:Event) {
  8.         // controls - spring, keys
  9.        
  10.         var k = .1;
  11.         var d = .2;
  12.        
  13.         if (mDown) {
  14.                 pl.vx += k*(mouseX-pl.x)-d*pl.vx;
  15.                 pl.vy += k*(mouseY-pl.y)-d*pl.vy;
  16.         }
  17.        
  18.         if (kLeft && !kRight) {
  19.                 pl.vx -= pl.speed;
  20.         } else if (kRight && !kLeft) {
  21.                 pl.vx += pl.speed;
  22.         }
  23.         if (kUp && !kDown) {
  24.                 pl.vy -= pl.speed;
  25.         } else if (kDown && !kUp) {
  26.                 pl.vy += pl.speed;
  27.         }
  28.        
  29.         pl.vx *= .85;
  30.         pl.vy *= .85;
  31.        
  32.        
  33.         // collisions + integration
  34.        
  35.         resolveCollisions();
  36.        
  37.         pl.x += pl.vx*timesliceRemaining;
  38.         pl.y += pl.vy*timesliceRemaining;
  39. }
  40.  
  41. // comparison vars as opposed to a struct at the moment
  42.  
  43. var testTime:Number;
  44. var testNx:Number;
  45. var testNy:Number;
  46. var testSurfaceArea:Number;
  47.  
  48.  
  49. function resolveCollisions() {
  50.         var bestCollision:Collision = new Collision();
  51.        
  52.         timesliceRemaining = 1;
  53.         var numberOfTimesSubdivided = 0;
  54.        
  55.         while (timesliceRemaining > TIMESLICE_EPSILON) {
  56.                 bestCollision.time = 1+TIMESLICE_EPSILON;
  57.                 var collided = false;
  58.                
  59.                 var collisions = 0;
  60.                 for (var i = 0; i < rects.length; ++i) {
  61.                         // broadphase check
  62.                        
  63.                         var bpx = pl.vx > 0 ? pl.x : pl.x + pl.vx;
  64.                         var bpy = pl.vy > 0 ? pl.y : pl.y + pl.vy;
  65.                         var bpw = pl.vx > 0 ? pl.vx + pl.width : pl.width - pl.vx;
  66.                         var bph = pl.vy > 0 ? pl.vy + pl.height : pl.height - pl.vy;
  67.                        
  68.                         var left = rects[i].x-(bpx+bpw);
  69.                         var right = (rects[i].x+rects[i].width)-bpx;
  70.                         var top = rects[i].y-(bpy+bph);
  71.                         var bottom = (rects[i].y+rects[i].height)-bpy;
  72.                        
  73.                         if (left > 0 || right < 0 || top > 0 || bottom < 0) continue;
  74.                        
  75.                        
  76.                        
  77.                         if (intersectionTest(rects[i])) {
  78.                                 if (testTime < bestCollision.time ||
  79.                                         (testTime < bestCollision.time+TIMESLICE_EPSILON/* && testSurfaceArea > bestCollision.surfaceArea*/)) {
  80.                                         collided = true;
  81.                                        
  82.                                        
  83.                                         bestCollision.time = testTime;
  84.                                         bestCollision.nx = testNx;
  85.                                         bestCollision.ny = testNy;
  86.                                         bestCollision.surfaceArea = testSurfaceArea;
  87.                                 }
  88.                         }
  89.                 }
  90.                
  91.                 if (!collided) break;
  92.                
  93.                 resolveCollision(bestCollision, timesliceRemaining);
  94.                
  95.                 timesliceRemaining = (1-bestCollision.time)*timesliceRemaining;
  96.                 numberOfTimesSubdivided++;
  97.                
  98.                 if (numberOfTimesSubdivided > MAX_TIMESLICE_SUBDIVISIONS) {
  99.                         trace("max subdivisions reached!");
  100.                         break;
  101.                 }
  102.         }
  103. }
  104.  
  105. function resolveCollision(collision, dt) {
  106.         // setting position to old position with corrected velocity
  107.        
  108.         pl.x = pl.x+pl.vx*collision.time;
  109.         pl.y = pl.y+pl.vy*collision.time;
  110.        
  111.        
  112.         var nx = collision.nx;
  113.         var ny = collision.ny;
  114.        
  115.         pl.vx *= dt;
  116.         pl.vy *= dt;
  117.        
  118.         // inelastic vector 'reflection' for velocity, essentially zeroing it out on the correct axis
  119.        
  120.         var ndv = nx*pl.vx+ny*pl.vy;
  121.         var rfmag = -1*ndv;
  122.         pl.vx += rfmag*nx;
  123.         pl.vy += rfmag*ny;
  124. }
  125.  
  126. function intersectionTest(rect:Object):Boolean {
  127.         var xInvEntry, yInvEntry;
  128.         var xInvExit, yInvExit;
  129.        
  130.         if (pl.vx > 0)  {
  131.                 xInvEntry = rect.x - (pl.x + pl.width);
  132.                 xInvExit = (rect.x + rect.width) - pl.x;
  133.         } else {
  134.                 xInvEntry = (rect.x + rect.width) - pl.x;
  135.                 xInvExit = rect.x - (pl.x + pl.width);
  136.         }
  137.  
  138.         if (pl.vy > 0) {
  139.                 yInvEntry = rect.y - (pl.y + pl.height);
  140.                 yInvExit = (rect.y + rect.height) - pl.y;
  141.         } else {
  142.                 yInvEntry = (rect.y + rect.height) - pl.y;
  143.                 yInvExit = rect.y - (pl.y + pl.height);
  144.         }
  145.        
  146.         var xEntry, yEntry;
  147.         var xExit, yExit;
  148.        
  149.         if (pl.vx == 0) {
  150.                 xEntry = Number.NEGATIVE_INFINITY;
  151.                 xExit = Number.POSITIVE_INFINITY;
  152.         } else {
  153.                 xEntry = xInvEntry/pl.vx;
  154.                 xExit = xInvExit/pl.vx;
  155.         }
  156.         if (pl.vy == 0) {
  157.                 yEntry = Number.NEGATIVE_INFINITY;
  158.                 yExit = Number.POSITIVE_INFINITY;
  159.         } else {
  160.                 yEntry = yInvEntry/pl.vy;
  161.                 yExit = yInvExit/pl.vy;
  162.         }
  163.        
  164.         var entryTime = Math.max(xEntry, yEntry);
  165.         var exitTime = Math.min(xExit, yExit);
  166.        
  167.         var mtd;
  168.        
  169.         // calculating mtd as difference between new position and 'incorrect' overlapping position-to-be
  170.        
  171.         if (entryTime > exitTime || xEntry < 0 && yEntry < 0 || xEntry > 1 && yEntry > 1) {
  172.                 return false;
  173.         } else {
  174.                 var normalx, normaly;
  175.                 // calculate normal of collided surface
  176.                 if (xEntry > yEntry)  {
  177.                         if (xInvEntry < 0) {
  178.                                 normalx = 1;
  179.                                 normaly = 0;
  180.                         } else {
  181.                                 normalx = -1;
  182.                                 normaly = 0;
  183.                         }
  184.                        
  185.                         var newx = pl.x+pl.vx*entryTime;
  186.                         mtd = Math.abs(newx-pl.x);
  187.                 } else {
  188.                         if (yInvEntry < 0) {
  189.                                 normalx = 0;
  190.                                 normaly = 1;
  191.                         } else {
  192.                                 normalx = 0;
  193.                                 normaly = -1;
  194.                         }
  195.                        
  196.                         var newy = pl.y+pl.vy*entryTime;
  197.                         mtd = Math.abs(newy-pl.y);
  198.                 }
  199.                
  200.                 if (entryTime > 1) return false;
  201.                
  202.                 testTime = entryTime;
  203.                 testNx = normalx;
  204.                 testNy = normaly;
  205.                
  206.                 testSurfaceArea = mtd;
  207.                
  208.                 return true;
  209.         }
  210.        
  211.         return false;
  212. }
clone this paste RAW Paste Data