Advertisement
Guest User

WaterTest

a guest
Dec 3rd, 2017
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haxe 17.26 KB | None | 0 0
  1. /*
  2.     Stencyl exclusively uses the Haxe programming language.
  3.     Haxe is similar to ActionScript and JavaScript.
  4.    
  5.     Want to use native code or make something reusable? Use the Extensions Framework instead.
  6.     http://www.stencyl.com/help/view/engine-extensions/
  7.    
  8.     Learn more about Haxe and our APIs
  9.     http://www.stencyl.com/help/view/haxe/
  10. */
  11.  
  12. package scripts;
  13.  
  14.  
  15. //==========================================================
  16. // Imports
  17. //==========================================================
  18.  
  19. import com.stencyl.graphics.BitmapWrapper;
  20. import com.stencyl.graphics.G;
  21. import openfl.display.CapsStyle;
  22. import openfl.display.GradientType;
  23. import openfl.display.LineScaleMode;
  24. import openfl.events.Event;
  25. import openfl.geom.Matrix;
  26. import openfl.text.TextFieldType;
  27.  
  28. import com.stencyl.behavior.Script;
  29. import com.stencyl.behavior.Script.*;
  30. import com.stencyl.behavior.ActorScript;
  31. import com.stencyl.behavior.SceneScript;
  32. import com.stencyl.behavior.TimedTask;
  33.  
  34. import com.stencyl.models.Actor;
  35. import com.stencyl.models.GameModel;
  36. import com.stencyl.models.actor.Animation;
  37. import com.stencyl.models.actor.ActorType;
  38. import com.stencyl.models.actor.Collision;
  39. import com.stencyl.models.actor.Group;
  40. import com.stencyl.models.Scene;
  41. import com.stencyl.models.Sound;
  42. import com.stencyl.models.Region;
  43. import com.stencyl.models.Font;
  44. import com.stencyl.models.Joystick;
  45.  
  46. import com.stencyl.Engine;
  47. import com.stencyl.Input;
  48. import com.stencyl.utils.Utils;
  49.  
  50. import nme.ui.Mouse;
  51. import nme.display.Graphics;
  52.  
  53. import motion.Actuate;
  54. import motion.easing.Back;
  55. import motion.easing.Cubic;
  56. import motion.easing.Elastic;
  57. import motion.easing.Expo;
  58. import motion.easing.Linear;
  59. import motion.easing.Quad;
  60. import motion.easing.Quart;
  61. import motion.easing.Quint;
  62. import motion.easing.Sine;
  63.  
  64. import openfl.text.TextField;
  65. import scripts.Particle2D;
  66. import openfl.display.BitmapData;
  67. import openfl.display.Bitmap;
  68. import openfl.display.Shape;
  69.  
  70. class WaterTest extends SceneScript
  71. {
  72.     //Expose your attributes like this:
  73.     //@:attribute("id='1' name='Display Name' desc='An Attribute'")
  74.     //public var attributeName:String;
  75.    
  76.     //Need further help? See: http://www.stencyl.com/help/view/code-mode/
  77.    
  78.     @:attribute("id='1' name='targetY' desc='The default height of the water. Default is 250.0' type='NUMBER' default='250.0'")
  79.     public var targetY:Float = 250.0;
  80.    
  81.     @:attribute("id='2' name='iterations' desc='How fast the wave points return to their resting position. Default is 3' type='INT' default='3'")
  82.     public var iterations:Int = 3;
  83.  
  84.     @:attribute("id='3' name='numberOfPoints' desc='How many points form the water. Make sure the screen width evenly divides this number and add 1 to the resulting number.' type='INT' default='49'")
  85.     public var numberOfPoints:Int = 49;
  86.    
  87.     @:attribute("id='4' name='NUM_BACKGROUND_WAVES' desc='Number of waves that form the movement of the water. Default is 4' type='INT' default='4'")
  88.     public var NUM_BACKGROUND_WAVES:Int = 4;
  89.    
  90.     @:attribute("id='5' name='BACKGROUND_WAVE_MAX_HEIGHT' desc='The max height of the waves. Default is 3' type='INT' default='3'")
  91.     public var BACKGROUND_WAVE_MAX_HEIGHT:Int = 3;
  92.    
  93.     @:attribute("id='6' name='BACKGROUND_WAVE_MAX_COMPRESSION' desc='Waves compression. Default is 0.5' type='NUMBER' default='0.5'")
  94.     public var BACKGROUND_WAVE_COMPRESSION:Float;
  95.  
  96.     @:attribute("id='7' name='offsetAmount' desc='Speed at which the waves move to the sides. Default is 0.3' type='NUMBER' default='0.3'")
  97.     private var offsetAmount:Float;
  98.  
  99.     @:attribute("id='8' name='NUM_SPLASHES' desc='How many splashes do we create. Default is 20' type='INT' default='20'")
  100.     private var NUM_SPLASHES:Int;
  101.  
  102.     @:attribute("id='9' name='splashRadius' desc='Minimum radius of a splash. Default is 8' type='INT' default='8'")
  103.     var splashRadius:Int;
  104.    
  105.     @:attribute("id='10' name='useWaterGradient' desc='If this is 1 we will use a gradient for the water. Else we will use a color. Default is 1' type='INT' default='1'")
  106.     var useWaterGradient:Int = 1;
  107.    
  108.     @:attribute("id='11' name='gAlpha' desc='The alpha value for the graphics drawing. Default is 1. Range from 0 to 1. ONLY USED if useWaterGradient is NOT 1.' type='NUMBER' default='1.0'")
  109.     var gAlpha:Float = 1.0;
  110.    
  111.    
  112.     @:attribute("id='12' name='gradAlpha' desc='The alpha value for the water gradient. Default is 0.16. Range from 0 to 1.' type='NUMBER' default='0.16'")
  113.     var gradAlpha:Float = 0.16;
  114.  
  115.     @:attribute("id='13' name='waterLineThickness' desc='The thickness for the water surface line. Default is 4.' type='INT' default='4'")
  116.     var waterLineThickness:Int = 4;
  117.  
  118.     @:attribute("id='14' name='topGradientColor' desc='Top color used by the gradient' type='COLOR' default='4'")
  119.     var topGradientColor:Int;
  120.  
  121.     @:attribute("id='15' name='bottomGradientColor' desc='Bottom color used by the gradient' type='COLOR' default='4'")
  122.     var bottomGradientColor:Int;
  123.  
  124.     @:attribute("id='16' name='gradientHeight' desc='height of the gradient' type='INT' default='65'")
  125.     var gradientHeight:Int = 65;
  126.  
  127.     @:attribute("id='17' name='randomSplashSpeed' desc='Movement speed of the splashes. IF this is 0 the splashes will have random speed based on their size. IF it's not 0 the number you have will be the splashes speed' type='INT' default='0'")
  128.     var randomSplashSpeed:Int;
  129.  
  130.     @:attribute("id='18' name='splashGravity' desc='Gravity applied to the splashes. Default is 0.4' type='Number' default='0.4'")
  131.     var splashGravity:Float = 0.4;
  132.  
  133.     @:attribute("id='19' name='splashAlpha' desc='Alpha applied to the splashes.Default is 0.9' type='Number' default='0.9'")
  134.     var splashAlpha:Float = 0.9;
  135.        
  136.     public var springConstant:Float;
  137.     public var damping:Float;
  138.     public var wavePoints:Array<WaterPoint>;
  139.    
  140.     private var offset:Float;
  141.    
  142.     private var sineOffsets:Array<Float>;
  143.     // Amounts by which a particular sine is amplified
  144.     private var sineAmplitudes:Array<Float>;
  145.     // Amounts by which a particular sine is stretched
  146.     private var sineStretches:Array<Float>;
  147.     // Amounts by which a particular sine's offset is multiplied
  148.     private var offsetStretches:Array<Float>;
  149.    
  150.    
  151.     var splashesArray:Array<Particle2D>;
  152.    
  153.    
  154.    
  155.     var gradientType:GradientType;
  156.     var gradientColors:Array<UInt>;
  157.     var gradientAlphas:Array<Float>;
  158.     var colorRatios:Array<Int>;
  159.     var gradientRotation:Float;
  160.    
  161.    
  162.    
  163.     override public function init()
  164.     {
  165.         //iterations = 3; //how fast the waves return to their resting position
  166.         //targetY = 250;
  167.         springConstant = 0.003;
  168.         damping = 0.99;
  169.         //numberOfPoints = 49;
  170.        
  171.         offset = 0;
  172.         //offsetAmount = 0.3; //how fast the waves move on the screen
  173.        
  174.         //NUM_BACKGROUND_WAVES = 4;
  175.         //BACKGROUND_WAVE_MAX_HEIGHT = 3;
  176.         //BACKGROUND_WAVE_COMPRESSION = 1/2;
  177.         wavePoints = new Array();
  178.        
  179.         //NUM_SPLASHES = 20; //how many splashes we create at once
  180.         splashesArray = new Array();
  181.         //splashRadius = 8; //max radius for our splashes
  182.        
  183.         createSineWaves();
  184.        
  185.         createWavePoints();
  186.        
  187.        
  188.        
  189.         //useWaterGradient = 1;
  190.         //gAlpha = 1;
  191.        
  192.         //gradAlpha = 0.16;
  193.         //waterLineThickness = 4;
  194.        
  195.         //topGradientColor = Utils.getColorRGB(45, 83, 180);
  196.         //trace ("topGradientColor = " + topGradientColor);
  197.         //bottomGradientColor = Utils.getColorRGB(62, 120, 202);
  198.         //trace ("bottomGradientColor = " + bottomGradientColor );
  199.         gradientType = GradientType.LINEAR;
  200.         gradientColors = [topGradientColor, bottomGradientColor];
  201.         gradientAlphas = [gradAlpha, 1];
  202.         colorRatios  = [1, 255];
  203.         gradientRotation = Math.PI / 2; //90 degrees
  204.         //gradientHeight = 65;
  205.        
  206.         //splashGravity = 0.40;
  207.         //randomSplashSpeed = 0;
  208.         //splashAlpha = 0.9;
  209.        
  210.         var xx = 240;
  211.         //createTF("randomSplashSpeed",     120, 60, false);
  212.        
  213.         /*createTF("splashGravity",         120, 20, true);
  214.         createTF("NUM_SPLASHES",        120, 40, false);
  215.         createTF("randomSplashSpeed",   120, 60, false);
  216.         createTF("splashRadius",        120, 80, false);
  217.         createTF("splashAlpha",         120, 100, true);
  218.         createTF("numberOfPoints",      120, 120, false);
  219.         createTF("iterations", xx, 20, false);
  220.         createTF("offsetAmount", xx, 40, true);
  221.         createTF("NUM_BACKGROUND_WAVES", xx, 60, false);
  222.         createTF("BACKGROUND_WAVE_MAX_HEIGHT", xx, 80, false);
  223.         createTF("BACKGROUND_WAVE_COMPRESSION", xx, 100, true);
  224.         //createTF("testGradient", 100, 120, false);
  225.         createTF("gAlpha", 100, 140, true);*/
  226.     }
  227.    
  228.     private function createWavePoints()
  229.     {
  230.         if (wavePoints.length > 0)
  231.         {
  232.             while (wavePoints.length > 0)
  233.             wavePoints.pop();
  234.         }
  235.         //create the water points
  236.         var distanceBetweenPoints = Math.ceil(getScreenWidth() / numberOfPoints);
  237.         for (i in 0...numberOfPoints)
  238.         {
  239.             var p = new WaterPoint(distanceBetweenPoints * i, targetY, 0);
  240.             wavePoints.push(p);
  241.         }
  242.     }
  243.     private function createSplashes(j:Int)
  244.     {  
  245.         //create the splashes
  246.         for (i in 0 ... NUM_SPLASHES)
  247.         {
  248.             var disp = Math.random() * 50; //displacement on the x axis from the position of the mouse
  249.             var xx = (getMousePressedX() - disp / 2) + Math.random() * (disp * 2) ;
  250.             var yy = wavePoints[j].y;
  251.             var radius = Math.round(splashRadius/2 + Math.random() * splashRadius);
  252.             var angle = 225 + Math.random() * 90; //splash the radius only up  
  253.             var vx:Float;
  254.             var vy:Float;
  255.             if (randomSplashSpeed == 0)
  256.             {
  257.                 vx = Math.cos(Utils.RAD * angle) * radius; //xSpeed of the splash
  258.                 vy = Math.sin(Utils.RAD * angle) * radius; //ySpeed of the splash
  259.             }
  260.             else
  261.             {
  262.                 vx = Math.cos(Utils.RAD * angle) * randomSplashSpeed; //xSpeed of the splash
  263.                 vy = Math.sin(Utils.RAD * angle) * randomSplashSpeed; //ySpeed of the splash
  264.             }
  265.             //create the splash and add it to the array
  266.             //var splash = new Particle2D(xx, yy, vx, vy, Utils.getColorRGB(45, 83, 180), radius, gAlpha);
  267.             var splash = new Particle2D(xx, yy, vx, vy, topGradientColor, radius, splashAlpha, splashGravity);
  268.             splashesArray.push(splash);
  269.         }
  270.     }
  271.    
  272.    
  273.     private function createTF(value:String, x:Float, y:Float, floatNum:Bool)
  274.     {
  275.         var tt = new TextField();
  276.         tt.x = x;
  277.         tt.y = y;
  278.         tt.width = 64;
  279.         tt.height = 18;
  280.         tt.border = true;
  281.         tt.type = TextFieldType.INPUT;
  282.         tt.restrict = "0-9 .";
  283.         tt.maxChars = 5;
  284.         tt.text = "" + Reflect.field(this, value);
  285.         Engine.engine.root.parent.addChild(tt);
  286.         tt.addEventListener(Event.CHANGE, function(e:Dynamic) {
  287.             if (floatNum)
  288.                 Reflect.setField(this, value, Std.parseFloat(tt.text));
  289.             else
  290.                 Reflect.setField(this, value, Std.parseInt(tt.text));
  291.             if (value == "numberOfPoints")
  292.                 createWavePoints();
  293.             createSineWaves();
  294.         });
  295.         var tx = new TextField();
  296.         tx.x = 5;
  297.         tx.y = y;
  298.         tx.width = tt.x - 5;
  299.         tx.type = TextFieldType.DYNAMIC;
  300.         tx.selectable = false;
  301.         tx.mouseEnabled = false;
  302.         tx.text = value;
  303.         Engine.engine.root.parent.addChild(tx);
  304.     }
  305.    
  306.     private function createSineWaves()
  307.     {
  308.         sineOffsets = new Array();
  309.         sineAmplitudes = new Array();
  310.         sineStretches = new Array();
  311.         offsetStretches = new Array();
  312.         //set the sine waves
  313.         for (i in 0...NUM_BACKGROUND_WAVES)
  314.         {
  315.             var sineOffset = -Math.PI + 2 * Math.PI * Math.random();
  316.                 sineOffsets.push(sineOffset);
  317.             var sineAmplitude = Math.random() * BACKGROUND_WAVE_MAX_HEIGHT;
  318.                 sineAmplitudes.push(sineAmplitude);
  319.             var sineStretch = Math.random() * BACKGROUND_WAVE_COMPRESSION;
  320.                 sineStretches.push(sineStretch);
  321.             var offsetStretch = Math.random() * BACKGROUND_WAVE_COMPRESSION;
  322.                 offsetStretches.push(offsetStretch);
  323.         }
  324.     }
  325.     /*public function onClick(array:Array<Dynamic>)
  326.     {
  327.         var distanceBetweenPoints = Math.ceil(getScreenWidth() / numberOfPoints);
  328.         var i = Math.ceil(getMousePressedX() / distanceBetweenPoints);
  329.         //trace ("Index = " + i + " mouseX = " + getMousePressedX());
  330.         wavePoints[i].ySpeed += 5;
  331.         createSplashes(i);
  332.     }*/
  333.     public function _customBlock_createwaves(__Xposition:Float):Void
  334.     {
  335.         var distanceBetweenPoints = Math.ceil(getScreenWidth() / numberOfPoints);
  336.         var i = Math.ceil(__Xposition / distanceBetweenPoints);
  337.         wavePoints[i].ySpeed += 5;
  338.         createSplashes(i);
  339.     }
  340.    
  341.     public inline function update(elapsedTime:Float)
  342.     {
  343.         //update the water points
  344.         for (i in 0...iterations)
  345.         {
  346.             for (n in 0...(wavePoints.length - 1))
  347.             {
  348.                 var p = wavePoints[n];
  349.                 var force:Float = 0;
  350.                 var forceFromLeft:Float;
  351.                 var forceFromRight:Float;
  352.                
  353.                 //force from left point
  354.                 var ld:Float = 0;
  355.                 if (n > 0 && n < (wavePoints.length -1))
  356.                     ld = wavePoints[n - 1].y - p.y;
  357.                 else
  358.                     ld = 0;
  359.                 forceFromLeft = springConstant * ld;
  360.                
  361.                 //force from right point
  362.                 var rd:Float = 0;
  363.                 if (n > 0 && n < (wavePoints.length -2))
  364.                     rd = wavePoints[n + 1].y - p.y;
  365.                 else
  366.                     rd = 0;
  367.                 forceFromRight = springConstant * rd;
  368.                
  369.                 //apply force toward the resting position of the spring
  370.                 var dy:Float = targetY - p.y;
  371.                 var forceToRestingPos = springConstant * dy;
  372.                
  373.                 //sum all the forces
  374.                 force += forceFromLeft;
  375.                 force += forceFromRight;
  376.                 force += forceToRestingPos;
  377.                
  378.                 var accel:Float = force / p.mass;
  379.                 //apply acceleration to the point
  380.                 p.ySpeed = p.ySpeed * damping + accel;
  381.                 //set the position based on the speed
  382.                 p.y += p.ySpeed;
  383.                
  384.             }
  385.         }
  386.        
  387.  
  388.     }
  389.    
  390.     private function overlapSines(x:Int)
  391.     {
  392.         var result:Float = 0;
  393.         for (i in 0...NUM_BACKGROUND_WAVES)
  394.         {
  395.             result = result
  396.                 + sineOffsets[i]
  397.                 + sineAmplitudes[i]
  398.                 * Math.sin(x * sineStretches[i] + offset * offsetStretches[i]);
  399.         }
  400.         return result;
  401.     }
  402.    
  403.     public inline function draw(g:G)
  404.     {
  405.         var matrix = new Matrix();
  406.         matrix.createGradientBox(100,gradientHeight,gradientRotation,0,targetY + 10);
  407.        
  408.         offset += offsetAmount; //add a small ammount to the waves offset. This makes the waves move to the right
  409.        
  410.         if (useWaterGradient == 1)
  411.         {
  412.             g.graphics.beginGradientFill(gradientType, gradientColors, gradientAlphas, colorRatios, matrix);
  413.             for(i in 0...wavePoints.length)
  414.             {
  415.                 g.graphics.lineStyle(waterLineThickness, gradientColors[1], gradAlpha,false,LineScaleMode.NORMAL, CapsStyle.NONE);
  416.                 if(i == 0)
  417.                 {
  418.                     g.graphics.moveTo(wavePoints[i].x * Engine.SCALE, wavePoints[i].y * Engine.SCALE + overlapSines(i));
  419.                 }
  420.                 else
  421.                 {
  422.                     g.graphics.lineTo(wavePoints[i].x * Engine.SCALE, wavePoints[i].y * Engine.SCALE + overlapSines(i));
  423.                 }
  424.                 if (i == wavePoints.length-1)
  425.                 {
  426.                     g.graphics.lineTo(wavePoints[i].x * Engine.SCALE, getScreenHeight() * Engine.SCALE);
  427.                     g.graphics.lineTo(wavePoints[0].x * Engine.SCALE, getScreenHeight() * Engine.SCALE);
  428.                 }  
  429.             }
  430.             g.graphics.endFill();
  431.         }
  432.         else
  433.         {
  434.             //DON't delete
  435.             g.fillColor = Utils.getColorRGB(62, 120, 202);
  436.             g.strokeColor = Utils.getColorRGB(45, 83, 180);
  437.             g.strokeSize = 2;
  438.             g.beginFillPolygon();
  439.             g.alpha = gAlpha;
  440.             for (i in 0...wavePoints.length)
  441.             {
  442.                 g.addPointToPolygon(wavePoints[i].x * Engine.SCALE, wavePoints[i].y * Engine.SCALE + overlapSines(i));
  443.             }
  444.             g.addPointToPolygon(wavePoints[wavePoints.length -1].x * Engine.SCALE, getScreenHeight() * Engine.SCALE);
  445.             g.addPointToPolygon(0, getScreenHeight() * Engine.SCALE);
  446.             g.endDrawingPolygon();
  447.        
  448.             //
  449.            
  450.             g.strokeColor = Utils.getColorRGB(74, 142, 213);
  451.             g.strokeSize = 4;      
  452.             for (i in 0...wavePoints.length - 1)
  453.             {
  454.                 g.alpha = Utils.scale(wavePoints[i].y + overlapSines(i), targetY - BACKGROUND_WAVE_MAX_HEIGHT, targetY + BACKGROUND_WAVE_MAX_HEIGHT, 0, 1);
  455.                 g.strokeSize = Math.round(Utils.scale(wavePoints[i].y + overlapSines(i), (targetY - BACKGROUND_WAVE_MAX_HEIGHT), (targetY + BACKGROUND_WAVE_MAX_HEIGHT), 1, 4));
  456.                 g.drawLine(wavePoints[i].x * Engine.SCALE, wavePoints[i].y * Engine.SCALE + overlapSines(i) + 5,wavePoints[i+1].x * Engine.SCALE, wavePoints[i+1].y * Engine.SCALE + overlapSines(i+1) + 5);
  457.             }
  458.         }
  459.         //update splashes if we have any on the screen
  460.         if (splashesArray.length > 0)
  461.         {
  462.             for (splash in splashesArray )
  463.             {
  464.                 splash.update(); //each splash updates it's speed and position
  465.                
  466.                 if (splash.y > targetY) //when the splash 'touches' the water
  467.                 {
  468.                     if (splash.x > 0 && splash.x - splash.radius < getScreenWidth()) //and if the splash is still on the screen
  469.                     {
  470.                         //calculate what point in the wavePoints array it is touching
  471.                         var distanceBetweenPoints = Math.floor(getScreenWidth() / numberOfPoints);
  472.                         var r = Math.round(splash.x / distanceBetweenPoints);
  473.                         if (r < wavePoints.length)
  474.                         {
  475.                             //and add some small speed to that point
  476.                             //this makes each splash move the water surface when it touches the water
  477.                             wavePoints[r].ySpeed += 1;
  478.                         }
  479.                     }
  480.                     //after the splash touches the water we simply remove it from the array and kill the splash
  481.                     //that way we don't compute splashes that are not on the screen or 'underwater'
  482.                     splashesArray.remove(splash);
  483.                     splash.dispose();
  484.                 }              
  485.             }
  486.         }
  487.     }
  488.    
  489.    
  490.     //==========================================================
  491.     // Don't edit below unless you know what you're doing
  492.     //==========================================================
  493.    
  494.     public function new(dummy:Int, dummy2:Engine)
  495.     {
  496.         super();   
  497.        
  498.         addWhenUpdatedListener(null, onUpdate);
  499.         addWhenDrawingListener(null, onDraw);
  500.         addMousePressedListener(onClick);
  501.     }
  502.    
  503.     public function onUpdate(elapsedTime:Float, list:Array<Dynamic>)
  504.     {
  505.         if(wrapper.enabled)
  506.         {
  507.             update(elapsedTime);
  508.         }
  509.     }
  510.    
  511.     public function onDraw(g:G, x:Float, y:Float, list:Array<Dynamic>)
  512.     {
  513.         if(wrapper.enabled)
  514.         {
  515.             draw(g);
  516.         }
  517.     }
  518. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement