gpt4 book ai didi

java - 我与 JPanel、getWidth 和 getHeight 作斗争

转载 作者:行者123 更新时间:2023-12-02 01:01:30 25 4
gpt4 key购买 nike

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

但是,我与边界作斗争。我似乎无法在 window 的右侧和底部获得“完美”的碰撞。立方体总是比预期走得远一点。

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

代码如下:

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,则速度应完全相反(负)并转向另一个方向。这确实有效,但是有点太晚了。看来我做的碰撞系统不起作用

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

提前致谢!

最佳答案

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

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

您在设置/确定首选尺寸之前打包窗口,这意味着窗口将希望采用可能的最小尺寸(作为内容的preferredSize)默认为 0x0)。

作为一般规则,您应该避免调用 setPreferredSize,但我特别避免在 JFrame 上使用它。

为什么?因为 JFrame 有装饰(窗口标题和边框),它们插入到窗口中,所以可视大小实际上是 frameSize -decorationInsets,这成为问题的核心稍后。

因此,我会重写 MyPanel 中的 getPreferredSize 并指定组件的“可视”范围

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.myGame 是一个 JFrame,您要求的是窗口大小,但正如我之前所说,框架有装饰,它们插入到框架中,减少组件可用的可视区域。相反,您应该使用组件本身的大小

public void actionPerformed(ActionEvent e) {

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

一些建议...

我认为这些的必要性......

public static JFrame myGame;
public static Timer timer;

但我在使用 static 时遇到问题;)。使 myGame 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;

它也不需要是静态(因为私有(private)它有点破坏任何好处),但是,JPanel实际上是一个ImageObserver,因此您只需将 this 传递给 drawImage

关于java - 我与 JPanel、getWidth 和 getHeight 作斗争,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60582651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com