⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 balldrop.java

📁 模拟正态分布现象的Java小程序
💻 JAVA
字号:
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.applet.*;


class Ball implements ImageObserver {
  static final double slowdown = .75;
  static final double getout = 1;

  double x,y,vx,vy,vlen,r;
  int w,h;
  Image itsImage = null;
  AudioClip itsBoink;

  Ball(double tx,double ty) {
    x=tx;
    y=ty;
    vx=0;
    vy=0;
    vlen=0;
  }

  void SetBoinkSound(AudioClip aClip) {
    itsBoink=aClip;
  }

  void Move() {
    x += vx;
    y += vy;
  }

  void Accelerate(double ax,double ay) {
    vx += ax;
    vy += ay;
    vlen=Math.sqrt(vx*vx+vy*vy);
  }

  boolean Boink(int pinx,int piny,double pinr) {
    double dx,dy,dist;

    dx=x-(double)pinx;
    dy=y-(double)piny;  
          
    dist=Math.sqrt(dx*dx+dy*dy);
              
    if(dist<=pinr+r) {
      double tvx,tvy,proj;

      if(itsBoink != null) {
        itsBoink.stop();
        itsBoink.play();
      }

      tvx = vx/vlen;
      tvy = vy/vlen;

      dx /= dist;
      dy /= dist;

      proj=tvx*dx+tvy*dy;

      tvx -= 2.0*proj*dx;
      tvy -= 2.0*proj*dy;

      vx = tvx*vlen;
      vy = tvy*vlen;

      do {
        x += vx;
        y += vy;

        dx=x-(double)pinx;
        dy=y-(double)piny;  
          
        dist=Math.sqrt(dx*dx+dy*dy);
      } while(dist<=pinr+r);


      vx *= slowdown;
      vy *= slowdown;

      vlen=Math.sqrt(vx*vx+vy*vy);

      return true;
    }

    else return false;
  }

  void SetImage(Image aImage) {
    itsImage=aImage;
    w=itsImage.getWidth(this);
    h=itsImage.getHeight(this);
    r=w/2.0;
  }

  void Draw(Graphics g) {
    if(itsImage != null)
      g.drawImage(itsImage,(int)x-w/2,(int)y-h/2, this);
  }

  public boolean imageUpdate(Image img,
                             int infoflags,
                             int x,
                             int y,
                             int width,
                             int height)
  {
    if((infoflags & (WIDTH | HEIGHT)) == (WIDTH | HEIGHT)) {
      if(img == itsImage) {
        w=width;
        h=height;
        r=w/2;
      }
      return false;
    }

    return true;
  }

}


public class BallDrop extends Applet implements Runnable {
    Thread itsThread = null;
    MediaTracker itsTracker = null;
    AudioClip itsBoink = null;

    Vector itsBalls;

    Dimension offDimension,backDimension;
    Image offImage,backImage;
    static final int numrows=8,numcolumns=20,numballs=10,delay=10,
      topspace=30,sidespace=20;

    Image pin,ball;
    double pinr;
    int ballw,ballh,pinw,pinh,numracks,rackheight[],rackdel[];

    public void init() {
      Dimension d = size();
      Ball aBall;

      itsTracker=new MediaTracker(this);

      ball = getImage(getDocumentBase(), "smallball.gif");
      pin = getImage(getDocumentBase(), "smallpin.gif");

      itsTracker.addImage(ball,0);
      itsTracker.addImage(pin,0);

      try {
        itsTracker.waitForAll();
      }
      catch (InterruptedException e) {
        return;
      }

//      itsBoink = getAudioClip(getDocumentBase(),"boink.au");

      itsBalls=new Vector();

      for(int i=0;i<numballs;++i) {
        aBall = new Ball(d.width/2,0);

        aBall.Accelerate((Math.random()-.5)*.5,0);

//        aBall.SetBoinkSound(itsBoink);

        itsBalls.addElement(aBall);
      }
    }

    public void start() {
      if (itsThread == null) {
        itsThread = new Thread(this);
        itsThread.start();
      }

    }

    public void stop() {
      itsThread = null;
      offImage = null;
      backImage = null;
    }

    public boolean mouseDown(Event e, int x, int y) {
      if (itsThread == null) {
        start();
      }
      else {
        itsThread = null;
      }
      return false;
    }

    public void run() {
      Ball aBall;

      // Remember the starting time
      long startTime = System.currentTimeMillis();

      // Use the media tracker to get the images
      try {
        itsTracker.waitForAll();
      }
      catch (InterruptedException e) {
        return;
      }

      pinw = pin.getWidth(this);
      pinh = pin.getHeight(this);
      pinr = pinw/2.0;
      ballw = ball.getWidth(this);
      ballh = ball.getHeight(this);

      for(Enumeration e = itsBalls.elements();e.hasMoreElements();) {
        aBall=(Ball)e.nextElement();

        aBall.SetImage(ball);
      }

      // Allocate rack information
      numracks=size().width/ballw;
      rackheight=new int[numracks];
      rackdel=new int[numracks];
      for(int i=0;i<numracks;++i) {
        rackheight[i]=0;
        rackdel[i]=0;
      }

      while (Thread.currentThread() == itsThread) {
        UpdateBalls();

        repaint();

        // Delay depending on how far we are behind.
        try {
          startTime += delay;
          Thread.sleep(Math.max(0, 
				      startTime-System.currentTimeMillis()));
        }
        catch (InterruptedException e) {
          break;
        }
      }
    }

    // Paint the previous frame (if any).
    public void paint(Graphics g) {
      Graphics offGraphics;
      Ball aBall;
      Dimension d = size();

      // Create the background image if necessary
      if ( (backImage == null)
          || (d.width != backDimension.width)
          || (d.height != backDimension.height) ) {
        Graphics backGraphics;

        backDimension = d;
        backImage = createImage(d.width, d.height);
        backGraphics = backImage.getGraphics();
  
        // Erase the previous image.
        backGraphics.setColor(getBackground());
        backGraphics.fillRect(0, 0, d.width, d.height);
        backGraphics.setColor(Color.black);

        //Paint the frame into the image.
        paintBackground(backGraphics);
      }
      else {
        updateRack(backImage.getGraphics());
      }

      if ( (offImage == null)
        || (d.width != offDimension.width)
        || (d.height != offDimension.height) ) {
          offDimension = d;
          offImage = createImage(d.width, d.height);
      }

      offGraphics = offImage.getGraphics();

      offGraphics.drawImage(backImage,0,0, this);

      for(Enumeration e = itsBalls.elements();e.hasMoreElements();) {
        aBall=(Ball)e.nextElement();
        aBall.Draw(offGraphics);
      }

      g.drawImage(offImage, 0, 0, this);
    }

    public void update(Graphics g) {
      paint(g);
    }

    void paintBackground(Graphics g) {
      Dimension d = size();
      int i,j,pinx,piny;
      double scale,x,y,oy;

      // Draw the pins

      for(i=0;i<numrows;++i) {  // Rows
        piny=i*(d.height-2*topspace)/(numrows*2)+topspace;
        scale=(double)(d.width-2*sidespace)/(double)numcolumns;

        for(j=0;j<numcolumns;++j) { // Columns
          pinx=(int)((j+(i%2)/2.0)*scale)+sidespace;
          g.drawImage(pin,pinx-pinw/2,piny-pinh/2, this);
        }
      }

      //  Draw density curve

      scale=(double)d.width/numracks;
      g.setColor(Color.black);
      oy=0;
      for(i=0;i<=numracks;++i) {
        x=numracks/2;        
        y=d.height*(1.0-.5*Math.exp(-(double)(i-x)*(i-x)/(2*81)));
        if(i>0) g.drawLine((int)((i-1)*scale),(int)oy,(int)(i*scale),(int)y);
        oy=y;
      }

      // Draw 'racks'


      for(i=0;i<numracks;++i) {
        for(j=0;j<rackheight[i];++j) {
          pinx=i*ballw;
          piny=d.height-(j+1)*ballh;
          g.drawImage(ball,pinx,piny, this);            
        }
      }
    }

    void updateRack(Graphics g) {
      int i,pinx,piny;

      Dimension d = size();

/*
      double sumr,sumrr,mean,stdev,num;
      sumr=0;
      sumrr=0;
      num=0;
*/

      for(i=0;i<numracks;++i) {
        while(rackdel[i]>0) {
          ++rackheight[i];
          pinx=i*ballw;
          piny=d.height-rackheight[i]*ballh;
          g.drawImage(ball,pinx,piny, this);            
          --rackdel[i];
        }
          
/*
        num += rackheight[i];
        sumr += rackheight[i]*i;
        sumrr += rackheight[i]*i*i;
*/
      }

/*
      if(num>0) {
        mean=sumr/num;
        stdev=Math.sqrt(sumrr/num - mean*mean);
        System.out.println(mean + " " + stdev);
      }
*/
    }

    void UpdateBalls() {
      int i,j,k,pinx,piny,rack,bottomy,fr,lr,fc,lc;
      double scale;
      Ball aBall;

      Dimension d = size();

      bottomy=d.height;

      for(Enumeration e = itsBalls.elements();e.hasMoreElements();) {
        aBall=(Ball)e.nextElement();

        aBall.Move();
            
        if(aBall.y>bottomy-aBall.r) {

          if(itsBoink != null) {
            itsBoink.stop();
            itsBoink.play();
          }

          if(aBall.vlen>.25) {
            aBall.vx = 0;
            aBall.vy = -aBall.vy*.25;
            aBall.y = bottomy-aBall.r;
          }
          else {
            rack=(int)(aBall.x/ballw);

            if(rack>=0 && rack<numracks) {
              ++rackdel[rack];
            }

            aBall.x=d.width/2;
            aBall.y=aBall.r;
      
            aBall.vx=(Math.random()-.5)/3;
            aBall.vy=0;
          }
        }
        else {
          k=(int)((aBall.y-topspace)*2*numrows/(d.height-2*topspace));

          fr= k<=0 ? 0 : k-1;
          lr= k>=numrows-1 ? numrows-1 : k+1;

          for(i=fr;i<=lr;++i) {  // Rows
            piny=i*(d.height-2*topspace)/(2*numrows)+topspace;

            scale=(double)(d.width-2*sidespace)/(double)numcolumns;

            k=(int)((aBall.x-sidespace)/scale-(i%2)/2.0);

            fc= k<=0 ? 0 : k-1;
            lc= k>=numcolumns-1 ? numcolumns-1 : k+1;

            for(j=fc;j<=lc;++j) { // Columns
              pinx=(int)((j+(i%2)/2.0)*scale+sidespace);

              aBall.Boink(pinx,piny,pinr);
            }
          }
        }


        aBall.Accelerate(0,.075);
      }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -