Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import javax.swing.*;
- import java.awt.*;
- import java.awt.geom.*;
- import java.awt.event.*;
- class Vector {
- final double x,y;
- Vector(double x, double y) {
- this.x = x;
- this.y = y;
- }
- public Vector setX(double x) {
- return new Vector(x, y);
- }
- public Vector setY(double y) {
- return new Vector(x, y);
- }
- public Vector add(Vector v) {
- return new Vector(x+v.x, y+v.y);
- }
- public Vector add(double x, double y) {
- return new Vector(this.x+x, this.y+y);
- }
- public Vector sub(Vector v) {
- return new Vector(x-v.x, y-v.y);
- }
- public Vector mul(double d) {
- return new Vector(x*d, y*d);
- }
- public Vector div(double d) {
- return new Vector(x/d, y/d);
- }
- public Vector neg() {
- return new Vector(-x, -y);
- }
- public Vector negX() {
- return new Vector(-x, y);
- }
- public Vector negY() {
- return new Vector(x, -y);
- }
- public double angle() {
- return Math.atan2(y, x);
- }
- public double length() {
- return Math.sqrt(x*x+y*y);
- }
- public double distance(Vector v) {
- return sub(v).length();
- }
- public Vector rotate(double angle) {
- double sin = Math.sin(angle);
- double cos = Math.cos(angle);
- return new Vector(x*cos - y*sin,
- x*sin + y*cos);
- }
- @Override
- public String toString() {
- return "Vector("+x+", "+y+")";
- }
- }
- class Ball {
- static Ellipse2D.Double circle = new Ellipse2D.Double();
- Vector pos, lastPos;
- Vector speed = new Vector(0,0);
- double radius;
- public Ball(Vector pos, double radius) {
- this.pos = pos;
- this.radius = radius;
- }
- public boolean contains(Vector v) {
- return v.sub(pos).length() <= radius;
- }
- public void update(double time) {
- lastPos = pos;
- pos = pos.add(speed.mul(time));
- }
- public void stepBack() {
- pos = lastPos;
- }
- public void paint(Graphics2D g) {
- circle.setFrame(pos.x-radius, pos.y-radius,radius*2,radius*2);
- g.fill(circle);
- }
- }
- class Paddle {
- static Rectangle2D.Double rectangle = new Rectangle2D.Double();
- static double damping = 0.000001;
- Vector pos, lastPos;
- Vector speed = new Vector(0,0);
- double width, height;
- public Paddle(Vector pos, double width, double height) {
- this.pos = pos;
- this.width = width;
- this.height = height;
- }
- Vector getCenter() {
- return pos.add(width/2, height/2);
- }
- public void update(double time) {
- lastPos = pos;
- speed = speed.mul(Math.pow(damping,time));
- if(speed.length() > 200) speed = speed.div(speed.length()).mul(200);
- pos = pos.add(speed.mul(time));
- }
- public void stepBack() {
- pos = lastPos;
- }
- public Vector[] getCorners() {
- return new Vector[] {pos, pos.add(width,0),
- pos.add(width, height), pos.add(0,height)};
- }
- public boolean collides(Ball b) {
- for(Vector corner: getCorners()) {
- if(b.contains(corner)) {
- return true;
- }
- }
- return (b.pos.x >= pos.x &&
- b.pos.x < pos.x+width &&
- b.pos.y+b.radius >= pos.y &&
- b.pos.y-b.radius < pos.y+height) ||
- (b.pos.x+b.radius >= pos.x &&
- b.pos.x-b.radius < pos.x+width &&
- b.pos.y >= pos.y &&
- b.pos.y < pos.y+height);
- }
- public void reflect(Ball b) {
- Vector relativeBallSpeed = b.speed.sub(speed);
- if(b.pos.x >= pos.x && b.pos.x < pos.x+width) {
- relativeBallSpeed = relativeBallSpeed.negY();
- } else if(b.pos.y >= pos.y && b.pos.y < pos.y+height) {
- relativeBallSpeed = relativeBallSpeed.negX();
- } else {
- Vector corner = null;
- for(Vector c: getCorners()) {
- if(corner == null) corner = c;
- else if(b.pos.distance(c) < b.pos.distance(corner)) {
- corner = c;
- }
- }
- double w1 = b.pos.sub(corner).angle();
- double w2 = relativeBallSpeed.angle();
- double incidenceAngle = w2-w1;
- relativeBallSpeed = relativeBallSpeed.neg().rotate(-2*incidenceAngle);
- }
- b.speed = relativeBallSpeed.add(speed);
- }
- public void paint(Graphics2D g) {
- rectangle.setFrame(pos.x, pos.y,width,height);
- g.fill(rectangle);
- }
- }
- public class Pong extends JPanel {
- Paddle paddle = new Paddle(new Vector(20,260), 15, 60);
- Ball ball = new Ball(new Vector(300,300), 10);
- volatile Vector target = paddle.getCenter();
- MouseAdapter mouseAdapter = new MouseAdapter() {
- public void mouseMoved(MouseEvent e) {
- target = new Vector(e.getX(), e.getY());
- }
- };
- public Pong() {
- addMouseMotionListener(mouseAdapter);
- }
- public void start() {
- ball.speed = new Vector(-200,20);
- long lastTime = System.nanoTime();
- while(true) {
- long currentTime = System.nanoTime();
- double time = (currentTime - lastTime)/1e9;
- lastTime = currentTime;
- Vector dist = target.sub(paddle.getCenter());
- paddle.speed = paddle.speed.add(dist.mul(time*100));
- ball.update(time);
- paddle.update(time);
- if(paddle.collides(ball)) {
- ball.stepBack();
- paddle.stepBack();
- paddle.reflect(ball);
- }
- if(ball.pos.x + ball.radius > getWidth()) {
- ball.pos = ball.pos.setX(getWidth()-ball.radius);
- ball.speed = ball.speed.setX(-Math.abs(ball.speed.x));
- }
- if(ball.pos.x - ball.radius < 0) {
- ball.pos = ball.pos.setX(ball.radius);
- ball.speed = ball.speed.setX(Math.abs(ball.speed.x));
- }
- if(ball.pos.y + ball.radius > getHeight()) {
- ball.pos = ball.pos.setY(getHeight()-ball.radius);
- ball.speed = ball.speed.setY(-Math.abs(ball.speed.y));
- }
- if(ball.pos.y - ball.radius < 0) {
- ball.pos = ball.pos.setY(ball.radius);
- ball.speed = ball.speed.setY(Math.abs(ball.speed.y));
- }
- repaint();
- try {
- Thread.sleep(16);
- } catch(Exception e) {
- }
- }
- }
- public static void main(String[] args) {
- JFrame frame = new JFrame();
- Pong pong = new Pong();
- pong.setPreferredSize(new Dimension(800,600));
- frame.add(pong);
- frame.pack();
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setVisible(true);
- pong.start();
- }
- @Override
- public void paint(Graphics g) {
- Graphics2D g2 = (Graphics2D)g;
- g2.setColor(Color.WHITE);
- g2.fillRect(0,0,getWidth(),getHeight());
- g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- g2.setColor(Color.BLACK);
- ball.paint(g2);
- paddle.paint(g2);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement