Advertisement
Pinkishu

Untitled

Oct 19th, 2014
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     g.Collisions =
  2.     {
  3.         toTile: function(input,downOnBorder)
  4.         {
  5.             if( downOnBorder == null ) { downOnBorder = false; }
  6.             var ret = Math.floor(input);
  7.             if( downOnBorder && ( input % 1 ) === 0 )
  8.             {
  9.                 ret--;
  10.             }
  11.             return ret;
  12.         },
  13.  
  14.         getTiles: function(x,y,w,h,layers)
  15.         {
  16.             var ret = [];
  17.  
  18.             for( var sY = 0; sY < h; sY++ )
  19.             {
  20.                 for( var sX = 0; sX < w; sX++ )
  21.                 {
  22.                     layers.forEach(function(layer)
  23.                     {
  24.                         ret.push(layer.layer.data[ y + sY ][ x + sX ]);
  25.                     });
  26.                 }
  27.             }
  28.  
  29.             return ret;
  30.  
  31.         },
  32.  
  33.  
  34.         /* isWall checks if a specified x/y tile is a wall
  35.         additionally it can check if a NPC also has its bounding box inside that tiles
  36.         @ x        (integer)                                   : x position to check (in tile coordinates)
  37.         @ y        (integer)                                   : y position to check (in tile coordinates)
  38.         @ layers   (Phaser.Group/Array of Phaser.TilemapLayer) : the layers of the map to check
  39.         @ checkNPC (boolean)                                   : if the function should check for NPC bounding boxes intersecting with the tile
  40.  
  41.         returns: object info
  42.         { collision, tileCollision, npcCollision }
  43.         @ collision     (boolean) : if a collision has been found
  44.         @ tileCollision (array)   : array of objects with info on the collision { layer, tile, collision } => layer is the layer of the collision, tile is the tile, collision is a boolean that says if it collided
  45.         @ npcCollision  (array)   : array of NPC objects that collided (if checkNPC was true)
  46.         */
  47.  
  48.         isWall: function(x, y, layers, checkNPC)
  49.         {
  50.             var tileCollisions = [];
  51.             var collision = false;
  52.  
  53.             var layer;
  54.             for( var i = 0, l = layers.length; i < l; i++ )
  55.             {
  56.                 if( layers.type === Phaser.GROUP )
  57.                 {
  58.                     layer = layers.getAt(i);
  59.                 }
  60.                 else
  61.                 {
  62.                     layer = layers[i];
  63.                 }
  64.                 tileCollisions.push( { layer: layer, tile: layer.layer.data[y][x], collision: layer.layer.data[y][x].collides } );
  65.                 if( layer.layer.data[y][x].collides )
  66.                 {
  67.                     collision = true;
  68.                 }
  69.             }
  70.             return { collision: collision, tileCollision: tileCollisions, npcCollision: [] };
  71.         },
  72.  
  73.         /* isAreaWall checks if a specified area has any collisions
  74.         this will call isWall and always pass checkNPC as false, since it easier to just run its own check on the whole area it is checking
  75.         @ x        (integer)                                   : x position to start the check (in tile coordinates)
  76.         @ y        (integer)                                   : y position to start the check (in tile coordinates)
  77.         @ w        (integer)                                   : width of the area to check (in tile coordinates)
  78.         @ h        (integer)                                   : height of the area to check (in tile coordinates)
  79.         @ layers   (Phaser.Group/Array of Phaser.TilemapLayer) : the layers of the map to check
  80.         @ checkNPC (boolean)                                   : if the function should check for NPC bounding boxes intersecting with the area
  81.  
  82.         returns: object info
  83.         { collision, tileCollision, npccollision }
  84.         @ collision     (boolean)  : if any collision has been found
  85.         @ tileCollided  (boolean)  : if a tile collided
  86.         @ npcCollided   (boolean)  : if a npc collided
  87.         @ tileCollision (2D-array) : 2D array of the checked area, each element being a return of isWall call
  88.         @ npcCollision  (array)    : array of NPCs that have a bounding box that intersects or overlaps with the checked area
  89.         */
  90.  
  91.         isAreaWall: function(x,y,w,h,layers,checkNPC)
  92.         {
  93.             var tileCollisions = [];
  94.             var tileCollision = false;
  95.             var collision = false;
  96.             var npcCollision = false;
  97.  
  98.             for( var sX = 0; sX < w; sX++ )
  99.             {
  100.                 tileCollisions[sX] = [];
  101.                 for( var sY = 0; sY < h; sY++ )
  102.                 {
  103.                     tileCollisions[sX][sY] = this.isWall( x + sX, y + sY, layers, false );
  104.                     if(tileCollisions[sX][sY].collision)
  105.                     {
  106.                         collision = true;
  107.                         tileCollision = true;
  108.                     }
  109.                 }
  110.             }
  111.  
  112.             return { collision: collision, tileCollided: tileCollision, npcCollided: npcCollision, tileCollision: tileCollisions, npcCollision: [] };
  113.         },
  114.  
  115.         /* isRectWall checks a rect with direction
  116.         @ x           (float)                                     : x position of where the rect start (in world coordinates)
  117.         @ y           (float)                                     : y position of where the rect starts (in world coordinates)
  118.         @ w           (float)                                     : width of the rect
  119.         @ h           (float)                                     : height of the rect
  120.         @ direction   (integer)                                   : direction to stop through the rect (0 = up, 1 = right, 2 = down, 3 = left)
  121.         @ layers      (Phaser.Group/Array of Phaser.TilemapLayer) : the layers of the map to check
  122.         @ checkNPC    (boolean)                                   : if the function should check for NPC bounding boxes intersecting with the rect
  123.         @ stopOnFirst (boolean)                                   : if to return on first step that has a collision or keep going
  124.  
  125.         returns object info
  126.         { steps, collision, collisions }
  127.         @ steps      (integer) : steps taken
  128.         @ collision  (boolean) : if a collision happened at all
  129.         @ collisions (array)   : array, step as index, each value being a return of isAreaWall (thus [0] will always be the first step and so on
  130.         */
  131.  
  132.         isRectWall: function(x,y,w,h,direction,layers,checkNPC,stopOnFirst)
  133.         {
  134.             var start;
  135.             var end;
  136.             var mod;
  137.  
  138.             var pos = [ x, y ];
  139.             var tilePos = [ this.toTile(x), this.toTile(y) ];
  140.             var size = [ w, h ];
  141.             var tileSize = [    Math.ceil(w) + ( ((x % 0) !== 0) && ((w % 0) === 0) ? 1 : 0 ),
  142.                                 Math.ceil(h) + ( ((y % 0) !== 0) && ((h % 0) === 0) ? 1 : 0 ) ];
  143.             if(direction === 3 || direction === 0)
  144.             {
  145.                 mod = -1;
  146.             }
  147.             else
  148.             {
  149.                 mod = 1;
  150.             }
  151.             var stepIndex = (direction === 1 || direction === 3) ? 0 : 1;
  152.  
  153.             start = pos[stepIndex] + (mod === -1 ? size[stepIndex] : 0 );
  154.             end = start + size[stepIndex] * mod;
  155.  
  156.             var startTile, endTile;
  157.             startTile = this.toTile( start, mod === 1 );
  158.             endTile = this.toTile( end, mod === 1 );
  159.             var steps = Math.abs(startTile - endTile);
  160.  
  161.             var checkPos, checkSize;
  162.  
  163.             if(startTile === endTile)
  164.             {
  165.                 return { steps: 0, collision: false, collisions: [] };
  166.             }
  167.             else
  168.             {
  169.                 var collisionInfo;
  170.                 var collisionInfos = [];
  171.                 var collision = false;
  172.                 for( var i = 0; i < steps; i++ )
  173.                 {
  174.                     checkPos = [ tilePos[0], tilePos[1] ];
  175.                     checkPos[stepIndex] = startTile + mod + i * mod;
  176.  
  177.                     checkSize = [ tileSize[0], tileSize[1] ];
  178.                     checkSize[stepIndex] = 1;
  179.  
  180.                     collisionInfo = this.isAreaWall( checkPos[0], checkPos[1], checkSize[0], checkSize[1], layers, checkNPC );
  181.  
  182.                     if(collisionInfo.collision)
  183.                     {
  184.                         if(stopOnFirst)
  185.                         {
  186.                             return { steps: i + 1, collision: true, collisions: [collisionInfo] };
  187.                         }
  188.                         else
  189.                         {
  190.                             collisionInfos[i] = collisionInfo;
  191.                             collision = true;
  192.                         }
  193.                     }
  194.                 }
  195.             }
  196.  
  197.             return { steps: i, collision: collision, collisions: collisionInfos };
  198.  
  199.         },
  200.  
  201.         /* collideMovement calls isRectWall with the right parameters and calculates the new move vector that should be applied
  202.         @ sprite     (Phaser.Sprite)                             : the sprite to check the collision for
  203.         @ moveVector (array)                                     : array of the x/y movement that is desired
  204.         @ layers     (Phaser.Group/Array of Phaser.TilemapLayer) : the layers of the map to check
  205.         @ checkNPC   (boolean)                                   : if the function should check for NPC bounding boxes intersecting with the sprite
  206.  
  207.         returns object
  208.         { newMoveVector, rectCollisionInfo }
  209.         @ newMoveVector     (array)            : x/y movement that should be applied
  210.         @ rectCollisionInfo (array of objects) : returns of isRectWall
  211.         */
  212.  
  213.         collideMovement: function(sprite,moveVector,layers,checkNPC)
  214.         {
  215.             var axisOrder = [ "x", "y" ];
  216.             var indexOrder = [ 0, 1 ];
  217.  
  218.             if( Math.abs(moveVector[1]) > Math.abs(moveVector[0]) )
  219.             {
  220.                 axisOrder = [ "y", "x" ];
  221.                 indexOrder = [ 1, 0 ];
  222.             }
  223.  
  224.             var pos = [ sprite.worldX, sprite.worldY ];
  225.  
  226.             var size = [ sprite.worldWidth, sprite.worldHeight ];
  227.             var centerPos = [ sprite.worldX + size[0] / 2, sprite.worldY + size[1] / 2 ];
  228.  
  229.             var checkSize = [ sprite.worldWidth + ( sprite.worldX % 1 === 0 ? 0 : 1 ), sprite.worldHeight + ( sprite.worldY % 1 === 0 ? 0 : 1 ) ];
  230.  
  231.             var rectCollisionInfo = [];
  232.  
  233.             var newMoveVector = [0,0];
  234.  
  235.             var other, nAxis, moveDistance, tilePos, axis, nm, m, mod, move, direction, inside, outside, start, end, rectSize, checkPos, firstCollision, collidedTile, returnObject = {};
  236.  
  237.             for( var i = 0, l = moveVector.length; i < l; i++ )
  238.             {
  239.                 m = indexOrder[i];
  240.                 other = ( i === 0 ? 1 : 0 );
  241.                 axis = axisOrder[i];
  242.                 nm = indexOrder[other];
  243.                 nAxis = axisOrder[other];
  244.  
  245.  
  246.                 move = moveVector[m];
  247.                 if( move === 0 ) { continue; }
  248.                 mod = ( move < 0 ? -1 : 1 );
  249.  
  250.                 if( axisOrder[i] === "x" )
  251.                 {
  252.                     direction = ( mod === -1 ? 3 : 1 );
  253.                 }
  254.                 else
  255.                 {
  256.                     direction = ( mod === -1 ? 0 : 2 );
  257.                 }
  258.  
  259.                 inside = centerPos[m] + size[m] / 2 * mod;
  260.                 outside = inside + move;
  261.  
  262.                 start = ( mod === -1 ? outside : inside );
  263.                 end = ( mod === -1 ? inside : outside );
  264.  
  265.                 rectSize = [];
  266.                 rectSize[m] = end - start;
  267.                 rectSize[nm] = checkSize[nm];
  268.  
  269.                 checkPos = [ pos[0], pos[1] ];
  270.                 checkPos[m] = start;
  271.  
  272.                 rectCollisionInfo[m] = this.isRectWall(checkPos[0], checkPos[1], rectSize[0], rectSize[1], direction, layers, checkNPC, false);
  273.                 //rectCollisionInfo = collisionInfo;
  274.  
  275.                 if(rectCollisionInfo[m].collision)
  276.                 {
  277.                     firstCollision = rectCollisionInfo[m].collisions[0];
  278.                     if(firstCollision.tileCollided)
  279.                     {
  280.                         collidedTile = firstCollision.tileCollision[0][0].tileCollision[0].tile;
  281.                         tilePos = collidedTile[axis] + ( mod === 1 ? 0 : 1 );
  282.  
  283.  
  284.                         moveDistance = tilePos - inside;
  285.                         newMoveVector[m] = moveDistance;
  286.                     }
  287.  
  288.                 }
  289.                 else
  290.                 {
  291.                     newMoveVector[m] = moveVector[m];
  292.                 }
  293.             }
  294.  
  295.             returnObject.newMoveVector = newMoveVector;
  296.             returnObject.rectCollisionInfo = rectCollisionInfo;
  297.             return returnObject;
  298.         },
  299.  
  300.         /* doMove just calls collideMovement and applies the return vector
  301.         @ sprite     (Phaser.Sprite)                             : the sprite to move
  302.         @ moveVector (array)                                     : x/y desired movement
  303.         @ layers     (Phaser.Group/Array of Phaser.TilemapLayer) : the layers of the map to check
  304.         @ checkNPC   (boolean)                                   : if the function should check for NPC bounding boxes intersecting with the sprite during the movement
  305.  
  306.         returns nothing
  307.         */
  308.  
  309.         doMove: function(sprite,newMoveVector,layers,checkNPC)
  310.         {
  311.             var result = this.collideMovement(sprite,newMoveVector,layers,checkNPC);
  312.  
  313.             sprite.worldX += result.newMoveVector[0];
  314.             sprite.worldY += result.newMoveVector[1];
  315.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement