我一直在努力在java中创建一个动态光系统,而不使用库。但是出于某些原因,似乎我无法获得有效运行的光。它闪烁并且滞后一吨。我之前没有对游戏中的照明引擎有所了解,所以我愿意接受建议。这是我目前的更新方法:
public void updateLight( ArrayList<Block> blocks )
{
//reset light
light.reset();
//add the x and y of this light
light.addPoint( x, y );
//precision for loops
int ires = 1;
int jres = 2;
for( int i = 0; i < width; i += ires )
{
//get radians of current angle
float rdir = (float)Math.toRadians( dir + i - width/2 );
//set up pixel vars
int px, py;
for( int j = 0; j < length; j += jres )
{
//get position of pixel
px = (int)ZZmath.getVectorX( x, rdir, j );
py = (int)ZZmath.getVectorY( y, rdir, j );
//if point gets found
boolean foundpoint = false;
for( int n = 0; n < blocks.size(); n ++ )
{
//check if block is solid
//also check that collision is possible really quickly for efficiency
if( blocks.get( n ).solid )
{
//get info on block
int bx = blocks.get( n ).x;
int by = blocks.get( n ).y;
//quick trim
if( Math.abs( bx - px ) <= 32 && Math.abs( by - py ) <= 32 )
{
int bw = blocks.get( n ).w;
int bh = blocks.get( n ).h;
if( ZZmath.pointInBounds( px, py, bx, by, bw, bh ) )
{
//add point to polygon
light.addPoint( px, py );
//found point
foundpoint = true;
}
}
}
}
//if a point is found, break
if( foundpoint )
{
break;
}
//if at end of loop, add point
//loose definition of "end" to prevent flickers
if( j >= length - jres*2 )
{
light.addPoint( px, py );
}
}
}
}
这会修改为灯光显示的多边形。我稍后会改变。我有什么方法可以让它运行得更好吗?此外,不,没有图书馆。我没有任何反对他们的东西,只是现在不想使用它。
答案 0 :(得分:1)
您的实现似乎没有使用我在这里看到的大部分内容:
http://www.cs.utah.edu/~shirley/books/fcg2/rt.pdf
我建议完全消化它。如果您的目标是深入了解光线追踪,那就应该如何完成。
答案 1 :(得分:0)
也许你的目标是通过编写自己的光线跟踪器来学习。根据我的经验,我最终会多次重写这段代码,但仍然没有完全正确。弄脏你的手是件好事,但这不一定是最有效的方法。
总的来说,您需要学习(面向对象的)编程概念,并采用数据结构和算法课程。
最重要的是可读性。记录您的代码,如果没有其他人,为了您未来的自我。这意味着在updateLight()
之前和期间清除评论。现有的评论是正确的(虽然他们释义代码而不是证明它),但是&#34;真的很快就能提高效率&#34;是骗人的。
对于可能对性能造成轻微拖累的小问题,请为blocks.get(n)
创建一个局部变量。将其命名为简短但描述性的,保存输入并仅进行一次方法调用以检索它。
&#34;如果在循环结束时#34;:我不知道你指的是哪个循环,for
循环有明确的结束。评论}//end for
或}//end for width
通常很有帮助。
检查块是否牢固是不必要的!只需将块存储在两个列表中,并且只能通过实体块。即使你有一些想要闪烁的块,一个删除和添加比O(宽度*长度* numbernotsolid)额外的工作便宜。
您可以通过多种方式构建块的存储方式,以便快速进行测试。您只需要或需要测试坐标靠近特定光线的块。基本策略是将空间划分为网格,并根据块落入网格的哪个部分对块进行排序。然后,当您在网格的特定部分中有光时,您知道您只需要在该部分中测试块(可能还有相邻的部分 - 根据其宽度和光线有详细信息)。
我不知道这是否符合正确方法。我对光线追踪知之甚少,尽管它过去或过去都很慢。看起来你有一个不错的天真实现。可能会有一种稍微不同的天真方法,这种方法更快,更难以(编码完成)算法中等但更快。
另外,我认为没有必要先做这个广度。为什么不一次解决一行(你称它们为像素?)。计算此代码调用Math.toRadians
的次数。看起来它只是一条无关紧要的线,因为你可以沿着相同的角度工作直到为下一个角度做好准备。