Realistic water simulation ! [NOT a game]

SadiQ

  • Posts: 1781
Hm, sorry, I tried a bit, but it seems to be unimplemented and I don't see a way to do it without modifying the source.

I managed to do it with code and a lot of trial and error. I got inspired from your Eye candy pack game.
I created an matrix with a gradient box to it and it worked :)
If you know how it can be improved please feel free to post some thoughts.
I uploaded it on the forge and did a quick test as posted here:
http://community.stencyl.com/index.php/topic,24306.0.html
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

spoogob

  • Posts: 1106
Looking good :)

I managed to put this into 3.0 - but I had to take out the new gradient code with it being haxe in 3.0. Do you think it would take much to alter it for this? Id have a go but its beyond me lol Looks nicer with a gradient though :)

SadiQ

  • Posts: 1781
Looking good :)

I managed to put this into 3.0 - but I had to take out the new gradient code with it being haxe in 3.0. Do you think it would take much to alter it for this? Id have a go but its beyond me lol Looks nicer with a gradient though :)
Unfortunately I don't have 3.0  so untill they release it I can't begin testing :(
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

spoogob

  • Posts: 1106
Yeah good point.

I looked at the code you put in to do the gradient - i know theres similarities between as3 and haxe - but i wouldn't really know what to change.

Good stuff anyhow :)

SadiQ

  • Posts: 1781
Yeah good point.

I looked at the code you put in to do the gradient - i know theres similarities between as3 and haxe - but i wouldn't really know what to change.

Good stuff anyhow :)
You're free to change everything in the drawing event, especially what's in the code blocks :P
Seriously thou... from what I read the matrix part is the same, so that only leaves you to figure out if you need to use something other than a shape to define the water (but I think that also works as is in flash), or how to draw on the scene ( the FlxG.buffer.draw() part).
 Maybe someone knows how that would be done? Is there the Eye Candy Pack in 3.0 in the forge? (that's where I saw how to draw my shape onto a scene :P)
 Following a tutorial on how to draw a square (or better yet a polygon) in haxe is basically all you need if you can actually draw it on the scene...the rest is trying NOT to read that API thingy like a newspaper (that is the hard part for me since I never coded anything in my life): http://haxe.org/api/flash/  and then trying to see on what you can apply a gradient (shape, Bitmap, Sprite or whatever else is there).
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

spoogob

  • Posts: 1106
Yeah I did have a brief play with the code - but it kept coming up with import errors (if i remember correctly - i have it closed at the moment).

The Eye candy pack is for 2.2 and previous versions i believe.

Ill have another go at this - but im not sure ill get very far haha. although i see the general idea is to draw a shape and apply the gradient. :) I expect ill report back at some point.

SadiQ

  • Posts: 1781
Do let me know how that works and maybe post a little demo to see how it behaves as I'm anxious to see for myself :)
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

spoogob

  • Posts: 1106
Already tearing my hair out, although I managed to fix the import problem. Now have 'var' problems lol

Wheres captain comic when i need him :-) haha.

captaincomic

  • *
  • Posts: 6109
Wheres captain comic when i need him :-) haha.
On holidays :D

I'm back now, so if you want I can look the problem now. Just post your code and error messages.

spoogob

  • Posts: 1106
Haha. Hope you enjoyed yourself :) You were the first person I thought of that maybe able to help convert the code to haxe/3.0. Anyhow, the code below is what Sadiq used for 2.2 to get the gradient on the water.

Code: [Select]
import flash.display.Shape;
import flash.display.GradientType;
import flash.geom.Matrix;

 
var WaterSurface:Shape = new Shape();

var type:String = GradientType.LINEAR;
// HEX colors taken from:http://html-color-codes.com/
//Light blue , Dark blue
var colors:Array = [0x3333FF,0x330099];
//alphas will be used to specify how opaque the colors are. Values from 0 to 1.
var alphas:Array = [_SurfaceOpacity, 1];
//ratios...the amount of light blue vs dark blue colors
var ratios:Array = [0, 255];
//rotation will be used to calculate how much we will rotate our gradient.
var rotation:Number = Math.PI/2; //90 degrees


var matrix = new Matrix();
//createGradientBox (width,height,rotation,transposeX,transposeY)
//transposeY can be _TargetHeight +or - some number...I use 10 for this scene height
matrix.createGradientBox(100,100,rotation,0,_TargetHeight + 10);
//WaterSurface.graphics.lineStyle(1,0x330089);
//Let's create a polygon based on the points we have in PositionList and HeightList.
WaterSurface.graphics.beginGradientFill(type, colors,alphas,ratios,matrix);
for(var i:int = 0; i < _PositionList.length ; i ++)
{
    if(i == 0)
      {
        WaterSurface.graphics.moveTo(_PositionList[i], _Heightlist[i]);
      }
    else
      {
        WaterSurface.graphics.lineTo(_PositionList[i], _Heightlist[i]);
      }
    if (i == _PositionList.length-1)
      {
      WaterSurface.graphics.lineTo(_PositionList[i], getScreenHeight());
      WaterSurface.graphics.lineTo(_PositionList[0], getScreenHeight());
     
      } 
}
WaterSurface.graphics.endFill();
//Now we can draw our water on the screen
FlxG.buffer.draw(WaterSurface);

I tried to get things working in 3.0, but I couldn't get very far. I managed to get past a couple of import errors but apart from that, its beyond me mostly!

captaincomic

  • *
  • Posts: 6109
Hey, here you go:

Imports must go in a custom import event (haxe is more picky than AS3)
Code: [Select]
import nme.display.Shape;
import nme.display.GradientType;
import nme.geom.Matrix;

And instead of using FlxG.buffer.draw to draw the shape, we can use the g.graphics directly, syntax of "for" loops is a bit different and a few types had to be changed (Number -> Float, Arrays must be typed.)
Code: [Select]
var type:GradientType = GradientType.LINEAR;
// HEX colors taken from:http://html-color-codes.com/
//Light blue , Dark blue
var colors:Array<UInt> = [0x3333FF,0x330099];
//alphas will be used to specify how opaque the colors are. Values from 0 to 1.
var alphas:Array<Dynamic> = [_SurfaceOpacity, 1];
//ratios...the amount of light blue vs dark blue colors
var ratios:Array<Dynamic> = [0, 255];
//rotation will be used to calculate how much we will rotate our gradient.
var rotation:Float = Math.PI/2; //90 degrees

var matrix = new Matrix();
//createGradientBox (width,height,rotation,transposeX,transposeY)
//transposeY can be _TargetHeight +or - some number...I use 10 for this scene height
matrix.createGradientBox(100,100,rotation,0,_TargetHeight + 10);
//g.graphics.lineStyle(1,0x330089);

//Let's create a polygon based on the points we have in PositionList and HeightList.
g.graphics.beginGradientFill(type, colors,alphas,ratios,matrix);

for(i in 0..._PositionList.length)
{
    if(i == 0)
      {
        g.graphics.moveTo(_PositionList[i], _Heightlist[i]);
      }
    else
      {
        g.graphics.lineTo(_PositionList[i], _Heightlist[i]);
      }
    if (i == _PositionList.length-1)
      {
      g.graphics.lineTo(_PositionList[i], getScreenHeight());
      g.graphics.lineTo(_PositionList[0], getScreenHeight());
      } 
}
g.graphics.endFill();

Edit: Now on Forge as well.

« Last Edit: August 24, 2013, 08:14:22 am by captaincomic »

spoogob

  • Posts: 1106
hi cc,

nice one!.. i managed to get as far as the imports - but after that I was just puzzled.

my version I have of this, I altered so I could place the water where I wanted and choose how big the water is (on the x of the screen).. Ive now incorperated the gradient and looks much nicer :)

So thanks to you both for that anyhow.

spoogob

  • Posts: 1106
hmm ok. before the gradient, i had it set up so you could place the water where you wanted it and what size you wanted it to be (it drew from actor space, and i set an actor as a kinda marker to where it should start).. but trying to implement the new gradient code, which does work, it doesnt seem to take into account the previous setup. is there something in the code that will prevent this? it would be great to have this configurable again (size and placement).

SadiQ

  • Posts: 1781
  To modify the placement you need to modify the PositionList. In my code in the Created event it starts at 0 (the X position) so you can replace it with your desired X position, and the end position is in the repeat block below those lines (Repeat 10 times -> add 8*currentLoopCount to positionlist will make the water 80 pixels in width).
   In the Drawing code you have these lines  g.graphics.lineTo(_PositionList, getScreenHeight()); and g.graphics.lineTo(_PositionList[0], getScreenHeight()); that make the water draw from the first number in the X position to the bottom of the screen, so you can just replace getScreenHeight() with the Y position you want and it should be done.
 The next challenge will be to add the water drops (I'll see if you can do it :P).

@captaincomic a quick question about programming
 you have these lines..
var colors:Array<UInt> = [0x3333FF,0x330099];
I assume this one creates a list of numbers that can include positive and negative numbers, so if you replace the UInt to just Int will that work (since there are no negative numbers in there)?
 And what is this var ratios:Array<Dynamic> = [0, 255]; ? Why the Dynamic? What does it do and why not use Int or Uint instead of it??
 And the last question...is it possible to have a float with less numbers after the comma? I use a few extra blocks in the Always event to stop the spring when the height becomes lower than 0.05 as without it I just calculate the height for values smaller (something like 0.000000001) and it eventually crashes.
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

SadiQ

  • Posts: 1781
  Actually ..can you post what exactly isn't working? If the gradient isn't applied correctly it can probably be fixed in this line matrix.createGradientBox(100,100,rotation,0,_TargetHeight + 10);.
  I had to manually test (a lot of) the numbers to get the gradient working so try messing with the last 2 numbers in there (0 and _TargetHeight + 10).
Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.