服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

水面的倒影源程序


  <!--startfragment-->******************************************************************************

// lake.java: applet

//

// (c) david griffiths, 1997

// this source code may not be reproduced without the express permission of the

// author.

//******************************************************************************

import java.applet.*;

import java.net.url;

import java.net.malformedurlexception;

import java.awt.*;

//==============================================================================

// main class for applet lake

//

//==============================================================================

public class lake extends applet implements runnable

{

// thread support:

// m_lake is the thread object for the applet

//--------------------------------------------------------------------------

thread m_lake = null;

// animation support:

// m_graphics used for storing the applet's graphics context

// m_wavegraphics used for storing the animation's graphics context

// m_image   the original image

// m_waveimage   the image containing the wave animations

// m_ncurrimage the index of the next image to be displayed

// m_imgwidth width of each image

// m_imgheight height of each image

// m_ovlwidth width of each overlay

// m_ovlheight height of each overlay

// m_fallloaded indicates whether all images have been loaded

// m_tanimate indicates that ok to do animation (changed by mouse

// click)

// num_frames      number of num_frames used in the animation

//--------------------------------------------------------------------------

private graphics m_graphics, m_wavegraphics;

private image m_image, m_overlay, m_waveimage;

private int m_ncurrimage;

private int m_nimgwidth  = 0;

private int m_nimgheight = 0;

private int m_novlwidth  = 0;

private int m_novlheight = 0;

private boolean  m_fallloaded = false, m_tanimate = true;

private final int num_frames = 12;

// parameter support:

// parameters allow an html author to pass information to the applet;

// the html author specifies them using the <param> tag within the <applet>

// tag.  the following variables are used to store the values of the

// parameters.

    //--------------------------------------------------------------------------

    // members for applet parameters

    // <type>       <membervar>    = <default value>

    //--------------------------------------------------------------------------

private string m_imagename = "";

private string m_overlayname = "";

private url m_href;

private string m_frame = "_self";

    // parameter names.  to change a name of a parameter, you need only make

// a single change.  simply modify the value of the parameter string below.

    //--------------------------------------------------------------------------

private final string param_image = "image";

private final string param_overlay = "overlay";

private final string param_href = "href";

private final string param_target = "target";

// lake class constructor

//--------------------------------------------------------------------------

public lake()

{

// todo: add constructor code here

}

// applet info support:

// the getappletinfo() method returns a string describing the applet's

// author, copyright date, or miscellaneous information.

    //--------------------------------------------------------------------------

public string getappletinfo()

{

return "name: lake v3.0 " +

       "author: david griffiths " +

       "created with microsoft visual j++ version 1.0";

}

// parameter support

// the getparameterinfo() method returns an array of strings describing

// the parameters understood by this applet.

//

    // lake parameter information:

    //  { "name", "type", "description" },

    //--------------------------------------------------------------------------

public string[][] getparameterinfo()

{

string[][] info =

{

{ param_image, "string", "jpg or gif file to reflect" },

{ param_overlay, "string", "jpg or gif file to use as overlay" },

{ param_href, "url", "url to link to" },

{ param_target, "string", "target frame" },

};

return info;

}

// the init() method is called by the awt when an applet is first loaded or

// reloaded.  override this method to perform whatever initialization your

// applet needs, such as initializing data structures, loading images or

// fonts, creating frame windows, setting the layout manager, or adding ui

// components.

    //--------------------------------------------------------------------------

public void init()

{

// parameter support

// the following code retrieves the value of each parameter

// specified with the <param> tag and stores it in a member

// variable.

//----------------------------------------------------------------------

string param;

// image: jpg of gif file to reflect

//----------------------------------------------------------------------

param = getparameter(param_image);

if (param != null)

m_imagename = param;

// overlay: jpg of gif file to use as overlay

//----------------------------------------------------------------------

param = getparameter(param_overlay);

if (param != null)

m_overlayname = param;

// href: url to link to

//----------------------------------------------------------------------

param = getparameter(param_href);

if (param != null)

                try

                {

                    m_href = new url(getdocumentbase(), param);

                }

                catch (malformedurlexception e)

                {

                    getappletcontext().showstatus("bad url: " + param);

                    return;

                }

// target: target frame

//----------------------------------------------------------------------

param = getparameter(param_target);

if (param != null)

m_frame = param;

}

// place additional applet clean up code here.  destroy() is called when

// when you applet is terminating and being unloaded.

//-------------------------------------------------------------------------

public void destroy()

{

// todo: place applet cleanup code here

}

    // animation support:

    // draws the next image, if all images are currently loaded

    //--------------------------------------------------------------------------

private void displayimage(graphics g)

{

if (!m_fallloaded)

return;

// draw frame of rippled lower half

//----------------------------------------------------------------------

if (m_waveimage != null) {

g.drawimage (m_waveimage, (-m_ncurrimage * m_nimgwidth), m_nimgheight, this);

g.drawimage (m_waveimage, ((num_frames-m_ncurrimage) * m_nimgwidth),

m_nimgheight, this);

}

// draw the original in the tophalf.

//----------------------------------------------------------------------

g.drawimage (m_image, 0, -1, this);

}

// lake paint handler

//--------------------------------------------------------------------------

public void paint(graphics g)

{

// animation support:

// the following code displays a status message until all the

// images are loaded. then it calls displayimage to display the current

// image.

//----------------------------------------------------------------------

if (m_fallloaded)

displayimage(g);

else

g.drawstring("loading images...", 10, 20);

// todo: place additional applet paint code here

}

// the start() method is called when the page containing the applet

// first appears on the screen. the appletwizard's initial implementation

// of this method starts execution of the applet's thread.

//--------------------------------------------------------------------------

public void start()

{

if (m_lake == null)

{

m_lake = new thread(this);

m_lake.start();

}

}

// the stop() method is called when the page containing the applet is

// no longer on the screen. the appletwizard's initial implementation of

// this method stops execution of the applet's thread.

//--------------------------------------------------------------------------

public void stop()

{

if (m_lake != null)

{

m_lake.stop();

m_lake = null;

}

}

// thread support

// the run() method is called when the applet's thread is started. if

// your applet performs any ongoing activities without waiting for user

// input, the code for implementing that behavior typically goes here. for

// example, for an applet that performs animation, the run() method controls

// the display of images.

//--------------------------------------------------------------------------

public void run()

{

m_ncurrimage = 0;

// if re-entering the page, then the images have already been loaded.

// m_fallloaded == true.

//----------------------------------------------------------------------

        if (!m_fallloaded)

{

    repaint();

    m_graphics = getgraphics();

    // now load up the image to be used in the animation. rather than do

// this asynchronously with imageupdate (which is a pain in the bum to

// use) we'll do it synchronously with a mediatracker. this hangs

// around until the image is loaded. using the waitforall method, just

// in case we ever add other images to the applet.

    //------------------------------------------------------------------

    mediatracker tracker = new mediatracker(this);

    string strimage;

    m_image = getimage(getdocumentbase(), m_imagename);

            if (!"".equals(m_overlayname))

    m_overlay = getimage(getdocumentbase(), m_overlayname);

            tracker.addimage(m_image, 0);

            if (!"".equals(m_overlayname))

tracker.addimage(m_overlay, 1);

    // wait until all images are fully loaded

    //------------------------------------------------------------------

try

{

tracker.waitforall();

m_fallloaded = !tracker.iserrorany();

}

catch (interruptedexception e) {}

if (!m_fallloaded)

{

    stop();

    m_graphics.drawstring("error loading images!", 10, 40);

    return;

}

// can now set width and height straight away because the

// mediatracker object has ensured this information is now available.

//--------------------------------------------------------------

    m_nimgwidth  = m_image.getwidth(this);

    m_nimgheight = m_image.getheight(this);

            if (!"".equals(m_overlayname)) {

    m_novlwidth  = m_overlay.getwidth(this);

    m_novlheight = m_overlay.getheight(this);

}

// now create the animation of the rippling waves.

//--------------------------------------------------------------

createanimation();

        }

repaint();

while (true)

{

try

// draw next image in animation

//--------------------------------------------------------------

if (m_tanimate)

{

displayimage(m_graphics);

if (++m_ncurrimage == num_frames)

m_ncurrimage = 0;

thread.sleep(50);

}

else

thread.sleep(500);

catch (interruptedexception e)

stop();

}

}

// mouse support:

// clicking on the applet starts/stops it.

// doesn't call 'stop()' directly because otherwise an interruptedexception

// is thrown. ..

//--------------------------------------------------------------------------

    public boolean mouseup(event event, int i, int j)

    {

        boolean flag = super.mouseup(event, i, j);

if (m_href == null)

m_tanimate = !m_tanimate; // toggle m_tanimate to start/stop animation.

else

{

showstatus("" + m_href);

getappletcontext().showdocument(m_href, m_frame);

}

        return true;

    }

// animation

// create the animation within a single background image. we use a single

// image rather than the default multiple images because it's quicker.

//---------------------------------------------------------------------------

    public void createanimation ()

{

// create inverted image of original loaded image.

// we create a background image (backimg) 1 pixel higher

// than the original because we'll need an extra line of

// pixels to play with when we flip the image upside down.

//--------------------------------------------------------       

image backimg = createimage (m_nimgwidth, m_nimgheight + 1);

        graphics backg = backimg.getgraphics();

// copy the original image (m_image) onto the background

// version.

//--------------------------------------------------------

        backg.drawimage (m_image, 0, 1, this);

// now flip the image upside down.

//--------------------------------------------------------

        for (int i = 0; i < (m_nimgheight >> 1); i++)

{

            backg.copyarea (0, i, m_nimgwidth, 1, 0, m_nimgheight - i);

            backg.copyarea (0, m_nimgheight - 1 - i, m_nimgwidth, 1,

        0, -m_nimgheight + 1 + (i << 1));

            backg.copyarea (0, m_nimgheight, m_nimgwidth, 1, 0, -1 - i);

        }

// now create the large (num_frames + 1 times the width) image

// that will store dithered copies of the inverted original.

//--------------------------------------------------------

        m_waveimage = createimage ((num_frames + 1) * m_nimgwidth, m_nimgheight);

        m_wavegraphics = m_waveimage.getgraphics();

        m_wavegraphics.drawimage (backimg, num_frames * m_nimgwidth, 0, this);

// now create dithered copies (sine displacement up or down) of the

// inverted original.

//--------------------------------------------------------

        for (int phase = 0; phase < num_frames; phase++)

            makewaves (m_wavegraphics, phase);

// now, if there is an overlay image, draw the top half of it

// over the frame. (the bottom half of the overlay will be drawn over

// the rippled image)

//------------------------------------------------------------

backg.drawimage (m_image, 0, 1, this);

if (!"".equals(m_overlayname))

backg.drawimage (m_overlay,

(m_nimgwidth - m_novlwidth) >> 1,

m_nimgheight - (m_novlheight >> 1), this);

m_image = backimg;

}

// animation

// take the initial (unwaved) image from the left-hand-side of the graphics

// and make num_frames copies of it - the pixels rows of each one dithered

// up or down depending upon the dispy sine function.

//---------------------------------------------------------------------------

public void makewaves (graphics g, int phase)

{

double p1;

int     dispx, dispy;

// convert the phase into radians (by splitting 2*pi into

// num_frames segments).

//--------------------------------------------------------

p1 = 2 * math.pi * (double)phase / (double)num_frames;

// dispx defines how far across the image has to be copied

// from the original lhs frame.

//--------------------------------------------------------

dispx = (num_frames - phase) * m_nimgwidth;

// now process each horizontal line of pixels. copy across

// from original frame on the left-had-side and displacing

// up or down wrt the dispy sine function.

//--------------------------------------------------------

for (int i = 0; i < m_nimgheight; i++)

{

// dispy defines the vertical sine displacement. it

// attenuates higher up the image, for perspective.

//--------------------------------------------------------

dispy = (int)((m_nimgheight/14) * ((double) i + 28.0)

* math.sin ((double)((m_nimgheight/14)*(m_nimgheight - i))

/(double)(i + 1)

+ p1)

/ (double) m_nimgheight);

// if no line dithers here then copy original.

//--------------------------------------------------------

if (i < -dispy)

g.copyarea (num_frames * m_nimgwidth, i, m_nimgwidth, 1,

-dispx, 0);

else

// else copy dithered line.

//--------------------------------------------------------

g.copyarea (num_frames * m_nimgwidth, i + dispy,

m_nimgwidth, 1, -dispx, -dispy);

}

// now, if there is an overlay image, draw the bottom half of it

// over the frame. (the top half of the overlay will be drawn over

// the original image)

//------------------------------------------------------------

if (!"".equals(m_overlayname))

g.drawimage (m_overlay,

(phase * m_nimgwidth) + ((m_nimgwidth - m_novlwidth) >> 1),

-m_novlheight >> 1, this);

}

}

扫描关注微信公众号