2016-08-17 23 views
-1
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(); 
     } 

    } 

} 

这是圆代码: -如何在javafx中反弹圈子和其他形状?

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); 
    } 
+1

那么现在会发生什么,你期望会发生什么? – matt

回答

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); 
    } 

} 

注意事项:

  • 在createBackground,我完全重绘背景。在你明确的方法中,你用最后的油漆填满所有的东西。这并不一定清楚你的背景。
  • 我使用了两种不同的方法来绘制球。 1)我使用添加到场景中的椭圆,然后我更新它们的位置。 2)我使用图形画布绘制阴影。

否则,如果你可以清理你的问题一点,并且实际解释什么是错的,有人可能能够修复你的代码。