标签: java-2d

Java2D:增加线宽

我想增加Line2D的宽度.我找不到任何方法来做到这一点.我是否需要为此目的制作一个小矩形?

java graphics swing java-2d

75
推荐指数
2
解决办法
13万
查看次数

Java2D性能问题

我在使用Java2D时遇到了奇怪的现象.我知道sun.java2d.opengl VM参数可以为2D启用3D加速,但即使使用它也有一些奇怪的问题.

以下是我运行的测试结果:

在JComponent
Image 1 = .bmp格式上绘制具有32x32像素图块的25x18地图,图像2 = A .png格式

没有-Dsun.java2d.opengl = true

120 FPS使用.BMP图像1
13 FPS使用.PNG图像2

使用-Dsun.java2d.opengl = true

12 FPS使用.BN图像1
700 FPS使用.PNG图像2

如果没有加速,我假设每次使用drawImage()我都会在软件中进行某种转换,并且在.PNG的情况下大大降低了FPS.但是,为什么加速时,结果会切换(而PNG实际上表现得更快)?!疯狂!

.BMP图像1被转换为TYPE_INT_RGB的图像类型..PNG图像2被转换为TYPE_CUSTOM的图像类型.为了在有和没有opengl加速的情况下获得一致的速度,我必须创建一个图像类型为TYPE_INT_ARGB的新BufferedImage,并将Image 1或Image 2绘制到这个新图像.

以下是运行的结果:

没有-Dsun.java2d.opengl = true

120 FPS使用.BMP图像1
120 FPS使用.PNG图像2

使用-Dsun.java2d.opengl = true

700 FPS使用.BN图像1
700 FPS使用.PNG图像2

我真正的问题是,我可以假设TYPE_INT_ARGB将是所有系统和平台的本机图像类型吗?我假设这个值可能不同.有没有办法让我获得原生值,以便我总能创建新的BufferedImages以获得最佳性能?

提前致谢...

java java-2d

50
推荐指数
2
解决办法
2万
查看次数

Java2D:将Graphics转换为Graphics2D总是安全的

假设我们总是使用Sun JVM(比如1.5+),那么将Graphics引用转换为Graphics2D总是安全的吗?

我还没有看到它导致任何问题,据我所知,Graphics类是遗留代码,但Java设计者不希望更改Swing和AWT类的接口以保持向后兼容性.

java java-2d

36
推荐指数
3
解决办法
1万
查看次数

Java 2D绘图最佳性能

我正在编写Java 2D游戏.我正在使用内置的Java 2D绘图库,绘制了一个Graphics2D,我从一个来自Canvas in JFrame的BufferStrategy中获取(有时是完全筛选的).BufferStrategy是双缓冲的.重绘是通过计时器主动完成的.我遇到了一些性能问题,特别是在Linux上.

Java2D有很多方法可以创建图形缓冲区和绘制图形,我只是不知道我做的是否正确.我一直在尝试使用graphics2d.getDeviceConfiguration().createCompatibleVolatileImage,看起来很有前景,但我没有真正的证据,如果我将绘图代码切换到那个,它会更快.

根据您的经验,在Java 1.5+中将2D图形渲染到屏幕上的最快方法是什么?请注意,游戏相当遥远,因此我不想切换到完全不同的绘图方法,如OpenGL或游戏引擎.我基本上想知道如何使用Graphics2D对象以最快的方式将内容绘制到屏幕上.

java graphics performance java-2d

31
推荐指数
3
解决办法
4万
查看次数

退出Swing应用程序时偶尔会出现InterruptedException

我最近将我的计算机更新为更强大的计算机,配备了四核超线程处理器(i7),因此可以提供大量真正的并发性.现在我在退出()我正在开发的应用程序(使用Swing GUI)时偶尔会出现以下错误System.exit(0):

Exception while removing reference: java.lang.InterruptedException
java.lang.InterruptedException
        at java.lang.Object.wait(Native Method)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
        at sun.java2d.Disposer.run(Disposer.java:125)
        at java.lang.Thread.run(Thread.java:619)
Run Code Online (Sandbox Code Playgroud)

好吧,鉴于它开始发生在具有更多并发能力的硬件上,并且它与线程有关,并且它偶尔发生,它显然是某种时间性的东西.但问题是堆栈跟踪太短了.我只有上面的列表.它根本不包括我自己的代码,因此有点难以猜测bug的位置.

以前有没有经历过这样的事情?任何想法如何开始解决它?

编辑:因为退出Swing应用程序System.exit(0)可能是"不干净",但我不想设置主框架,EXIT_ON_CLOSE因为我想确保应用程序退出时没有任何关键的事情,我添加了一个机制,以便它执行dispose()调用之前的主框架方法System.exit(0).所以它现在应该很干净,但偶尔也会发生异常.它发生在System.exit(0)被召唤之后; dispose()工作没有问题.也就是说,它必须来自一个关闭钩子:

mainFrame.dispose(); // No problem! After this returns, all visible GUI is gone.
// In fact, if there were no other threads around, the VM could terminate here.
System.exit(0); // Throws an InterruptedException from sun.java2d.Disposer.run
Run Code Online (Sandbox Code Playgroud)

我甚至尝试Window通过循环遍历Window.getWindows()数组显式处理所有s (它包含无主Dialog …

java concurrency multithreading java-2d interrupted-exception

27
推荐指数
2
解决办法
2万
查看次数

设置LCD伽玛/对比度(IntelliJ IDEA,JDK 8)

我在IntelliJ IDEA中遇到了反锯齿文本的问题.那个东西由于某种原因附带了自己版本的OpenJDK 8.无论如何......子像素别名对于明亮的暗文本是可以接受的:

在此输入图像描述

但对于明亮的黑暗文本,伽玛是错误的:

在此输入图像描述

这意味着在这个方案中,文本看起来好像是粗体和水平模糊/模糊.

是否可以指定系统属性或破解系统,否则将AA插值的伽玛值更改为更暗的颜色?我已经选择了一个非常精细的字体(FicaCode Light),在这台计算机上没有显示较少粗体的字体(带有Gnome 3,19000x1080显示屏的Linux).


编辑:我真的在寻找一种控制AA伽玛的方法.我没有使用过IDEA 2017.1 EAP,但是发布版本已经附带了"固定"捆绑调整版本1.8.0_112,这在gist评论中提到过.如果我下载该版本,我会得到与上面两张图像完全相同的像素输出.这些是idea64.jvmoptions:

自定义IntelliJ IDEA VM选项

-Xms128m
-Xmx750m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Dawt.useSystemAAFontSettings=lcd
-Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine
-Djava2d.font.loadFontConf=false
Run Code Online (Sandbox Code Playgroud)

添加或删除最后一个属性只是使零差价,也改变从lcdonoff具有零效果.

将这些图片与我通过Debian安装的常规OpenJDK 1.8.0_121进行比较:

在此输入图像描述

很明显,这里的AA被破坏了(1:1它看起来完全是彩色的).所以我认为捆绑版本的子像素渲染基本上是正确的.只有在深色背景上使用错误的伽玛才能显示浅色文字.


编辑:经过更多的调查,问题归结为:我可以使用之间的自定义font.conf文件,和.对于轻微提示,字体在宽高比方面看起来平衡,但抗锯齿具有错误的伽玛,因此字体线条很粗(一切看起来都是粗体).对于中等或完全提示,字体看起来更细,更清晰,但现在宽高比被打破,字体太宽.hintstylehintslighthintmediumhintfull

java intellij-idea java-2d antialiasing text-rendering

26
推荐指数
1
解决办法
874
查看次数

如何在Java中绘制有向箭头线?

我想在Java中绘制一条有向箭头线.

目前,我正在用java.awt.Line2D.Double班级画一条线

g2.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); // g2 is an instance of Graphics2D
g2.draw(new Line2D.Double(x1,y1,x2,y2));
Run Code Online (Sandbox Code Playgroud)

但只显示该行,并且不显示有向箭头. BasicStroke.Join_BEVEL用于绘制有向箭头.当两个线段相遇时应用它.

我绘制的线条符合矩形的边框,但没有绘制有向箭头.只绘制一条简单的线条.

有什么我想念的吗?

java drawing line java-2d

24
推荐指数
4
解决办法
6万
查看次数

具有复杂形状的碰撞检测

我想制作一个从图像中加载每个级别的游戏.我想在Photoshop中绘制整个关卡,然后将其设置为背景并允许玩家走过它.我希望另一个不可见的图像越过顶部,在我想要碰撞的所有地方都是黑色的.

我之所以不想使用瓷砖,这对于矩形碰撞更容易,因为会有复杂的角落而不是一切都是矩形的.

这是一个好主意,是否可以轻松完成?这会是一个大CPU占用还是有更好的方法来做到这一点?

水平图像

水平图像

障碍物以红色显示

红色的障碍

java image awt java-2d collision

22
推荐指数
1
解决办法
8763
查看次数

如何绘制一个给定X和Y坐标作为圆的中间点的圆?

我开发了一种用于定位塔架信号强度的电信应用.我使用了java swing,当我在移动信号发射塔位置的给定点周围绘制圆圈时遇到问题.我已经计算了X,Y坐标和半径值.

请找到我用来绘制圆圈的下面的代码,它有问题.

JPanel panelBgImg = new JPanel() {
    public void paintComponent(Graphics g) {
        g.drawOval(X, Y, r, r);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,它创建了圆圈,但没有将X和Y坐标作为中心点.将X和Y坐标作为圆的左上角.

任何人都可以通过将给定的X和Y坐标作为圆的中心点来帮助我绘制圆.

java swing java-2d jpanel paintcomponent

22
推荐指数
3
解决办法
17万
查看次数

以OO方式进行游戏设计

我正在设计一个简单的游戏,它使用Java 2D和牛顿物理.目前我的主要"游戏循环"看起来像:

do {
  for (GameEntity entity : entities) {
    entity.update(gameContext);
  }

  for (Drawable drawable : drawables) {
    drawable.draw(graphics2d);
  }
} while (gameRunning);
Run Code Online (Sandbox Code Playgroud)

当指示实体自我更新时,它将根据施加于其上的当前力来调整其速度和位置.但是,我需要实体展示其他行为; 例如,如果玩家射杀了"坏人",则该实体应该被摧毁并从游戏世界中移除.

我的问题:以面向对象的方式实现这一目标的最佳方法是什么?到目前为止,我所见过的所有例子都将游戏循环合并到一个称为类似的神类中Game,执行步骤:检测碰撞,检查是否坏人杀死,检查是否被玩家杀死,重新绘制等等.封装了所有游戏状态(剩下的生命等).换句话说,它是非常程序化的,所有逻辑都在Game类中.有谁能推荐更好的方法?

以下是我到目前为止所考虑的选项:

  • GameContext如果需要,将a传递给实体可以从中移除的每个实体,或更新游戏状态(例如,如果玩家被杀,则"不运行").
  • 将每个人注册GameEntity为中央Game班级的听众,并采取面向事件的方法; 例如,碰撞会导致CollisionEvent向碰撞中的两个参与者发射.

java oop java-2d

21
推荐指数
2
解决办法
4261
查看次数