Я расширяю Canvas
и добавляю его к JFrame
. Я понимаю, что AWT и Swing не следует смешивать, и предпочтительнее рисовать на JPanel, но я пытаюсь следовать учебному пособию по игровому движку, и я хотел бы придерживаться его, поскольку до сих пор он работал. Canvas
имеет minimumSize
, maximumSize
и prefferedSize
размеры, равные 550, 400
. Когда я делаю вызов отрисовки graphics.draw(0,0,550,400)
, он не заполняет весь экран, как должен. Я изменил вызов отрисовки на graphics.draw(0,0,560,410)
, добавив к нему 10 пикселей, и он заполнил весь экран. Что случилось?
Кстати: graphics.draw(10,10,550,400
точно рисует прямоугольник, начинающийся с угла, поэтому я не думаю, что проблема в JFrame.
Основной вызов внутри класса Launcher
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
game.setMinimumSize(DIMENSIONS);
game.setMaximumSize(DIMENSIONS);
game.setPreferredSize(DIMENSIONS);
game.frame = new JFrame(NAME);
game.frame.setLayout(new BorderLayout());
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.add(game, BorderLayout.CENTER);
game.frame.pack();
game.frame.setResizable(false);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
Logger.log(TAG, "Game starting");
game.start();
}
});
}
Вызов отрисовки, Launcher.HEIGHT
и WIDTH
равны 550,400
public void draw(float deltaTime, Graphics2D graphics) {
graphics.setColor(Color.BLACK);
graphics.fillRect(0, 0, 550, 400);
graphics.setColor(Color.DARK_GRAY);
graphics.fillRect(0, 0, 150, 40);
graphics.fillRect(0, Launcher.HEIGHT - 100, Launcher.WIDTH, 100);
graphics.setColor(Color.LIGHT_GRAY);
graphics.fillRect(125, Launcher.HEIGHT - 100, 100, 350);
}
Расширенный класс Canvas
public abstract class Game extends Canvas implements Runnable {
private static final String TAG = "Game";
public JFrame frame;
public JPanel panel;
public boolean isApplet = false;
private boolean gameRunning = false;
BufferStrategy bufferStrategy;
private Screen screen;
private Thread renderThread;
public synchronized void start() {
// Canvas
setBounds(0, 0, 550, 400);
setIgnoreRepaint(true);
createBufferStrategy(2);
bufferStrategy = getBufferStrategy();
// Screen, Handlers, ETC
screen = getStartScreen();
// Threads
renderThread = new Thread(this, Launcher.NAME + "_main");
renderThread.start();
gameRunning = true;
}
@Override
public void run() {
long startTime = System.nanoTime();
while (gameRunning) {
float deltaTime = (System.nanoTime() - startTime) / 1000000000.0f;
startTime = System.nanoTime();
screen.update(deltaTime);
Graphics2D graphics = (Graphics2D) bufferStrategy.getDrawGraphics();
screen.draw(deltaTime, graphics);
graphics.dispose();
bufferStrategy.show();
// FPS Counter
// FPS Capper
}
}
}
Запрошено SSCCE
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class Game extends Canvas implements Runnable {
public static final int WIDTH = 550;
public static final int HEIGHT = 400;
public static final Dimension DIMENSIONS = new Dimension(WIDTH, HEIGHT);
public static final String NAME = "SSCCE";
public boolean gameRunning = false;
public JFrame frame;
public BufferStrategy bufferStrategy;
public static void main (String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Game game = new Game();
game.setMinimumSize(DIMENSIONS);
game.setMaximumSize(DIMENSIONS);
game.setPreferredSize(DIMENSIONS);
game.frame = new JFrame(NAME);
game.frame.setLayout(new BorderLayout());
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.add(game, BorderLayout.CENTER);
game.frame.pack();
game.frame.setResizable(false);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
System.out.println("Game started");
game.start();
}
});
}
public synchronized void start() {
setSize(550, 400);
setBounds(0, 0, 550, 400);
setIgnoreRepaint(true);
createBufferStrategy(2);
bufferStrategy = getBufferStrategy();
// Threads
Thread renderThread = new Thread(this, NAME + "_main");
renderThread.start();
gameRunning = true;
}
@Override
public void run() {
while (gameRunning) {
Graphics2D graphics = (Graphics2D) bufferStrategy.getDrawGraphics();
graphics.setColor(Color.BLACK);
graphics.fillRect(0, 0, WIDTH, HEIGHT);
graphics.dispose();
bufferStrategy.show();
}
}
}
Что касается учебника по игре Java 2D, я следую за тем, что это веб-серия. Тем не менее, ссылка следующая: нажмите здесь. Я довольно много изменил код.
Модифицировано для MadProgrammer
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class Game extends Canvas implements Runnable {
public static final int WIDTH = 550;
public static final int HEIGHT = 400;
public static final Dimension DIMENSIONS = new Dimension(WIDTH, HEIGHT);
public static final String NAME = "SSCCE";
public boolean gameRunning = false;
public JFrame frame;
public BufferStrategy bufferStrategy;
public static void main (String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Game game = new Game();
game.setMinimumSize(DIMENSIONS);
game.setMaximumSize(DIMENSIONS);
game.setPreferredSize(DIMENSIONS);
game.frame = new JFrame(NAME);
game.frame.setLayout(new BorderLayout());
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.add(game, BorderLayout.CENTER);
game.frame.pack();
game.frame.setResizable(false);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
System.out.println("Game started");
game.start();
}
});
}
public synchronized void start() {
setSize(550, 400);
setBounds(0, 0, 550, 400);
setIgnoreRepaint(true);
createBufferStrategy(2);
bufferStrategy = getBufferStrategy();
// Threads
Thread renderThread = new Thread(this, NAME + "_main");
renderThread.start();
gameRunning = true;
}
@Override
public void run() {
while (gameRunning) {
Graphics2D graphics = (Graphics2D) bufferStrategy.getDrawGraphics();
graphics.setColor(Color.RED);
// Using getWidth()
graphics.fillRect(0, 0, getWidth(), getHeight());
graphics.setColor(Color.GREEN);
// Using WIDTH which was used to set the size of the canvas
graphics.fillRect(5, 5, WIDTH, HEIGHT);
graphics.dispose();
bufferStrategy.show();
try {
Thread.sleep(60);
} catch (InterruptedException ex) {
}
}
}
}
minimumSize
,maximumSize
иprefferedSize
недостаточна без менеджера компоновки - чтобы установить фактический размер, используйтеsetSize()
- person Andreas Fester   schedule 05.02.2013getWidth
иgetHeight
. Убедитесь, что вы создаете свою буферную стратегию сCanvas
, а не с фрейма. - person MadProgrammer   schedule 05.02.2013560, 410
вместо550, 400
, вы заметите разницу. Другим ярким примером может быть сдвигx, y
в вызове отрисовки на 10 пикселей. СgetWidth
иgetHeight
он заполнит весь экран. Если я не ошибаюсь,getWidth
иgetHeight
не должны быть550, 400
? - person synjunked   schedule 05.02.2013getWidth()
, было560
, а значениеWIDTH
содержало550
. Таким образом, он не мог заполнить весь экран, кроме того, если вы внимательно посмотрите и сравните, вы увидите, что часть правой и нижней стороны не заполнена. Я понимаю, почему getWidth/Height следует использовать для обеспечения гибкости, но установкаsetResizable(false)
не отменяет этого? Кроме того, что я могу сделать, чтобы getWidth/Height вернул мне550/400
? Что касается предоставленной информации, то я очень благодарен. - person synjunked   schedule 05.02.2013getWidth/Height
с холста означает, что у вас есть более надежный источник информации - ИМХО - person MadProgrammer   schedule 05.02.2013