Java 从JFrame中删除JPanel后添加它

Java 从JFrame中删除JPanel后添加它,java,swing,jframe,jpanel,paintcomponent,Java,Swing,Jframe,Jpanel,Paintcomponent,我正在开发一个Java游戏。我陷入了困境,在游戏结束后我需要重新启动整个游戏。以下是我的程序框架: package projectflappy; import java.awt.*; public final class TheGame extends JFrame implements MouseListener{ JPanel jp; //declaration of the varibles int x_width = 500; int y_height = 500; int

我正在开发一个Java游戏。我陷入了困境,在游戏结束后我需要重新启动整个游戏。以下是我的程序框架:

package projectflappy;

import java.awt.*;


public final class TheGame extends JFrame  implements MouseListener{
JPanel jp;
//declaration of the varibles

int x_width = 500;
int y_height = 500;

int count = 5 ;

Ellipse2D Ball;


int x_ball;
int y_ball;
int cord_xup1,cord_xdown1;
int cord_xup2,cord_xdown2;
int cord_xup3,cord_xdown3;
int cord_xup4,cord_xdown4;
int cord_xup5,cord_xdown5;

Boolean flag = true;

RoundRectangle2D up1,down1,up2,down2,up3,down3,up4,down4;

Font font = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,40);
Font font1 = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,20);
Font font3 = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,20);

float das[] = {10.0f};
BasicStroke color = new BasicStroke(10,BasicStroke.CAP_ROUND,BasicStroke.JOIN_BEVEL,20.0f,das,0.0f); 


GradientPaint gp2 = new GradientPaint(20, 0, 
Color.DARK_GRAY, 0, 10, Color.GRAY, true);

GradientPaint gp3 = new GradientPaint(30, 0, 
Color.BLACK, 0, 20, Color.GREEN, true);

Toolkit kit = Toolkit.getDefaultToolkit();

 //Getting the "background.jpg" image we have in the folder
Image background = kit.getImage("D:\\College\\Programs\\ProjectFLAPPY\\src\\projectflappy\\1.png");

JLabel a = new JLabel("Get Ready ! Click to Start.");
JLabel retry = new JLabel(new ImageIcon("D:\\College\\Programs\\ProjectFLAPPY\\src\\projectflappy\\unnamed.png"));

int score = 0;


    //constructor
    public TheGame() throws IOException 
    {

        super("Simple Drawing");

        setSize(x_width, y_height);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        jp = new DrawingPanel();

        add(jp);

        addMouseListener(this);
    }

      ActionListener action = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent ae) {
           update();

           repaint();
        }

     };
    Timer t = new Timer(50,action);   


    public void init()
    {
        x_ball = 30;
        y_ball = 200;

        cord_xup1 = 175; cord_xdown1 = 175;
        cord_xup2 = 320; cord_xdown2 = 320;
        cord_xup3 = 460; cord_xdown3 = 460;
        cord_xup4 = 585; cord_xdown4 = 585;
        cord_xup5 = 700; cord_xdown5 = 700;

       retry.setVisible(false);
            retry.setBounds(175,260,46,46);
            a.setForeground(Color.YELLOW);
            a.setFont(font1);
            a.setVisible(true);
            a.setBounds(105,200,300,100);

  }


    @Override
    public void mouseClicked(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        a.setVisible(false);
        if( flag == false)
        {
            t.stop();

        }
        else
        {
            t.start();

        }
       y_ball = y_ball - 40;
        count--; 


    }

    @Override
    public void mousePressed(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.


    }

    @Override
    public void mouseExited(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    // for drawing on the panel
    class DrawingPanel extends JPanel{
        private static final long serialVersionUID = 1L;

        public DrawingPanel() {
            setPreferredSize(new Dimension(300, 300));
            setLayout(null);
            init();
            add(a);
            add(retry);

           // addMouseListener(this);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D d = (Graphics2D)g;

            d.drawImage(background, -270,-30, this);
            Ball = new Ellipse2D.Double(x_ball,y_ball,30,30);

            d.setColor(Color.green);
            d.setFont(font3);


            up1 = new RoundRectangle2D.Double(cord_xup1,-5,30,175,20,20);
            down1 = new RoundRectangle2D.Double(cord_xdown1,310,30,155,20,20);

            up2 = new RoundRectangle2D.Double(cord_xup2,-5,30,200,20,20);
            down2 = new RoundRectangle2D.Double(cord_xdown2,310,30,175,20,20);

            up3 = new RoundRectangle2D.Double(cord_xup3,-5,30,230,20,20);
            down3 = new RoundRectangle2D.Double(cord_xdown3,350,30,135,20,20);

            up4 = new RoundRectangle2D.Double(cord_xup4,-5,30,115,20,20);
            down4 = new RoundRectangle2D.Double(cord_xdown4,240,30,115,20,20);

            d.setPaint(gp2);
            d.setStroke(color);
            d.fill(up1);
            d.fill(down1);

            d.fill(up2);
            d.fill(down2);

            d.fill(up3);
            d.fill(down3);

            d.fill(up4);
            d.fill(down4);


            d.setPaint(gp3);
            d.setStroke(color);
            d.fill(Ball);
            d.setColor(Color.BLACK);
            d.setFont(font1);
            d.drawString(""+score ,200,50);
            if( Ball.intersects(up1.getBounds()) || Ball.intersects(down1.getBounds()) || Ball.intersects(up2.getBounds()) || Ball.intersects(down2.getBounds()) || Ball.intersects(up3.getBounds()) || Ball.intersects(down3.getBounds()) || Ball.intersects(up4.getBounds()) || Ball.intersects(down4.getBounds()))
        {
            t.stop();
            flag = false;
            d.setColor(Color.red);
            d.setFont(font);
            d.drawString("Game Over : "+score ,100,250);
            retry.setVisible(true);
        }

            retry.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent event) {
            init(); //reset properties
        }

        //...

                @Override
                public void mousePressed(MouseEvent e) {
                 //   throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                   // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                 //   throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }

                @Override
                public void mouseExited(MouseEvent e) {
                   // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                }
    });




        }

    }   
    public void update()
    {

        cord_xdown1 -= 5;
        cord_xup1 -= 5;

        cord_xdown2 -= 5;
        cord_xup2 -= 5;

        cord_xdown3 -= 5;
        cord_xup3 -= 5;

        cord_xdown4 -= 5;
        cord_xup4 -= 5;

        cord_xdown5 -= 5;
        cord_xup5 -= 5;

        if( cord_xup1 <=-20)
        {
            cord_xup1 = 500;
            cord_xdown1 = 500;
        }
        if( cord_xup2 <=-20)
        {
            cord_xup2 = 500;
            cord_xdown2 = 500;
        }
        if( cord_xup3 <=-20)
        {
            cord_xup3 = 500;
            cord_xdown3 = 500;
        }
        if( cord_xup4 <=-20)
        {
            cord_xup4 = 500;
            cord_xdown4 = 500;
        }
        if( cord_xup5 <=-20)
        {
            cord_xup5 = 500;
            cord_xdown5 = 500;
        }

        if(count >= 0)
        {
            y_ball = y_ball - 7;
            count--;

            if( y_ball == y_height)
            {
                t.stop();
            }
        }
        else
        {
            y_ball = y_ball + 7;
            if( y_ball == y_height-70)
            {
                t.stop();
            }
        }

        if(cord_xdown1 == x_ball || cord_xdown2 == x_ball || cord_xdown3 == x_ball || cord_xdown4  == x_ball)
            {   
                score = score+1;

            }

    }



     public static void main(String[] args) throws IOException {
        new TheGame();

    }

}
packageprojectflappy;
导入java.awt.*;
公共最终类游戏扩展JFrame实现MouseStener{
JPanel jp,;
//变量声明
int x_宽度=500;
int y_高度=500;
整数计数=5;
椭圆球;
int x_球;
国际球;
内部跳线xup1,跳线xdown1;
int跳线xup2、跳线xdown2;
内部跳线xup3,跳线xdown3;
内部电源线xup4,电源线xDOW4;
内部跳线xup5,跳线xdown5;
布尔标志=真;
圆形矩形2D向上1、向下1、向上2、向下2、向上3、向下3、向上4、向下4;
Font Font=新字体(“Matura MT脚本大写字母”,字体:罗马字母,40);
Font font1=新字体(“Matura MT脚本大写字母”,字体:罗马字母,20);
Font font3=新字体(“Matura MT脚本大写字母”,字体:罗马字母,20);
浮点das[]={10.0f};
基本行程颜色=新的基本行程(10,基本行程圆帽,基本行程连接斜面,20.0f,das,0.0f);
GradientPaint gp2=新的GradientPaint(20,0,
颜色:深灰色,0,10,颜色:灰色,真);
GradientPaint gp3=新的GradientPaint(30,0,
颜色。黑色,0,20,颜色。绿色,真);
Toolkit kit=Toolkit.getDefaultToolkit();
//获取文件夹中的“background.jpg”图像
Image background=kit.getImage(“D:\\College\\Programs\\ProjectFLAPPY\\src\\ProjectFLAPPY\\1.png”);
JLabel a=新的JLabel(“准备好!单击开始”);
JLabel retry=newjlabel(新图像图标(“D:\\College\\Programs\\ProjectFLAPPY\\src\\ProjectFLAPPY\\unnamed.png”);
智力得分=0;
//建造师
public TheGame()抛出IOException
{
超级(“简单图纸”);
设置尺寸(x_宽度,y_高度);
setDefaultCloseOperation(关闭时退出);
setVisible(真);
jp=新绘图面板();
加(jp);;
addMouseListener(这个);
}
ActionListener动作=新建ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
更新();
重新油漆();
}
};
定时器t=新定时器(50,动作);
公共void init()
{
x_-ball=30;
y_球=200;
跳线xup1=175;跳线xdown1=175;
跳线xup2=320;跳线xdown2=320;
软线xup3=460;软线xdown3=460;
跳线xup4=585;跳线xdown4=585;
跳线xup5=700;跳线xdown5=700;
retry.setVisible(false);
重试.setBounds(175260,46,46);
a、 设置前景(颜色:黄色);
a、 setFont(font1);
a、 setVisible(真);
a、 立根(105200300100);
}
@凌驾
公共无效mouseClicked(MouseEvent e){
//抛出新的UnsupportedOperationException(“尚未受支持”);//若要更改生成的方法体,请选择“工具”“模板”。
a、 setVisible(假);
如果(标志==false)
{
t、 停止();
}
其他的
{
t、 start();
}
y球=y球-40;
计数--;
}
@凌驾
公共无效鼠标按下(MouseEvent e){
//抛出新的UnsupportedOperationException(“尚未受支持”);//若要更改生成的方法体,请选择“工具”“模板”。
}
@凌驾
公共无效MouseEvent(MouseEvent e){
//抛出新的UnsupportedOperationException(“尚未受支持”);//若要更改生成的方法体,请选择“工具”“模板”。
}
@凌驾
公共无效鼠标事件(鼠标事件e){
//抛出新的UnsupportedOperationException(“尚未受支持”);//若要更改生成的方法体,请选择“工具”“模板”。
}
@凌驾
公共无效mouseExited(MouseEvent e){
//抛出新的UnsupportedOperationException(“尚未受支持”);//若要更改生成的方法体,请选择“工具”“模板”。
}
//用于在面板上绘制
类DrawingPanel扩展了JPanel{
私有静态最终长serialVersionUID=1L;
公共绘图面板(){
setPreferredSize(新尺寸(300300));
setLayout(空);
init();
添加(a);
添加(重试);
//addMouseListener(这个);
}
@凌驾
公共组件(图形g){
超级组件(g);
图形2d=(图形2d)g;
d、 drawImage(背景,-270,-30,此);
Ball=新的椭圆E2D.双(x_-Ball,y_-Ball,30,30);
d、 setColor(Color.green);
d、 setFont(font3);
up1=新的圆形矩形2D.双(跳线xup1,-5,30175,20,20);
down1=新的圆形矩形2D.双(跳线直径1310,30155,20,20);
up2=新的圆形矩形2D.双(跳线xup2,-5,30200,20,20);
down2=新的圆形矩形2D.双(跳线\u xDOW2310,30175,20,20);
up3=新的圆形矩形2D.双(跳线xup3,-5,30230,20,20);
down3=新的圆形矩形2D.双(跳线向下3350,30135,20,20);
up4=新的圆形矩形2D.双(跳线xup4,-5,30115,20,20);
down4=新的圆形矩形2D.双(线下4240,30115,20,20);
d、 setPaint(gp2);
d、 设定行程(颜色);
d、 填充(up1);
d、 填充(向下1);
d、 填充(up2);
d、 填充(向下2);
d、 填充(up3);
d、 填充(向下3);
d、 填充(up4);
d、 填充(向下4);
d、 setPaint(gp3);
d、 设定行程(颜色);
d、 填充(球);
d、 设置颜色(颜色为黑色);
d、 setFont(font1);
d、 抽绳(“+”分数,200,50);
if(Ball.intersects(up1.getBounds())| Ball.intersects(down1.getBounds())| Ball.intersects(up2.getBounds())| Ball.intersects(up3.getBounds())| Ball.intersects(down3.getBounds())| Ball.intersects(up4.getBounds())| Ball.intersects(down4.getBounds())
{
t、 停止();
flag=false;
d、 setColor(Color.red);
import java.awt.*;
import java.awt.event.*;

 public class ResetTest extends Frame{

Button b;
TextField tf;
Frame f;
Panel p;

public ResetTest(){
    f=this;  //intialize frame f to this to have access to our frame in event handler methods
    resetAll(); //first time call to resetAll will initialize all the parameters of the frame
    f.pack();
    addWindowListener(new WindowAdapter(){

        public void windowClosing(WindowEvent we){
            System.exit(0);
        }

    });


    this.setLayout(new FlowLayout(FlowLayout.CENTER,20,20));
    this.setVisible(true);

}

/**
This method will be called on click of button to 
reset all the parameters of the frame so that we
get fresh new frame, everything as it was before.
**/
public void resetAll(){
    b=new Button("Reset");
    p=new Panel(new FlowLayout(FlowLayout.CENTER,20,20));
    p.add(b);
    tf = new TextField("Edit And Reset");
    p.add(tf);

    b.addActionListener(new ActionListener(){

        public void actionPerformed(ActionEvent ae){
            remove(p); //remove the panel that contains all our components
            resetAll(); // reset all the components
            f.pack(); //refreshes the view of frame when everything is reset.
        }

    });

        add(p);     
    }
}

class NewClass{
    public static void main(String[] args) {
         ResetTest fReset = new ResetTest();
    }
}
//Contains the properties that will change during gameplay
void init() {
    retry.setVisible(false);
    a.setForeground(Color.YELLOW);
    //...
}
public DrawingPanel() {
    setPreferredSize(new Dimension(300, 300));
    setPreferredSize(new Dimension(300, 300));
    setLayout(null);

    init(); //sets properties
    a.setFont(font1);
    a.setVisible(true);
    a.setBounds(105,200,300,100);
    add(a);

    retry.setBounds(175,260,46,46);
    retry.addMouseListener(new MouseListener() {
        public void mouseClicked(MouseEvent event) {
            init(); //reset properties
        }

        //...
    });
    add(retry);            
}
public class Launcher {
    public static void main(String[] args) throws IOException {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setResizable(false);
                frame.add(new TheGame());
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }
}
@SuppressWarnings("serial")
public final class TheGame extends JPanel implements MouseListener, ActionListener {
    public static final int WIDTH = 500, HEIGHT = 500;

    private final String START_SCORE = "0", 
            START_MESSAGE = "Get Ready ! Click to Start.",
            BACKGROUND_URL = "/res/flappy.png";

    private boolean currentlyPlaying, readyToJump, isAlive = true;
    private int score;

    private Timer timer;
    private Image background;
    private GameLabel messageLabel, scoreLabel;
    private Collection<Obstacle> obstaclesInOrder;
    private LinkedList<Obstacle> obstacles;
    private Ball ball;

    public TheGame() {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));

        addMouseListener(this);
        timer = new Timer(50, this);

        background = loadBackgroundImage();
        messageLabel = new GameLabel(START_MESSAGE, 150, 240);
        scoreLabel = new GameLabel(START_SCORE, 250, 60);

        obstacles = new LinkedList<>();
        obstacles.removeAll(obstacles);
        obstaclesInOrder = Arrays.asList(new Obstacle(175, 20, 45), new Obstacle(320), new Obstacle(460), new Obstacle(585), new Obstacle(700));
        obstacles.addAll(obstaclesInOrder);
        ball = new Ball(30, 100);
    }


    @Override
    public void mouseClicked(MouseEvent e) {
        if (!currentlyPlaying) {
            startGame();
        } else if (!isAlive) {
            reset();
        }

        readyToJump = true;
    }

    private void startGame() {
        currentlyPlaying = true;
        messageLabel.update("");
        timer.start();
    }

    private void endGame() {
        isAlive = false;
        scoreLabel.update("");
        messageLabel.update("Game Over. Your score was " + Integer.toString(score));
        timer.stop();
    }

    private void reset() {
        ball.reset();
        for (Obstacle obstacle : obstacles)
            obstacle.reset();

        messageLabel.update(START_MESSAGE, 150, 240);
        scoreLabel.update(START_SCORE, 250, 60);

        obstacles.removeAll(obstacles);
        obstacles.addAll(obstaclesInOrder);

        score = 0;
        isAlive = true;
        currentlyPlaying = false;
        repaint();
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        update();
        repaint();
    }

    private void update() {
        if (isAlive) {
            updateBallPosition();
            updateObstaclePositions();

            if(ballOutOfBounds() || playerCollidedWithObstacle()) {
                endGame();
            } else if(ballPassedObstacle()) {
                addToScore();
                setupNextObstacle();
            }
        }
    }

    private void updateBallPosition() {
        if (readyToJump) {
            readyToJump = false;
            ball.jump();
        } else {
            ball.fall();
        }
    }

    private void updateObstaclePositions() {
        for (Obstacle obstacle : obstacles) {
            if (obstacle.getX() <= -obstacle.getWidth()) {
                obstacle.moveToBack();
                continue;
            }

            obstacle.moveForward();
        }
    }

    private void addToScore() {
        scoreLabel.update(Integer.toString(++score));
    }

    private void setupNextObstacle() {
        obstacles.addLast(obstacles.removeFirst());
    }

    private boolean ballOutOfBounds() {
        return ball.getY() >= HEIGHT || ball.getY() <= 0;
    }

    private boolean ballAtObstacle() {
        Obstacle currentObstacle = obstacles.getFirst();
        return ball.getX() + ball.getWidth() >= currentObstacle.getX() && ball.getX() <= currentObstacle.getX() + currentObstacle.getWidth();
    }

    private boolean ballPassedObstacle() {
        Obstacle currentObstacle = obstacles.getFirst();

        return ball.getX() >= (currentObstacle.getX() + currentObstacle.getWidth());
    }

    private boolean playerCollidedWithObstacle() {
        boolean collided = false;

        if(ballAtObstacle()) {
                for (Obstacle obstacle : obstacles) {
                    RoundRectangle2D top = obstacle.getTop();
                    RoundRectangle2D bottom = obstacle.getBottom();

                    if (ball.intersects(top.getX(), top.getY(), top.getWidth(), top.getHeight()) || ball.intersects(bottom.getX(), bottom.getY(), bottom.getWidth(), bottom.getHeight())) {
                        collided = true;
                    }
                }
        }

        return collided;
    }

    private Image loadBackgroundImage() {
        Image background = null;
        URL backgroundPath = getClass().getResource(BACKGROUND_URL);

        if(backgroundPath == null) {
            background = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        } else {
            try {
                background = ImageIO.read(backgroundPath);
            } catch (IOException e) {
                e.printStackTrace();
            }
       }

        return background;
    }

    @Override
    public void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);
        Graphics2D g = (Graphics2D) graphics;

        g.drawImage(background, 0, 0, null);
        ball.paint(g);
        for (Obstacle obstacle : obstacles)
            obstacle.paint(g);

        scoreLabel.paint(g);
        messageLabel.paint(g);
    }

    //...
}
private void update() {
    if (ballOutOfBounds() || playerCollidedWithObstacle()) {
        endGame();
    } else if (ballPassedObstacle()) {
        addToScore();
        setupNextObstacle();
    }


    updateBallPosition();
    updateObstaclePositions();
}
private boolean playerCollidedWithObstacle() {
    boolean collided = false;

    if (ballAtObstacle()) {
        for (Obstacle obstacle : obstacles) {
            RoundRectangle2D top = obstacle.getTop();
            RoundRectangle2D bottom = obstacle.getBottom();

            if (ball.intersects(top.getX(), top.getY(), top.getWidth(), top.getHeight()) || ball.intersects(bottom.getX(), bottom.getY(), bottom.getWidth(), bottom.getHeight())) {
                collided = true;
            }
        }
    }

    return collided;
}
public class GameLabel {
    private String message;
    private Font font;
    private Color color;

    private int x, y;

    public GameLabel(String message, int x, int y, Color color, Font font) {
        update(message, x, y, color, font);
    }

    public GameLabel(String message, int x, int y) {
        this(message, x, y, Color.BLACK, new Font("Matura MT Script Capitals", Font.ROMAN_BASELINE, 20));
    }

    public GameLabel() {
        this("", 0, 0);
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public void setFont(Font font) {
        this.font = font;
    }

    public final void update(String message, int x, int y, Color color, Font font) {
        this.message = message;
        this.x = x;
        this.y = y;
        this.color = color;
        this.font = font;
    }

    public void update(String message, int x, int y) {
        update(message, x, y, color, font);
    }

    public void update(String message) {
        update(message, x, y);
    }

    public void paint(Graphics2D g) {
        g.setFont(font);
        g.setColor(color);
        g.drawString(message, x, y);
    }

    public Font getFont() {
        return font;
    }

    public Color getColor() {
        return color;
    }

    public String getMessage() {
        return message;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}
public class Obstacle {
    public static final int DEFAULT_TOP_HEIGHT = 175;
    public static final int DEFAULT_BOTTOM_HEIGHT = 175;
    public static final int DEFAULT_WIDTH = 30;
    public static final int DEFAULT_ARCH_WIDTH = 20;
    public static final int DEFAULT_ARCH_HEIGHT = 20;
    public static final int DEFAULT_TOP_INSET = -5;
    public static final int DEFAULT_BOTTOM_INSET = TheGame.HEIGHT + 5;

    private RoundRectangle2D top, bottom;
    private BasicStroke stroke;
    private GradientPaint gradient;
    private int initialX, x, width;

    public Obstacle(int x, int width, int topHeight, int bottomHeight) {
        this.x = initialX = x;
        this.width = width;

        top = new RoundRectangle2D.Double(x, DEFAULT_TOP_INSET, width, topHeight, DEFAULT_ARCH_WIDTH, DEFAULT_ARCH_HEIGHT);
        bottom = new RoundRectangle2D.Double(x, DEFAULT_BOTTOM_INSET-bottomHeight, width, bottomHeight, DEFAULT_ARCH_WIDTH, DEFAULT_ARCH_HEIGHT);

        stroke = new BasicStroke(10, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 20.0f, new float[] { 10.0f }, 0.0f);
        gradient = new GradientPaint(20, 0, Color.DARK_GRAY, 0, 10, Color.GRAY, true);
    }

    public Obstacle(int x, int topHeight, int bottomHeight) {
        this(x, DEFAULT_WIDTH, topHeight, bottomHeight);
    }

    public void reset() {
        x = initialX;
        top.setRoundRect(initialX, top.getY(), top.getWidth(), top.getHeight(), top.getArcWidth(), top.getArcHeight());
        bottom.setRoundRect(initialX, bottom.getY(), bottom.getWidth(), bottom.getHeight(), bottom.getArcWidth(), bottom.getArcHeight());
    }

    public Obstacle(int x, int width) {
        this(x, width, DEFAULT_TOP_HEIGHT, DEFAULT_BOTTOM_HEIGHT);
    }

    public Obstacle(int x) {
        this(x, DEFAULT_WIDTH);
    }

    public void moveToBack() {
        x = 600;
    }

    public void moveForward() {
        x -= 5;
        top.setRoundRect(x, top.getY(), top.getWidth(), top.getHeight(), top.getArcWidth(), top.getArcHeight());
        bottom.setRoundRect(x, bottom.getY(), bottom.getWidth(), bottom.getHeight(), bottom.getArcWidth(), bottom.getArcHeight());
    }

    public RoundRectangle2D getTop() {
        return top;
    }

    public RoundRectangle2D getBottom() {
        return bottom;
    }

    public int getX() {
        return x;
    }

    public int getWidth() {
        return width;
    }

    public void paint(Graphics2D g) {
        g.setPaint(gradient);
        g.setStroke(stroke);
        g.fill(top);
        g.fill(bottom);
    }
}
public class Ball {
    public static final int DEFAULT_DROP_SPEED = 7;

    private Ellipse2D ball;
    private GradientPaint gradient;
    private int initialY, x, y, width = 30, height = 30, dropSpeed = DEFAULT_DROP_SPEED;

    public Ball(int x, int y) {
        this.x = x;
        this.y = initialY = y;
        width = height = 30;

        ball = new Ellipse2D.Double(x, y, width, height);
        gradient = new GradientPaint(30, 0, Color.BLACK, 0, 20, Color.GREEN, true);
    }

    public void reset() {
        y = initialY;
        updateBall();
    }

    public void jump() {
        dropSpeed = DEFAULT_DROP_SPEED;
        y -= 40;
        updateBall();
    }

    public void fall() {
        y += dropSpeed++;
        updateBall();
    }

    private void updateBall() {
        ball.setFrame(x, y, width, height);
    }



    public boolean intersects(double x, double y, double w, double h) {
        return ball.intersects(x, y, w, h);
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return width;
    }

    public void paint(Graphics2D g) {
        g.setPaint(gradient);
        g.fill(ball);
    }

    public void moveForward() {
        x += 7;
    }
}