Java 动态照明的有效实现是什么?
我目前正在开发一个2D Java游戏,并且正在实现动态照明,例如火把、灯泡和太阳。然而,我遇到了一个问题。许多不同实现的尝试都没有达到预期的效果,要么不是我所期待的,要么没有按照预期工作,要么落后于整个游戏。我尝试了以下实现:Java 动态照明的有效实现是什么?,java,lighting,Java,Lighting,我目前正在开发一个2D Java游戏,并且正在实现动态照明,例如火把、灯泡和太阳。然而,我遇到了一个问题。许多不同实现的尝试都没有达到预期的效果,要么不是我所期待的,要么没有按照预期工作,要么落后于整个游戏。我尝试了以下实现: 使用RadialGradientPaint创建的(缓冲图像)遮罩 异步填洪 同步填洪 RadialGradientPaint遮罩并不是我想要的,我的实现并没有处理屏幕上的任何元素,这意味着光线会“穿透”墙壁 第二个实现是异步泛洪填充,无法正常工作。它只渲染了部分光线,
- 使用RadialGradientPaint创建的(缓冲图像)遮罩
- 异步填洪
- 同步填洪
public void lightQueue(int x, int y, float level, boolean isSun){
float newLevel;
Queue<LightData> queue = new LinkedList<LightData>();
queue.add(new LightData(x,y,level));
while(!queue.isEmpty()){
LightData d = queue.remove();
try{
newLevel = d.level - Level.getBlock(d.x, d.y).getLightBlockAmount();
}catch(NullPointerException e){
continue;
}
if(newLevel <= Level.getBlock(d.x, d.y).getLightLevel()) continue;
if(newLevel > 1f){
Level.getBlock(d.x, d.y).setLightLevel(1f);
} else {
Level.getBlock(d.x, d.y).setLightLevel(newLevel);
}
queue.add(new LightData(d.x + 1, d.y, newLevel));
queue.add(new LightData(d.x - 1, d.y, newLevel));
queue.add(new LightData(d.x, d.y + 1, newLevel));
queue.add(new LightData(d.x, d.y - 1, newLevel));
}
}
public void tick(){
for(Emitter e:emitters){
e.tick();
}
if(Main.tickCount % 20 == 0){
for(Emitter e:emitters){
if(e instanceof Sun){
lightRec((int) e.getLocation().getX(), (int)e.getLocation().getY(), e.lightLevel, true);
} else if(Level.shouldRender(e.getLocation(), Level.camera)){
lightRec((int) e.getLocation().getX(), (int)e.getLocation().getY(), e.lightLevel, false);
}
}
}
}
public void render(Graphics g, Camera c){
g.drawImage(texture, c.getRelativePixelX(getLocation().getPixelX()), c.getRelativePixelY(getLocation().getPixelY()), null);
g.setColor(new Color(0f, 0f, 0f, 1f - lightLevel));
g.fillRect(c.getRelativePixelX(getLocation().getPixelX()), c.getRelativePixelY(getLocation().getPixelY()), getBounds(c).width, getBounds(c).height);
g.setColor(Color.WHITE);
}
RelativePixel只是一个从游戏坐标系到屏幕像素的转换,用于正确放置
此代码每秒运行两次,以确保游戏不会立即冻结。多个光源或大于1f的光源(增加半径)将冻结游戏
所以我的问题是,有没有更有效/更好的方法来实现动态照明?
如果没有,我有什么办法可以改进当前的系统吗
如果有任何不清楚的地方,请告诉我!谢谢你我已经回答了这个问题,从上往下看。。。 …但我是同一个问题 使用光线跟踪
老实说,正确的方法是使用别人编写的代码。你可以用3D程序模拟2D,这就是我要走的路线。搜索“java opengl库”并使用其中一个结果。问题是,您将花费与3D程序一样多的时间来编写和调试此2D代码,因此只使用3D是有意义的。您使用Java2D而不是像JOGL或LWJGL这样的OpenGL包装器有什么原因吗?“正确”的方法是使用现有的库。@Kevin这样做有两个原因,第一个原因是这个项目是计算机科学项目(现在已经交了),我们不能使用任何外部库,第二个原因是我从来没有真正想过这一点。在过去的几周里,我已经在考虑实施LWJGL了,但我认为必须有一种方法让它像这样工作。@KevoSoftworks我绝对建议查看LWJGL,或者更好的libGDX。我相信这在Java2D中是可以做到的,但它不会特别快或漂亮。我想我不太确定你的问题是什么,对不起@KevinWorkman感谢您提供的信息,这是对我的问题的正确回答=)。我将看一看libGDX,如果它很好用的话,我将实现它。谢谢分享!我以前看过那篇文章,但忘了试一试。我用这种方法仍然获得了合理的性能,因此优化将使其正常运行。这真的帮了我大忙!非常感谢您接受这个答案!关于如何提高光线跟踪的性能,当然有很多选择,尽管我不认为这是非常糟糕的。。。。(对我来说效果非常好——我甚至在移动设备上也使用了它)