Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Jul 15th, 2011  |  syntax: ActionScript 3  |  size: 9.29 KB  |  views: 447  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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. }