繁体   English   中英

如何使用Java绘制的球从面板边缘反弹?

[英]How to make ball drawn with Java bounce off the edges of the panel?

我有一个在扩展 JPanel 类的类中绘制一个红球的 Java 代码,我有一个由一个按钮启用的计时器,该按钮使用计时器 ctor 变量 elapse 更新球的位置。 我试图获得面板的高度和绘制圆圈的 YPOSITION 的差异,如果它小于 0,则弹跳球需要继续向下移动,否则它应该向上移动,我的球撞到墙上并继续击中它. 帮助我调试导致这种情况发生的代码。 右面板类

import javax.swing.*;
import java.awt.*;

public class RightPanel extends JPanel {
    //define the position where the circle will be drawn
    private int positionX=150;
    private int positionY=150;
    private int radius=100;//as the shape is a circle
    //override the paint method to draw the bounce ball on the second panel


    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d= (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.RED);
        g2d.fillOval(positionX,positionY,radius,radius);
    }
     //let's us update the position of the ball from another class
    public int getPositionY(){
    public void setPositionX(int positionX) {
        this.positionX = positionX;
    }
    public void setPositionY(int positionY){
        this.positionY=positionY;
    }
    
    public int getPositionX(){
        return this.positionX;
    }
   
        return this.positionY;
    }
}

下面计时器类中的逻辑是我需要GameInterface 类帮助的逻辑

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;

public class GameInterface extends JFrame {
    //declare a Timer object to start the movement
    Graphics ctx;
    RightPanel rightpanel;
    private int height;
    //declare a timer to start moving the ball
    Timer mytimer= new Timer(50, new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            //check this and keep moving the ball down
            if(rightpanel.getPositionY()- rightpanel.getHeight()<0){

                rightpanel.setPositionY(rightpanel.getPositionY()+5);
                rightpanel.paint(rightpanel.getGraphics());
            }else{

            //move the ball up
                rightpanel.setPositionY(rightpanel.getPositionY()-5);
                rightpanel.paint(rightpanel.getGraphics());
            }


        }
    });
    public GameInterface(){
        setSize(new Dimension(800, 600));
        height=this.getHeight();
        setResizable(false);
        setTitle("Bounce Game");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBackground(Color.black);
        //define a new JSplitPane and use it to add two JPanels
        JPanel leftpanel= new JPanel();
        //add buttons to the left panel programatically
        JButton up= new JButton("Move up");
        //set the event listeners for the buttons
        up.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //start he timer
                mytimer.start();


            }
        });
        JButton down = new JButton("Move down");
        down.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //move my ball down
                rightpanel.setPositionX(rightpanel.getPositionX());
                rightpanel.setPositionY(rightpanel.getPositionY()+5);
                rightpanel.paint(rightpanel.getGraphics());

            }
        });
        leftpanel.add(up);
        leftpanel.add(down);
        rightpanel= new RightPanel();
        JSplitPane splitpane= new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftpanel,rightpanel);
        this.add(splitpane);
        setVisible(true);
        ctx=this.getGraphics();

    }
}

基本思想是,当你“放下”球时,你需要确定球应该移动的运动方向。当timer滴答作响时,它将应用该运动方向,直到它到达底部,此时三角洲被反转,或者它到达顶部。

这里重要的部分是, timer需要的所有状态都应该在timer启动之前确定,而不是在timer本身内计算,因为它需要的状态不再相关。

例如...

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Ball ball = new Ball(20);
                JFrame frame = new JFrame();
                frame.add(new MainPane(ball));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Ball {
        private Point location;
        private Dimension size;
        private Shape shape;

        public Ball(int radius) {
            location = new Point(0, 0);
            size = new Dimension(radius * 2, radius * 2);
            shape = new Ellipse2D.Double(0, 0, radius * 2, radius * 2);
        }

        public Rectangle getBounds() {
            return new Rectangle(location, size);
        }

        public void setLocation(Point p) {
            location = new Point(p);
        }

        public void paint(Graphics2D g2d) {
            g2d = (Graphics2D) g2d.create();
            g2d.setColor(Color.RED);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.translate(location.x, location.y);
            g2d.fill(shape);
            g2d.dispose();
        }
    }

    public class SurfacePane extends JPanel {

        private Ball ball;
        private Timer timer;
        private int yDelta;

        public SurfacePane(Ball ball) {
            this.ball = ball;
            this.ball.setLocation(new Point(200 - (ball.getBounds().width / 2), 0));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            ball.paint(g2d);
            g2d.dispose();
        }

        public void moveBallDown() {
            Rectangle bounds = ball.getBounds();
            Dimension size = ball.size;
            Point location = bounds.getLocation();
            location.y += size.height;
            if (location.y + size.height > getHeight()) {
                location.y = getHeight() - size.height;
            }
            ball.setLocation(location);
            repaint();
        }

        public void dropBall() {
            if (timer != null) {
                return;
            }
            Rectangle bounds = ball.getBounds();
            Dimension size = ball.size;
            Point location = bounds.getLocation();
            if (location.y + size.height > getHeight()) {
                yDelta = -1;
            } else {
                yDelta = 1;
            }

            timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Rectangle bounds = ball.getBounds();
                    Dimension size = ball.size;
                    Point location = bounds.getLocation();
                    location.y += yDelta;
                    if (location.y < 0) {
                        location.y = 0;
                        yDelta = 0;
                        timer.stop();
                        timer = null;
                    } else if (location.y + size.height > getHeight()) {
                        location.y = getHeight() - size.height;
                        yDelta *= -1;
                    }
                    ball.setLocation(location);
                    repaint();
                }
            });
            timer.start();
        }
    }

    public class MainPane extends JPanel {

        private Ball ball;
        private SurfacePane surfacePane;

        public MainPane(Ball ball) {
            setLayout(new BorderLayout());
            this.ball = ball;
            surfacePane = new SurfacePane(ball);
            add(surfacePane);

            JPanel actionPane = new JPanel(new GridBagLayout());
            JButton up = new JButton("Up");
            JButton down = new JButton("Down");

            actionPane.add(up);
            actionPane.add(down);

            add(actionPane, BorderLayout.SOUTH);

            up.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    surfacePane.dropBall();
                }
            });
            down.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    surfacePane.moveBallDown();
                }
            });
        }

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM