黑马程序员技术交流社区

标题: 一个非常有意思的小程序,大家可运行一下,里面涉及算法很多,能看懂也就是牛人了 [打印本页]

作者: 黑马-唐磊    时间: 2012-7-6 17:49
标题: 一个非常有意思的小程序,大家可运行一下,里面涉及算法很多,能看懂也就是牛人了
  1. import java.applet.Applet;
  2. import java.awt.Color;
  3. import java.awt.Graphics;
  4. import java.net.URL;
  5. import java.util.Random;
  6. //有哪位牛人可以试着解释其中的原理,主要是awt和一些算法,我觉得学安卓的话awt得要有很好基础
  7. public class Yanhua extends Applet implements Runnable{
  8.         public int speed,variability,Max_Number,Max_Energy,Max_Patch,Max_length,G;
  9.         public String sound;
  10.         private int width,height;
  11.         private Thread thread=null;
  12.         private BeaClassDemo bcd[];
  13.         public void init(){
  14.                 int i;
  15.                 this.setSize(400,400);
  16.                 width=getSize().width-1;
  17.                 height=getSize().height-1;
  18.                 speed=30;
  19.                 variability=10;
  20.                 Max_Number=100;
  21.                 Max_Energy=width+50;
  22.                 Max_Patch=80;//最大斑点数
  23.                 Max_length=200;
  24.                 G=50;//向地面弯曲力度
  25.                 bcd=new BeaClassDemo[Max_Number];
  26.                 for(i=0;i<Max_Number;i++)
  27.                         bcd[i]=new BeaClassDemo(width,height,G);
  28.                
  29.         }
  30.         public void start() {
  31.                 if(thread==null){
  32.                         thread=new Thread(this);
  33.                         thread.start();
  34.                 }
  35.                
  36.         }
  37.         public void stop(){
  38.                 if(thread!=null){
  39.                         thread.stop();
  40.                         thread=null;
  41.                 }
  42.         }
  43.         public void run(){
  44.                 int i;
  45.                 int E=(int)(Math.random()*Max_Energy*3/4)+Max_Energy/4+1;
  46.                 int P=(int)(Math.random()*Max_Patch*3/4)+Max_Patch/4+1;
  47.                 int L=(int)(Math.random()*Max_length*3/4)+Max_length/4+1;
  48.                 long s=(long)(Math.random()*10000);
  49.                 boolean sleep;
  50.                 Graphics g=getGraphics();
  51.                 URL u=null;
  52.                 while(true){
  53.                         try{
  54.                                 thread.sleep(1000/speed);
  55.                         }catch(InterruptedException x){
  56.                                
  57.                         }
  58.                         sleep=true;
  59.                         for(int i1=0;i1<Max_Number;i1++)
  60.                                 sleep=sleep&& bcd[i1].sleep;
  61.                         if(sleep&&Math.random()*100<variability){
  62.                                 E=(int)(Math.random()*Max_Energy*3/4)+Max_Energy/4+1;
  63.                                 P=(int)(Math.random()*Max_Patch*3/4)+Max_Patch/4+1;
  64.                                 L=(int)(Math.random()*Max_length*3/4)+Max_length/4+1;
  65.                                 s=(long)(Math.random()*10000);
  66.                         }
  67.                         for(i=0;i<Max_Number;i++){
  68.                                 if(bcd[i].sleep&&Math.random()*Max_Number*L<1){
  69.                                         bcd[i].init(E,P,L,s);
  70.                                         bcd[i].start();
  71.                                 }
  72.                                 bcd[i].show(g);
  73.                         }
  74.                 }
  75.         }
  76.         public void paint(Graphics g){
  77.                 g.setColor(Color.BLACK);
  78.                 g.fillRect(0, 0, width+1, height+1);
  79.         }
  80. }
  81. class BeaClassDemo{
  82.         public boolean sleep=true;
  83.         private int energy,patch,length,width,height,G,Xx,Xy,Ex[],Ey[],x,y,Red,Blue,Green,t;
  84.         private Random random;
  85.         public  BeaClassDemo(int a,int b,int g){
  86.                 width=a;
  87.                 height=b;
  88.                 G=g;
  89.         }
  90.         public void init(int e,int p,int l,long seed){
  91.                 energy=e;
  92.                 patch=p;
  93.                 length=l;
  94.                 random=new Random(seed);
  95.                 Ex=new int[patch];
  96.                 Ey=new int[patch];
  97.                 Red=(int)(random.nextDouble()*128)+128;
  98.                 Blue=(int)(random.nextDouble()*128)+128;
  99.                 Green=(int)(random.nextDouble()*128)+128;
  100.                 Xx=(int)(Math.random()*width/2)+width/4;
  101.                 Xy=(int)(Math.random()*height/2)+height/4;
  102.                 for(int i=0;i<patch;i++){
  103.                         Ex[i]=(int)(Math.random()*energy)-energy/2;
  104.                         Ey[i]=(int)(Math.random()*energy*7/8)-energy/8;
  105.                 }
  106.         }
  107.         public void start(){
  108.                 t=0;
  109.                 sleep=false;
  110.         }
  111.         public void show(Graphics g){
  112.                 if(!sleep)
  113.                         if(t<length){
  114.                                 int i,c;
  115.                                 double s;
  116.                                 Color color;
  117.                                 c=(int)(random.nextDouble()*64)-32+Red;
  118.                                 if(c>0&&c<256)
  119.                                         Red=c;
  120.                                 c=(int)(random.nextDouble()*64)-32+Blue;
  121.                                 if(c>=0&&c<256)
  122.                                         Blue=c;
  123.                                 c=(int)(random.nextDouble()*64)-32+Green;
  124.                                 if(c>=0&&c<256)
  125.                                         Green=c;
  126.                                 color=new Color(Red,Blue,Green);
  127.                                 for(i=0;i<patch;i++){
  128.                                         s=(double)t/100;
  129.                                         x=(int)(Ex[i]*s);
  130.                                         y=(int)(Ey[i]*s-G*s*s);
  131.                                         g.setColor(color);
  132.                                         g.drawLine(Xx+x, Xy-y, Xx+x, Xy-y);
  133.                                         if(t>=length/2){
  134.                                                 int j;
  135.                                                 for(j=0;j<2;j++){
  136.                                                         s=(double)((t-length/2)*2+j)/100;
  137.                                                         x=(int)(Ex[i]*s);
  138.                                                         y=(int)(Ey[i]*s-G*s*s);
  139.                                                         g.setColor(Color.BLACK);
  140.                                                         g.drawLine(Xx+x, Xy-y, Xx+x, Xy-y);
  141.                                                 }
  142.                                         }
  143.                                 }
  144.                                 t++;
  145.                         }else{
  146.                                 sleep=true;
  147.                         }
  148.         }
  149. }
复制代码

作者: 温少邦    时间: 2012-7-6 21:05
添加了一些注释
主要就是用一些发散的点连成线来模拟烟花
每个点都有一个向量记录方向,speed值记录速度
加上模拟重力的影响,搞出烟花的感觉


  1. import java.applet.Applet;
  2. import java.awt.Color;
  3. import java.awt.Graphics;
  4. import java.net.URL;
  5. import java.util.Random;


  6. //有哪位牛人可以试着解释其中的原理,主要是awt和一些算法,我觉得学安卓的话awt得要有很好基础
  7. public class Yanhua extends Applet implements Runnable{
  8.         public int speed,variability,Max_Number,Max_Energy,Max_Patch,Max_length,G;
  9.         public String sound;
  10.         private int width,height;
  11.         private Thread thread=null;
  12.         private BeaClassDemo bcd[];
  13.         public void init(){
  14.                 int i;
  15.                 this.setSize(400,400);
  16.                 width=getSize().width-1;                                        //Applet宽
  17.                 height=getSize().height-1;                                        //Applet高
  18.                 speed=30;                                                                        //烟花的产生间隔
  19.                 variability=10;                                                                //用来随即产生烟花的一个系数 越小烟花越少
  20.                 Max_Number=100;                                                                //烟花总数
  21.                 Max_Energy=width+50;                                                //记录一个类似冲量的玩意 相当于烟花爆炸的力度
  22.                 Max_Patch=80;                                                                //最大斑点数                                       
  23.                 Max_length=200;                                                                //烟花有多长
  24.                 G=50;                                                                                //向地面弯曲力度
  25.                 bcd=new BeaClassDemo[Max_Number];                        //烟花实例对象的数组
  26.                 for(i=0;i<Max_Number;i++)
  27.                         bcd[i]=new BeaClassDemo(width,height,G);
  28.                
  29.         }
  30.         public void start() {
  31.                 if(thread==null){
  32.                         thread=new Thread(this);
  33.                         thread.start();
  34.                 }
  35.                
  36.         }
  37.         public void stop(){
  38.                 if(thread!=null){
  39.                         thread.stop();
  40.                         thread=null;
  41.                 }
  42.         }
  43.         public void run(){
  44.                 int i;
  45.                 int E=(int)(Math.random()*Max_Energy*3/4)+Max_Energy/4+1;                //EPL值对应上面的Energy Patch Length
  46.                 int P=(int)(Math.random()*Max_Patch*3/4)+Max_Patch/4+1;
  47.                 int L=(int)(Math.random()*Max_length*3/4)+Max_length/4+1;
  48.                 long s=(long)(Math.random()*10000);                                                                //s产生一个随机数种子
  49.                 boolean sleep;
  50.                 Graphics g=getGraphics();        //Applet的画笔 画背景和烟花的show方法都用这个画笔
  51.                 URL u=null;
  52.                 while(true){                                //这个while循环用来创建新的烟花
  53.                         try{
  54.                                 thread.sleep(1000/speed);                //间隔
  55.                         }catch(InterruptedException x){
  56.                                 
  57.                         }
  58.                         sleep=true;
  59.                         for(int i1=0;i1<Max_Number;i1++)
  60.                                 sleep=sleep&& bcd[i1].sleep;                                        //判断是否所有的烟花都在sleep
  61.                         if(sleep&&Math.random()*100<variability){                                //如果所有的烟花都在sleep 就更新一下EPLS的值  这样连续放的烟花就是同一种烟花
  62.                                 E=(int)(Math.random()*Max_Energy*3/4)+Max_Energy/4+1;               
  63.                                 P=(int)(Math.random()*Max_Patch*3/4)+Max_Patch/4+1;
  64.                                 L=(int)(Math.random()*Max_length*3/4)+Max_length/4+1;               
  65.                                 s=(long)(Math.random()*10000);                                                               
  66.                         }
  67.                         for(i=0;i<Max_Number;i++){
  68.                                 if(bcd[i].sleep&&Math.random()*Max_Number*L<1){                                //烟花是sleep且一个奇怪的判断后开始初始化烟花并设置sleep=false 就是开始放了
  69.                                         bcd[i].init(E,P,L,s);
  70.                                         bcd[i].start();
  71.                                 }
  72.                                 bcd[i].show(g);
  73.                         }
  74.                 }
  75.         }
  76.         public void paint(Graphics g){                                                //覆盖paint方法,使背景一直显示黑色
  77.                 g.setColor(Color.BLACK);
  78.                 g.fillRect(0, 0, width+1, height+1);
  79.         }
  80. }
  81. class BeaClassDemo{
  82.         public boolean sleep=true;                                //是否在放
  83.         private int energy,patch,length,width,height,G,Xx,Xy,Ex[],Ey[],x,y,Red,Blue,Green,t;
  84.         private Random random;                                        //用来产生随机数
  85.         public  BeaClassDemo(int a,int b,int g){
  86.                 width=a;
  87.                 height=b;
  88.                 G=g;
  89.         }
  90.         public void init(int e,int p,int l,long seed){
  91.                 energy=e;                //对应EPL
  92.                 patch=p;
  93.                 length=l;
  94.                 random=new Random(seed);
  95.                 Ex=new int[patch];                                                                //这个Ex和Ey相当于一个向量 记录烟花里每个小点点的冲量大小与方向
  96.                 Ey=new int[patch];
  97.                 Red=(int)(random.nextDouble()*128)+128;                        //随即初始化一下RGB值
  98.                 Blue=(int)(random.nextDouble()*128)+128;
  99.                 Green=(int)(random.nextDouble()*128)+128;                        
  100.                 Xx=(int)(Math.random()*width/2)+width/4;                //Xx和Yy记录烟花的位置
  101.                 Xy=(int)(Math.random()*height/2)+height/4;        
  102.                 for(int i=0;i<patch;i++){
  103.                         Ex[i]=(int)(Math.random()*energy)-energy/2;                //初始化一下每个小点点的冲量
  104.                         Ey[i]=(int)(Math.random()*energy*7/8)-energy/8;
  105.                 }
  106.         }
  107.         public void start(){
  108.                 t=0;
  109.                 sleep=false;
  110.         }
  111.         public void show(Graphics g){                //show方法在主线程的最后用那个for循环挨个调用的
  112.                 if(!sleep)
  113.                         if(t<length){                //length是最大长度 t记录当前走过的长度
  114.                                 int i,c;
  115.                                 double s;
  116.                                 Color color;
  117.                                 c=(int)(random.nextDouble()*64)-32+Red;        //随即改变RGB的值 +-32之间
  118.                                 if(c>0&&c<256)
  119.                                         Red=c;
  120.                                 c=(int)(random.nextDouble()*64)-32+Blue;
  121.                                 if(c>=0&&c<256)
  122.                                         Blue=c;
  123.                                 c=(int)(random.nextDouble()*64)-32+Green;
  124.                                 if(c>=0&&c<256)
  125.                                         Green=c;
  126.                                 color=new Color(Red,Blue,Green);
  127.                                 for(i=0;i<patch;i++){                                        //这个for循环依次枚举构成烟花的那些点
  128.                                         s=(double)t/100;                                //根据走过的长度计算一个速度值 烟花越到后面走的越慢
  129.                                         x=(int)(Ex[i]*s);                                //根据那个类似动能的玩意和类似速度的那玩意算出x偏移值和y偏移值
  130.                                         y=(int)(Ey[i]*s-G*s*s);                        //
  131.                                         g.setColor(color);
  132.                                         g.drawLine(Xx+x, Xy-y, Xx+x, Xy-y);                //根据x偏移值和y偏移值画一个小点点
  133.                                         if(t>=length/2){                                //如果烟花走过一半 前面的点点就要慢慢的消失了
  134.                                                 int j;
  135.                                                 for(j=0;j<2;j++){                        //回头擦2个点
  136.                                                         s=(double)((t-length/2)*2+j)/100;                //推算原来的s值
  137.                                                         x=(int)(Ex[i]*s);
  138.                                                         y=(int)(Ey[i]*s-G*s*s);
  139.                                                         g.setColor(Color.BLACK);                                //用背景颜色擦掉点点
  140.                                                         g.drawLine(Xx+x, Xy-y, Xx+x, Xy-y);
  141.                                                 }
  142.                                         }
  143.                                 }
  144.                                 t++;        //走过的长度要++
  145.                         }else{
  146.                                 sleep=true;                //t>length 说明烟花走完了 重新sleep
  147.                         }
  148.         }
  149. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2