【问题标题】:Reversing JFrame Bounds反转 JFrame 边界
【发布时间】:2015-11-23 13:10:11
【问题描述】:

我正在尝试制作一个弹跳球。设置的边界允许球在超出框架边界后从起点开始。我无法让球反弹。一旦击中边界(框架的外部边缘),我如何让球反弹?我相信问题出在 moveBall() 方法上。

主类 导入 javax.swing.JFrame;

public class MainForm {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        MainFrame mainFrame = new MainFrame();
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setSize(220, 270);
        mainFrame.setVisible(true);
    }

}

二等

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainFrame extends JFrame {

    private CustomPanel _panel;

    public MainFrame()
    {
        super("Bouncing Ball");

        _panel = new CustomPanel();
        add(_panel, BorderLayout.CENTER);
    }
}

第三类

import java.awt.Graphics;
import javax.swing.JPanel;


public class CustomPanel extends JPanel{

    private final BouncingBall _ball1;
    private final BouncingBall _ball2;
    private final BouncingBall _ball3;

    public CustomPanel ()
    {
        _ball1 = new BouncingBall(this, 20, 3);
        Thread thread1 = new Thread(_ball1);
        _ball2 = new BouncingBall(this, 40, 6);
        Thread thread2 = new Thread(_ball2);
        _ball3 = new BouncingBall(this, 60, 9);
        Thread thread3 = new Thread(_ball3);

        thread1.start();
        thread2.start();
        thread3.start();
    }

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

        _ball1.draw(g);
        _ball2.draw(g);
        _ball3.draw(g);
    }
}

第四课

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;


public class BouncingBall implements Runnable {

    private JPanel _panel;
    private int _xComponent;
    private int _yComponent;
    private int _sleepDelay;

    public BouncingBall(JPanel panel, int startingYPosition, int sleepDelay)
    {
        _panel = panel;
        _xComponent = 0;
        _yComponent = startingYPosition;
        _sleepDelay = sleepDelay;
    }

    @Override
    public void run()
    {
        while(true)
        {
            try
            {
                Thread.sleep(_sleepDelay);

                moveBall();
                _panel.repaint();
            }

            catch (InterruptedException ex)
            {
                Logger.getLogger(BouncingBall.class.getName()).log(Level.SEVERE,null, ex);
            }
        }
    }

    public void draw(Graphics g)
    {
        g.setColor(new Color(255, 0, 0));
        g.fillOval(_xComponent, _yComponent, 20, 20);
    }

    private void moveBall()
    {
        _xComponent += 2;

        Rectangle bounds = _panel.getBounds();

        if(_xComponent >= bounds.width)
            _xComponent = -_xComponent;
    }
}

【问题讨论】:

    标签: java swing concurrency bounds


    【解决方案1】:

    你需要倒转速度(步数)。

    假设边界是相对的,在 (0, 0) 处,并且从边界内开始。

        x += dx;
        y += dy;
    
        if (x < 0 || x > bounds.width) {
            dx = -dx;
            x += dx;
        }
        if (y < 0 || y > bounds.height) {
            dy = -dy;
            y += dy;
        }
    

    x_xComponent 的简写)

    【讨论】:

    • dx 和 dy 代表什么?
    • 因此,当我反转代码时,我要么没有帧,要么在窗格右侧停止或闪烁球。还是没有反转。 _xComponent += 2;矩形边界 = _panel.getBounds(); if(_xComponent + 20 = bounds.width) { _xComponent = -2; _xComponent += 2;
    • 不,引入一个新字段int dx = 2;(速度向量)。到达右侧时,它将被设置为 -2,因此当调用 _xComponent += dx; 时,它会向后移动。
    【解决方案2】:

    _xComonent 是球元件框的左上角。因此,要从边界的右侧和底部“检测碰撞”,您必须

    if(_xComponent+ball.width &gt;= bounds.width)

    代替

    if(_xComponent &gt;= bounds.width).

    必须对高度进行相同操作才能与底部“碰撞”。 可以直接检测顶部和左侧碰撞。

    现在另一件事是,当您反转您的 _xComponentinsteed 从 /add 减去它时,您将立即移动您的绑定“球”。请记住,(0,0) 是组件/屏幕的左上角,而不是它的中心。所以基本上所有负点的分量都会导致屏幕外绘制。

    在这里,您可以直接从 Oracle 获得一些有关 Swing 坐标系的信息。 https://docs.oracle.com/javase/tutorial/2d/overview/coordinate.html

    【讨论】:

    • 我没有可以使用 if(_xComponent+ball.width) 的球变量。我也不明白第二部分。好吧,如果我加/减它会使它超出界限,这是有道理的。那么如何操纵框架以使球反转方向的边界?
    • 你没有ball.width,但根据g.fillOval(_xComponent, _yComponent, 20, 20);,你的球是20 px w/h 首先你需要明白你看到的并不是组件的实际。因此,例如,您的球组件不是椭圆形,而是在其中绘制了椭圆形而没有任何背景的矩形。
    • 我的 ide 无法识别命令 ball.width。如果我发布整个代码会有帮助吗?我有 4 个文件。
    猜你喜欢
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    相关资源
    最近更新 更多