反转 JFrame 边界
Reversing JFrame Bounds
我正在尝试做一个弹跳球。设置的边界允许球在超出框架边界后从起点开始。我无法让球反弹。一旦击中边界(框架的外侧边缘),我如何让球反弹?我认为问题出在 moveBall() 方法中。
主要Class
导入 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);
}
}
第 2 class
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);
}
}
第 3 class
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);
}
}
第 4 class
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;
}
}
_xComonent
是球组件框的左上角。所以从右边到边界的底部 "detect collision" 你必须
if(_xComponent+ball.width >= bounds.width)
而不是
if(_xComponent >= bounds.width)
.
对于底部的高度 "collide" 也必须这样做。
可以直接检测顶部和左侧碰撞。
现在另一件事是,当你反转你的 _xComponent
而不是从 /add 中减去它时,你将立即移动你的 "ball" 的边界。请记住 (0,0)
是 compoent/screen 的左上角,而不是它的中心。所以基本上点的所有负分量都会导致屏幕外的绘图。
在这里,您直接从 Oracle 获得了有关 Swing 坐标系的一些信息。
https://docs.oracle.com/javase/tutorial/2d/overview/coordinate.html
您需要倒车的速度(步数)。
假设边界是相对的,在 (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
的缩写)
我正在尝试做一个弹跳球。设置的边界允许球在超出框架边界后从起点开始。我无法让球反弹。一旦击中边界(框架的外侧边缘),我如何让球反弹?我认为问题出在 moveBall() 方法中。
主要Class 导入 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);
}
}
第 2 class
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);
}
}
第 3 class
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);
}
}
第 4 class
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;
}
}
_xComonent
是球组件框的左上角。所以从右边到边界的底部 "detect collision" 你必须
if(_xComponent+ball.width >= bounds.width)
而不是
if(_xComponent >= bounds.width)
.
对于底部的高度 "collide" 也必须这样做。 可以直接检测顶部和左侧碰撞。
现在另一件事是,当你反转你的 _xComponent
而不是从 /add 中减去它时,你将立即移动你的 "ball" 的边界。请记住 (0,0)
是 compoent/screen 的左上角,而不是它的中心。所以基本上点的所有负分量都会导致屏幕外的绘图。
在这里,您直接从 Oracle 获得了有关 Swing 坐标系的一些信息。 https://docs.oracle.com/javase/tutorial/2d/overview/coordinate.html
您需要倒车的速度(步数)。
假设边界是相对的,在 (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
的缩写)