JURVANOERLE.nl

This simple application adds the effect of waterdrops to an image.
It is made in Netbeans using simple algorithms taken from gamedev.com
Download it here.
The source code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//WaterDrops.java

package water;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import java.applet.Applet;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 *
 * @author deleo
 */
public class WaterDroplets extends Applet implements Runnable
{
    int width, height;
    JFrame          frame;
    JLabel          label;
    Simulat         sim;
    Random          rando = null;
    
    public void start( )
    {
        init( );
        
        BufferedImage image = null;
        frame   = new JFrame( "Waterdrops." );
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                    
        try 
        {
            image   = ImageIO.read( getClass( ).getResource( "/graylake.jpg" ) );
            width   = image.getWidth( );
            height  = image.getHeight( );
        } catch ( IOException ex ) 
        {            
            Logger.getLogger( WaterDroplets.class.getName( ) ).log( Level.SEVERE, null, ex );
        }
        rando   = new Random( System.currentTimeMillis( ) );
        label = new JLabel( new ImageIcon( image ) );
        
        frame.setSize( getDrawWidth( ), getDrawHeight( ) );
        frame.setVisible( true );
        frame.add( label );
                
        sim  = new Simulat( this, frame, image );
        new Thread( this ).start( );
    }
    
    public void init( )
    {
        
    }
    
    public void drawFrame( JFrame frame, BufferedImage image )
    {
        label.setIcon( new ImageIcon( image ) );
        frame.repaint( );
    }
    
    public int getDrawWidth( )
    {
        return width;
    }
    
    public int getDrawHeight( )
    {
        return height;
    }

    public void run( ) 
    {
        while ( true )
        {
            try
            {
                sim.addRain( Math.abs( rando.nextInt( ) ) % getDrawWidth( ), Math.abs( rando.nextInt( ) ) % getDrawHeight( ) );
                Thread.sleep( 120 );
            } catch ( Exception e )
            {
            }
        }
    }
}


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
//Simulat.java

package water;
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import java.awt.image.BufferedImage;
import javax.swing.JFrame;

/**
 *
 * @author deleo
 */
public class Simulat implements Runnable
{
    private final int[]         _texture;
    private final BufferedImage _image;
    
    private final int           _width, _height;    
    private final WaterDroplets _listener;
    private final JFrame        _frame;
    
    private int _old[][];
    private int _new[][];
            
    public Simulat( WaterDroplets listener, JFrame frame, BufferedImage image )
    {
        _listener   = listener;
        _frame      = frame;
        _width      = _listener.getDrawWidth( );
        _height     = _listener.getDrawHeight( );
        
        _new        = new int[_width][_height];
        _old        = new int[_width][_height];
        
        _texture    = new int[_width * _height];
        _image      = image;
        image.getRGB( 0, 0, _width, _height, _texture, 0, _width );
        new Thread( this ).start( );
    }

    public void run( ) 
    {
        while ( true )
        {
            try
            {
                updateImage( _texture, _image );
                Thread.sleep( 1L );
            } catch ( Exception e )
            {
                
            }
        }
    }
    
    //calculates where the waves will roll. tex is the original image.
    private void updateImage( int[] tex, BufferedImage nTex )
    {
        for ( int x = 1; x < _width - 1; ++x )
        {
            for ( int y = 1; y < _height - 1; ++y )
            {
                _new[x][y]  = ( (
                        _old[x - 1][y] +
                        _old[x + 1][y] +
                        _old[x][y + 1] +
                        _old[x][y - 1] ) >> 1 ) - _new[x][y];
                _new[x][y]  -= ( _new[x][y] >> 6 );
                
                int  data   = ( short )( 1024 - _new[x][y] );
                
                int a       = ( ( x - _width ) * data / 1024 ) + _width;
                int b       = ( ( y - _height ) * data / 1024 ) + _height;
                
                if ( a >= _width ) a = _width - 1;
                if ( a < 0 ) a = 0;
                if ( b >= _height ) b = _height - 1;
                if ( b < 0 ) b = 0;
                
                _image.setRGB( x, y, tex[a + b * _width] );
            }
        }
        int[][] temp    = _new;
        _new            = _old;
        _old            = temp;
        _listener.drawFrame( _frame, nTex );
    }
    
    public void addRain( int x, int y )
    {
            if (		x > _width - 1
                            ||  x < 1
                            ||  y > _height - 1
                            ||  y< 1
            )
                    return;

            for ( int i = -3 ; i < 3; ++i )
                    for ( int j = -3; j < 3; ++j )
                            _new[x + i][y + j] = 200;	

    }
}