黑马程序员技术交流社区
标题:
一个非常有意思的小程序,大家可运行一下,里面涉及算法很多,能看懂也就是牛人了
[打印本页]
作者:
黑马-唐磊
时间:
2012-7-6 17:49
标题:
一个非常有意思的小程序,大家可运行一下,里面涉及算法很多,能看懂也就是牛人了
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;
height=getSize().height-1;
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;
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);
boolean sleep;
Graphics g=getGraphics();
URL u=null;
while(true){
try{
thread.sleep(1000/speed);
}catch(InterruptedException x){
}
sleep=true;
for(int i1=0;i1<Max_Number;i1++)
sleep=sleep&& bcd[i1].sleep;
if(sleep&&Math.random()*100<variability){
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){
bcd[i].init(E,P,L,s);
bcd[i].start();
}
bcd[i].show(g);
}
}
}
public void paint(Graphics g){
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;
patch=p;
length=l;
random=new Random(seed);
Ex=new int[patch];
Ey=new int[patch];
Red=(int)(random.nextDouble()*128)+128;
Blue=(int)(random.nextDouble()*128)+128;
Green=(int)(random.nextDouble()*128)+128;
Xx=(int)(Math.random()*width/2)+width/4;
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){
if(!sleep)
if(t<length){
int i,c;
double s;
Color color;
c=(int)(random.nextDouble()*64)-32+Red;
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++){
s=(double)t/100;
x=(int)(Ex[i]*s);
y=(int)(Ey[i]*s-G*s*s);
g.setColor(color);
g.drawLine(Xx+x, Xy-y, Xx+x, Xy-y);
if(t>=length/2){
int j;
for(j=0;j<2;j++){
s=(double)((t-length/2)*2+j)/100;
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;
}
}
}
复制代码
作者:
温少邦
时间:
2012-7-6 21:05
添加了一些注释
主要就是用一些发散的点连成线来模拟烟花
每个点都有一个向量记录方向,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
}
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2