Java Canvas fillRect()未填充定义的画布
我正在扩展Java Canvas fillRect()未填充定义的画布,java,swing,awt,java-2d,Java,Swing,Awt,Java 2d,我正在扩展画布,并将其添加到JFrame。我知道AWT和Swing不应该混合使用,而且在JPanel上绘图是首选,但我正在尝试遵循游戏引擎教程,我希望坚持使用它,因为到目前为止我已经使用它了。画布将最小尺寸、最大尺寸和首选尺寸设置为550400的尺寸。当我调用draw调用graphics.draw(0,0550400)时,它不会像应该的那样填满整个屏幕。我将draw调用改为graphics.draw(0,0560410)基本上是向它添加10px,它填充了整个屏幕。怎么了 顺便说一句:graphi
画布
,并将其添加到JFrame
。我知道AWT和Swing不应该混合使用,而且在JPanel上绘图是首选,但我正在尝试遵循游戏引擎教程,我希望坚持使用它,因为到目前为止我已经使用它了。画布
将最小尺寸
、最大尺寸
和首选尺寸
设置为550400
的尺寸。当我调用draw调用graphics.draw(0,0550400)时,它不会像应该的那样填满整个屏幕。我将draw调用改为graphics.draw(0,0560410)基本上是向它添加10px,它填充了整个屏幕。怎么了
顺便说一句:graphics.draw(10,10550400
精确地绘制从拐角处开始的矩形,因此我认为JFrame不是问题所在
启动器
类中的主调用
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();
}
});
}
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
}
}
}
绘图调用,Launcher.HEIGHT
和WIDTH
是550400
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);
}
扩展的画布
类
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();
}
});
}
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游戏教程,我现在关注的是一个web系列。不过,链接如下。我对代码做了很多修改
为程序员修改
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) {
}
}
}
}
您提供的示例运行良好。我对其进行了一些修改,以演示
getWidth/height
public void run() {
while (gameRunning) {
Graphics2D graphics = (Graphics2D) bufferStrategy.getDrawGraphics();
graphics.setColor(Color.RED);
graphics.fillRect(0, 0, getWidth(), getHeight());
graphics.setColor(Color.GREEN);
int width = getWidth() - 50;
int height = getHeight() - 50;
graphics.fillRect(25, 25, width, height);
graphics.setColor(Color.BLACK);
FontMetrics fm = graphics.getFontMetrics();
graphics.drawString("Frame Size: " + frame.getWidth() + "x" + frame.getHeight(), 0, fm.getAscent());
graphics.drawString("Canvas Size: " + getWidth() + "x" + getHeight(), 0, fm.getAscent() + fm.getHeight());
graphics.dispose();
bufferStrategy.show();
try {
Thread.sleep(60);
} catch (InterruptedException ex) {
}
}
}
您可以发布一些您目前拥有的代码吗?您可以显示一些代码吗?如果没有布局管理器,仅设置
minimumSize
、maximumSize
和preferedSize
是不够的-要设置实际大小,请使用setSize()
LayoutManager可能会改变画布的大小。发布构建gui的代码。发布代码,感谢所有的回复!为了更快地获得帮助,请发布一个。我编辑了我的问题,请编译它以了解我的意思。我不明白为什么getWidth
会给我一个比WIDTH
wh高10像素的值我使用了画布的尺寸、边界和大小。我还将JFrame设置为不可调整大小。我知道getWidth
会给我更精确的尺寸,但最终我要做的是WIDTH
和getWidth
共享类似的值。框架总是比画布大。frame有一个边框。这是确保您是从画布而不是框架创建缓冲区策略的重要方式。对,但我将画布设置为这些维度,而不是框架。框架没有维度,只是拉伸以适应画布。@synjunked从您更新的示例中,我仍然没有问题。请确保在画布上调用getWidth/Height
,而不是在框架上调用。啊,我想这是一个在静态宽度上使用getWidth
的完美示例。不同的操作系统有着如此不同的功能。谢谢您的示例!