[英]Add moving objects to JFrame
我正在创建一个Java游戏。 游戏中有英雄和泡沫。 当我按箭头键时,英雄应该移动,并且气泡应该有连续的对角线移动。 当我分别将英雄或气泡直接添加到JFrame
会获得所需的行为,但是当我将它们都添加时,我只会得到一个很小的正方形! 我试图将它们添加到相同的JPanel
,然后将该JPanel
添加到JFrame
但是它不起作用。 可能我必须为JPanel
定义某种类型的布局。
我究竟做错了什么?
码:
public class Pang {
public static void main(String[] args) {
JFrame f=new JFrame();
JPanel gamePanel=new JPanel();
gamePanel.setPreferredSize(new Dimension(800, 600));
DrawHero d=new DrawHero();
DrawBubble bubble=new DrawBubble();
gamePanel.add(d);
gamePanel.add(bubble);
f.add(gamePanel);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800, 600);
}
}
public class DrawHero extends JPanel implements ActionListener, KeyListener {
Timer myTimer = new Timer(5, this);
int x = 0, y = 0, dx = 0, dy = 0, step = 10;
private transient Image imageHero = null;
public DrawHero() {
myTimer.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
imageHero = getHeroImage();
g2.drawImage(imageHero, x, y, 40, 40, null);
}
public Image getHeroImage() {
Image image = null;
image = getImage("hero.png");
return image;
}
public Image getImage(String path) {
Image tempImage = null;
try {
URL heroiURL = DrawHero.class.getResource(path);
tempImage = Toolkit.getDefaultToolkit().getImage(heroiURL);
} catch (Exception e) {
System.out.println("Error loading hero image! - "
+ e.getMessage());
}
return tempImage;
}
public void actionPerformed(ActionEvent e) {
repaint();
}
public void moveUp() {
y = y - step;
}
public void moveDown() {
y = y + step;
}
public void moveLeft() {
x = x - step;
}
public void moveRight() {
x = x + step;
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP) {
moveUp();
}
if (keyCode == KeyEvent.VK_DOWN) {
moveDown();
}
if (keyCode == KeyEvent.VK_LEFT) {
moveLeft();
}
if (keyCode == KeyEvent.VK_RIGHT) {
moveRight();
}
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
public class DrawBubble extends JPanel implements ActionListener, KeyListener {
Timer myTimer = new Timer(5, this);
int x = 100, y = 200, dx = 0, dy = 0, step = 10;
private transient Image imageHero = null;
public DrawBubble() {
myTimer.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(new Ellipse2D.Double(x, y, 40, 40));
}
public void actionPerformed(ActionEvent e) {
x=x+dx;
y=y+dy;
repaint();
}
public void moveBubble() {
dy=2;
dx=2;
}
public void keyPressed(KeyEvent e) {
moveBubble();
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
当我分别将英雄或气泡直接添加到JFrame中时,会得到所需的行为,但是当我将它们都添加时,我只会得到一个很小的正方形!
JFrame的默认布局管理器是BorderLayout。 当您使用没有约束的add(component)时,组件将转到CENTER。 只能将一个组件添加到CENTER,因此仅显示最后一个添加的组件。
我试图将它们添加到相同的JPanel中,然后将该JPanel添加到JFrame中,但是它不起作用。
JPanel的默认布局管理器是FlowLayout,它遵循组件的首选大小。 问题是您不重写getPreferredSize()
方法,因此大小为(0,0),没有任何内容可绘制。
可能我必须为JPanels定义某种类型的布局。
实际上,由于需要随机运动,因此需要在面板上使用null布局,然后使用组件的setSize()
和setLocation()
方法来放置组件。
然后,当您执行此操作时,自定义绘制应始终在(0,0)而不是(x,y)进行,因为该位置将控制组件在面板上的绘制位置。
我建议DrawHero
或DrawBubble
(分别称为Hero
或Bubble
)都不应扩展任何JComponent
。 相反,每个人都应该简单地知道如何在请求时将自己绘制到传递给它的Graphics
对象。
然后,一个GameField
或PlayingArea
类应保留对所有Bubble
对象和Hero
引用,然后draw调用这些对象的draw(Graphics)
方法。
使用这种方法,不必担心GameField
组件内的布局(它们变得无关紧要)。
这就是我对[ 具有复杂形状的碰撞检测]的 答案中渲染静止对象的基本策略。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.