所以我昨天开始了这个“项目”,我想尝试一个程序,其中一个立方体与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,则速度应为相反的总和(负),反之亦然。这可行,但为时已晚。我制作的碰撞系统似乎不起作用
很抱歉将所有代码放在一个类中!
提前感谢!
所以,立即,这似乎是错误的...
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.myGame
是JFrame
,您要询问窗口的大小,但是正如我之前说的,框架具有装饰物,这些装饰物嵌入到框架中,从而减小了组件可用的可视区域。相反,您应该使用组件本身的大小]
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
] >