java基础球绑绑 java基础球绑绑


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bounceboxframework;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

/**
 *
 * @author p0073862
 */
public class BounceController implements ActionListener {
    BounceModel model;
    Timer timer;
    int refreshInterval;
    double doubleInterval;
    public BounceController(BounceModel model, int refreshInterval)  {
        this.model = model;
        this.refreshInterval = refreshInterval;
        timer = new Timer(refreshInterval,this);
        doubleInterval = refreshInterval/1000.0;
    }
    
    public void start() {
            timer.start();
    }

    public void actionPerformed(ActionEvent e) {
        model.moveShapes(doubleInterval);
    }

}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bounceboxframework;

import java.util.List;
import java.util.LinkedList;
import java.util.Observable;

/**
 *
 * @author p0073862
 */
public class BounceModel extends Observable {
    
    private List<Shape> shapes  = new LinkedList<Shape>();
    private List<Wall> walls = new LinkedList<Wall>();
    
    public void addShape(Shape shape){
        shapes.add(shape);
    }
    
    public void addWall(Wall wall) {
        walls.add(wall);
    }
    
    public void moveShapes(double time) {
        int first = 1;
        int size = shapes.size();
        for (Shape s:shapes) {
            for (Wall w: walls) {
                s.interactWall(w);
            }
            for(Shape s2: shapes.subList(first, size)) {
                s.interactShape(s2);
            }
            first++;
        }
        for (Shape s:shapes) {
            s.move(time);
        }
       setChanged();
        notifyObservers();
    }
}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bounceboxframework;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JPanel;

/**
 *
 * @author p0073862
 */
public class BouncePanel extends JPanel {
    private int width;
    private int height;
    private List<Drawable> drawshapes = new LinkedList<Drawable>();
    
    public BouncePanel(int width, int height) {
        super();
        this.width = width;
        this.height = height;
        setPreferredSize(new Dimension(width, height));
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setColor(Color.WHITE);
        g2.fillRect(0, 0, width, height);
        
        for (Drawable d: drawshapes) {
            d.draw(g2);
        }
    }
    
    public void addDrawable(Drawable d) {
        drawshapes.add(d);
  
    }
}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bounceboxframework;

import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;

/**
 *
 * @author p0073862
 */
public class BounceView implements Observer  {
    
    private JFrame frame;
    private  BouncePanel panel;
    private BounceModel model;
    
    public BounceView(int width, int height, BounceModel model) {
        this.model = model;
       model.addObserver(this);
        
        frame = new JFrame("Bounce Box");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel = new BouncePanel(width, height);
        frame.setContentPane(panel);
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);
    }

    public void update(Observable obs,  Object arg) {
        panel.repaint();
    }
 
    public void addDrawable(Drawable d) {
        panel.addDrawable(d);
    }
}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bounceboxframework;

import java.awt.Graphics2D;

/**
 *
 * @author p0073862
 */
public interface Drawable {
    public  void draw(Graphics2D g);
}


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package bounceboxframework;

/**
 *
 * @author p0074487
 */
public interface Moveable {
    public void move(double  time);
    public double getX();
    public double getY();
    public void setVelocity(double vx, double vy);
}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bounceboxframework;

import java.awt.Color;

/**
 *
 * @author p0073862
 */
public abstract class Shape implements Drawable, Moveable{
    private double x;
    private double y;
    private double vx = 0;
    private double vy = 0;
    private Color color = Color.BLACK;
    
    public Shape(int x, int y) {
        this.x = x;
        this.y  =y;
    }
    @Override
    public double getX(){return x;}
    @Override
    public double getY(){return y;}
    //public void setX(int x) {this.x = x;}
    //public void setY(int y) {this.y = x;}
    
    @Override
    public void setVelocity(double vx, double vy) {
        this.vx = vx;
        this.vy = vy;
    }
    
    public void setColor(Color color) {
        this.color = color;
    }
    
    public Color getColor() {return color;}
    public void move(double time) {
        x+= vx * time;
        y+= vy * time;
    }
    
    private void reflect(double nx, double ny) {
        double dot = Util.dotprod(nx,ny,vx,vy);
        double absn = Util.mag(nx, ny);
        vx -= 2*nx*dot/(absn*absn);
        vy -= 2*ny*dot/(absn*absn);
    }
    
    /**
     * Interact with a wall bounding the space ax+by+c>0 in which the shape can
     * We assume (a,b) is normalised
     * move
     * @param a
     * @param b
     * @param c
     */
    public void interactWall(Wall wall) {
        double a = wall.getA();
        double b = wall.getB();
        double c = wall.getC();
        //are we close enough to the wall to bounce
        if (Util.dotprod(x, y, a, b) + c < getContactRadius()) {
            //are we moving towards the wall
            if (Util.dotprod(vx, vy, a, b)<0) {
                reflect(a, b);
            }
            
        }
    }
    
    public void interactShape(Shape s) {
        double dx = s.x-x;
        double dy = s.y-y;
        // are the two shapes close enough to interact
        if (Util.mag(dx, dy) < (getContactRadius() + s.getContactRadius())) {
            double dvx = s.vx-vx;
            double dvy = s.vy-vy;
            //are the two shapes moving together
            if (Util.dotprod(dx, dy, dvx, dvy)<0) {
               //ndx,ndy = normalised (dx,dy)
                double magd = Util.mag(dx, dy);
                double ndx = dx/magd;
                double ndy = dy/magd;
                
               //uperp = velocity of this perpendicular to line between shapes
               double uperp = Util.dotprod(vx, vy, -ndy, ndx);
               //usperp = velocity of s perpendicular to line between shapes
               double usperp = Util.dotprod(s.vx, s.vy, -ndy, ndx);
               //upar = init. velocity of this parallel to line between shapes
               double upar = Util.dotprod(vx, vy, ndx, ndy);
               //uspar = init. velocity of s parallel to line between shapes
               double uspar = Util.dotprod(s.vx, s.vy, ndx, ndy);
               
               double m = getMass();
               double ms = s.getMass();
               
               //vpar = final velocity of this parallel to line between shapes
               double vpar = (upar*(m-ms)+2*ms*uspar)/(m+ms); 
               //vspar = final velocity of this parallel to line between shapes
               double vspar = (uspar*(ms-m)+2*m*upar)/(m+ms); 
               
               vx = vpar*ndx-uperp*ndy;
               vy = vpar*ndy+uperp*ndx;
               s.vx = vspar*ndx-usperp*ndy;
               s.vy = vspar*ndy+usperp*ndx;
               
               
            }
        }
    }
    
    public abstract double getContactRadius();
    public abstract double getMass();
    
}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bounceboxframework;

/**
 *
 * @author p0073862
 */
public class Util {
    public static double dotprod(double x1, double y1, double x2, double y2) {
        return x1*x2+y1*y2;
    }
    
    public static double mag(double x, double y) {
        return Math.sqrt(x*x + y*y);
    
    }

}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bounceboxframework;

/**
 *
 * @author p0073862
 */
// a wall that restricts shapes to moving in the area ax+by+c>0
public class Wall {
    private double a,b,c;
    
    public Wall(double a, double b, double c) {
        this.a=a; this.b=b; this.c=c;
    }
    
    public double getA(){return a;}
    public double getB(){return b;}
    public double getC(){return c;}
}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bouncebox;

import bounceboxframework.Shape;
import bounceboxframework.Wall;
import bounceboxframework.BounceModel;
import bounceboxframework.BounceController;
import bounceboxframework.BounceView;

/**
 *
 * @author p0073862
 */
public class BounceBox {
    BounceModel model;
    BounceView view;
    BounceController controller;
    public static final int TIMER_INTERVAL = 50;
    
    public BounceBox(int width, int height) {
        
        model = new BounceModel();
        
        model.addWall(new Wall(1,0,0));
        model.addWall(new Wall(-1, 0, width));
        model.addWall(new Wall(0, 1, 0));
        model.addWall(new Wall(0, -1, height));
        
        view = new BounceView(width, height, model);
        controller = new BounceController(model, TIMER_INTERVAL);
    }
    
  
    public void addShape(Shape s) {
        model.addShape(s);
        view.addDrawable(s);
    }
    
   
    
    public void start() {
        controller.start();
    }

}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bouncebox;

import bounceboxframework.Shape;
import java.awt.Graphics2D;

/**
 *
 * @author p0073862
 */
public class Circle extends Shape {
    
    private int radius;
    public Circle(int x, int y, int radius) {
        super(x,y);
        this.radius = radius;
    }
    
    public int getRadius(){return radius;}
    
    public double getContactRadius() {return radius;}
    public double getMass() {return Math.PI*radius*radius;}
    
    public void draw(Graphics2D g) {
        g.setColor(getColor());
        double left = getX() - getRadius();
        double top = getY() - getRadius();
        g.fillOval((int)left,(int)top,getRadius()*2,
                                      getRadius()*2);
    }
}



import bounceboxframework.Shape;
import java.awt.Graphics2D;

/**
 *
 * @author p0073862
 */
public class Square extends Shape {
    
    private double contactRadius;
    private int width;
    
    public Square(int x, int y, int width) {
        super(x,y);
        this.width = width;
        contactRadius = Math.sqrt(width*width/2);
    }
    
    public int getWidth(){return width;}
    
    public double getContactRadius() {return contactRadius;}
    public double getMass() {return width*width;}
    public void draw(Graphics2D g) {
        g.setColor(getColor());
       
        int left = (int) (getX()-width/2);
        int top = (int) (getY()-width/2);
        g.fillRect(left,top, width, width);
        
  
    }
}


img

img

上面是相关代码,图片是要求,写main代码


import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

import bouncebox.BounceBox;
import bouncebox.Circle;
import bouncebox.Shape;
import bouncebox.Square;

public class Main {
    
    public static void main(String[] args) throws FileNotFoundException {
        
        BounceBox bb = new BounceBox(600, 500);
        int numCircles = 0, numSquares = 0;
        double totalArea = 0.0;
        
        Scanner scanner = new Scanner(new File("practical8.txt"));
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            String[] tokens = line.split("\\s+");
            if (tokens[0].equals("Circle")) {
                try {
                    int x = Integer.parseInt(tokens[1]);
                    int y = Integer.parseInt(tokens[2]);
                    int r = Integer.parseInt(tokens[3]);
                    
                    Circle circle = new Circle(x, y, r);
                    bb.addShape(circle);
                    
                    numCircles++;
                    totalArea += Math.PI * r * r;
                    
                    if (tokens.length >= 6) {
                        double vx = Double.parseDouble(tokens[4]);
                        double vy = Double.parseDouble(tokens[5]);
                        circle.setVelocity(vx, vy);
                        if (tokens.length == 9) {
                            int red = Integer.parseInt(tokens[6]);
                            int green = Integer.parseInt(tokens[7]);
                            int blue = Integer.parseInt(tokens[8]);
                            Color color = new Color(red, green, blue);
                            circle.setColor(color);
                        }
                    }
                    
                } catch (NumberFormatException e) {
                    // ignore invalid input
                }
                
            } else if (tokens[0].equals("Square")) {
                try {
                    int x = Integer.parseInt(tokens[1]);
                    int y = Integer.parseInt(tokens[2]);
                    int width = Integer.parseInt(tokens[3]);
                    
                    Square square = new Square(x, y, width);
                    bb.addShape(square);
                    
                    numSquares++;
                    totalArea += width * width;
                    
                    if (tokens.length >= 6) {
                        double vx = Double.parseDouble(tokens[4]);
                        double vy = Double.parseDouble(tokens[5]);
                        square.setVelocity(vx, vy);
                        if (tokens.length == 9) {
                            int red = Integer.parseInt(tokens[6]);
                            int green = Integer.parseInt(tokens[7]);
                            int blue = Integer.parseInt(tokens[8]);
                            Color color = new Color(red, green, blue);
                            square.setColor(color);
                        }
                    }
                    
                } catch (NumberFormatException e) {
                    // ignore invalid input
                }
            }
        }
        scanner.close();
        
        System.out.println("Number of circles: " + numCircles);
        System.out.println("Number of squares: " + numSquares);
        System.out.println("Total area of all shapes: " + totalArea);
        
        bb.start();
    }
}

仅供参考

 
import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
 
import bouncebox.BounceBox;
import bouncebox.Circle;
import bouncebox.Shape;
import bouncebox.Square;
 
public class Test{
    
    public static void main(String[] args) throws FileNotFoundException {
        
        BounceBox bb = new BounceBox(500, 500);
        int numCircles = 0, numSquares = 0;
        double totalArea = 0.0;
        
        Scanner scanner = new Scanner(new File("practical8.txt"));
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            String[] tokens = line.split("\\s+");
            if (tokens[0].equals("Circle")) {
                try {
                    int x = Integer.parseInt(tokens[1]);
                    int y = Integer.parseInt(tokens[2]);
                    int r = Integer.parseInt(tokens[3]);
                    
                    Circle circle = new Circle(x, y, r);
                    bb.addShape(circle);
                    
                    numCircles++;
                    totalArea += Math.PI * r * r;
                    
                    if (tokens.length >= 6) {
                        double vx = Double.parseDouble(tokens[4]);
                        double vy = Double.parseDouble(tokens[5]);
                        circle.setVelocity(vx, vy);
                        if (tokens.length == 9) {
                            int red = Integer.parseInt(tokens[6]);
                            int green = Integer.parseInt(tokens[7]);
                            int blue = Integer.parseInt(tokens[8]);
                            Color color = new Color(red, green, blue);
                            circle.setColor(color);
                        }
                    }
                    
                } catch (NumberFormatException e) {
                    // ignore invalid input
                }
                
            } else if (tokens[0].equals("Square")) {
                try {
                    int x = Integer.parseInt(tokens[1]);
                    int y = Integer.parseInt(tokens[2]);
                    int width = Integer.parseInt(tokens[3]);
                    
                    Square square = new Square(x, y, width);
                    bb.addShape(square);
                    
                    numSquares++;
                    totalArea += width * width;
                    
                    if (tokens.length >= 6) {
                        double vx = Double.parseDouble(tokens[4]);
                        double vy = Double.parseDouble(tokens[5]);
                        square.setVelocity(vx, vy);
                        if (tokens.length == 9) {
                            int red = Integer.parseInt(tokens[6]);
                            int green = Integer.parseInt(tokens[7]);
                            int blue = Integer.parseInt(tokens[8]);
                            Color color = new Color(red, green, blue);
                            square.setColor(color);
                        }
                    }
                    
                } catch (NumberFormatException e) {
                    // ignore invalid input
                }
            }
        }
        scanner.close();
        
        System.out.println("Number of circles: " + numCircles);
        System.out.println("Number of squares: " + numSquares);
        System.out.println("Total area of all shapes: " + totalArea);
        
        bb.start();
    }
}