添加了一些注释
主要就是用一些发散的点连成线来模拟烟花
每个点都有一个向量记录方向,speed值记录速度
加上模拟重力的影响,搞出烟花的感觉
- import java.applet.Applet;
- import java.awt.Color;
- import java.awt.Graphics;
- import java.net.URL;
- import java.util.Random;
- //有哪位牛人可以试着解释其中的原理,主要是awt和一些算法,我觉得学安卓的话awt得要有很好基础
- public class Yanhua extends Applet implements Runnable{
- public int speed,variability,Max_Number,Max_Energy,Max_Patch,Max_length,G;
- public String sound;
- private int width,height;
- private Thread thread=null;
- private BeaClassDemo bcd[];
- public void init(){
- int i;
- this.setSize(400,400);
- width=getSize().width-1; //Applet宽
- height=getSize().height-1; //Applet高
- speed=30; //烟花的产生间隔
- variability=10; //用来随即产生烟花的一个系数 越小烟花越少
- Max_Number=100; //烟花总数
- Max_Energy=width+50; //记录一个类似冲量的玩意 相当于烟花爆炸的力度
- Max_Patch=80; //最大斑点数
- Max_length=200; //烟花有多长
- G=50; //向地面弯曲力度
- bcd=new BeaClassDemo[Max_Number]; //烟花实例对象的数组
- for(i=0;i<Max_Number;i++)
- bcd[i]=new BeaClassDemo(width,height,G);
-
- }
- public void start() {
- if(thread==null){
- thread=new Thread(this);
- thread.start();
- }
-
- }
- public void stop(){
- if(thread!=null){
- thread.stop();
- thread=null;
- }
- }
- public void run(){
- int i;
- int E=(int)(Math.random()*Max_Energy*3/4)+Max_Energy/4+1; //EPL值对应上面的Energy Patch Length
- int P=(int)(Math.random()*Max_Patch*3/4)+Max_Patch/4+1;
- int L=(int)(Math.random()*Max_length*3/4)+Max_length/4+1;
- long s=(long)(Math.random()*10000); //s产生一个随机数种子
- boolean sleep;
- Graphics g=getGraphics(); //Applet的画笔 画背景和烟花的show方法都用这个画笔
- URL u=null;
- while(true){ //这个while循环用来创建新的烟花
- try{
- thread.sleep(1000/speed); //间隔
- }catch(InterruptedException x){
-
- }
- sleep=true;
- for(int i1=0;i1<Max_Number;i1++)
- sleep=sleep&& bcd[i1].sleep; //判断是否所有的烟花都在sleep
- if(sleep&&Math.random()*100<variability){ //如果所有的烟花都在sleep 就更新一下EPLS的值 这样连续放的烟花就是同一种烟花
- E=(int)(Math.random()*Max_Energy*3/4)+Max_Energy/4+1;
- P=(int)(Math.random()*Max_Patch*3/4)+Max_Patch/4+1;
- L=(int)(Math.random()*Max_length*3/4)+Max_length/4+1;
- s=(long)(Math.random()*10000);
- }
- for(i=0;i<Max_Number;i++){
- if(bcd[i].sleep&&Math.random()*Max_Number*L<1){ //烟花是sleep且一个奇怪的判断后开始初始化烟花并设置sleep=false 就是开始放了
- bcd[i].init(E,P,L,s);
- bcd[i].start();
- }
- bcd[i].show(g);
- }
- }
- }
- public void paint(Graphics g){ //覆盖paint方法,使背景一直显示黑色
- g.setColor(Color.BLACK);
- g.fillRect(0, 0, width+1, height+1);
- }
- }
- class BeaClassDemo{
- public boolean sleep=true; //是否在放
- private int energy,patch,length,width,height,G,Xx,Xy,Ex[],Ey[],x,y,Red,Blue,Green,t;
- private Random random; //用来产生随机数
- public BeaClassDemo(int a,int b,int g){
- width=a;
- height=b;
- G=g;
- }
- public void init(int e,int p,int l,long seed){
- energy=e; //对应EPL
- patch=p;
- length=l;
- random=new Random(seed);
- Ex=new int[patch]; //这个Ex和Ey相当于一个向量 记录烟花里每个小点点的冲量大小与方向
- Ey=new int[patch];
- Red=(int)(random.nextDouble()*128)+128; //随即初始化一下RGB值
- Blue=(int)(random.nextDouble()*128)+128;
- Green=(int)(random.nextDouble()*128)+128;
- Xx=(int)(Math.random()*width/2)+width/4; //Xx和Yy记录烟花的位置
- Xy=(int)(Math.random()*height/2)+height/4;
- for(int i=0;i<patch;i++){
- Ex[i]=(int)(Math.random()*energy)-energy/2; //初始化一下每个小点点的冲量
- Ey[i]=(int)(Math.random()*energy*7/8)-energy/8;
- }
- }
- public void start(){
- t=0;
- sleep=false;
- }
- public void show(Graphics g){ //show方法在主线程的最后用那个for循环挨个调用的
- if(!sleep)
- if(t<length){ //length是最大长度 t记录当前走过的长度
- int i,c;
- double s;
- Color color;
- c=(int)(random.nextDouble()*64)-32+Red; //随即改变RGB的值 +-32之间
- if(c>0&&c<256)
- Red=c;
- c=(int)(random.nextDouble()*64)-32+Blue;
- if(c>=0&&c<256)
- Blue=c;
- c=(int)(random.nextDouble()*64)-32+Green;
- if(c>=0&&c<256)
- Green=c;
- color=new Color(Red,Blue,Green);
- for(i=0;i<patch;i++){ //这个for循环依次枚举构成烟花的那些点
- s=(double)t/100; //根据走过的长度计算一个速度值 烟花越到后面走的越慢
- x=(int)(Ex[i]*s); //根据那个类似动能的玩意和类似速度的那玩意算出x偏移值和y偏移值
- y=(int)(Ey[i]*s-G*s*s); //
- g.setColor(color);
- g.drawLine(Xx+x, Xy-y, Xx+x, Xy-y); //根据x偏移值和y偏移值画一个小点点
- if(t>=length/2){ //如果烟花走过一半 前面的点点就要慢慢的消失了
- int j;
- for(j=0;j<2;j++){ //回头擦2个点
- s=(double)((t-length/2)*2+j)/100; //推算原来的s值
- x=(int)(Ex[i]*s);
- y=(int)(Ey[i]*s-G*s*s);
- g.setColor(Color.BLACK); //用背景颜色擦掉点点
- g.drawLine(Xx+x, Xy-y, Xx+x, Xy-y);
- }
- }
- }
- t++; //走过的长度要++
- }else{
- sleep=true; //t>length 说明烟花走完了 重新sleep
- }
- }
- }
复制代码 |