我为JPanel奋斗,getWidth和getHeight [已解决]

问题描述 投票:0回答:1

所以我昨天开始了这个“项目”,我想尝试一个程序,其中一个立方体与Windows边框碰撞。看起来很简单。

但是,我在边界上挣扎。我似乎无法在窗口的右侧和底部获得“完美的”碰撞。多维数据集总是超出预期。

我会认为问题与我设置窗口大小的方式有关?我不确定,但我确实尝试了一些更改,但没有成功。

这里是代码:

package spritesInJava;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.ImageObserver;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Game {

public static JFrame myGame;
public static Timer timer;

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {


        public void run() {
            createGame();
            timer.start();

        }


    });

}
public static void createGame() {

    myGame = new JFrame("Felicia");
    myGame.add(new MyPanel());
    myGame.pack();
    myGame.setSize(new Dimension(1000,1000));
    myGame.setPreferredSize(new Dimension(1000,1000));
    myGame.setVisible(true);
    myGame.setDefaultCloseOperation(1);
    MyPanel.loadImage();
}


}
class MyPanel extends JPanel implements ActionListener {

private static Image image; //Sprite
private static final long serialVersionUID = 1251340649341903871L;
private static ImageObserver observer;
private  int x = 50;
private int y = 50;
private int width = 200;
private int height = 100;
private int speedx = 2;
private int speedy = 2;

MyPanel() {

    Game.timer = new Timer(10,this);


}
@Override
public void actionPerformed(ActionEvent e) {

    int screenWidth = Game.myGame.getWidth();
    int screenHeight = Game.myGame.getHeight();
    x+=speedx;
    y+=speedy;

    if(x >= screenWidth - width) {
        speedx = -speedx;

    }
    else if(x < 0 ) {
        speedx = -speedx;


    }

    if(y >= screenHeight- height ) {

        speedy = -speedy;
    }
    else if(y < 0 ) {
        speedy = -speedy;

    }

    repaint();

}
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    //g.drawImage(image, x, y,width,height,observer);   //Uses the image that was loaded below and draws it.
    g.fillRect(x, y, width, height);
}

public static void loadImage() {    //Load the image
    ImageIcon icon = new ImageIcon("photos/Felicia.png");
    image = icon.getImage();    //Set the "temp" ImageIcon icon to the public ImageIcon
}


}

该多维数据集应该到达4个边界之一,然后更改为“ -speed”,因此,如果速度为5,则速度应为相反的总和(负),反之亦然。这可行,但为时已晚。我制作的碰撞系统似乎不起作用

很抱歉将所有代码放在一个类中!

提前感谢!

java jpanel
1个回答
2
投票

所以,立即,这似乎是错误的...

myGame.add(new MyPanel());
myGame.pack();
myGame.setSize(new Dimension(1000, 1000));
myGame.setPreferredSize(new Dimension(1000, 1000));
myGame.setVisible(true);

您在设置/确定了首选大小之前的窗口pack,这意味着窗口将要假定可能的最小大小(因为内容的preferredSize默认为0x0

您应该避免一般性地调用setPreferredSize,但我尤其要避免在JFrame上使用它。

为什么?因为JFrame具有装饰物(窗口标题和边框),这些装饰物已插入窗口中,所以可见的尺寸实际上是frameSize - decorationInsets,这稍后成为问题的核心。

因此,我将在getPreferredSize中覆盖MyPanel并指定组件的“可见”范围

class MyPanel extends JPanel implements ActionListener {

    //...

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

然后在您的主班级中,您可以...

myGame = new JFrame("Felicia");
myGame.add(new MyPanel());
myGame.pack();
myGame.setVisible(true);

API将为您解决这个问题。

好,转到下一个问题...

public void actionPerformed(ActionEvent e) {

    int screenWidth = Game.myGame.getWidth();
    int screenHeight = Game.myGame.getHeight();

Game.myGameJFrame,您要询问窗口的大小,但是正如我之前说的,框架具有装饰物,这些装饰物嵌入到框架中,从而减小了组件可用的可视区域。相反,您应该使用组件本身的大小]

public void actionPerformed(ActionEvent e) {

    int screenWidth = getWidth();
    int screenHeight = getHeight();

一些建议...

我认为需要这些...

public static JFrame myGame;
public static Timer timer;

但是我在使用static时有问题;)。设置为myGame static使“轻松”从代码中没有任何责任的位置访问其功能。

Timer在这种情况下有些争论,但是我可能很想拥有一个封装了它的“更新引擎”和过度更新工作流程,但这就是我;)

我认为这不是必需的(是static

public static void loadImage() {    //Load the image
    ImageIcon icon = new ImageIcon("photos/Felicia.png");
    image = icon.getImage();    //Set the "temp" ImageIcon icon to the public ImageIcon
}

该功能应在创建组件时(或通过其他“设置”阶段)由组件本身创建。我也鼓励使用ImageIO.read,因为出了问题时它会生成IOException,而ImageIcon会失败而无法静音。

作为(ImageIO.read的一项附带好处,您还将知道图像何时完成加载,因为该方法直到它完成才返回,这意味着您不会冒一些空白帧的风险。

您不需要...

private static ImageObserver observer;

也不需要是static(就像private一样,它没有任何好处),但是JPanel实际上是ImageObserver,因此您可以将this传递给drawImage] >

© www.soinside.com 2019 - 2024. All rights reserved.