环形扩散
这是我用processing写出的扩散效果
package Exercise;
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PImage;
/**
* @author Administrator
*
*/
public class Animation {
//声明全局变量
PApplet zoomApplet;
扩散的圆圈
PImage photo;
int animateWidth;
int animateHeigth;
int centerX;
int centerY;
float radius;
private int progressive = 1;
private int circleAlpha = 255;
//构造函数
public Animation(PApplet zoomApplet,int animateWidth,int animateHeigth,int centerX,int centerY) {
this.zoomApplet = zoomApplet;
this.animateWidth = animateWidth;
this.animateHeigth = animateHeigth;
this.centerX = centerX;
this.centerY = centerY;
}
//镭射线效果
float originRadius;
float secondRadius;
public void setupDiffusionRadiumRays(PGraphics zoomGraphics) {
//photo = zoomApplet.loadImage("Resources\\Images\\3.jpg");
originRadius = radius;
secondRadius = radius-animateWidth/4;
}
public void drawDiffusionRadiumRays(PGraphics zoomGraphics) {
zoomGraphics.noFill();
//zoomGraphics.image(photo, 0, 0);
radius += 1;
secondRadius += 1;
float pointX;
float pointY;
zoomGraphics.strokeWeight(10);
for(int i=0;i<180;i++)
{
int angle = i*2;
zoomGraphics.stroke(zoomGraphics.color(angle,180,60));
float originX = centerX + PApplet.cos((float) (angle*Math.PI/180))*radius;
float originY = centerY + PApplet.sin((float) (angle*Math.PI/180))*radius;
pointX = centerX + PApplet.cos((float) (angle*Math.PI/180))*(radius - 20);
pointY = centerY + PApplet.sin((float) (angle*Math.PI/180))*(radius - 20);
zoomGraphics.line(originX, originY, pointX, pointY);
if (secondRadius>0) {
float pointX1 = centerX + PApplet.cos((float) (angle*Math.PI/180))*(secondRadius-20);
float pointY1 = centerY + PApplet.sin((float) (angle*Math.PI/180))*(secondRadius-20);
float pointX2 = centerX + PApplet.cos((float) (angle*Math.PI/180))*secondRadius;
float pointY2 = centerY + PApplet.sin((float) (angle*Math.PI/180))*secondRadius;
zoomGraphics.line(pointX1, pointY1, pointX2, pointY2);
}
}
if (radius>animateWidth/2) {
radius = originRadius;
}
if (secondRadius>animateWidth/2) {
secondRadius = originRadius;
}
}
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
}
}
火 焰
这是我用processing写出的火焰效果
河 流
这是我用processing写出的类似于河流的效果
海 域
这是我用processing写出的一片海域的效果
以上三个是做出来的效果,下面上processing代码
火焰
package Exercise;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import processing.core.PApplet;
import processing.core.PImage;
import processing.core.PVector;
public class FireApplet extends PApplet{
/**
*
*/
private static final long serialVersionUID = 1L;
//初始化自定义粒子系统类变量
ParticleSystem particleSystem;
//动画的初始化方法
public void setup()
{
size(800,800);
PImage image = loadImage("../Resources/Images/fire.png");
particleSystem = new ParticleSystem(0, new PVector(width/2,500), image);
}
//动画的绘画方法
public void draw()
{
background(0);
float dx = map((float)mouseX, 0, (float)width, (float)-0.2, (float)0.2);
PVector wind = new PVector(dx,0);
//particleSystem.applyForce(wind);
particleSystem.run();
for (int i = 0; i < 2; i++) {
particleSystem.addParticle();
}
}
// TODO 创建Particle类有助于降低复杂度
class Particle {
PVector loc;
PVector vel;
PVector acc;
float lifespan;
PImage image;
Particle(PVector pVector,PImage img) {
acc = new PVector(0,0);
float vx = (float) (randomGaussian()*0.3);
float vy = (float) (randomGaussian()*0.3 -1.0);
vel = new PVector(vx,vy);
loc = CloneSeries.clone(pVector);
lifespan = 100;
image = img;
}
void run()
{
update();
render();
}
void applyForce(PVector fPVector)
{
acc.add(fPVector);
}
void update()
{
vel.add(acc);
loc.add(vel);
lifespan -= 2.5;
acc.mult(0);
}
void render()
{
imageMode(CENTER);
tint(255,lifespan);
image(image,loc.x,loc.y);
}
boolean isDead()
{
if (lifespan<=0) {
return true;
}
else
{
return false;
}
}
}
// TODO 创建Particle系统类
class ParticleSystem
{
ArrayList<Particle>particles;
PVector origin;
PImage image;
ParticleSystem(int num,PVector v,PImage img) {
particles = new ArrayList<Particle>();
origin = CloneSeries.clone(v);
image = img;
for(int i=0;i<num;i++)
{
particles.add(new Particle(origin, image));
}
}
void run()
{
for(int i=particles.size()-1;i>=0;i--)
{
Particle particle = particles.get(i);
particle.run();
if (particle.isDead()) {
particles.remove(i);
}
}
}
void applyForce(PVector dir)
{
for(Particle p:particles)
{
p.applyForce(dir);
}
}
void addParticle()
{
particles.add(new Particle(origin, image));
}
}
static class CloneSeries {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T clone(T obj){
T cloneObj = null;
try {
//写入字节流
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream obs = new ObjectOutputStream(out);
obs.writeObject(obj);
obs.close();
//分配内存,写入原始对象,生成新对象
ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(ios);
//返回生成的新对象
cloneObj = (T) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObj;
}
}
}
河流
package Exercise;
import java.awt.Container;
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PImage;
public class RiverApplet extends PApplet{
/**
*
*/
private static final long serialVersionUID = 1L;
PGraphics riverPhics;
PApplet riverApplet;
float yoff = (float) 0.0; // 2nd dimension of perlin noise
int [] xRows;
int [] yRows1;
int [] yRows2;
PImage[] plan3DImage;
public void setup() {
size(1000,1000);
}
public void draw() {
//
clear();
background(color(16,120,180));
fill(color(60,140,255));
// We are going to draw a polygon out of the wave points
beginShape();
float xoff = 0; // Option #1: 2D Noise
//float xoff = yoff; // Option #2: 1D Noise
// Iterate over horizontal pixels
for (float x = 0; x <= width; x += 5) {
// Calculate a y value according to noise, map to
float y = map(noise(xoff, yoff), 0, 1, 250,300); // Option #1: 2D Noise
//float y = map(noise(xoff), 0, 1, 200,300); // Option #2: 1D Noise
// Set the vertex
vertex(x, y);
// Increment x dimension for noise
xoff += 0.05;
}
for (float x2 = width; x2 >=0; x2 -= 5) {
// Calculate a y value according to noise, map to
float y2 = map(noise(xoff, yoff), 0, 1, 450,500); // Option #1: 2D Noise
//float y = map(noise(xoff), 0, 1, 200,300); // Option #2: 1D Noise
// Set the vertex
vertex(x2, y2);
// Increment x dimension for noise
xoff += 0.05;
}
// increment y dimension for noise
yoff += 0.01;
endShape(CLOSE);
}
//以上这个是使用noise()方法绘制出来的效果,这种效果很逼真,但是无法根据实际的河流坐标进行修改,所以我使用了下面的这个方法,绘制特定路线的河流,并添加河流的动画效果
package Exercise;
import java.awt.Container;
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PImage;
public class RiverApplet extends PApplet{
/**
*
*/
private static final long serialVersionUID = 1L;
PGraphics riverPhics;
PApplet riverApplet;
float yoff = (float) 0.0; // 2nd dimension of perlin noise
int [] xRows;
int [] yRows1;
int [] yRows2;
PImage[] plan3DImage;
public void setup() {
size(1000,1000);
setupRiverLines();
}
public void draw() {
riverPhics.beginDraw();
riverPhics.background(102);
riverPhics.stroke(255);
drawRiverLines();
riverPhics.endDraw();
plan3DImage[0] = riverPhics.get();
image(riverPhics, 100, 100);
frameRate(5);
//
public void setupRiverLines()
{
plan3DImage = new PImage[1];
//background(255);
riverPhics = createGraphics(800, 800);
riverPhics.background(255);
xRows = new int [21];
yRows1 = new int [21];
yRows2 = new int [21];
}
public void drawRiverLines() {
riverPhics.stroke(color(0));
riverPhics.strokeWeight(8);
//riverPhics.fill(75,121,199);
for(int i=0;i<=20;i++)
{
xRows[i] = 40*i;
yRows1[i] = (int) (random(100, 150) + 60);
yRows2[i] = (int) (random(200, 250) + 160);
}
riverPhics.beginShape();
for(int j=0;j<xRows.length;j++)
{
riverPhics.curveVertex(xRows[j], yRows1[j]);
}
for(int k=xRows.length;k>0;k--)
{
riverPhics.curveVertex(xRows[k-1], yRows2[k-1]);
}
riverPhics.endShape();
}
}
海域
package Exercise;
import processing.core.PApplet;
import processing.core.PShape;
public class SeaApplet extends PApplet {
/**
*
*/
private static final long serialVersionUID = 1L;
int screenWidth = 800;
int screenHeigth = 800;
float increment = (float) 0.01;
int directX = -1;// X轴移动方向1\-1
int directY = 1;// Y轴移动方向1\-1
float moveMent = (float) 0.05;// 代表海面移动速度0.1--0.01之间
float xoff = 0;
float yoff = 0;
int [] xRows;
int [] yRows;
int loopNum;
// 启动程序入口
public void setup() {
size(screenWidth, screenHeigth,P2D);
background(15, 101, 180);
drawShapeLine();
fill(color(60, 140, 255));
stroke(0);
}
// 循环绘画方法
public void draw() {
// 循环海域,绘制noise即浪花
xoff = yoff = increment;
for (int x = 0; x <= 650; x++) {
yoff = increment;
for (int y = 0; y < height; y++) {
float rcolor = map(noise(xoff, yoff), 0, 1, 10, 60);
float gcolor = map(noise(xoff, yoff), 0, 1, 80, 120);
float bcolor = map(noise(xoff, yoff), 0, 1, 160, 255);
// System.out.println("R:"+rcolor+"G:"+gcolor+"B:"+bcolor);
if (x<=100) {
set(x, y, color(rcolor, gcolor, bcolor));
}
else if (x>100&&x<=200) {
caculateMethod(100, 800, 250, 550);
boolean isIn = DownAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>200&&x<=250&&y>550) {
caculateMethod(100, 800, 250, 550);
boolean isIn = DownAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>200&&x<=250&&y<=550) {
caculateMethod(200, 0, 500, 80);
boolean isIn = UpAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>250&&x<=350&&y<=550) {
caculateMethod(200, 0, 500, 80);
boolean isIn = UpAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>250&&x<=350&&y>550) {
caculateMethod(350, 750, 250, 550);
boolean isIn = DownAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>350&&x<=500&&y<=80) {
caculateMethod(200, 0, 500, 80);
boolean isIn = UpAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>350&&x<=500&&y>80) {
caculateMethod(350, 750, 600, 500);
boolean isIn = DownAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>500&&x<=550&&y<=350) {
caculateMethod(500, 80, 600, 50);
boolean isIn = UpAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>500&&x<=550&&y>350) {
caculateMethod(350, 750, 600, 500);
boolean isIn = DownAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>550&&x<=600&&y<=80) {
caculateMethod(500, 80, 600, 50);
boolean isIn = UpAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>550&&x<=600&&y<=350&&y>80) {
caculateMethod(550, 350, 650, 150);
boolean isIn = DownAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>550&&x<=600&&y>350&&y<=500) {
caculateMethod(550, 350, 600, 500);
boolean isIn = UpAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>550&&x<=600&&y>500) {
caculateMethod(350, 750, 600, 500);
boolean isIn = DownAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>600&&x<=650&&y<=350&&y<=150) {
caculateMethod(600, 50, 650, 150);
boolean isIn = UpAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
else if (x>600&&x<=650&&y<=350&&y>150) {
caculateMethod(550, 350, 650, 150);
boolean isIn = DownAnalysePoint(x, y);
if (isIn) {
set(x, y, color(rcolor, gcolor, bcolor));
}
}
yoff += (0.01 * directY);
}
xoff += (0.01 * directX);
}
increment += moveMent;
// 海岸线拐点(0,0)(200,0)(500,80)(600,50)(650,150)(550,350)(650,500)(350,750)(250,550)(100,800)(0,800)
// 开始绘制海域
// noFill();
// beginShape();
// vertex(width, 0);
// vertex(200, 0);
// vertex(500, 80);
// vertex(600, 50);
// vertex(650, 150);
// vertex(550, 350);
// vertex(600, 500);
// vertex(350, 750);
// vertex(250, 550);
// vertex(100, 800);
// vertex(width, height);
// endShape(CORNER);
// 绘画帧数
frameRate(20);
}
public void drawShapeLine()
{
loopNum = 0;
//坐标数组
xRows = new int [11];
yRows = new int [11];
xRows[0] = width;
yRows[0] = 0;
xRows[1] = 200;
yRows[1] = 0;
xRows[2] = 500;
yRows[2] = 80;
xRows[3] = 600;
yRows[3] = 50;
xRows[4] = 650;
yRows[4] = 150;
xRows[5] = 550;
yRows[5] = 350;
xRows[6] = 600;
yRows[6] = 500;
xRows[7] = 350;
yRows[7] = 750;
xRows[8] = 250;
yRows[8] = 550;
xRows[9] = 100;
yRows[9] = height;
xRows[10] = width;
yRows[10] = height;
System.out.println("数组:"+xRows+yRows);
noFill();
stroke(color(123,123,123));
beginShape();
curveVertex(xRows[loopNum], yRows[loopNum]);
for(int i=loopNum;i<=10;i++)
{
curveVertex(xRows[i], yRows[i]);
}
if (loopNum>0&&loopNum<11) {
for(int i=0;i<loopNum;i++)
{
curveVertex(xRows[i], yRows[i]);
}
curveVertex(xRows[loopNum], yRows[loopNum]);
}
else
{
curveVertex(xRows[10], yRows[10]);
}
loopNum++;
if (loopNum>10) {
loopNum=0;
}
endShape(CLOSE);
}
double [] result;
public double[] caculateMethod(int x1,int y1,int x2,int y2)
{
y1 = screenHeigth-y1;
y2 = screenHeigth-y2;
result = new double[2];
float k,a;
k=(float)(y2-y1)/(x2-x1);
a=y2-k*x2;
result[0]=k;
result[1]=a;
return result;
}
public boolean UpAnalysePoint(int x,int y)
{
float resultY = 0;
y = screenHeigth-y;
if (result!=null) {
float k=(float) result[0];
float a=(float) result[1];
resultY= k*x + a;
}
if (resultY>=y) {
return true;
}
else
{
return false;
}
}
public boolean DownAnalysePoint(int x,int y)
{
float resultY = 0;
y = screenHeigth-y;
if (result!=null) {
float k=(float) result[0];
float a=(float) result[1];
resultY= k*x + a;
}
if (resultY<=y) {
return true;
}
else
{
return false;
}
}
}
//这个方法的核心依然是noise()。
以上就是项目中使用到的动画效果。