Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >还能做些什么来增加摇摆JPanel图纸的质量呢?

还能做些什么来增加摇摆JPanel图纸的质量呢?
EN

Code Review用户
提问于 2012-08-08 06:16:03
回答 1查看 2.3K关注 0票数 8

如果我没有把题目写得很好,很抱歉,让我来解释一下。

我正在创建一个游戏,实际上有几个,而且我看到在大多数情况下,我使用JPanel进行绘画,所以我去找了一种很好的绘画方法(即,当绘制多个精灵等时,它具有很好的性能)参见这里:https://stackoverflow.com/questions/1963494/java-2d-game-graphics。我在我自己的GameJPanel中实现了这一点,这将允许我在游戏JPanels上画画时始终保持性能。现在,我在绘图时添加了setDoubleBuffered(true)RenderHints这样的方法:

代码语言:javascript
运行
AI代码解释
复制
                if (isTextRenderHintsOn()) {
                    bg.setRenderingHints(textRenderHints);
                }
                if (isImageRenderHintsOn()) {
                    bg.setRenderingHints(imageRenderHints);
                }
                if (isColorRenderHintsOn()) {
                    bg.setRenderingHints(colorRenderHints);
                }
                if (isInterpolationRenderHintsOn()) {
                    bg.setRenderingHints(iterpolationRenderHints);
                }
                if (isRenderHintsOn()) {
                    bg.setRenderingHints(renderHints);
                }

现在,不去其他图书馆等,我还能做些什么来调整JPanels的质量和性能?

可能还需要了解一下,我使用GraphicsEnviroment并将JFrameJPanel设置为全屏,以便通过缓冲区策略(不是swing中的链接性能绘图也使用了一些很好的技术)获得硬件加速映像,下面是一个实现Java2D游戏图形链接方法和呈现提示的GameDrawLibrary示例,FullScreen类将用于设置全屏模式,测试驱动程序就是:):

测试司机:

代码语言:javascript
运行
AI代码解释
复制
import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 * Test Driver
 *
 * @author David
 */
public class PureSwingPaintingTest extends JFrame {

    static GameDrawLibrary gdl;
    static Image image;
    static final FullScreen fs = new FullScreen();
    static int width = fs.getWidth(), height = fs.getHeight();

    public PureSwingPaintingTest() {
        setSize(width, height);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gdl.createPanel();//create the panel
        JPanel panel = gdl.getPanel();
        JButton button = new JButton("Exit");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        getContentPane().add(button, BorderLayout.SOUTH);
        getContentPane().add(panel, BorderLayout.CENTER);
    }

    public static void main(String[] args) {

        try {
            image = ImageIO.read(new File("c:/chess.jpg")).getScaledInstance(width, height, Image.SCALE_SMOOTH);
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        gdl = new GameDrawLibrary(width, height, true, true, true, true, true, true) {

            @Override
            void updateGame() {
                //update logic here
            }

            @Override
            void renderGame(Graphics2D g) {
                g.drawImage(image, 0, 0, this);
            }
        };

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                if (fs.isSupported()) {
                    fs.setFullScreen(new PureSwingPaintingTest());
                } else {
                    fs.emulateFullScreen(new PureSwingPaintingTest());
                }

                gdl.showPanel();
            }
        });
    }
}

游戏JPanel类库:

代码语言:javascript
运行
AI代码解释
复制
import java.awt.*;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

abstract class GameDrawLibrary extends JPanel {

    private int width;
    private int height;
    private int scale;
    private boolean isRunning = true;
    private Canvas canvas;
    private BufferStrategy strategy;
    private BufferedImage background;
    private Graphics2D backgroundGraphics;
    private Graphics2D graphics;
    private GraphicsConfiguration config = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    //graphics quaultiy settings
    private boolean textRenderHintsOn;
    private boolean imageRenderHintsOn;
    private boolean colorRenderHintsOn;
    private boolean interpolationRenderHintsOn;
    private boolean renderHintsOn;
    private RenderingHints textRenderHints = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    private RenderingHints imageRenderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    private RenderingHints colorRenderHints = new RenderingHints(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    private RenderingHints iterpolationRenderHints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    private RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

    public GameDrawLibrary() {
        setIgnoreRepaint(true);
        this.textRenderHintsOn = false;
        this.imageRenderHintsOn = false;
        this.colorRenderHintsOn = false;
        this.interpolationRenderHintsOn = false;
        this.renderHintsOn = false;
    }

    GameDrawLibrary(int width, int height) {
        setIgnoreRepaint(true);
        this.width = width;
        this.height = height;
        this.scale = 1;
        this.textRenderHintsOn = false;
        this.imageRenderHintsOn = false;
        this.colorRenderHintsOn = false;
        this.interpolationRenderHintsOn = false;
        this.renderHintsOn = false;

    }

    GameDrawLibrary(int width, int height, int scale) {
        setIgnoreRepaint(true);
        this.width = width;
        this.height = height;
        this.scale = scale;
        this.textRenderHintsOn = false;
        this.imageRenderHintsOn = false;
        this.colorRenderHintsOn = false;
        this.interpolationRenderHintsOn = false;
        this.renderHintsOn = false;
    }

    public GameDrawLibrary(int width, int height, boolean textRenderHintsOn, boolean imageRenderHintsOn, boolean colorRenderHintsOn, boolean interpolationRenderHintsOn, boolean renderHintsOn, boolean isDoubleBuffered) {
        super(isDoubleBuffered);
        setIgnoreRepaint(true);
        this.width = width;
        this.height = height;
        this.scale = 1;
        this.textRenderHintsOn = textRenderHintsOn;
        this.imageRenderHintsOn = imageRenderHintsOn;
        this.colorRenderHintsOn = colorRenderHintsOn;
        this.interpolationRenderHintsOn = interpolationRenderHintsOn;
        this.renderHintsOn = renderHintsOn;
    }

    public GameDrawLibrary(int width, int height, int scale, boolean textRenderHintsOn, boolean imageRenderHintsOn, boolean colorRenderHintsOn, boolean interpolationRenderHintsOn, boolean renderHintsOn, boolean isDoubleBuffered) {
        super(isDoubleBuffered);
        this.width = width;
        this.height = height;
        this.scale = scale;
        this.textRenderHintsOn = textRenderHintsOn;
        this.imageRenderHintsOn = imageRenderHintsOn;
        this.colorRenderHintsOn = colorRenderHintsOn;
        this.interpolationRenderHintsOn = interpolationRenderHintsOn;
        this.renderHintsOn = renderHintsOn;
    }
    // Screen and buffer stuff

    private Graphics2D getBuffer() {
        if (graphics == null) {
            try {
                graphics = (Graphics2D) strategy.getDrawGraphics();
            } catch (IllegalStateException e) {
                return null;
            }
        }
        return graphics;
    }

    private boolean updateScreen() {
        graphics.dispose();
        graphics = null;
        try {
            strategy.show();
            Toolkit.getDefaultToolkit().sync();
            return (!strategy.contentsLost());

        } catch (NullPointerException | IllegalStateException e) {
            return true;

        }
    }

    // update game logic here
    abstract void updateGame();

    //paint stuff here
    abstract void renderGame(Graphics2D g);

    //create and return the already sized JFrame
    public void createPanel() {
        setSize(getRealWidth(), getRealHeight());
    }

    public void showPanel() {
        // Canvas
        canvas = new Canvas(config);
        canvas.setSize(width * scale, height * scale);
        add(canvas, 0);
        // Background & Buffer
        background = create(width, height, false);
        canvas.createBufferStrategy(2);
        do {
            strategy = canvas.getBufferStrategy();
        } while (strategy == null);

        startThread();//start thread to draw to the canvas
    }

    private void startThread() {
        new Thread(new Runnable() {

            @Override
            public void run() {

                backgroundGraphics = (Graphics2D) background.getGraphics();
                long fpsWait = (long) (1.0 / 30 * 1000);

                main:
                while (isRunning) {
                    long renderStart = System.nanoTime();
                    updateGame();

                    // Update Graphics
                    do {
                        Graphics2D bg = getBuffer();

                        if (isTextRenderHintsOn()) {
                            bg.setRenderingHints(textRenderHints);
                        }
                        if (isImageRenderHintsOn()) {
                            bg.setRenderingHints(imageRenderHints);
                        }
                        if (isColorRenderHintsOn()) {
                            bg.setRenderingHints(colorRenderHints);
                        }
                        if (isInterpolationRenderHintsOn()) {
                            bg.setRenderingHints(iterpolationRenderHints);
                        }
                        if (isRenderHintsOn()) {
                            bg.setRenderingHints(renderHints);
                        }

                        if (!isRunning) {
                            break main;
                        }
                        renderGame(backgroundGraphics); // this calls your draw method
                        // thingy
                        if (scale != 1) {
                            bg.drawImage(background, 0, 0, width * scale, height * scale, 0, 0, width, height, null);
                        } else {
                            bg.drawImage(background, 0, 0, null);
                        }
                        bg.dispose();
                    } while (!updateScreen());

                    // Better do some FPS limiting here
                    long renderTime = (System.nanoTime() - renderStart) / 1000000;
                    try {
                        Thread.sleep(Math.max(0, fpsWait - renderTime));
                    } catch (InterruptedException e) {
                        Thread.interrupted();
                        break;
                    }
                    // renderTime = (System.nanoTime() - renderStart) / 1000000;

                }

            }
        }).start();
    }

    public JPanel getPanel() {
        return this;
    }

    // create a hardware accelerated image
    public final BufferedImage create(final int width, final int height, final boolean alpha) {
        return config.createCompatibleImage(width, height, alpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE);
    }

    public void setColorRenderHintsOn(boolean colorRenderHintsOn) {
        this.colorRenderHintsOn = colorRenderHintsOn;
    }

    public void setRenderHintsOn(boolean renderHintsOn) {
        this.renderHintsOn = renderHintsOn;
    }

    public void setInterpolationRenderHintsOn(boolean interpolationRenderHintsOn) {
        this.interpolationRenderHintsOn = interpolationRenderHintsOn;
    }

    public void setImageRenderHintsOn(boolean imageRenderHintsOn) {
        this.imageRenderHintsOn = imageRenderHintsOn;
    }

    public void setTextRenderHintsOn(boolean textRenderHintsOn) {
        this.textRenderHintsOn = textRenderHintsOn;
    }

    public boolean isColorRenderHintsOn() {
        return colorRenderHintsOn;
    }

    public boolean isInterpolationRenderHintsOn() {
        return interpolationRenderHintsOn;
    }

    public boolean isTextRenderHintsOn() {
        return textRenderHintsOn;
    }

    public boolean isImageRenderHintsOn() {
        return imageRenderHintsOn;
    }

    public boolean isRenderHintsOn() {
        return renderHintsOn;
    }

    public int getRealHeight() {
        return height * scale;

    }

    public int getRealWidth() {
        return width * scale;
    }

    @Override
    public int getHeight() {
        return height;
    }

    @Override
    public int getWidth() {
        return width;
    }

    public int getScale() {
        return scale;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public void setScale(int scale) {
        this.scale = scale;
    }
}

全屏课程:

代码语言:javascript
运行
AI代码解释
复制
import java.awt.Dimension;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import javax.swing.JFrame;

/**
 *
 * @author David
 */
public class FullScreen {

    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice gs = ge.getDefaultScreenDevice();
    Dimension screenSize;

    public FullScreen() {
        screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    }

    public void setFullScreen(JFrame frame) {
        if (gs.getFullScreenWindow() == null) {

            frame.dispose();
            frame.setUndecorated(true);
            gs.setFullScreenWindow(frame);
            frame.setVisible(true);

        } else {// back to windowed mode
            emulateFullScreen(frame);
        }
    }

    public void emulateFullScreen(JFrame frame) {
        frame.dispose();
        frame.setUndecorated(false);
        gs.setFullScreenWindow(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(screenSize);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public int getWidth() {
        return gs.getDisplayMode().getWidth();

    }

    public int getHeight() {
        return gs.getDisplayMode().getHeight();
    }

    public boolean isSupported() {
        return gs.isFullScreenSupported();
    }
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2012-08-08 08:10:27

这是一段相当有趣的代码,当我有更多的时间时,我会更喜欢阅读它;)

关于唯一的事情跳出我是你是如何缩放你的图形。在讨论http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html和一些替代算法时,我建议阅读一下getScaledInstance

除此之外,我几年前被告知,你可以通过将图像缩小4来伪造反混叠。也就是说,如果你想要一个800*600的图像输出,你需要从一个4倍大小的图像开始,然后缩小它,这将产生一个“假的”反混叠,不依赖于硬件渲染。

这也许不再成立,但对你来说可能是有价值的。

票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/14460

复制
相关文章
手摸手实现一个编译器(上)
PEG.js 是一个简单的 JavaScript 解析器生成器,可以生成具有出色错误报告的快速解析器。您可以使用它来处理复杂的数据或计算机语言,并轻松构建转换器、解释器、编译器和其他工具。
码农小余
2022/06/16
7890
手摸手实现一个编译器(上)
PEG.js学习笔记
PEG.js 是一个JavaScript的表达式语法解析器,它使您能够轻松地建立复杂的数据或计算机程序语言的快速分析器。
IMWeb前端团队
2019/12/03
8540
PEG.js学习笔记
本文介绍了PEG.js,一种JavaScript的表达式语法解析器,可用于快速分析数据或建立复杂计算机程序。PEG.js可以用于快速解析形成抽象语法树,从而进行代码生成、代码优化、代码解析等任务。PEG.js支持多种编程范式,包括函数式、命令式、面向对象等,具有易学易用、高性能、高度可扩展等特点。PEG.js还提供了丰富的库和工具,包括语法分析、数据转换、词法分析、代码生成等,可广泛应用于各种场景。同时,PEG.js还提供了高度可配置的插件系统,可以灵活扩展其功能。
IMWeb前端团队
2018/01/08
1.2K0
聊聊PegJS
在开发前端BFF框架的时候,需要将团队后台使用的JCE协议(类似ProtoBuff协议)转换成nodejs对应的语法,这里参考@tencent/jce2node-cli的实现,使用PEG.js解析生成AST,下面就来介绍一下PEG.js是如何进行解析的? 我们在对文本进行解析的时候,通常可以使用正则表达式从目标文本中提取所需信息。但是仅使用正则表达式来解析,会发现非常难以阅读,可维护性比较差,而PegJs 则是一种更加简便可维护的 parser 工具。 PEG.js是一个JavaScript的词法解析器,
QQ音乐前端团队
2021/04/19
1.5K0
elf文件解析器_elf文件下载
前两天网上投递了简历,面试了一家C++公司,然后对面负责人给我发了一份笔试题,题目是:
全栈程序员站长
2022/11/16
1.6K0
nodejs中module.exports 与 exports区别?
请牢记一条原则:无论使用 exports 暴露成员,或是 module.exports 暴露成员,最终暴露的结果,都是以 module.exports 所指向的对象为准。
蓓蕾心晴
2022/12/03
7020
还不会在vim中保存另存退出文件?
介绍 Vim (Vi IMproved) 是用于 Unix 或 Linux 系统的开源文本编辑器。 Vim被称为编辑器之神,所以我们必须要掌握. 使用 Vim 模式 当 Vim 启动时,文件默认以命令模式打开。这意味着你可以四处移动和编辑文件,但不能插入新文本。 此模式下的所有字母数字键都等于命令,按下它们不会在屏幕上显示它们的值。例如,按字母w会将光标向前移动一个单词。 要键入文本,你必须处于插入模式。要切换到插入模式,请按i键。现在你可以在文件中键入文本。 要切换回命令模式,请按ESC按钮。 Vim 保
入门笔记
2022/06/02
1.9K0
还不会在vim中保存另存退出文件?
node.js中exports 和 module.exports 的区别
解释:a 是一个对象,b 是对 a 的引用,即 a 和 b 指向同一块内存,所以前两个输出一样。当对 b 作修改时,即 a 和 b 指向同一块内存地址的内容发生了改变,所以 a 也会体现出来,所以第三四个输出一样。当 b 被覆盖时,b 指向了一块新的内存,a 还是指向原来的内存,所以最后两个输出不一样。
acoolgiser
2019/01/17
9580
​Python 之父的解析器系列之三:生成一个 PEG 解析器
声明 | 本翻译是出于交流学习的目的,基于 CC BY-NC-SA 4.0 授权协议。为便于阅读,内容略有改动。
Python猫
2019/08/15
7870
配置SpringMVC的文件上传解析器
在Web应用程序中,文件上传是一项常见的任务。Spring MVC框架提供了一个强大的文件上传解析器,可以方便地处理文件上传。
堕落飞鸟
2023/05/14
9380
export default和module.exports
我们可以看到使用require引入util.js中写的export default失败了
阿超
2022/08/17
7470
export default和module.exports
node.js中exports与module.exports的区别
node.js中,每个js文件都可以当成一个模块,每个模块中,都隐含了一个名为module的对象,module对象中有一个exports属性,这个属性的功能是将模块中的变量暴露给其他模块调用。
章鱼喵
2018/08/02
1K0
node.js中exports与module.exports的区别
python中解析和生成pdf文件
python中可以对pdf文件进行解析和生成,分别需要安装pdfminer/pdfminer3k和reportlab文件库。
py3study
2020/01/08
2.7K0
python之configparser配置文件解析器
configparser 模块是 Python 标准库中用于处理配置文件的模块,它可以读取、写入和修改配置文件。配置文件通常用于存储程序的配置选项、参数或者其他需要持久化的配置信息。下面简单写一下 configparser 模块的使用示例
不止于python
2023/09/05
2010
python之configparser配置文件解析器
exports 和 module.exports 的区别
https://cnodejs.org/topic/5231a630101e574521e45ef8
bear_fish
2018/09/19
7190
exports和module.exports介绍
为了让nodejs开发过程中,为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统,模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。
OECOM
2020/07/01
1.6K0
springboot中引入日志文件生成的配置
知识浅谈
2023/10/10
3360
WebLogic中JSP文件生成Servlet后保留.java文件 WeblogicJSPJavaServletWeb
WebLogic中JSP文件生成Servlet后保留.java文件在weblogic.xml中设置keepgenerated为true即可 默认是在 user_projects     domains         yourdomain             beaserver                 .wlnotdelete                     extract 相应你的应用程序目录中,不过生成.java编译为.class后,.java就被删除了,所以你需要在weblogic.xml里设置如下即可保留.java文件 这样,你就可以在这里找到你的应用程序JSP文件编译成Servlet文件再编译成.class文件了。
阿敏总司令
2019/02/28
1.1K0
PE文件解析器的编写(二)——PE文件头的解析
之前在学习PE文件格式的时候,是通过自己查看各个结构,自己一步步计算各个成员在结构中的偏移,然后在计算出其在文件中的偏移,从而找到各个结构的值,但是在使用C语言编写这个工具的时候,就比这个方便的多,只要将对应的指针类型转化为各个结构类型,就可以使用指针中的箭头来直接寻址到结构中的各个成员。 这次主要说明的是PE文件头的解析,也就是之前看到的第一个界面中显示的内容,这个部分涉及到CPeFileInfo这个解析类的部分代码,以及CPeFileInfoDlg这个对话框类的代码。
Masimaro
2018/08/31
1.4K0
Module.exports和exports的区别
学习Seajs时,看到了exports.doSomething和module.exports,想对这两者的区别一探究竟。 [1486958877980_3135_1486958879213.png]
金朝麟
2017/02/11
1.3K0
Module.exports和exports的区别

相似问题

PEGJS :嵌套pegjs语法

16

PEGJS:为谓词第一语法生成AST

15

PEGJS谓词文法

11

PEGjs中的条件语法规则

11

PegJS数学解析

17
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档