Итак, сразу, это кажется неправильным ...
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
, что позже станет ядром вашей проблемы.
Поэтому вместо этого я wold override 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