Advertisement
JuiceBoxx

Untitled

Sep 28th, 2016
2,568
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haxe 26.52 KB | None | 0 0
  1. package;
  2.  
  3. import flash.display.BitmapData;
  4. import flixel.FlxBasic;
  5. import flixel.addons.tile.FlxTilemapExt;
  6. import flixel.addons.tile.FlxTileSpecial;
  7. import flixel.FlxCamera;
  8. import flixel.FlxG;
  9. import flixel.FlxObject;
  10. import flixel.graphics.frames.FlxFrame;
  11. import flixel.graphics.frames.FlxFramesCollection;
  12. import flixel.math.FlxMath;
  13. import flixel.math.FlxMatrix;
  14. import flixel.math.FlxPoint;
  15. import flixel.tile.FlxTile;
  16. import flixel.tile.FlxTilemap;
  17. import flixel.tile.FlxTilemapBuffer;
  18. import flixel.util.FlxDestroyUtil;
  19.  
  20. // TODO: add support for tilemap scaling
  21. // TODO: try to make it cleaner (i mean rendering and animated tiles)
  22.  
  23. /**
  24.  * Extended FlxTilemap class that provides collision detection against slopes
  25.  * Based on the original by Dirk Bunk.
  26.  * ---
  27.  * Also add support to flipped / rotated tiles.
  28.  * @author Peter Christiansen
  29.  * @author MrCdK
  30.  * @author adrianulima
  31.  * @link https://github.com/TheTurnipMaster/SlopeDemo
  32.  */
  33. class HoloTilemapExt extends FlxTilemap
  34. {
  35.     // Slope related variables
  36.     private var _snapping:Int = 2;
  37.     private var _slopePoint:FlxPoint = FlxPoint.get();
  38.     private var _objPoint:FlxPoint = FlxPoint.get();
  39.    
  40.     private var _slopeNorthwest:Array<Int> = [];
  41.     private var _slopeNortheast:Array<Int> = [];
  42.     private var _slopeSouthwest:Array<Int> = [];
  43.     private var _slopeSoutheast:Array<Int> = [];
  44.    
  45.     private var _slopeThickGentle:Array<Int> = [];
  46.     private var _slopeThinGentle:Array<Int> = [];
  47.     private var _slopeThickSteep:Array<Int> = [];
  48.     private var _slopeThinSteep:Array<Int> = [];
  49.    
  50.     // Animated and flipped tiles related variables
  51.     private var _specialTiles:Array<FlxTileSpecial>;
  52.    
  53.     override public function destroy():Void
  54.     {
  55.         _slopePoint = FlxDestroyUtil.put(_slopePoint);
  56.         _objPoint = FlxDestroyUtil.put(_objPoint);
  57.        
  58.         _slopeNorthwest = null;
  59.         _slopeNortheast = null;
  60.         _slopeSouthwest = null;
  61.         _slopeSoutheast = null;
  62.        
  63.         _slopeThickGentle = null;
  64.         _slopeThinGentle = null;
  65.         _slopeThickSteep = null;
  66.         _slopeThinSteep = null;
  67.        
  68.         super.destroy();
  69.        
  70.         _specialTiles = FlxDestroyUtil.destroyArray(_specialTiles);
  71.     }
  72.    
  73.     override public function update(elapsed:Float):Void
  74.     {
  75.         super.update(elapsed);
  76.        
  77.         if (_specialTiles != null && _specialTiles.length > 0)
  78.         {
  79.             for (tile in _specialTiles)
  80.             {
  81.                 if (tile != null && tile.hasAnimation())
  82.                 {
  83.                     tile.update(elapsed);
  84.                 }
  85.             }
  86.         }
  87.     }
  88.    
  89.     /**
  90.      * THIS IS A COPY FROM FlxTilemap BUT IT DEALS WITH FLIPPED AND ROTATED TILES
  91.      * Internal function that actually renders the tilemap to the tilemap buffer.  Called by draw().
  92.      * @param   Buffer      The FlxTilemapBuffer you are rendering to.
  93.      * @param   Camera      The related FlxCamera, mainly for scroll values.
  94.      */
  95.     override private function drawTilemap(Buffer:FlxTilemapBuffer, Camera:FlxCamera):Void
  96.     {
  97.         if (FlxG.renderBlit)
  98.         {
  99.             Buffer.fill();
  100.         }
  101.         else
  102.         {
  103.             getScreenPosition(_point, Camera).copyToFlash(_helperPoint);
  104.            
  105.             _helperPoint.x = isPixelPerfectRender(Camera) ? Math.floor(_helperPoint.x) : _helperPoint.x;
  106.             _helperPoint.y = isPixelPerfectRender(Camera) ? Math.floor(_helperPoint.y) : _helperPoint.y;
  107.         }
  108.        
  109.         var scaledWidth:Float = _tileWidth;
  110.         var scaledHeight:Float = _tileHeight;
  111.        
  112.         var drawX:Float;
  113.         var drawY:Float;
  114.        
  115.         var _tileTransformMatrix:FlxMatrix = null;
  116.         var matrixToUse:FlxMatrix;
  117.        
  118.         var isColored:Bool = ((alpha != 1) || (color != 0xffffff));
  119.        
  120.         // Copy tile images into the tile buffer
  121.         _point.x = (Camera.scroll.x * scrollFactor.x) - x; //modified from getScreenXY()
  122.         _point.y = (Camera.scroll.y * scrollFactor.y) - y;
  123.         var screenXInTiles:Int = Math.floor(_point.x / _tileWidth);
  124.         var screenYInTiles:Int = Math.floor(_point.y / _tileHeight);
  125.         var screenRows:Int = Buffer.rows;
  126.         var screenColumns:Int = Buffer.columns;
  127.        
  128.         // Bound the upper left corner
  129.         screenXInTiles = Std.int(FlxMath.bound(screenXInTiles, 0, widthInTiles - screenColumns));
  130.         screenYInTiles =  Std.int(FlxMath.bound(screenYInTiles, 0, heightInTiles - screenRows));
  131.        
  132.         var rowIndex:Int = screenYInTiles * widthInTiles + screenXInTiles;
  133.         _flashPoint.y = 0;
  134.         var columnIndex:Int;
  135.         var tile:FlxTile;
  136.         var frame:FlxFrame;
  137.         var special:FlxTileSpecial;
  138.  
  139.         #if !FLX_NO_DEBUG
  140.         var debugTile:BitmapData;
  141.         #end
  142.        
  143.         var isSpecial = false;
  144.        
  145.         for (row in 0...screenRows)
  146.         {
  147.             columnIndex = rowIndex;
  148.             _flashPoint.x = 0;
  149.            
  150.             for (column in 0...screenColumns)
  151.             {
  152.                 isSpecial = false;
  153.                 special = null;
  154.                 tile = _tileObjects[_data[columnIndex]];
  155.                
  156.                 if (_specialTiles != null && _specialTiles[columnIndex] != null)
  157.                 {
  158.                     special = _specialTiles[columnIndex];
  159.                     isSpecial = special.isSpecial();
  160.                 }
  161.                
  162.                 if (FlxG.renderBlit)
  163.                 {
  164.                     if (isSpecial)
  165.                     {
  166.                         special.paint(Buffer.pixels, _flashPoint);
  167.                         Buffer.dirty = (special.dirty || Buffer.dirty);
  168.                     }
  169.                     else if (tile != null && tile.visible && tile.frame.type != FlxFrameType.EMPTY)
  170.                     {
  171.                         tile.frame.paint(Buffer.pixels, _flashPoint, true);
  172.                     }
  173.                
  174.             #if !FLX_NO_DEBUG
  175.                 if (FlxG.debugger.drawDebug && !ignoreDrawDebug)
  176.                 {
  177.                     if (tile != null)
  178.                     {
  179.                         if (tile.allowCollisions <= FlxObject.NONE)
  180.                         {
  181.                             debugTile = _debugTileNotSolid;
  182.                         }
  183.                         else if (tile.allowCollisions != FlxObject.ANY)
  184.                         {
  185.                             debugTile = _debugTilePartial;
  186.                         }
  187.                         else
  188.                         {
  189.                             debugTile = _debugTileSolid;
  190.                         }
  191.                        
  192.                         Buffer.pixels.copyPixels(debugTile, _debugRect, _flashPoint, null, null, true);
  193.                     }
  194.                 }
  195.             #end
  196.            
  197.                 }
  198.                 else
  199.                 {
  200.                     frame = (isSpecial) ? special.currFrame : tile.frame;
  201.                    
  202.                     if (frame != null)
  203.                     {
  204.                         drawX = _helperPoint.x + (columnIndex % widthInTiles) * scaledWidth;
  205.                         drawY = _helperPoint.y + Math.floor(columnIndex / widthInTiles) * scaledHeight;
  206.                        
  207.                         if (isSpecial)
  208.                         {
  209.                             _tileTransformMatrix = special.getMatrix();
  210.                             matrixToUse = _tileTransformMatrix;
  211.                         }
  212.                         else
  213.                         {
  214.                             frame.prepareMatrix(_matrix);
  215.                             matrixToUse = _matrix;
  216.                         }
  217.                        
  218.                         matrixToUse.translate(drawX, drawY);
  219.                         Camera.drawPixels(frame, matrixToUse, colorTransform, blend);
  220.                     }
  221.                 }
  222.                
  223.                 if (FlxG.renderBlit)
  224.                 {
  225.                     _flashPoint.x += _tileWidth;
  226.                 }
  227.                 columnIndex++;
  228.             }
  229.            
  230.             rowIndex += widthInTiles;
  231.             if (FlxG.renderBlit)
  232.             {
  233.                 _flashPoint.y += _tileHeight;
  234.             }
  235.         }
  236.        
  237.         Buffer.x = screenXInTiles * _tileWidth;
  238.         Buffer.y = screenYInTiles * _tileHeight;
  239.        
  240.         if (FlxG.renderBlit)
  241.         {
  242.             if (isColored)
  243.             {
  244.                 Buffer.colorTransform(colorTransform);
  245.             }
  246.             Buffer.blend = blend;
  247.         }
  248.     }
  249.    
  250.     /**
  251.      * Set the special tiles (rotated or flipped)
  252.      * @param   tiles   An Array with all the FlxTileSpecial
  253.      */
  254.     public function setSpecialTiles(tiles:Array<FlxTileSpecial>):Void
  255.     {
  256.         _specialTiles = new Array<FlxTileSpecial>();
  257.        
  258.         var tile:FlxTileSpecial;
  259.         for (i in 0...tiles.length)
  260.         {
  261.             tile = tiles[i];
  262.             if (tile != null && tile.isSpecial())
  263.             {
  264.                 _specialTiles[i] = tile;
  265.                
  266.                 tile.currTileId -= _startingIndex;
  267.                 tile.frames = this.frames;
  268.                
  269.                 if (tile.hasAnimation())
  270.                 {
  271.                     var animFrames:Array<Int> = tile.animation.frames;
  272.                     var preparedFrames:Array<Int> = [];
  273.                    
  274.                     for (j in 0...animFrames.length)
  275.                     {
  276.                         preparedFrames[j] = animFrames[j] - _startingIndex;
  277.                     }
  278.                    
  279.                     tile.animation.frames = preparedFrames;
  280.                 }
  281.             }
  282.             else
  283.             {
  284.                 _specialTiles[i] = null;
  285.             }
  286.         }
  287.     }
  288.    
  289.     /**
  290.      * THIS IS A COPY FROM FlxTilemap
  291.      * I've changed draw() to give a chance to set the buffer dirty
  292.      * ---
  293.      * Draws the tilemap buffers to the cameras.
  294.      */
  295.     override public function draw():Void
  296.     {
  297.         var cameras = cameras;
  298.         var camera:FlxCamera;
  299.         var buffer:FlxTilemapBuffer;
  300.         var i:Int = 0;
  301.         var l:Int = cameras.length;
  302.        
  303.         while (i < l)
  304.         {
  305.             camera = cameras[i];
  306.             if (!camera.visible || !camera.exists)
  307.             {
  308.                 continue;
  309.             }
  310.            
  311.             if (_buffers[i] == null)
  312.             {
  313.                 _buffers[i] = new FlxTilemapBuffer(_tileWidth, _tileHeight, widthInTiles, heightInTiles, camera);
  314.                 _buffers[i].pixelPerfectRender = pixelPerfectRender;
  315.             }
  316.            
  317.             buffer = _buffers[i++];
  318.            
  319.             if (FlxG.renderBlit)
  320.             {
  321.                 if (!buffer.dirty)
  322.                 {
  323.                     // Copied from getScreenXY()
  324.                     _point.x = x - (camera.scroll.x * scrollFactor.x) + buffer.x;
  325.                     _point.y = y - (camera.scroll.y * scrollFactor.y) + buffer.y;
  326.                     buffer.dirty = (_point.x > 0) || (_point.y > 0) || (_point.x + buffer.width < camera.width) || (_point.y + buffer.height < camera.height);
  327.                 }
  328.                
  329.                 if (buffer.dirty)
  330.                 {
  331.                     buffer.dirty = false;
  332.                     drawTilemap(buffer, camera);
  333.                 }
  334.                
  335.                 // Copied from getScreenXY()
  336.                 _flashPoint.x = x - (camera.scroll.x * scrollFactor.x) + buffer.x;
  337.                 _flashPoint.y = y - (camera.scroll.y * scrollFactor.y) + buffer.y;
  338.                 buffer.draw(camera, _flashPoint);
  339.                
  340.             }
  341.             else
  342.             {
  343.                 drawTilemap(buffer, camera);
  344.             }
  345.            
  346.             #if !FLX_NO_DEBUG
  347.             FlxBasic.visibleCount++;
  348.             #end
  349.         }
  350.     }
  351.  
  352.     /**
  353.      * THIS IS A COPY FROM FlxTilemap BUT IT SOLVES SLOPE COLLISION TOO
  354.      * Checks if the Object overlaps any tiles with any collision flags set,
  355.      * and calls the specified callback function (if there is one).
  356.      * Also calls the tile's registered callback if the filter matches.
  357.      *
  358.      * @param   Object              The FlxObject you are checking for overlaps against.
  359.      * @param   Callback            An optional function that takes the form "myCallback(Object1:FlxObject,Object2:FlxObject)", where Object1 is a FlxTile object, and Object2 is the object passed in in the first parameter of this method.
  360.      * @param   FlipCallbackParams  Used to preserve A-B list ordering from FlxObject.separate() - returns the FlxTile object as the second parameter instead.
  361.      * @param   Position            Optional, specify a custom position for the tilemap (useful for overlapsAt()-type funcitonality).
  362.      *
  363.      * @return Whether there were overlaps, or if a callback was specified, whatever the return value of the callback was.
  364.      */
  365.     override public function overlapsWithCallback(Object:FlxObject, ?Callback:FlxObject->FlxObject->Bool, FlipCallbackParams:Bool = false, ?Position:FlxPoint):Bool
  366.     {
  367.         var results:Bool = false;
  368.        
  369.         var X:Float = x;
  370.         var Y:Float = y;
  371.        
  372.         if (Position != null)
  373.         {
  374.             X = Position.x;
  375.             Y = Position.y;
  376.         }
  377.        
  378.         //Figure out what tiles we need to check against
  379.         var selectionX:Int = Math.floor((Object.x - X) / _tileWidth);
  380.         var selectionY:Int = Math.floor((Object.y - Y) / _tileHeight);
  381.         var selectionWidth:Int = selectionX + (Math.ceil(Object.width / _tileWidth)) + 1;
  382.         var selectionHeight:Int = selectionY + Math.ceil(Object.height / _tileHeight) + 1;
  383.        
  384.         //Then bound these coordinates by the map edges
  385.         selectionX = FlxMath.maxInt(selectionX, 0);
  386.         selectionY = FlxMath.maxInt(selectionY, 0);
  387.         selectionWidth = FlxMath.minInt(selectionWidth, widthInTiles);
  388.         selectionHeight = FlxMath.minInt(selectionHeight, heightInTiles);
  389.        
  390.         // Then loop through this selection of tiles and call FlxObject.separate() accordingly
  391.         var rowStart:Int = selectionY * widthInTiles;
  392.         var row:Int = selectionY;
  393.         var column:Int;
  394.         var tile:FlxTile;
  395.         var overlapFound:Bool;
  396.         var deltaX:Float = X - last.x;
  397.         var deltaY:Float = Y - last.y;
  398.        
  399.         while (row < selectionHeight)
  400.         {
  401.             column = selectionX;
  402.            
  403.             while (column < selectionWidth)
  404.             {
  405.                 overlapFound = false;
  406.                 tile = _tileObjects[_data[rowStart + column]];
  407.                
  408.                 if (tile.allowCollisions != 0)
  409.                 {
  410.                     tile.x = X + column * _tileWidth;
  411.                     tile.y = Y + row * _tileHeight;
  412.                     tile.last.x = tile.x - deltaX;
  413.                     tile.last.y = tile.y - deltaY;
  414.                    
  415.                     if (Callback != null)
  416.                     {
  417.                         if (FlipCallbackParams)
  418.                         {
  419.                             overlapFound = Callback(Object, tile);
  420.                         }
  421.                         else
  422.                         {
  423.                             overlapFound = Callback(tile, Object);
  424.                         }
  425.                     }
  426.                     else
  427.                     {
  428.                         overlapFound = (Object.x + Object.width > tile.x) && (Object.x < tile.x + tile.width) && (Object.y + Object.height > tile.y) && (Object.y < tile.y + tile.height);
  429.                     }
  430.                    
  431.                     // New generalized slope collisions
  432.                     if (overlapFound || (!overlapFound && checkArrays(tile.index)))
  433.                     {
  434.                         if ((tile.callbackFunction != null) && ((tile.filter == null) || Std.is(Object, tile.filter)))
  435.                         {
  436.                             tile.mapIndex = rowStart + column;
  437.                             tile.callbackFunction(tile, Object);
  438.                         }
  439.                         results = true;
  440.                     }
  441.                 }
  442.                 else if ((tile.callbackFunction != null) && ((tile.filter == null) || Std.is(Object, tile.filter)))
  443.                 {
  444.                     tile.mapIndex = rowStart + column;
  445.                     tile.callbackFunction(tile, Object);
  446.                 }
  447.                 column++;
  448.             }
  449.            
  450.             rowStart += widthInTiles;
  451.             row++;
  452.         }
  453.        
  454.         return results;
  455.     }
  456.    
  457.     /**
  458.      * Sets the slope arrays, which define which tiles are treated as slopes.
  459.      *
  460.      * @param   Northwest   An array containing the numbers of the tiles facing Northwest to be treated as floor tiles with a slope on the left.
  461.      * @param   Northeast   An array containing the numbers of the tiles facing Northeast to be treated as floor tiles with a slope on the right.
  462.      * @param   Southwest   An array containing the numbers of the tiles facing Southwest to be treated as ceiling tiles with a slope on the left.
  463.      * @param   Southeast   An array containing the numbers of the tiles facing Southeast to be treated as ceiling tiles with a slope on the right.
  464.      */
  465.     public function setSlopes(?Northwest:Array<Int>, ?Northeast:Array<Int>, ?Southwest:Array<Int>, ?Southeast:Array<Int>):Void
  466.     {
  467.         if (Northwest != null)
  468.         {
  469.             _slopeNorthwest = Northwest;
  470.         }
  471.         if (Northeast != null)
  472.         {
  473.             _slopeNortheast = Northeast;
  474.         }
  475.         if (Southwest != null)
  476.         {
  477.             _slopeSouthwest = Southwest;
  478.         }
  479.         if (Southeast != null)
  480.         {
  481.             _slopeSoutheast = Southeast;
  482.         }
  483.        
  484.         setSlopeProperties();
  485.     }
  486.    
  487.     /**
  488.      * Sets the gentle slopes. About 26.5 degrees.
  489.      *
  490.      * @param   ThickTiles  An array containing the numbers of the tiles to be treated as thick slope.
  491.      * @param   ThinTiles   An array containing the numbers of the tiles to be treated as thin slope.
  492.      */
  493.     public function setGentle(ThickTiles:Array<Int>, ThinTiles:Array<Int>)
  494.     {
  495.         if (ThickTiles != null)
  496.         {
  497.             _slopeThickGentle = ThickTiles;
  498.         }
  499.        
  500.         if (ThinTiles != null)
  501.         {
  502.             _slopeThinGentle = ThinTiles;
  503.             for (tile in _slopeThinGentle)
  504.             {
  505.                 _tileObjects[tile].allowCollisions = (_slopeSouthwest.indexOf(tile) >= 0 || _slopeSoutheast.indexOf(tile) >= 0 )? FlxObject.CEILING : FlxObject.FLOOR;
  506.             }
  507.         }
  508.     }
  509.    
  510.     /**
  511.      * Sets the steep slopes. About 63.5 degrees.
  512.      *
  513.      * @param   ThickTiles  An array containing the numbers of the tiles to be treated as thick slope.
  514.      * @param   ThinTiles   An array containing the numbers of the tiles to be treated as thin slope.
  515.      */
  516.     public function setSteep(ThickTiles:Array<Int>, ThinTiles:Array<Int>)
  517.     {
  518.         if (ThickTiles != null)
  519.         {
  520.             _slopeThickSteep = ThickTiles;
  521.         }
  522.        
  523.         if (ThinTiles != null)
  524.         {
  525.             _slopeThinSteep = ThinTiles;
  526.             for (tile in _slopeThinSteep)
  527.             {
  528.                 _tileObjects[tile].allowCollisions = (_slopeSouthwest.indexOf(tile) >= 0 || _slopeNorthwest.indexOf(tile) >= 0 )? FlxObject.RIGHT : FlxObject.LEFT;
  529.             }
  530.         }
  531.     }
  532.    
  533.     /**
  534.      * Internal helper functions for comparing a tile to the slope arrays to see if a tile should be treated as STEEP or GENTLE slope.
  535.      *
  536.      * @param   TileIndex   The Tile Index number of the Tile you want to check.
  537.      * @return  Returns true if the tile is listed in one of the slope arrays. Otherwise returns false.
  538.      */
  539.     private function checkThickGentle(TileIndex:Int):Bool
  540.     {
  541.         return _slopeThickGentle.indexOf(TileIndex) >= 0;
  542.     }
  543.    
  544.     private function checkThinGentle(TileIndex:Int):Bool
  545.     {
  546.         return _slopeThinGentle.indexOf(TileIndex) >= 0;
  547.     }
  548.    
  549.     private function checkThickSteep(TileIndex:Int):Bool
  550.     {
  551.         return _slopeThickSteep.indexOf(TileIndex) >= 0;
  552.     }
  553.    
  554.     private function checkThinSteep(TileIndex:Int):Bool
  555.     {
  556.         return _slopeThinSteep.indexOf(TileIndex) >= 0;
  557.     }
  558.    
  559.     /**
  560.      * Bounds the slope point to the slope
  561.      *
  562.      * @param   Slope   The slope to fix the slopePoint for
  563.      */
  564.     private function fixSlopePoint(Slope:FlxTile):Void
  565.     {
  566.         _slopePoint.x = FlxMath.bound(_slopePoint.x, Slope.x, Slope.x + _tileWidth);
  567.         _slopePoint.y = FlxMath.bound(_slopePoint.y, Slope.y, Slope.y + _tileHeight);
  568.     }
  569.    
  570.     /**
  571.      * Ss called if an object collides with a floor slope
  572.      *
  573.      * @param   Slope   The floor slope
  574.      * @param   Object  The object that collides with that slope
  575.      */
  576.     private function onCollideFloorSlope(Slope:FlxObject, Object:FlxObject):Void
  577.     {
  578.         // Set the object's touching flag
  579.         Object.touching = FlxObject.FLOOR;
  580.        
  581.         // Adjust the object's velocity
  582.         Object.velocity.y = Math.min(Object.velocity.y, 0);
  583.        
  584.         // Reposition the object
  585.         Object.y = _slopePoint.y - Object.height;
  586.        
  587.         if (Object.y < Slope.y - Object.height)
  588.         {
  589.             Object.y = Slope.y - Object.height;
  590.         }
  591.     }
  592.    
  593.     /**
  594.      * Is called if an object collides with a ceiling slope
  595.      *
  596.      * @param   Slope   The ceiling slope
  597.      * @param   Object  The object that collides with that slope
  598.      */
  599.     private function onCollideCeilSlope(Slope:FlxObject, Object:FlxObject):Void
  600.     {
  601.         // Set the object's touching flag
  602.         Object.touching = FlxObject.CEILING;
  603.        
  604.         // Adjust the object's velocity
  605.         Object.velocity.y = Math.max(Object.velocity.y, 0);
  606.        
  607.         // Reposition the object
  608.         Object.y = _slopePoint.y;
  609.        
  610.         if (Object.y > Slope.y + _tileHeight)
  611.         {
  612.             Object.y = Slope.y + _tileHeight;
  613.         }
  614.     }
  615.    
  616.     /**
  617.      * Solves collision against a left-sided floor slope
  618.      *
  619.      * @param   Slope   The slope to check against
  620.      * @param   Object  The object that collides with the slope
  621.      */
  622.     private function solveCollisionSlopeNorthwest(Slope:FlxObject, Object:FlxObject):Void
  623.     {
  624.         // Calculate the corner point of the object
  625.         _objPoint.x = Math.floor(Object.x + Object.width + _snapping);
  626.         _objPoint.y = Math.floor(Object.y + Object.height);
  627.        
  628.         // Calculate position of the point on the slope that the object might overlap
  629.         // this would be one side of the object projected onto the slope's surface
  630.         _slopePoint.x = _objPoint.x;
  631.         _slopePoint.y = (Slope.y + _tileHeight) - (_slopePoint.x - Slope.x);
  632.        
  633.         var tileId:Int = cast(Slope, FlxTile).index;
  634.         if (checkThinSteep(tileId))
  635.         {
  636.             if (_slopePoint.x - Slope.x <= _tileWidth / 2)
  637.             {
  638.                 return;
  639.             }
  640.             else
  641.             {
  642.                 _slopePoint.y = Slope.y + _tileHeight * (2 - (2 * (_slopePoint.x - Slope.x) / _tileWidth)) + _snapping;
  643.             }
  644.         }
  645.         else if (checkThickSteep(tileId))
  646.         {
  647.             _slopePoint.y = Slope.y + _tileHeight * (1 - (2 * ((_slopePoint.x - Slope.x) / _tileWidth))) + _snapping;
  648.         }
  649.         else if (checkThickGentle(tileId))
  650.         {
  651.             _slopePoint.y = Slope.y + (_tileHeight - _slopePoint.x + Slope.x) / 2;
  652.         }
  653.         else if (checkThinGentle(tileId))
  654.         {
  655.             _slopePoint.y = Slope.y + _tileHeight - (_slopePoint.x - Slope.x) / 2;
  656.         }
  657.        
  658.         // Fix the slope point to the slope tile
  659.         fixSlopePoint(cast(Slope, FlxTile));
  660.        
  661.         // Check if the object is inside the slope
  662.         if (_objPoint.x > Slope.x - _snapping && _objPoint.x < Slope.x + _tileWidth + Object.width + _snapping
  663.             && (_objPoint.y >= _slopePoint.y || _objPoint.y >= _slopePoint.y - _snapping && Object.velocity.x < 0 && Object.velocity.y >= 0)
  664.             && _objPoint.y <= Slope.y + _tileHeight)
  665.         {
  666.             // Call the collide function for the floor slope
  667.             onCollideFloorSlope(Slope, Object);
  668.             trace(_slopePoint.y + ' / ' + Slope.y);
  669.         }
  670.     }
  671.    
  672.     /**
  673.      * Solves collision against a right-sided floor slope
  674.      *
  675.      * @param   Slope   The slope to check against
  676.      * @param   Object  The object that collides with the slope
  677.      */
  678.     private function solveCollisionSlopeNortheast(Slope:FlxObject, Object:FlxObject):Void
  679.     {
  680.         // Calculate the corner point of the object
  681.         _objPoint.x = Math.floor(Object.x - _snapping);
  682.         _objPoint.y = Math.floor(Object.y + Object.height);
  683.        
  684.         // Calculate position of the point on the slope that the object might overlap
  685.         // this would be one side of the object projected onto the slope's surface
  686.         _slopePoint.x = _objPoint.x;
  687.         _slopePoint.y = (Slope.y + _tileHeight) - (Slope.x - _slopePoint.x + _tileWidth);
  688.        
  689.         var tileId:Int = cast(Slope, FlxTile).index;
  690.         if (checkThinSteep(tileId))
  691.         {
  692.             if (_slopePoint.x - Slope.x >= _tileWidth / 2)
  693.             {
  694.                 return;
  695.             }
  696.             else
  697.             {
  698.                 _slopePoint.y = Slope.y + _tileHeight * 2 * ((_slopePoint.x - Slope.x) / _tileWidth) + _snapping;
  699.             }
  700.         }
  701.         else if (checkThickSteep(tileId))
  702.         {
  703.             _slopePoint.y = Slope.y - _tileHeight * (1 + (2 * ((Slope.x - _slopePoint.x) / _tileWidth))) + _snapping;
  704.         }
  705.         else if (checkThickGentle(tileId))
  706.         {
  707.             _slopePoint.y = Slope.y + (_tileHeight - Slope.x + _slopePoint.x - _tileWidth) / 2;
  708.         }
  709.         else if (checkThinGentle(tileId))
  710.         {
  711.             _slopePoint.y = Slope.y + _tileHeight - (Slope.x - _slopePoint.x + _tileWidth) / 2;
  712.         }
  713.        
  714.         // Fix the slope point to the slope tile
  715.         fixSlopePoint(cast(Slope, FlxTile));
  716.        
  717.         // Check if the object is inside the slope
  718.         if (_objPoint.x > Slope.x - (Object.width + _snapping) && _objPoint.x < Slope.x + (_tileWidth - _snapping)
  719.             && (_objPoint.y >= _slopePoint.y || _objPoint.y >= _slopePoint.y - _snapping*2 && Object.velocity.x > 0 && Object.velocity.y >= 0)
  720.             && _objPoint.y <= Slope.y + _tileHeight)
  721.         {
  722.             // Call the collide function for the floor slope
  723.             onCollideFloorSlope(Slope, Object);
  724.             trace(_slopePoint.y + ' / ' + Slope.y);
  725.         }
  726.     }
  727.    
  728.     /**
  729.      * Solves collision against a left-sided ceiling slope
  730.      *
  731.      * @param   Slope   The slope to check against
  732.      * @param   Object  The object that collides with the slope
  733.      */
  734.     private function solveCollisionSlopeSouthwest(Slope:FlxObject, Object:FlxObject):Void
  735.     {
  736.         // Calculate the corner point of the object
  737.         _objPoint.x = Math.floor(Object.x + Object.width + _snapping);
  738.         _objPoint.y = Math.ceil(Object.y);
  739.        
  740.         // Calculate position of the point on the slope that the object might overlap
  741.         // this would be one side of the object projected onto the slope's surface
  742.         _slopePoint.x = _objPoint.x;
  743.         _slopePoint.y = Slope.y + (_slopePoint.x - Slope.x);
  744.        
  745.         var tileId:Int = cast(Slope, FlxTile).index;
  746.         if (checkThinSteep(tileId))
  747.         {
  748.             if (_slopePoint.x - Slope.x <= _tileWidth / 2)
  749.             {
  750.                 return;
  751.             }
  752.             else
  753.             {
  754.                 _slopePoint.y = Slope.y - _tileHeight * (1 + (2 * ((Slope.x - _slopePoint.x) / _tileWidth))) - _snapping;
  755.             }
  756.         }
  757.         else if (checkThickSteep(tileId))
  758.         {
  759.             _slopePoint.y = Slope.y + _tileHeight * 2 * ((_slopePoint.x - Slope.x) / _tileWidth) - _snapping;
  760.         }
  761.         else if (checkThickGentle(tileId))
  762.         {
  763.             _slopePoint.y = Slope.y + _tileHeight - (Slope.x - _slopePoint.x + _tileWidth) / 2;
  764.         }
  765.         else if (checkThinGentle(tileId))
  766.         {
  767.             _slopePoint.y = Slope.y + (_tileHeight - Slope.x + _slopePoint.x - _tileWidth) / 2;
  768.         }
  769.        
  770.         // Fix the slope point to the slope tile
  771.         fixSlopePoint(cast(Slope, FlxTile));
  772.        
  773.         // Check if the object is inside the slope
  774.         if (_objPoint.x > Slope.x + _snapping && _objPoint.x < Slope.x + _tileWidth + Object.width + _snapping && _objPoint.y <= _slopePoint.y && _objPoint.y >= Slope.y)
  775.         {
  776.             // Call the collide function for the floor slope
  777.             onCollideCeilSlope(Slope, Object);
  778.         }
  779.     }
  780.    
  781.     /**
  782.      * Solves collision against a right-sided ceiling slope
  783.      *
  784.      * @param   Slope   The slope to check against
  785.      * @param   Object  The object that collides with the slope
  786.      */
  787.     private function solveCollisionSlopeSoutheast(Slope:FlxObject, Object:FlxObject):Void
  788.     {
  789.         // Calculate the corner point of the object
  790.         _objPoint.x = Math.floor(Object.x - _snapping);
  791.         _objPoint.y = Math.ceil(Object.y);
  792.        
  793.         // Calculate position of the point on the slope that the object might overlap
  794.         // this would be one side of the object projected onto the slope's surface
  795.         _slopePoint.x = _objPoint.x;
  796.         _slopePoint.y = (Slope.y) + (Slope.x - _slopePoint.x + _tileWidth);
  797.        
  798.         var tileId:Int = cast(Slope, FlxTile).index;
  799.         if (checkThinSteep(tileId))
  800.         {
  801.             if (_slopePoint.x - Slope.x >= _tileWidth / 2)
  802.             {
  803.                 return;
  804.             }
  805.             else
  806.             {
  807.                 _slopePoint.y = Slope.y + _tileHeight * (1 - (2 * ((_slopePoint.x - Slope.x) / _tileWidth))) - _snapping;
  808.             }
  809.         }
  810.         else if (checkThickSteep(tileId))
  811.         {
  812.             _slopePoint.y = Slope.y + _tileHeight * (2 - (2 * (_slopePoint.x - Slope.x) / _tileWidth)) - _snapping;
  813.         }
  814.         else if (checkThickGentle(tileId))
  815.         {
  816.             _slopePoint.y = Slope.y + _tileHeight - (_slopePoint.x - Slope.x) / 2;
  817.         }
  818.         else if (checkThinGentle(tileId))
  819.         {
  820.             _slopePoint.y = Slope.y + (_tileHeight - _slopePoint.x + Slope.x) / 2;
  821.         }
  822.        
  823.         // Fix the slope point to the slope tile
  824.         fixSlopePoint(cast(Slope, FlxTile));
  825.        
  826.         // Check if the object is inside the slope
  827.         if (_objPoint.x > Slope.x - Object.width - _snapping && _objPoint.x < Slope.x + _tileWidth + _snapping && _objPoint.y <= _slopePoint.y && _objPoint.y >= Slope.y)
  828.         {
  829.             // Call the collide function for the floor slope
  830.             onCollideCeilSlope(Slope, Object);
  831.         }
  832.     }
  833.    
  834.     /**
  835.      * Internal helper function for setting the tiles currently held in the slope arrays to use slope collision.
  836.      * Note that if you remove items from a slope, this function will not unset the slope property.
  837.      */
  838.     private function setSlopeProperties():Void
  839.     {
  840.         for (tile in _slopeNorthwest)
  841.         {
  842.             setTileProperties(tile, FlxObject.RIGHT | FlxObject.FLOOR, solveCollisionSlopeNorthwest);
  843.         }
  844.         for (tile in _slopeNortheast)
  845.         {
  846.             setTileProperties(tile, FlxObject.LEFT | FlxObject.FLOOR, solveCollisionSlopeNortheast);
  847.         }
  848.         for (tile in _slopeSouthwest)
  849.         {
  850.             setTileProperties(tile, FlxObject.RIGHT | FlxObject.CEILING, solveCollisionSlopeSouthwest);
  851.         }
  852.         for (tile in _slopeSoutheast)
  853.         {
  854.             setTileProperties(tile, FlxObject.LEFT | FlxObject.CEILING, solveCollisionSlopeSoutheast);
  855.         }
  856.     }
  857.    
  858.     /**
  859.      * Internal helper function for comparing a tile to the slope arrays to see if a tile should be treated as a slope.
  860.      *
  861.      * @param   TileIndex   The Tile Index number of the Tile you want to check.
  862.      * @return  Returns true if the tile is listed in one of the slope arrays. Otherwise returns false.
  863.      */
  864.     private function checkArrays(TileIndex:Int):Bool
  865.     {
  866.         return _slopeNorthwest.indexOf(TileIndex) >= 0 || _slopeNortheast.indexOf(TileIndex) >= 0 || _slopeSouthwest.indexOf(TileIndex) >= 0 || _slopeSoutheast.indexOf(TileIndex) >= 0;
  867.     }
  868.    
  869.     override private function set_frames(value:FlxFramesCollection):FlxFramesCollection
  870.     {
  871.         super.set_frames(value);
  872.        
  873.         if (value != null && _specialTiles != null && _specialTiles.length > 0)
  874.         {
  875.             for (tile in _specialTiles)
  876.             {
  877.                 if (tile != null)
  878.                 {
  879.                     tile.frames = frames;
  880.                 }
  881.             }
  882.         }
  883.        
  884.         return value;
  885.     }
  886. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement