游戏的 JFrame 、 JPanel 或 Canvas (Java)?
JFrame , JPanel or Canvas for a game (Java)?
你好,目前我正在 java 制作一个简单的 2d 游戏,现在我的问题是什么是最好的机会? JFrame 、 JPanel 还是 Canvas ?我说的是 java 中的每个 2d 游戏,所以我没有添加代码
一种流行的方法是像这样覆盖 JPanel 中的 paintComponent:
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// put drawing code here
}
您可以通过调用 JPanel 中其他地方的 repaint
方法来调用它,通常是为了响应用户提供的输入的键事件,或者来自 Timer
的固定间隔更新。
这里有一些代码可以帮助您入门:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;
public class GameFrame extends JFrame {
private static final long serialVersionUID = 1L;
public GameFrame() {
super("Game Frame");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().add(new GamePanel(), BorderLayout.CENTER);
pack();
setResizable(false);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new GameFrame();
frame.setVisible(true);
}
});
}
}
class GamePanel extends JPanel implements ActionListener, KeyListener {
private static final long serialVersionUID = 1L;
private static final Dimension PANEL_SIZE = new Dimension(640, 480);
private static final int REFRESH_RATE = 1000;
private static final int CHARACTER_WIDTH = 32;
private static final int CHARACTER_HEIGHT = 64;
private Timer timer = new Timer(REFRESH_RATE, this);
private int currentRow = 0;
private int currentCol = 0;
private int randomRow = 0;
private int randomCol = 0;
public GamePanel() {
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
timer.start();
}
public Dimension getPreferredSize() {
return PANEL_SIZE;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(randomCol, randomRow, CHARACTER_WIDTH, CHARACTER_HEIGHT);
g.drawRect(currentCol, currentRow, CHARACTER_WIDTH, CHARACTER_HEIGHT);
}
public void actionPerformed(ActionEvent e) {
int min = 0;
int maxRow = (int)PANEL_SIZE.getHeight() - CHARACTER_HEIGHT;
int maxCol = (int)PANEL_SIZE.getWidth() - CHARACTER_WIDTH;
Random rand = new Random();
randomRow = rand.nextInt((maxRow - min) + 1) + min;
randomCol = rand.nextInt((maxCol - min) + 1) + min;
repaint();
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
int rowIncrement = 0;
int colIncrement = 0;
if(code == KeyEvent.VK_LEFT) {
colIncrement--;
}
else if(code == KeyEvent.VK_RIGHT) {
colIncrement++;
}
else if(code == KeyEvent.VK_UP) {
rowIncrement--;
}
else {
if(code == KeyEvent.VK_DOWN) {
rowIncrement++;
}
}
if(isInBounds(rowIncrement, colIncrement)) {
currentRow += rowIncrement;
currentCol += colIncrement;
repaint();
}
}
private boolean isInBounds(int rowIncrement, int colIncrement) {
int top = currentRow + rowIncrement;
int left = currentCol + colIncrement;
int right = left + CHARACTER_WIDTH;
int bottom = top + CHARACTER_HEIGHT;
return (top >= 0 && left >= 0 && right <= PANEL_SIZE.getWidth() && bottom <= PANEL_SIZE.getHeight());
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
}
https://github.com/jackmead515/java_game_engine
以上link引用了我个人的游戏引擎。我使用 java.awt.Canvas 组件并将其添加到 JFrame。使用 Canvas class 很有用,因为您可以创建缓冲策略来预加载帧。你可以用 JPanel 做同样的事情,但你只能调用一个名为 setDoubleBuffered(true) 的方法来激活双缓冲(这应该真的是你所需要的。当然取决于你的游戏......)
注意:我提前道歉。这个游戏引擎目前正在生产中,所以如果 link 不工作,请把它交给我!另外,如果以后没有Canvas,那是因为我找到了更好的解决办法!干杯!
^^^ 将其添加到 JFrame。
GameCanvas canvas = new GameCanvas();
canvas.setBounds(0, 0, Stats.getScreenWidth(), Stats.getScreenHeight());
canvas.addMouseListener(InputManager.getMouse());
canvas.addMouseMotionListener(InputManager.getMouse());
canvas.addKeyListener(InputManager.getKeyboard());
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.getContentPane().setLayout(null);
this.add(gameCanvas);
this.pack();
canvas.createBufferStrategy(2);
^^^调用paint方法调用你的东西!
public void paint() {
BufferStrategy bs = this.getBufferStrategy();
Graphics2D g2 = (Graphics2D) bs.getDrawGraphics();
g2.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
Main.world.render(g2, this);
bs.show();
g2.dispose();
}
你好,目前我正在 java 制作一个简单的 2d 游戏,现在我的问题是什么是最好的机会? JFrame 、 JPanel 还是 Canvas ?我说的是 java 中的每个 2d 游戏,所以我没有添加代码
一种流行的方法是像这样覆盖 JPanel 中的 paintComponent:
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// put drawing code here
}
您可以通过调用 JPanel 中其他地方的 repaint
方法来调用它,通常是为了响应用户提供的输入的键事件,或者来自 Timer
的固定间隔更新。
这里有一些代码可以帮助您入门:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;
public class GameFrame extends JFrame {
private static final long serialVersionUID = 1L;
public GameFrame() {
super("Game Frame");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().add(new GamePanel(), BorderLayout.CENTER);
pack();
setResizable(false);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new GameFrame();
frame.setVisible(true);
}
});
}
}
class GamePanel extends JPanel implements ActionListener, KeyListener {
private static final long serialVersionUID = 1L;
private static final Dimension PANEL_SIZE = new Dimension(640, 480);
private static final int REFRESH_RATE = 1000;
private static final int CHARACTER_WIDTH = 32;
private static final int CHARACTER_HEIGHT = 64;
private Timer timer = new Timer(REFRESH_RATE, this);
private int currentRow = 0;
private int currentCol = 0;
private int randomRow = 0;
private int randomCol = 0;
public GamePanel() {
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
timer.start();
}
public Dimension getPreferredSize() {
return PANEL_SIZE;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(randomCol, randomRow, CHARACTER_WIDTH, CHARACTER_HEIGHT);
g.drawRect(currentCol, currentRow, CHARACTER_WIDTH, CHARACTER_HEIGHT);
}
public void actionPerformed(ActionEvent e) {
int min = 0;
int maxRow = (int)PANEL_SIZE.getHeight() - CHARACTER_HEIGHT;
int maxCol = (int)PANEL_SIZE.getWidth() - CHARACTER_WIDTH;
Random rand = new Random();
randomRow = rand.nextInt((maxRow - min) + 1) + min;
randomCol = rand.nextInt((maxCol - min) + 1) + min;
repaint();
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
int rowIncrement = 0;
int colIncrement = 0;
if(code == KeyEvent.VK_LEFT) {
colIncrement--;
}
else if(code == KeyEvent.VK_RIGHT) {
colIncrement++;
}
else if(code == KeyEvent.VK_UP) {
rowIncrement--;
}
else {
if(code == KeyEvent.VK_DOWN) {
rowIncrement++;
}
}
if(isInBounds(rowIncrement, colIncrement)) {
currentRow += rowIncrement;
currentCol += colIncrement;
repaint();
}
}
private boolean isInBounds(int rowIncrement, int colIncrement) {
int top = currentRow + rowIncrement;
int left = currentCol + colIncrement;
int right = left + CHARACTER_WIDTH;
int bottom = top + CHARACTER_HEIGHT;
return (top >= 0 && left >= 0 && right <= PANEL_SIZE.getWidth() && bottom <= PANEL_SIZE.getHeight());
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
}
https://github.com/jackmead515/java_game_engine
以上link引用了我个人的游戏引擎。我使用 java.awt.Canvas 组件并将其添加到 JFrame。使用 Canvas class 很有用,因为您可以创建缓冲策略来预加载帧。你可以用 JPanel 做同样的事情,但你只能调用一个名为 setDoubleBuffered(true) 的方法来激活双缓冲(这应该真的是你所需要的。当然取决于你的游戏......)
注意:我提前道歉。这个游戏引擎目前正在生产中,所以如果 link 不工作,请把它交给我!另外,如果以后没有Canvas,那是因为我找到了更好的解决办法!干杯!
^^^ 将其添加到 JFrame。
GameCanvas canvas = new GameCanvas();
canvas.setBounds(0, 0, Stats.getScreenWidth(), Stats.getScreenHeight());
canvas.addMouseListener(InputManager.getMouse());
canvas.addMouseMotionListener(InputManager.getMouse());
canvas.addKeyListener(InputManager.getKeyboard());
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.getContentPane().setLayout(null);
this.add(gameCanvas);
this.pack();
canvas.createBufferStrategy(2);
^^^调用paint方法调用你的东西!
public void paint() {
BufferStrategy bs = this.getBufferStrategy();
Graphics2D g2 = (Graphics2D) bs.getDrawGraphics();
g2.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
Main.world.render(g2, this);
bs.show();
g2.dispose();
}