Advertisement
Guest User

Untitled

a guest
Jul 15th, 2011
679
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package  {
  2.     import flash.display.BitmapData;
  3.     import flash.display.Graphics;
  4.     import flash.display.Sprite;
  5.     import flash.geom.Matrix;
  6.     import flash.geom.Point;
  7.     import flash.geom.Rectangle;
  8.     import net.flashpunk.Entity;
  9.     import net.flashpunk.FP;
  10.     import net.flashpunk.graphics.Stamp;
  11.     import net.flashpunk.masks.Grid;
  12.     import net.flashpunk.utils.Draw;
  13.     import net.flashpunk.utils.Input;
  14.     /**
  15.      * ...
  16.      * @author grigri
  17.      */
  18.     public class Water extends Entity
  19.     {
  20.         /* Variables */
  21.         public var cells:Vector.<Vector.<int>> = new Vector.<Vector.<int>>();//contains the data.
  22.         public var mass:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>();//to calculate step.
  23.         private var new_mass:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>();// / to calculate step.
  24.        
  25.         private var waterMask:Grid;
  26.        
  27.         private var mapWidth:int = 0;
  28.         private var mapHeight:int = 0;
  29.        
  30.         /* Constants */
  31.         private const MAX_MASS:Number = 1.0;
  32.         private const COMPRESSION:Number = 0.02;//how much extra water pressure in can be stored in the cell below.
  33.         private const MIN_MASS:Number = 0.0001;//ignore very dry cells.
  34.  
  35.         private const MIN_FLOW:Number = 0.01;
  36.         private const MAX_MOVEMENT:Number = 1;//Max units of water moved between two cells per turn.
  37.        
  38.         private var tilesBmp:BitmapData;
  39.         private var srcRect:Rectangle = new Rectangle(0, 0, 16, 16);
  40.         private var dstPoint:Point = new Point;
  41.         /*
  42.         private var s:Sprite;
  43.         private var g:Graphics;
  44.         private var m:Matrix;
  45.         */
  46.        
  47.         public function Water(grid:Grid, width:int, height:int)
  48.         {
  49.             super(0, 0, null, waterMask);
  50.            
  51.             mask = waterMask = new Grid(width, height, 16, 16);
  52.             mapWidth = width >> 4;
  53.             mapHeight = height >> 4;
  54.            
  55.             //m = new Matrix;
  56.             //s = new Sprite;
  57.             //g = s.graphics;
  58.            
  59.             type = "water";
  60.            
  61.             var w:int, h:int;
  62.             for(w = 0; w < mapWidth; w++)
  63.             {
  64.                 cells[w] = new Vector.<int>();
  65.                 mass[w] = new Vector.<Number>();
  66.                 new_mass[w] = new Vector.<Number>();
  67.                
  68.                 for(h = 0; h < mapHeight; h++)
  69.                 {
  70.                     cells[w][h] = 0;
  71.                     mass[w][h] = 0;
  72.                     new_mass[w][h] = 0;
  73.                 }
  74.             }
  75.            
  76.             //read grid
  77.             for(w = 0; w < mapWidth; w += 2)
  78.             {
  79.                 for(h = 0; h < mapHeight; h += 2)
  80.                 {
  81.                     if(grid.getTile(w >> 1, h >> 1))
  82.                     {
  83.                         cells[w][h] = 1;
  84.                         cells[w + 1][h] = 1;
  85.                         cells[w][h + 1] = 1;
  86.                         cells[w + 1][h + 1] = 1;
  87.                     }
  88.                 }
  89.             }
  90.            
  91.             //layer = Layer.WATER;
  92.            
  93.             tilesBmp = new BitmapData(16 * 16, 16 * 2, true, 0);
  94.             Draw.setTarget(tilesBmp);
  95.             var alpha:Number;
  96.             for (w = 0; w < 16; w++) {
  97.                 alpha = w / 15.0;
  98.                 if (alpha > 0.6) alpha = 0.6;
  99.                 Draw.rect(w * 16, 16 - w - 1, 16, w + 1, 0x5980FF, alpha, true);
  100.                 Draw.rect(w * 16, 16, 16, 16, 0x5980FF, alpha, true);
  101.             }
  102.             Draw.resetTarget();
  103.         }
  104.        
  105.         /*
  106.         override public function added():void {
  107.             super.added();
  108.             world.addGraphic(new Stamp(tilesBmp), 0, 0, 100);
  109.         }
  110.         */
  111.        
  112.         override public function update():void
  113.         {
  114.             super.update();
  115.            
  116.             var flow:Number = 0;
  117.             var remaining_mass:Number;
  118.             var w:int, h:int, x:int, y:int;
  119.             var nMass:Number = 0;
  120.            
  121.             for(x = mapWidth - 1; x > 0; x--)
  122.             {
  123.                 for(y = mapHeight - 1; y > 0; y--)
  124.                 {
  125.                     if(cells[x][y] == 1) continue;//Skip ground blocks.
  126.                    
  127.                     flow = 0;
  128.                     remaining_mass = mass[x][y];
  129.                    
  130.                     if(remaining_mass <= 0) continue;
  131.                    
  132.                     //check flow beneath.
  133.                     if(y < mapHeight - 1 && cells[x][y+1] != 1)
  134.                     {
  135.                         nMass = mass[x][y + 1]
  136.                         //if (nMass < mass[x][y]) {
  137.                             flow = distributeWater(remaining_mass + nMass) - nMass;
  138.                             if(flow > MIN_FLOW)
  139.                             {
  140.                                 flow *= 0.5;//smoothens water flow.
  141.                             }
  142.                             if (flow < 0) flow = 0;
  143.                             if (flow > MAX_MOVEMENT) flow = MAX_MOVEMENT;
  144.                             if (flow > remaining_mass) flow = remaining_mass;
  145.                             //flow = constrainRange(flow, 0, remaining_mass);
  146.                            
  147.                             new_mass[x][y] -= flow;
  148.                             new_mass[x][y + 1] += flow;
  149.                             remaining_mass -= flow;
  150.                         //}
  151.                     }
  152.                    
  153.                     if(remaining_mass <= 0) continue;
  154.                    
  155.                     //Check to the left.
  156.                     if(x > 0 && cells[x-1][y] != 1)
  157.                     {
  158.                         //if (mass[x - 1][y] < mass[x][y]) {
  159.                             flow = (mass[x][y] - mass[x - 1][y]) * 0.25;
  160.                             if(flow > MIN_FLOW)
  161.                             {
  162.                                 flow *= 0.5;
  163.                             }
  164.                             if (flow < 0) flow = 0;
  165.                             //if (flow > MAX_MOVEMENT) flow = MAX_MOVEMENT;
  166.                             if (flow > remaining_mass) flow = remaining_mass;
  167.                             //flow = constrainRange(flow, 0, remaining_mass);
  168.                            
  169.                             new_mass[x][y] -= flow;
  170.                             new_mass[x - 1][y] += flow;
  171.                             remaining_mass -= flow;
  172.                         //}
  173.                     }
  174.                    
  175.                     if(remaining_mass <= 0) continue;
  176.                    
  177.                     //check to the right.
  178.                     if(x < mapWidth - 1 && cells[x+1][y] != 1)
  179.                     {
  180.                         //if (mass[x + 1][y] < mass[x][y]) {
  181.                             flow = (mass[x][y] - mass[x + 1][y]) * 0.25;
  182.                             if(flow > MIN_FLOW)
  183.                             {
  184.                                 flow *= 0.5;
  185.                             }
  186.                             if (flow < 0) flow = 0;
  187.                             //if (flow > MAX_MOVEMENT) flow = MAX_MOVEMENT;
  188.                             if (flow > remaining_mass) flow = remaining_mass;
  189.                             //flow = constrainRange(flow, 0, remaining_mass);
  190.                            
  191.                             new_mass[x][y] -= flow;
  192.                             new_mass[x + 1][y] += flow;
  193.                             remaining_mass -= flow;
  194.                         //}
  195.                     }
  196.                    
  197.                     if(remaining_mass <= 0) continue;
  198.                    
  199.                     //Up. Only compressed water should flows upwards.
  200.                     if(y > 0 && cells[x][y-1] != 1)
  201.                     {
  202.                         //if (mass[x][y-1] < remaining_mass) {
  203.                             flow = remaining_mass - distributeWater(remaining_mass + mass[x][y - 1]);
  204.                             if(flow > MIN_FLOW)
  205.                             {
  206.                                 flow *= 0.5;
  207.                             }
  208.                             if (flow < 0) flow = 0;
  209.                             if (flow > MAX_MOVEMENT) flow = MAX_MOVEMENT;
  210.                             if (flow > remaining_mass) flow = remaining_mass;
  211.                             //flow = constrainRange(flow, 0, (MAX_MOVEMENT < remaining_mass) ? MAX_MOVEMENT : remaining_mass);
  212.                            
  213.                             new_mass[x][y] -= flow;
  214.                             new_mass[x][y - 1] += flow;
  215.                             remaining_mass -= flow;
  216.                         //}
  217.                     }
  218.                 }
  219.             }
  220.            
  221.             //generate water.
  222.             if (Input.mouseDown)
  223.             {
  224.                 var xPos:int = world.mouseX >> 4;
  225.                 var yPos:int = world.mouseY >> 4;
  226.                 if(xPos < 0) xPos = 0;
  227.                 if(xPos > mapWidth - 1) xPos = mapWidth - 1;
  228.                 if(yPos < 0) yPos = 0;
  229.                 if(yPos > mapHeight - 1) yPos = mapHeight - 1;
  230.                 if (cells[xPos][yPos] != 1)
  231.                 {
  232.                     cells[xPos][yPos] = 2;
  233.                     //mass[xPos][yPos] = 1;
  234.                     new_mass[xPos][yPos] = 1;
  235.                 }
  236.             }
  237.            
  238.             for(w = 0; w < mapWidth; w++)
  239.             {
  240.                 mass[w][0] = 0;
  241.                 mass[w][mapHeight - 1] = 0;
  242.                
  243.                 for(h = 0; h < mapHeight; h++)
  244.                 {
  245.                     nMass = new_mass[w][h];
  246.                     //mass[w][h] = nMass;
  247.                    
  248.  
  249.                     if (cells[w][h] == 1) {
  250.                         //waterMask.clearTile(w, h);
  251.                     }
  252.                     else
  253.                     {
  254.                         if (mass[w][h] != nMass) {
  255.  
  256.                         cells[w][h] = nMass > MIN_MASS ? 2 : 0;
  257.                         waterMask.setTile(w, h, nMass > 0.5);
  258.  
  259.                         mass[w][h] = nMass;
  260.                         }
  261.  
  262.                     }
  263.                 }
  264.             }
  265.            
  266.             for (h = 0; h < mapHeight; h++)
  267.             {
  268.                 mass[0][h] = 0;
  269.                 mass[mapWidth - 1][h] = 0;
  270.             }
  271.         }
  272.        
  273.         private function distributeWater(total_mass:Number):Number
  274.         {
  275.             if ( total_mass <= 1 )
  276.             {
  277.                 return 1;
  278.             }
  279.             else if ( total_mass < 2.02) //else if ( total_mass < 2 * MAX_MASS + COMPRESSION)
  280.             {
  281.                 return (1 + total_mass * 0.02) * 0.98;// / 1.02; //return (MAX_MASS + total_mass * COMPRESSION) / (MAX_MASS + COMPRESSION);
  282.             }
  283.             else
  284.             {
  285.                 return (total_mass + COMPRESSION) * 0.5;
  286.             }
  287.         }
  288.        
  289.         private function constrainRange(value:Number, min:Number, max:Number):Number
  290.         {
  291.             if (value > max) return max;
  292.             else if (value < min) return min;
  293.             else return value;
  294.         }
  295.        
  296.         protected function solid(x:int, y:int):Boolean
  297.         {
  298.             var n:int = cells[x][y]
  299.             return n == 1;
  300.         }
  301.        
  302.         protected function water(x:int, y:int):Boolean
  303.         {
  304.             return cells[x][y] == 2;
  305.         }
  306.        
  307.         override public function render():void
  308.         {
  309.             var nMass:Number = 0;
  310.             //var x:Number = 16, y:Number = 16;
  311.             var height:Number, alpha:Number;
  312.            
  313.             dstPoint.x = 16;// - FP.camera.x;
  314.             dstPoint.y = 16;// - FP.camera.y;
  315.            
  316.             //Draw.resetTarget();
  317.            
  318.             for(var w:int = 1; w < mapWidth - 1; w++)
  319.             {
  320.                 for(var h:int = 1; h < mapHeight - 1; h++)
  321.                 {
  322.                     nMass = mass[w][h];
  323.                     //var x:Number = w << 4;
  324.                     //var y:Number = h << 4;
  325.                    
  326.                     if(cells[w][h] == 2)
  327.                     {
  328.                         height = mass[w][h];
  329.                         if (height < 0) continue;// height = 0;
  330.                         if (height > 1) height = 1;
  331.                        
  332.                         srcRect.x = Math.ceil(height * 15) * 16;
  333.                         //alpha = height;
  334.                         //height *= 16;
  335.                         //if (alpha > 0.6) alpha = 0.6;
  336.                         /*
  337.                         var height:Number = (16 * constrainRange(mass[w][h], 0, 1));
  338.                         va
  339.                         g.beginFill(0x5980FF, constrainRange(nMass, 0, 0.6));
  340.                         */
  341.                         if((cells[w][h - 1] != 2) && (cells[w + 1][h - 1] != 2))
  342.                         {
  343.                             srcRect.y = 0;
  344.                             //Draw.rect(x, y + (16 - height), 16, height, 0x5980FF, alpha, true);
  345.                             //g.drawRect(x, y + (16 - height), 16, height);
  346.                         }
  347.                         else {
  348.                             srcRect.y = 16;
  349.                             //Draw.rect(x, y, 16, 16, 0x5980FF, alpha, true);
  350.                             //g.drawRect(x, y, 16, 16);
  351.                         }
  352.                         FP.buffer.copyPixels(tilesBmp, srcRect, dstPoint);
  353.                     }
  354.                     dstPoint.y += 16;
  355.                 }
  356.                 dstPoint.y = 16;
  357.                 dstPoint.x += 16;
  358.             }
  359.            
  360.             //m.tx = -FP.camera.x;
  361.             //m.ty = -FP.camera.y;
  362.             //FP.buffer.draw(s, m);
  363.             //g.clear();
  364.         }
  365.     }
  366.  
  367.  
  368. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement