首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >分块优化

分块优化
EN

Code Review用户
提问于 2014-03-26 08:15:30
回答 2查看 106关注 0票数 8

我已经编写了下面的代码作为我正在编写的游戏引擎的水平渲染部分。我非常高兴它的工作方式,但由于它是由单个块组成的背景/水平图形,它需要快速。

它的外观是从其他地方加载的资源中获取图形,如果它在查看窗口中,则将其缩放到块上。

Blocksize是块的大小,可以增加缩小,并用于缩放块,使缩放效果。

如何从速度和缩短代码的速度来提高代码的可读性?

代码语言:javascript
复制
public void render(Graphics g){

    //Ensure player co-ords updated
    camerax=playerx-(gamewidth/2);
    cameray=playery-(gameheight/2);


    int blockwidth=blocksize-2;
    //Draw coloured blocks
    int screenx=-(int)camerax-blocksize;
    for (int x=0;x<sizex;x++){
          screenx+=blocksize;
          if (screenx>-blocksize && screenx<gamewidth){
              int screeny=-(int)cameray-blocksize;   
              for (int y=0;y<sizey;y++){
              screeny+=blocksize;    
              if (screeny>-blocksize && screeny<gameheight){              
                if (tiles[x][y][0]>0){
                    g.drawImage(levelgraphics, screenx,screeny, screenx+blockwidth,screeny+blockwidth, graphicsize,0,graphicsize*2,graphicsize, null);
                } else {
                    g.setColor(new Color( tiles[x][y][1]));
                    g.fillRect(screenx,screeny,blockwidth,blockwidth);   

                    g.setColor(Color.WHITE);
                    g.drawString(String.valueOf(x+y*sizex), screenx+5,screeny+20);
                }
              }
            }
        }
     }           

    //world - camera = screen, algebra that world = screen + camera
    //Add camerax to mouse screen co-ords to convert to world co-ords.    
    int cursorx_world=(int)camerax+(int)GameInput.mousex;
    int cursorx_grid=(int)cursorx_world/blocksize;  // World Co-ords / gridsize give grid co-ords
    int cursorx_screen=-(int)camerax+(cursorx_grid*blocksize);

    //Add cameray to mouse screen co-ords to convert to world co-ords.         
    int cursory_world=(int)cameray+(int)GameInput.mousey;
    int cursory_grid=(int)cursory_world/blocksize;
    int cursory_screen=-(int)cameray+(cursory_grid*blocksize);  


    //Draw on screen cursor
   if (cursorx_grid>=0 && cursory_grid>=0 && cursorx_grid<sizex && cursory_grid<sizey){
            //if (detect(cursorx_grid,cursory_grid)){
            //if (tiles[cursorx_grid][cursory_grid][0]>1){
                g.setColor(Color.yellow);
                g.drawRect(cursorx_screen,cursory_screen,blockwidth,blockwidth);       
            //}
    }
    //Draw on screen map
    for (int x=0;x<sizex;x++){
        for (int y=0;y<sizey;y++){
            g.setColor(new Color((int) tiles[x][y][1]));
            g.fillRect(mapx+x*mapsize, mapy+y*mapsize, mapsize, mapsize);
        }
    } 

   //Outline
            g.drawRect(mapx,mapy,mapsize*sizex ,mapsize*sizey );

   //Map location box
            g.setColor(Color.RED);
            g.drawRect(mapx+mapsize*((int)camerax/blocksize),mapy+mapsize*((int)cameray/blocksize),(gamewidth/blocksize)*mapsize ,(gameheight/blocksize)*mapsize );
}

最后一段代码将地图添加到屏幕上,并在其上弹出一个缩放框,这样玩家就可以看到他们正在查看的地图的哪一部分。

EN

回答 2

Code Review用户

发布于 2014-03-26 17:39:15

空白是免费的,使用它们

您的代码很难阅读,因为所有的操作符都挤在一起。

避免分支

一个遗漏的分支预测会迫使您的CPU放弃它所做的所有推测执行。虽然现代CPU非常擅长分支预测,但在可能的情况下避免分支是一个很好的实践。在您的例子中,它将减少循环中的迭代。

代码语言:javascript
复制
int screenx = -(int)camerax - blocksize;
for (int x = 0; x < sizex; x++){
    screenx += blocksize;
    if (screenx > -blocksize && screenx < gamewidth){

应:

代码语言:javascript
复制
int screenx = -(int)camerax - blocksize;
int xstart = Math.max(0, -(blocksize + screenx) / blocksize);
int xend = Math.min(sizex, (gamewidth - screenx) / blocksize);
screenx += blocksize * xstart; // Edit: We need to keep this value updated too.
for (int x = xstart; x < xend; ++x){
    screenx += blocksize;

内环也是如此。取决于相机大小和级别大小的比率(如果我正确地解释了您的代码),这可能会带来很大的加速。

提示:y方向迭代开始值和结束值在x方向上独立于当前迭代,因此在进入第一个循环之前计算yend和ystart。

注意:由于我不知道所有变量是什么,上面的xstartxend可能是一个接一个的,请根据口味进行调整。

编辑: Oops刚刚意识到这就是Neil在他回答的第一点中提到的。但我会把这个放在这里,因为这是他说的一个例子。

Edit2:在进入循环之前错过了screenx的增量。

票数 7
EN

Code Review用户

发布于 2014-03-26 09:49:36

我注意到三件事:

  1. 一般来说,当你有一个for和一个巨大的,如果组成for的内容,这是因为你正在检查一个条件,以便做某事。如果此条件与您正在迭代的内容相关,则可以修改for循环以确保条件为真。在不知道您的代码是如何工作的情况下,我不太愿意自己来修复它,但是如果处理得当,您就不需要包含这个巨大的内部if。
  2. 你要把整个矩阵循环两次。这是低效的,不应该这样做,除非您需要的信息只能通过至少一次传递所有数据(例如矩阵值和)才能获得。如果您担心这会使您的代码更加混乱,那么请看下面的要点。
  3. 将每个绘图任务分离到自己的方法中。任务的这种分离使得维护和读取变得更容易,因为如果您试图修复与绘制有色块相关的问题,则不需要查看绘制地图位置框的代码。在嵌套循环的情况下,例如循环遍历所有矩阵项时,应该将整个循环放置在自己的方法中,对于要为每个块执行的每次绘制操作,调用自己的方法传递所需的任何信息。

我希望这能帮上忙。

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

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

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档