package application;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
private static Canvas canvas;
private static int clickCount = 0;
private static int x1 = 0;
private static int y1 = 0;
static ArrayList<Circle> circleArr = new ArrayList<Circle>();
private Timeline timeline;
@Override
public void start(Stage primaryStage) {
try {
primaryStage.setTitle("Graphics Demo App");
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 800, 500);
canvas = new Canvas(800, 475);
canvas.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
if (clickCount % 2 == 0) {
x1 = x;
y1 = y;
} else {
int x2 = x;
int y2 = y;
int r = (int) Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
int x_corner = x1 - r;
int y_corner = y1 - r;
Circle c = new Circle(x_corner, y_corner, r);
circleArr.add(c);
c.drawOn(canvas);
}
clickCount++;
}
});
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
root.setCenter(canvas);
Button circleButton = new Button("Circle");
circleButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
// System.out.println("Circle");
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setStroke(Color.AQUAMARINE);
Random rand = new Random();
int x = rand.nextInt((int) canvas.getWidth());
int y = rand.nextInt((int) canvas.getHeight());
Circle c = new Circle(x, y, 50);
c.drawOn(canvas);
// gc.strokeOval(x, y, 200, 200);
}
});
Button squareButton = new Button("Square");
squareButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
// System.out.println("square");
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setStroke(Color.AQUAMARINE);
Random rand = new Random();
int x = rand.nextInt((int) canvas.getWidth());
int y = rand.nextInt((int) canvas.getHeight());
int w = rand.nextInt((int) canvas.getWidth());
int h = rand.nextInt((int) canvas.getHeight());
Square s = new Square(x, y, w, h);
s.drawOn(canvas);
// gc.strokeOval(x, y, 200, 200);
}
});
Button stepButton = new Button("Step");
stepButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
step();
}
});
Button playButton = new Button("Play");
playButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
timeline = new Timeline(new KeyFrame(Duration.millis(100), ae -> step()));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
});
Button stopButton = new Button("Stop");
stopButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
if (timeline != null) {
timeline.stop();
}
}
});
FlowPane buttonsPane = new FlowPane();
buttonsPane.setAlignment(Pos.CENTER);
buttonsPane.getChildren().add(circleButton);
buttonsPane.getChildren().add(squareButton);
Button saveButton = new Button("Save");
Button restoreButton = new Button("Restore");
restoreButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
restore();
}
});
buttonsPane.getChildren().add(saveButton);
buttonsPane.getChildren().add(restoreButton);
buttonsPane.getChildren().add(stepButton);
buttonsPane.getChildren().add(playButton);
buttonsPane.getChildren().add(stopButton);
root.setBottom(buttonsPane);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void step() {
clearScreen();
for (Circle c : circleArr) {
c.step(canvas);
}
}
private static void clearScreen() {
canvas.getGraphicsContext2D().fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
}
public static void main(String[] args) {
launch(args);
}
public static void restore() {
try {
// Setting up to read the text file
FileReader reader = new FileReader("shapes.txt");
BufferedReader bufferReader = new BufferedReader(reader);
// Read the first line in the file
String line = bufferReader.readLine();
while (line != null && line.trim().length() > 0) {
String[] parts = line.split(":");
String left = parts[0];
String right = parts[1];
if (left.equals("C")) {
String[] components = right.trim().split(" ");
int x = Integer.parseInt(components[0]);
int y = Integer.parseInt(components[1]);
int r = Integer.parseInt(components[2]);
Circle c = new Circle(x, y, r);
c.drawOn(canvas);
} else if (left.equals("S")) {
System.out.println("This is a square: " + right);
}
line = bufferReader.readLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这是圆圈代码: -
package application;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
public class Circle {
int x;
int y;
int radius;
int x_direction = 1;
int y_direction = 1;
int dx = 11, dy = 7;
public Circle(){
}
public Circle(int x, int y, int r){
this.x = x;
this.y = y;
this.radius = r;
}
public void print(){
System.out.println("Circle: " + x + " " + y + " " + radius);
}
public void drawOn(Canvas canvas){
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setStroke(Color.AQUAMARINE);
gc.strokeOval(x, y, 2*radius, 2*radius);
}
public void step(Canvas canvas){
x += 5 * x_direction;
y += 5 * y_direction;
if (x + radius * 2 > canvas.getWidth()){
x_direction = x_direction * -1;
}
if (y + radius * 2 > canvas.getHeight()){
y_direction = y_direction * -1;
}
if ((x - radius + dx < 0) || (x + radius + dx > canvas.getWidth()))
dx = -dx;
if ((y - radius + dy < 0) || (y + radius + dy > canvas.getHeight()))
dy = -dy;
// Move the circle.
x += dx;
y += dy;
drawOn(canvas);
}
答案 0 :(得分:0)
这是我想出的。由于你没有说出你的问题,我做了一个例子。我没有使用时间线,我只是使用了另一个不断更新的线程。
package helloworld;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Ellipse;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Matt on 17/08/16.
*/
public class AnimatedScene extends Application{
List<AnimatedCircle> circles = new ArrayList<>();
Canvas custom;
boolean quit = false;
@Override
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
custom = new Canvas(600, 600);
GraphicsContext gc = custom.getGraphicsContext2D();
createBackground(gc);
root.getChildren().add(custom);
circles.add(new AnimatedCircle(50, 50));
circles.add(new AnimatedCircle(50, 100));
circles.add(new AnimatedCircle(50, 150));
circles.add(new AnimatedCircle(50, 200));
for(AnimatedCircle circle: circles) {
root.getChildren().add(circle.shape);
}
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.addEventHandler(WindowEvent.WINDOW_CLOSE_REQUEST, evt->{
quit=true;
});
startMainLoop();
}
private void startMainLoop(){
new Thread(()->{
Thread.currentThread().setName("bounce loop");
long time = System.currentTimeMillis();
int step = (int)(1000.0/60.0);
while(!(Thread.interrupted()||quit)){
synchronized (circles) {
for(int i = 0; i<circles.size(); i++){
for(int j = i+1; j<circles.size(); j++){
AnimatedCircle a = circles.get(i);
AnimatedCircle b = circles.get(j);
double dx = b.cx - a.cx;
double dy = b.cy - a.cy;
double distance = Math.sqrt(dx*dx + dy*dy);
if(distance<a.radius + b.radius){
//collision
b.vx = dx/distance;
b.vy = dy/distance;
a.vx = -dx/distance;
a.vy = dy/distance;
}
}
}
for (AnimatedCircle circle : circles) {
circle.update();
}
}
Platform.runLater(()->{
sync();
});
try{
long nt = System.currentTimeMillis();
long wait = step - (nt - time);
if(wait>=0) {
Thread.sleep(wait);
time = nt+wait;
} else{
time = nt;
}
} catch(InterruptedException exc){
//just exit.
}
}
}).start();
}
void sync(){
synchronized (circles){
GraphicsContext gc = custom.getGraphicsContext2D();
createBackground(gc);
for(AnimatedCircle circle: circles){
circle.sync();
gc.setFill(new Color(0, 0, 0, 0.2));
gc.fillOval(circle.cx - circle.radius-15, circle.cy - circle.radius-5, 50, 50);
}
}
}
void createBackground(GraphicsContext gc){
gc.setFill(Color.RED);
RadialGradient gradient = new RadialGradient(
0, 0, 300, 300, 300, false,
CycleMethod.NO_CYCLE,
new Stop(0.0, Color.RED), new Stop(1.0, Color.DARKRED));
gc.setFill(gradient);
gc.fillRect(100, 100, 400, 400);
gc.setFill(new Color(1, 0.2, 0.2, 1));
gc.fillPolygon(
new double[]{ 0, 100, 100, 0},
new double[]{ 0, 100, 500, 600},
4
);
gc.setFill(new Color(1, 0.25, 0.25, 1));
gc.fillPolygon(
new double[]{ 0, 100, 500, 600},
new double[]{ 0, 100, 100, 0},
4
);
gc.setFill(new Color(0.5, 0., 0., 1));
gc.fillPolygon(
new double[]{ 500, 600, 600, 500},
new double[]{ 100, 0, 600, 500},
4
);
gc.setFill(new Color(0.8, 0., 0., 1));
gc.fillPolygon(
new double[]{ 0, 100, 500, 600},
new double[]{ 600, 500, 500, 600},
4
);
}
public static void main(String[] args){
launch(args);
}
}
class AnimatedCircle{
public Ellipse shape;
RadialGradient gradient;
double vx;
double vy;
double cx, cy;
double speed = 5;
double radius = 25;
public AnimatedCircle(double x, double y){
cx = x;
cy = y;
vx = 2*(Math.random() - 0.5);
vy = Math.sqrt(1 - vx*vx);
if(Math.random()>=0.5){
vy = -vy;
}
shape = new Ellipse(cx, cy, radius, radius);
final String label = x + ", " + y;
shape.addEventHandler(MouseEvent.MOUSE_CLICKED, evt->{
System.out.println(label);
});
gradient = new RadialGradient(0, 0, 0.75, 0.6, 1, true, CycleMethod.NO_CYCLE, new Stop(0.0, Color.WHITE), new Stop(1.0, Color.BLACK));
shape.setFill(gradient);
}
void update(){
double nx = cx + vx*speed;
if(nx + shape.getRadiusX()>600 || nx - shape.getRadiusX()<0){
vx = -vx;
nx = cx;
}
double ny = cy + vy*speed;
if(ny + shape.getRadiusY()>600 || ny - shape.getRadiusY()<0 ){
vy = -vy;
ny = cy;
}
cy = ny;
cx = nx;
}
public void sync(){
shape.setCenterX(cx);
shape.setCenterY(cy);
}
}
注意事项:
否则,如果你能稍微清理一下你的问题,并解释一下有什么问题可能会修复你的代码。