我正在尝试创建一个类似于此tutorial的游戏,您可以在其中找到源代码。在GameFrame中,有GamePanel。在GamePanel中,有StatsPanel和PlayPanel。 GameFnel和GamePanel分别是1280乘640,StatPaPanel在GamePanel的顶部是1280乘40,PlayPanel底部是PlayPanel的1280乘600.
但是,我希望让游戏全屏,但由于不同屏幕尺寸的差异,我不希望更改坐标系。所以这是我的问题:如何拉伸游戏以适应屏幕尺寸并保持坐标系参考?
我相信有可能将游戏渲染为图像,然后缩放以适应屏幕。通过这种方式,我仍然可以参考1280乘640边界框内的组件。我不知道在哪里以及如何实现这一点。
到目前为止我所尝试的内容(参考教程的源代码):
GameFrame(扩展JFrame)
构造
this.setLocation((int)((Toolkit.getDefaultToolkit().getScreenSize().getWidth()-WIDTH)/2),
((int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight()-HEIGHT)/2));
this.setSize(WIDTH,HEIGHT);
替换为:
this.setLocation(0,0);
this.setSize(Toolkit.getDefaultToolkit().getScreenSize());
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
this.setUndecorated(true);
GameManager(扩展线程)
run()方法:
gamePanel.repaintGame();
替换为:
gamePanel.repaint();
GamePanel(扩展JPanel)
repaintGame()方法:
public void repaintGame(){
playPanel.repaint();
}
替换为paintComponent()方法:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
playPanel.repaint();
BufferedImage img = new BufferedImage(1280, 640, BufferedImage.TYPE_INT_RGB);
g.drawImage(img, 0, 0, getWidth(), getHeight(), 0, 0, 1280, 640, null);
}
这些更改并未使游戏适应屏幕大小。虽然GameFrame和黑色GamePanel跨越屏幕大小,但StatsPanel和PlayPanel似乎仍保留在1280 x 640边界框中。
我对Java不太有经验,所以请原谅我的疏忽。
编辑:更改后的图像(忽略终端窗口):
评论了c0der的回答:
我的主要问题是维护坐标系。例如,点(500,300)在1920×1080屏幕上与其在1280×640屏幕中的位置不同。因此,我想知道是否可以将GamePanel及其组件StatsPanel和PlayPanel在整个屏幕GameFrame中拉伸为图像或其他方式。这样,点(500,300)将始终引用GamePanel中的(500,300),随后GamePanel将在屏幕上拉伸。我已将照片上传到我的帖子。我希望将游戏扩展到屏幕大小。
答案 0 :(得分:0)
假设这是布局的良好表示:
import java.awt.Color;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GameFrame extends JFrame {
public static final int WIDTH=1280;
public static final int HEIGHT=640;
public GameFrame(GamePanel gamePanel){
//set frame to appear at the center of the screen
this.setLocation((int)((Toolkit.getDefaultToolkit().getScreenSize().getWidth()-WIDTH)/2),
((int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight()-HEIGHT)/2));
this.setSize(WIDTH,HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
this.add(gamePanel);
setVisible(true);
}
public static void main(String[] args) {
new GameFrame(new GamePanel());
}
}
class GamePanel extends JPanel{
public static final int PLAY_PANEL_HEIGHT=640;
public static final int STATS_HEIGHT=40;
public GamePanel(){
this.setSize(WIDTH, HEIGHT);
setLayout(null);
setBackground(Color.BLACK);
JPanel statsPanel= new JPanel();
statsPanel.setSize(GameFrame.WIDTH, STATS_HEIGHT);
statsPanel.setLayout(null);
statsPanel.setBackground(Color.CYAN);
statsPanel.setLocation(0, 0);
this.add(statsPanel);
JPanel playPanel=new JPanel();
playPanel.setSize(GameFrame.WIDTH, PLAY_PANEL_HEIGHT);
playPanel.setLayout(null);
playPanel.setBackground(Color.DARK_GRAY);
playPanel.setLocation(0, STATS_HEIGHT);
this.add(playPanel);
}
}
按照评论中的说明进行更改,使其全屏显示:
public class GameFrame extends JFrame {
public GameFrame(GamePanel gamePanel){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
this.add(gamePanel);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setUndecorated(true);
setVisible(true); //make sure you have means to close the window
}
public static void main(String[] args) {
new GameFrame(new GamePanel());
}
}
class GamePanel extends JPanel{
public static final int STATS_HEIGHT=40;
public GamePanel(){
//using null layout manager requires that you manually handle all size or
//other layout changes. a much better practice is to use layout manager
setLayout(new BorderLayout());//use BorderLayout instead of null
setBackground(Color.BLACK);
JPanel statsPanel= new JPanel();
//width is ignored for NORTH components of BorderLyayout
statsPanel.setPreferredSize(new Dimension(0, STATS_HEIGHT));
statsPanel.setLayout(null);
statsPanel.setBackground(Color.CYAN);
this.add(statsPanel, BorderLayout.NORTH);
JPanel playPanel=new JPanel();
//height is ignored for CENTER components of BorderLyayout
playPanel.setPreferredSize(new Dimension(WIDTH, 0));
playPanel.setBackground(Color.DARK_GRAY);
this.add(playPanel, BorderLayout.CENTER);
}
}
修改强>
拉伸图像意味着要么让每个像素变大,要么不控制,或者在你的情况下增加像素。
添加像素显然会将(500,300)
坐标(作为示例)更改为其他内容。
我看到两个选择:
一个。无论帧大小如何,都要将GamePanel
保持为固定大小。
湾根据实际大小动态计算坐标,而不是使用(500,300)
等固定值。
我建议选择b。