簡體   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