效果:
已修改,使用timeline,不用线程。画雪花曲线。
package funny;
import com.sun.org.slf4j.internal.Logger;
import com.sun.org.slf4j.internal.LoggerFactory;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.layout.Background;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.canvas.Canvas;
import javafx.util.Duration;
import lombok.Data;
import java.awt.*;
import java.util.*;
import java.util.List;
/**
* @Author sangchen
* @Date 2021/7/8 10:36
**/
public class Spider extends Application {
double sonW = 200d;
int sonC = 4;
/**
* 屏幕尺寸
*/
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
private double width = screenSize.getWidth();
private double height = screenSize.getHeight();
GraphicsContext gc;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
Pane root = new StackPane();
Canvas canvas = new Canvas(width, height);
gc = canvas.getGraphicsContext2D();
canvas.setOnMouseClicked(event -> {
System.out.println("111");
});
root.getChildren().add(canvas);
//透明底
root.setBackground(Background.EMPTY);
primaryStage.initStyle(StageStyle.TRANSPARENT);
Scene scene = new Scene(root, width, height);
scene.setFill(null);
primaryStage.setScene(scene);
//常驻顶层
primaryStage.setAlwaysOnTop(true);
primaryStage.show();
funny();
}
private void funny() {
Random random = new Random();
gc.setLineWidth(1);
gc.setStroke(Color.rgb(57, 125, 198));
List<Sth> list = new ArrayList();
Double randomFx[] = {0.1d, 0.15d, 0.2d, 0.25d};
Double randomFy[] = {0.1d, 0.2d, 0.3d, 0.15d};
for (int i = 0; i < sonC; i++) {
//随机出生地
double x = random.nextInt((int) width);
double y = random.nextInt((int) height);
int fx = random.nextInt(4) % 2 == 0 ? -1 : 1;
int fy = random.nextInt(4) % 2 == 0 ? -1 : 1;
Sth sth = new Sth(x, y, fx, fy, (random.nextInt(4) % 2 == 0 ? -1 : 1) * (0.001 * random.nextInt(1000)));
list.add(sth);
}
Timeline timeline = new Timeline();
// 动画执行的次数(Timeline.INDEFINITE表示随机,就是鬼才知道什么结束的那种)
timeline.setCycleCount(Timeline.INDEFINITE);
// 是否还原为初始状态(如果设置为true,会在执行次数内还会切换,至于这个初始状态什么意思自己体会吧)
timeline.setAutoReverse(true);
KeyFrame keyFrame = new KeyFrame(Duration.millis(1), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
gc.clearRect(0, 0, width, height);
int k = 0;
for (Sth sth : list) {
drawSth(sth);
k++;
double x = sth.getX();
double y = sth.getY();
x += randomFx[k % randomFx.length] * sth.fx;
y += randomFy[k % randomFy.length] * sth.fy;
//撞墙折返x
if (x > width - sonW/10) {
System.out.println("x 大了");
sth.setFx(-1);
sth.setOffset((random.nextInt(4) % 2 == 0 ? -1 : 1) * (0.001 * random.nextInt(1000)));
}
if (x < sonW/10) {
System.out.println("x 小了");
sth.setFx(1);
}
//撞墙折返y
if (y > height - sonW/10) {
sth.setFy(-1);
sth.setOffset((random.nextInt(4) % 2 == 0 ? -1 : 1) * (0.001 * random.nextInt(1000)));
}
if (y < sonW/10) {
System.out.println("y 小了");
sth.setFy(1);
}
//碰撞折返
for (Sth s : list) {
if (s != sth) {
if (Math.abs(s.getX() - sth.getX()) < sonW * 2
&& Math.abs(s.getY() - sth.getY()) < sonW * 2) {
int fyt = s.getFy();
int fxt = s.getFx();
sth.setFy(s.getFy());
sth.setFx(s.getFx());
s.setFx(fxt);
s.setFy(fyt);
}
}
}
sth.setX(x);
sth.setY(y);
sth.setAngle(sth.angle + 0.01d * sth.offset);
}
}
});
timeline.getKeyFrames().add(keyFrame);
timeline.play();
}
private void drawSth(Sth sth) {
int n = 4;
double x = sth.getX();
double y = sth.getY();
double len = sonW / 3;
double angle = sth.getAngle();
kochCurve(x, y, angle, len, n);
x = x + len * Math.cos(angle);
y = y - len * Math.sin(angle);
angle -= Math.PI * 2 / 3;
kochCurve(x, y, angle, len, n);
x = x + len * Math.cos(angle);
y = y - len * Math.sin(angle);
angle -= Math.PI * 2 / 3;
kochCurve(x, y, angle, len, n);
}
private void kochCurve(double x, double y, double angle, double len, int n) {
if (n == 0) {
double x1 = x + len * Math.cos(angle);
double y1 = y - len * Math.sin(angle);
gc.strokeLine(x, y, x1, y1);
} else {
n = n - 1;
len /= 3;
kochCurve(x, y, angle, len, n);
x = x + len * Math.cos(angle);
y = y - len * Math.sin(angle);
angle += Math.PI * 1 / 3;
kochCurve(x, y, angle, len, n);
x = x + len * Math.cos(angle);
y = y - len * Math.sin(angle);
angle -= Math.PI * 2 / 3;
kochCurve(x, y, angle, len, n);
x = x + len * Math.cos(angle);
y = y - len * Math.sin(angle);
angle += Math.PI * 1 / 3;
kochCurve(x, y, angle, len, n);
}
}
@Data
class Sth {
double offset; //随便给个偏移量
double x, y; //坐标
int fx, fy; //飞行方向
double angle = 0d;
Sth(double x, double y, int fx, int fy, double offset) {
this.x = x;
this.y = y;
this.fx = fx;
this.fy = fy;
this.offset = offset;
}
}
}
撸的我心态崩了,数学知识忘得差不多了,雪花画不出来