Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Stencyl exclusively uses the Haxe programming language.
- Haxe is similar to ActionScript and JavaScript.
- Want to use native code or make something reusable? Use the Extensions Framework instead.
- http://www.stencyl.com/help/view/engine-extensions/
- Learn more about Haxe and our APIs
- http://www.stencyl.com/help/view/haxe/
- */
- package scripts;
- //==========================================================
- // Imports
- //==========================================================
- import com.stencyl.graphics.BitmapWrapper;
- import com.stencyl.graphics.G;
- import openfl.display.CapsStyle;
- import openfl.display.GradientType;
- import openfl.display.LineScaleMode;
- import openfl.events.Event;
- import openfl.geom.Matrix;
- import openfl.text.TextFieldType;
- import com.stencyl.behavior.Script;
- import com.stencyl.behavior.Script.*;
- import com.stencyl.behavior.ActorScript;
- import com.stencyl.behavior.SceneScript;
- import com.stencyl.behavior.TimedTask;
- import com.stencyl.models.Actor;
- import com.stencyl.models.GameModel;
- import com.stencyl.models.actor.Animation;
- import com.stencyl.models.actor.ActorType;
- import com.stencyl.models.actor.Collision;
- import com.stencyl.models.actor.Group;
- import com.stencyl.models.Scene;
- import com.stencyl.models.Sound;
- import com.stencyl.models.Region;
- import com.stencyl.models.Font;
- import com.stencyl.models.Joystick;
- import com.stencyl.Engine;
- import com.stencyl.Input;
- import com.stencyl.utils.Utils;
- import nme.ui.Mouse;
- import nme.display.Graphics;
- import motion.Actuate;
- import motion.easing.Back;
- import motion.easing.Cubic;
- import motion.easing.Elastic;
- import motion.easing.Expo;
- import motion.easing.Linear;
- import motion.easing.Quad;
- import motion.easing.Quart;
- import motion.easing.Quint;
- import motion.easing.Sine;
- import openfl.text.TextField;
- import scripts.Particle2D;
- import openfl.display.BitmapData;
- import openfl.display.Bitmap;
- import openfl.display.Shape;
- class WaterTest extends SceneScript
- {
- //Expose your attributes like this:
- //@:attribute("id='1' name='Display Name' desc='An Attribute'")
- //public var attributeName:String;
- //Need further help? See: http://www.stencyl.com/help/view/code-mode/
- @:attribute("id='1' name='targetY' desc='The default height of the water. Default is 250.0' type='NUMBER' default='250.0'")
- public var targetY:Float = 250.0;
- @:attribute("id='2' name='iterations' desc='How fast the wave points return to their resting position. Default is 3' type='INT' default='3'")
- public var iterations:Int = 3;
- @: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'")
- public var numberOfPoints:Int = 49;
- @: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'")
- public var NUM_BACKGROUND_WAVES:Int = 4;
- @:attribute("id='5' name='BACKGROUND_WAVE_MAX_HEIGHT' desc='The max height of the waves. Default is 3' type='INT' default='3'")
- public var BACKGROUND_WAVE_MAX_HEIGHT:Int = 3;
- @:attribute("id='6' name='BACKGROUND_WAVE_MAX_COMPRESSION' desc='Waves compression. Default is 0.5' type='NUMBER' default='0.5'")
- public var BACKGROUND_WAVE_COMPRESSION:Float;
- @:attribute("id='7' name='offsetAmount' desc='Speed at which the waves move to the sides. Default is 0.3' type='NUMBER' default='0.3'")
- private var offsetAmount:Float;
- @:attribute("id='8' name='NUM_SPLASHES' desc='How many splashes do we create. Default is 20' type='INT' default='20'")
- private var NUM_SPLASHES:Int;
- @:attribute("id='9' name='splashRadius' desc='Minimum radius of a splash. Default is 8' type='INT' default='8'")
- var splashRadius:Int;
- @: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'")
- var useWaterGradient:Int = 1;
- @: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'")
- var gAlpha:Float = 1.0;
- @: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'")
- var gradAlpha:Float = 0.16;
- @:attribute("id='13' name='waterLineThickness' desc='The thickness for the water surface line. Default is 4.' type='INT' default='4'")
- var waterLineThickness:Int = 4;
- @:attribute("id='14' name='topGradientColor' desc='Top color used by the gradient' type='COLOR' default='4'")
- var topGradientColor:Int;
- @:attribute("id='15' name='bottomGradientColor' desc='Bottom color used by the gradient' type='COLOR' default='4'")
- var bottomGradientColor:Int;
- @:attribute("id='16' name='gradientHeight' desc='height of the gradient' type='INT' default='65'")
- var gradientHeight:Int = 65;
- @: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'")
- var randomSplashSpeed:Int;
- @:attribute("id='18' name='splashGravity' desc='Gravity applied to the splashes. Default is 0.4' type='Number' default='0.4'")
- var splashGravity:Float = 0.4;
- @:attribute("id='19' name='splashAlpha' desc='Alpha applied to the splashes.Default is 0.9' type='Number' default='0.9'")
- var splashAlpha:Float = 0.9;
- public var springConstant:Float;
- public var damping:Float;
- public var wavePoints:Array<WaterPoint>;
- private var offset:Float;
- private var sineOffsets:Array<Float>;
- // Amounts by which a particular sine is amplified
- private var sineAmplitudes:Array<Float>;
- // Amounts by which a particular sine is stretched
- private var sineStretches:Array<Float>;
- // Amounts by which a particular sine's offset is multiplied
- private var offsetStretches:Array<Float>;
- var splashesArray:Array<Particle2D>;
- var gradientType:GradientType;
- var gradientColors:Array<UInt>;
- var gradientAlphas:Array<Float>;
- var colorRatios:Array<Int>;
- var gradientRotation:Float;
- override public function init()
- {
- //iterations = 3; //how fast the waves return to their resting position
- //targetY = 250;
- springConstant = 0.003;
- damping = 0.99;
- //numberOfPoints = 49;
- offset = 0;
- //offsetAmount = 0.3; //how fast the waves move on the screen
- //NUM_BACKGROUND_WAVES = 4;
- //BACKGROUND_WAVE_MAX_HEIGHT = 3;
- //BACKGROUND_WAVE_COMPRESSION = 1/2;
- wavePoints = new Array();
- //NUM_SPLASHES = 20; //how many splashes we create at once
- splashesArray = new Array();
- //splashRadius = 8; //max radius for our splashes
- createSineWaves();
- createWavePoints();
- //useWaterGradient = 1;
- //gAlpha = 1;
- //gradAlpha = 0.16;
- //waterLineThickness = 4;
- //topGradientColor = Utils.getColorRGB(45, 83, 180);
- //trace ("topGradientColor = " + topGradientColor);
- //bottomGradientColor = Utils.getColorRGB(62, 120, 202);
- //trace ("bottomGradientColor = " + bottomGradientColor );
- gradientType = GradientType.LINEAR;
- gradientColors = [topGradientColor, bottomGradientColor];
- gradientAlphas = [gradAlpha, 1];
- colorRatios = [1, 255];
- gradientRotation = Math.PI / 2; //90 degrees
- //gradientHeight = 65;
- //splashGravity = 0.40;
- //randomSplashSpeed = 0;
- //splashAlpha = 0.9;
- var xx = 240;
- //createTF("randomSplashSpeed", 120, 60, false);
- /*createTF("splashGravity", 120, 20, true);
- createTF("NUM_SPLASHES", 120, 40, false);
- createTF("randomSplashSpeed", 120, 60, false);
- createTF("splashRadius", 120, 80, false);
- createTF("splashAlpha", 120, 100, true);
- createTF("numberOfPoints", 120, 120, false);
- createTF("iterations", xx, 20, false);
- createTF("offsetAmount", xx, 40, true);
- createTF("NUM_BACKGROUND_WAVES", xx, 60, false);
- createTF("BACKGROUND_WAVE_MAX_HEIGHT", xx, 80, false);
- createTF("BACKGROUND_WAVE_COMPRESSION", xx, 100, true);
- //createTF("testGradient", 100, 120, false);
- createTF("gAlpha", 100, 140, true);*/
- }
- private function createWavePoints()
- {
- if (wavePoints.length > 0)
- {
- while (wavePoints.length > 0)
- wavePoints.pop();
- }
- //create the water points
- var distanceBetweenPoints = Math.ceil(getScreenWidth() / numberOfPoints);
- for (i in 0...numberOfPoints)
- {
- var p = new WaterPoint(distanceBetweenPoints * i, targetY, 0);
- wavePoints.push(p);
- }
- }
- private function createSplashes(j:Int)
- {
- //create the splashes
- for (i in 0 ... NUM_SPLASHES)
- {
- var disp = Math.random() * 50; //displacement on the x axis from the position of the mouse
- var xx = (getMousePressedX() - disp / 2) + Math.random() * (disp * 2) ;
- var yy = wavePoints[j].y;
- var radius = Math.round(splashRadius/2 + Math.random() * splashRadius);
- var angle = 225 + Math.random() * 90; //splash the radius only up
- var vx:Float;
- var vy:Float;
- if (randomSplashSpeed == 0)
- {
- vx = Math.cos(Utils.RAD * angle) * radius; //xSpeed of the splash
- vy = Math.sin(Utils.RAD * angle) * radius; //ySpeed of the splash
- }
- else
- {
- vx = Math.cos(Utils.RAD * angle) * randomSplashSpeed; //xSpeed of the splash
- vy = Math.sin(Utils.RAD * angle) * randomSplashSpeed; //ySpeed of the splash
- }
- //create the splash and add it to the array
- //var splash = new Particle2D(xx, yy, vx, vy, Utils.getColorRGB(45, 83, 180), radius, gAlpha);
- var splash = new Particle2D(xx, yy, vx, vy, topGradientColor, radius, splashAlpha, splashGravity);
- splashesArray.push(splash);
- }
- }
- private function createTF(value:String, x:Float, y:Float, floatNum:Bool)
- {
- var tt = new TextField();
- tt.x = x;
- tt.y = y;
- tt.width = 64;
- tt.height = 18;
- tt.border = true;
- tt.type = TextFieldType.INPUT;
- tt.restrict = "0-9 .";
- tt.maxChars = 5;
- tt.text = "" + Reflect.field(this, value);
- Engine.engine.root.parent.addChild(tt);
- tt.addEventListener(Event.CHANGE, function(e:Dynamic) {
- if (floatNum)
- Reflect.setField(this, value, Std.parseFloat(tt.text));
- else
- Reflect.setField(this, value, Std.parseInt(tt.text));
- if (value == "numberOfPoints")
- createWavePoints();
- createSineWaves();
- });
- var tx = new TextField();
- tx.x = 5;
- tx.y = y;
- tx.width = tt.x - 5;
- tx.type = TextFieldType.DYNAMIC;
- tx.selectable = false;
- tx.mouseEnabled = false;
- tx.text = value;
- Engine.engine.root.parent.addChild(tx);
- }
- private function createSineWaves()
- {
- sineOffsets = new Array();
- sineAmplitudes = new Array();
- sineStretches = new Array();
- offsetStretches = new Array();
- //set the sine waves
- for (i in 0...NUM_BACKGROUND_WAVES)
- {
- var sineOffset = -Math.PI + 2 * Math.PI * Math.random();
- sineOffsets.push(sineOffset);
- var sineAmplitude = Math.random() * BACKGROUND_WAVE_MAX_HEIGHT;
- sineAmplitudes.push(sineAmplitude);
- var sineStretch = Math.random() * BACKGROUND_WAVE_COMPRESSION;
- sineStretches.push(sineStretch);
- var offsetStretch = Math.random() * BACKGROUND_WAVE_COMPRESSION;
- offsetStretches.push(offsetStretch);
- }
- }
- /*public function onClick(array:Array<Dynamic>)
- {
- var distanceBetweenPoints = Math.ceil(getScreenWidth() / numberOfPoints);
- var i = Math.ceil(getMousePressedX() / distanceBetweenPoints);
- //trace ("Index = " + i + " mouseX = " + getMousePressedX());
- wavePoints[i].ySpeed += 5;
- createSplashes(i);
- }*/
- public function _customBlock_createwaves(__Xposition:Float):Void
- {
- var distanceBetweenPoints = Math.ceil(getScreenWidth() / numberOfPoints);
- var i = Math.ceil(__Xposition / distanceBetweenPoints);
- wavePoints[i].ySpeed += 5;
- createSplashes(i);
- }
- public inline function update(elapsedTime:Float)
- {
- //update the water points
- for (i in 0...iterations)
- {
- for (n in 0...(wavePoints.length - 1))
- {
- var p = wavePoints[n];
- var force:Float = 0;
- var forceFromLeft:Float;
- var forceFromRight:Float;
- //force from left point
- var ld:Float = 0;
- if (n > 0 && n < (wavePoints.length -1))
- ld = wavePoints[n - 1].y - p.y;
- else
- ld = 0;
- forceFromLeft = springConstant * ld;
- //force from right point
- var rd:Float = 0;
- if (n > 0 && n < (wavePoints.length -2))
- rd = wavePoints[n + 1].y - p.y;
- else
- rd = 0;
- forceFromRight = springConstant * rd;
- //apply force toward the resting position of the spring
- var dy:Float = targetY - p.y;
- var forceToRestingPos = springConstant * dy;
- //sum all the forces
- force += forceFromLeft;
- force += forceFromRight;
- force += forceToRestingPos;
- var accel:Float = force / p.mass;
- //apply acceleration to the point
- p.ySpeed = p.ySpeed * damping + accel;
- //set the position based on the speed
- p.y += p.ySpeed;
- }
- }
- }
- private function overlapSines(x:Int)
- {
- var result:Float = 0;
- for (i in 0...NUM_BACKGROUND_WAVES)
- {
- result = result
- + sineOffsets[i]
- + sineAmplitudes[i]
- * Math.sin(x * sineStretches[i] + offset * offsetStretches[i]);
- }
- return result;
- }
- public inline function draw(g:G)
- {
- var matrix = new Matrix();
- matrix.createGradientBox(100,gradientHeight,gradientRotation,0,targetY + 10);
- offset += offsetAmount; //add a small ammount to the waves offset. This makes the waves move to the right
- if (useWaterGradient == 1)
- {
- g.graphics.beginGradientFill(gradientType, gradientColors, gradientAlphas, colorRatios, matrix);
- for(i in 0...wavePoints.length)
- {
- g.graphics.lineStyle(waterLineThickness, gradientColors[1], gradAlpha,false,LineScaleMode.NORMAL, CapsStyle.NONE);
- if(i == 0)
- {
- g.graphics.moveTo(wavePoints[i].x * Engine.SCALE, wavePoints[i].y * Engine.SCALE + overlapSines(i));
- }
- else
- {
- g.graphics.lineTo(wavePoints[i].x * Engine.SCALE, wavePoints[i].y * Engine.SCALE + overlapSines(i));
- }
- if (i == wavePoints.length-1)
- {
- g.graphics.lineTo(wavePoints[i].x * Engine.SCALE, getScreenHeight() * Engine.SCALE);
- g.graphics.lineTo(wavePoints[0].x * Engine.SCALE, getScreenHeight() * Engine.SCALE);
- }
- }
- g.graphics.endFill();
- }
- else
- {
- //DON't delete
- g.fillColor = Utils.getColorRGB(62, 120, 202);
- g.strokeColor = Utils.getColorRGB(45, 83, 180);
- g.strokeSize = 2;
- g.beginFillPolygon();
- g.alpha = gAlpha;
- for (i in 0...wavePoints.length)
- {
- g.addPointToPolygon(wavePoints[i].x * Engine.SCALE, wavePoints[i].y * Engine.SCALE + overlapSines(i));
- }
- g.addPointToPolygon(wavePoints[wavePoints.length -1].x * Engine.SCALE, getScreenHeight() * Engine.SCALE);
- g.addPointToPolygon(0, getScreenHeight() * Engine.SCALE);
- g.endDrawingPolygon();
- //
- g.strokeColor = Utils.getColorRGB(74, 142, 213);
- g.strokeSize = 4;
- for (i in 0...wavePoints.length - 1)
- {
- g.alpha = Utils.scale(wavePoints[i].y + overlapSines(i), targetY - BACKGROUND_WAVE_MAX_HEIGHT, targetY + BACKGROUND_WAVE_MAX_HEIGHT, 0, 1);
- g.strokeSize = Math.round(Utils.scale(wavePoints[i].y + overlapSines(i), (targetY - BACKGROUND_WAVE_MAX_HEIGHT), (targetY + BACKGROUND_WAVE_MAX_HEIGHT), 1, 4));
- 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);
- }
- }
- //update splashes if we have any on the screen
- if (splashesArray.length > 0)
- {
- for (splash in splashesArray )
- {
- splash.update(); //each splash updates it's speed and position
- if (splash.y > targetY) //when the splash 'touches' the water
- {
- if (splash.x > 0 && splash.x - splash.radius < getScreenWidth()) //and if the splash is still on the screen
- {
- //calculate what point in the wavePoints array it is touching
- var distanceBetweenPoints = Math.floor(getScreenWidth() / numberOfPoints);
- var r = Math.round(splash.x / distanceBetweenPoints);
- if (r < wavePoints.length)
- {
- //and add some small speed to that point
- //this makes each splash move the water surface when it touches the water
- wavePoints[r].ySpeed += 1;
- }
- }
- //after the splash touches the water we simply remove it from the array and kill the splash
- //that way we don't compute splashes that are not on the screen or 'underwater'
- splashesArray.remove(splash);
- splash.dispose();
- }
- }
- }
- }
- //==========================================================
- // Don't edit below unless you know what you're doing
- //==========================================================
- public function new(dummy:Int, dummy2:Engine)
- {
- super();
- addWhenUpdatedListener(null, onUpdate);
- addWhenDrawingListener(null, onDraw);
- addMousePressedListener(onClick);
- }
- public function onUpdate(elapsedTime:Float, list:Array<Dynamic>)
- {
- if(wrapper.enabled)
- {
- update(elapsedTime);
- }
- }
- public function onDraw(g:G, x:Float, y:Float, list:Array<Dynamic>)
- {
- if(wrapper.enabled)
- {
- draw(g);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement