Java 拉伸游戏以适应屏幕大小并保持坐标系

Java 拉伸游戏以适应屏幕大小并保持坐标系,java,jframe,jpanel,Java,Jframe,Jpanel,我正在尝试创建一个类似的游戏,在那里你可以找到源代码。在游戏框架中,有一个游戏面板。在GamePanel中,有StatsPanel和PlayPanel。GameFrame和GamePanel在GamePanel顶部为1280 x 640,StatsPanel在GamePanel顶部为1280 x 40,PlayPanel在GamePanel底部为1280 x 600 然而,我希望使游戏全屏,但我不希望改变坐标系,因为涉及不同的屏幕大小的差异。因此,我的问题是:如何拉伸游戏以适应屏幕大小并保持坐标

我正在尝试创建一个类似的游戏,在那里你可以找到源代码。在游戏框架中,有一个游戏面板。在GamePanel中,有StatsPanel和PlayPanel。GameFrame和GamePanel在GamePanel顶部为1280 x 640,StatsPanel在GamePanel顶部为1280 x 40,PlayPanel在GamePanel底部为1280 x 600

然而,我希望使游戏全屏,但我不希望改变坐标系,因为涉及不同的屏幕大小的差异。因此,我的问题是:如何拉伸游戏以适应屏幕大小并保持坐标系参考

我相信有可能将游戏渲染为图像,然后缩放以适应屏幕。通过这种方式,我仍然可以引用1280x40边界框中的组件。我不知道在哪里以及如何实施这一点

到目前为止我尝试的内容(参考教程的源代码):

游戏框架(扩展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);
gamePanel.repaint();
GameManager(扩展线程)

run()方法:

替换为:

this.setLocation(0,0);
this.setSize(Toolkit.getDefaultToolkit().getScreenSize());
this.setExtendedState(JFrame.MAXIMIZED_BOTH); 
this.setUndecorated(true);
gamePanel.repaint();
游戏面板(扩展JPanel)

repaingame()方法:

替换为paintComponent()方法:

这些变化并没有使游戏适应屏幕大小。当游戏框架和黑色游戏面板跨越屏幕大小时,StatsPanel和PlayPanel似乎保留在1280x640的边界框中

我对Java不是很有经验,所以请原谅我可能犯的任何疏忽

编辑:更改后的图像(忽略终端窗口):

正如对科德回答的评论:


我的主要问题是维护坐标系。例如,点(500300)在1920 x 1080屏幕中与其在1280 x 640屏幕中的位置不同。因此,我想知道是否有可能将GamePanel及其组件StatsPanel和PlayPanel作为图像或其他方式在全屏游戏框架中进行拉伸。这样,点(500300)将始终指向GamePanel中的(500300),GamePanel随后将在屏幕上拉伸。我已经上传了一张照片到我的帖子上。我想把游戏扩展到屏幕大小


假设这是布局的良好表示:

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);
    }
}
编辑
拉伸图像意味着要么使每个像素变大(这是您无法控制的),要么在您的情况下添加像素
添加像素显然会将
(500300)
坐标(例如)更改为其他坐标
我看到两种选择:
a。将
GamePanel
保持在固定大小,而不考虑帧大小。
b。根据实际尺寸动态计算坐标,而不是使用固定值,如
(500300)


我推荐选项b。

假设这是布局的良好表示:

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);
    }
}
编辑
拉伸图像意味着要么使每个像素变大(这是您无法控制的),要么在您的情况下添加像素
添加像素显然会将
(500300)
坐标(例如)更改为其他坐标
我看到两种选择:
a。将
GamePanel
保持在固定大小,而不考虑帧大小。
b。根据实际尺寸动态计算坐标,而不是使用固定值,如
(500300)


我建议选择b。

欢迎使用SO。“有了GameFrame,就有GamePanel。在GamePanel中,有StatsPanel和PlayPanel。”-我相信它描述了一个简单的布局问题,一个JFrame中的主面板,包含两个嵌套的JPanel。这与特定的游戏无关。考虑发帖:这会使帮助变得更容易(也将帮助你解决一个解决方案)是当前布局的一个很好的表示?我认为它比简单的布局问题要复杂一点,因为我还希望保持坐标系统和精灵相对于Prand面板的位置。我会考虑在我有时间的时候发布一个更完整、简单的程序。欢迎来到。“有了GameFrame,就有GamePanel。在GamePanel中,有StatsPanel和PlayPanel。”-我相信它描述了一个简单的布局问题,一个JFrame中的主面板,包含两个嵌套的JPanel。这与特定的游戏无关。考虑发帖:这会使帮助变得更容易(也将帮助你解决一个解决方案)是当前布局的一个很好的表示?我认为它比简单的布局问题要复杂一点,因为我还希望保持坐标系统和精灵相对于Prand面板的位置。我会考虑发布一个更完整,简单的程序稍后我有时间。谢谢你的回应!我试过你的代码,但我想你误解了我的问题。我的主要问题是维护坐标系。例如,点(500300)在1920 x 1080屏幕中与其在1280 x 640屏幕中的位置不同。因此,我想知道是否有可能将GamePanel及其组件StatsPanel和PlayPanel作为图像或其他方式在全屏游戏框架中进行拉伸。这样,点(500300)将始终指向GamePanel中的(500300),GamePanel随后将在屏幕上拉伸。我已将图片上传到我的帖子。我希望将游戏扩展到屏幕大小。感谢您的回复!我试过你的代码,但我想你误解了我的问题。我的主要问题是维护坐标系。例如,点(500300)在1920 x 1080屏幕中与其在1280 x 640屏幕中的位置不同。因此,我想知道它是否是p