Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >还能做些什么来增加摇摆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

复制
相关文章
可组合的 Vue
2021年5月来自全球各地的Vue.js开发者齐聚线上,一起见证了VueConf 2021 杭州的成功举办。
@超人
2021/07/05
4890
可组合的 Vue
函数c()_函数的调用
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/15
3.7K0
匿名函数自调用_自己调用自己的函数叫
我们知道一个HTML文件在被加载的时候是从根标签html依次往下的,在遇到link,script等标签引入的外部资源时,下载外部资源,并执行外部资源。在js中,表达式会被立即执行,也就是说,不管是引入的外部js文件还是嵌入在html文件中的js脚本,其中的表达式都会被立即执行。 函数名是一个指向函数的指针。在JavaScript中,定义函数有常见的两种形式:函数声明和函数直接量(或者叫函数表达式)。 函数声明:采用function定义声明函数的标准写法,包括function,函数名,函数体。如
全栈程序员站长
2022/11/09
2.6K0
奇怪的函数调用
整理移动硬盘时,发现一个名为 attack 的目录,进去以后发现原来是一段简单的 C 语言代码。代码如下:
码农UP2U
2021/09/02
1.8K0
奇怪的函数调用
oracle函数的调用应使用execute命令_matlab函数调用
之前一直使用的MySQL数据库,第一次接触Oracle就用到了函数和存储过程,今天跟大家分享一下使用过程.
全栈程序员站长
2022/10/04
2.3K0
oracle函数的调用应使用execute命令_matlab函数调用
JavaScript 的 this 小结纯粹的函数调用作为对象方法的调用作为构造函数调用apply 调用
函数的不同使用场合,this有不同的值。 总的来说,this就是函数运行时所在的环境对象。 下面分情况,详细讨论
JavaEdge
2018/08/02
2.8K0
JavaScript 的 this 小结纯粹的函数调用作为对象方法的调用作为构造函数调用apply 调用
c++函数调用,函数编写(写自己的函数)以及数组调用,传递
在matlab里.m文件分执行文件和函数文件 在c++中执行文件指:main函数 函数文件:其他所有需要用到的函数
用户7886150
2021/02/03
2.4K0
Lua函数的冒号调用和点调用
冒号定义函数中的self指向函数所属表对象,即self是table类型,通过self表可以:访问挂载在该表下的所有冒号定义函数 如,有定义A={},A:b() A:c();函数b,c都是冒号定义函数,在b,c函数内部self是地址指向A的表,在b函数中可以通过self:c()来调用c函数,同理在c函数中也可以通过self:b()来调用b函数 代码示例:
bering
2020/03/19
3.4K0
python之函数的调用
  实际开发过程中,经常会遇到很多完全相同或者非常相似的操作,这时,可以将实现类似操作的代码封装为函数,然后在需要的地方调用该函数。这样不仅可以实现代码的复用,还可以使代码更有条理性,增加代码的可靠性。下面我们来介绍一下python的调用相关内容。
jiankang666
2022/12/05
1.1K0
python之函数的调用
Python调用PHP的函数
        在电子商务的web平台中有可能存在这样的需求,在月末进行分红账务结算,这样就需要在web服务器下写脚本定时执行数据库的操作,这里有很多种可选的方案,Python调
py3study
2020/01/07
3.5K0
函数的调用约定 _cdecl
_cdecl(C declaration,即C声明)是源起C语言的一种调用约定,它规定,在C语言中,函数实参在线程栈上按照从右至左的顺序依次压栈,也就是说,函数参数从右往左传入。
叶茂林
2023/07/28
3870
函数的调用约定 _cdecl
(十七)函数的调用签名
# 一、函数的调用签名 说明 函数的调用签名跟我们上节课使用 type 来定义函数类型的效果基本类型是一样的 但是它支持函数附带额外属性的情况,因为在 javasctipt 里面函数也是一个特殊的对象,可以包含额外的属性 例 // 和我们之前 使用 type 定义函数类型是一样的,只是调用签名是对象形式 type RequesCallback = { (result: string): void // 以为是对象形式,所以不能使用箭头函数 } function request(callba
老怪兽
2023/02/22
1K0
函数的定义和调用
1.1函数的定义方式 方式1 函数声明方式 function 关键字 (命名函数) function fn(){} 方式2 函数表达式(匿名函数) var fn = function(){} 方式3 new Function( '参数1', '参数2',' 函数体'); var f = new Function('a', 'b', 'console.log(a + b)'); f(1, 2); console.1og(f instanceof Object ); //instanceof
星辰_大海
2020/10/26
1.6K0
函数的定义和调用
【编程经验】函数的调用
主调函数使用被调函数的功能,称为函数调用。在 C 语言中,只有在函数调用时,函数体中定义的功 能才会被执行。
编程范 源代码公司
2018/07/24
8350
函数的定义和调用
1.函数的定义和调用 1.1函数的定义方式 方式1 函数声明方式 function 关键字 (命名函数) function fn(){} 方式2 函数表达式(匿名函数) var fn = function(){ 方式3 new Function() var f = new Function('a', 'b', 'console.log(a + b)'); f(1, 2); ​ var fn = new Function('参数1','参数2'..., '函数体') 1.2函数的调用方式 普通函数
梨涡浅笑
2020/10/27
9120
函数的定义和调用
image.png
清出于兰
2022/05/11
9970
函数的定义和调用
JavaScript 函数调用
在 HTML 中默认的全局对象是 HTML 页面本身,所以函数是属于 HTML 页面。
陈不成i
2021/07/19
2.3K0
关于调用函数
在调用函数时只需要传入指定数量和指定类型的值在参数表的指定位置这些值将在方法启动前赋值给形参
算法与编程之美
2022/10/28
1.5K0
关于调用函数
函数调用约定
现代的几乎所有的编程语言都离不开函数和参数的概念。而这个概念是编程语言级别的,而不是硬件级别的。也就是说硬件上本来没有函数的概念。只是函数的用的太普遍,硬件开始为函数准备专用的指令。
战神伽罗
2019/08/13
2.4K0
函数调用约定
在前面的文章中,可以发现无论是x86架构还是x64架构的程序,其内部的函数在被调用时候, 都是首先将函数参数压入栈中(而且是从右向左),然后调用函数,最后还需要调整栈帧。
Elapse
2020/08/17
2K0

相似问题

可组合函数可以调用不可组合函数吗?

12

从可鼠标调用可组合函数

11

可观测函数中调用可组合函数的问题

13

如何在可组合内部调用内部函数?

17

如何从不可组合函数调用可组合通知对话框

16
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

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

洞察 腾讯核心技术

剖析业界实践案例

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