【问题标题】:Java more elegant way to write if statements with imagesJava 更优雅的方式来编写带有图像的 if 语句
【发布时间】:2011-03-08 21:24:10
【问题描述】:

有没有更优雅/更短/更有条理的方式来编写这段代码?

for (int i = 0; i < SCREENSIZE; i++) {
        for (int j = 0; j < SCREENSIZE; j++) {
            if (map[y + i][x + j] == '@')
                g.drawImage(item, j * TILESIZE,i * TILESIZE, null);
            else if (map[y + i][x + j] == ' ')
                g.drawImage(ground, j * TILESIZE,i * TILESIZE, null);
            else if (map[y + i][x + j] == 'i')
                g.drawImage(bush, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '~')
                g.drawImage(ocean, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '=')
                g.drawImage(fence, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '#')
                g.drawImage(grass, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == 'Y')
                g.drawImage(townsPerson, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '/')
                g.drawImage(house01, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '¯')
                g.drawImage(house02, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '\\')
                g.drawImage(house03, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '[')
                g.drawImage(house04, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == 'n')
                g.drawImage(house05, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '_')
                g.drawImage(house06, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == ']')
                g.drawImage(house07, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '`')
                g.drawImage(cground, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == 'O')
                g.drawImage(boulder, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == 'Ÿ')
                g.drawImage(alien, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == '.')
                g.drawImage(tree01, j * TILESIZE, i * TILESIZE, null);
            else if (map[y + i][x + j] == 'T')
                g.drawImage(tree02, j * TILESIZE, i * TILESIZE, null);
        }
    }

【问题讨论】:

  • Map&lt;Char,Image&gt; tiles;,将所有这些添加到映射.put('O', boulder),使用映射作为查找表?

标签: java image short


【解决方案1】:

第一个改进可能是使用 switch/case 结构,但在您的情况下,一个简单的映射 (Map&lt;Char,Image&gt;) 会更好。

更进一步,您可以使用枚举而不是字符来识别对象,这将帮助您避免拼写错误,但至少您应该使用字符常量,例如

public static final char MAP_ITEM = '@';
public static final char MAP_GROUND = ' ';

等等。

【讨论】:

    【解决方案2】:

    某处(在构造函数中?),将Map 保存为成员变量:

    images = new HashMap<Character, Image>();
    images.put('@', item);
    images.put(' ', ground);
    

    然后,您的绘图将如下所示:

    for (int i = 0; i < SCREENSIZE; i++) {
        for (int j = 0; j < SCREENSIZE; j++) {
            g.drawImage(images.get(map[y+i][x+j]), j * TILESIZE, i * TILESIZE, null)
        }
    }
    

    【讨论】:

    • 我尝试将代码放入我的编译器并声明我的 HashMap,如下所示:HashMap images;。它在声明时和使用 images.put 时给我警告。我在使用images = new HashMap&lt;char, Image&gt;(); 时也遇到错误,它表示此标记之后的预期尺寸(char 带下划线)?
    • 像这样声明它参数化:HashMap&lt;Char, Image&gt;。您还必须使用带有大写“c”的Char,因为Java 的有趣 类型系统以及它允许​​您用作模板参数的内容。
    • 对不起,这是Character 而不是Char。
    【解决方案3】:

    由于您基于角色,您可以使用switch 语句。 您可以做的另一件事是,由于您在每种情况下都使用g.drawImage(SOMETHING, j * TILESIZE, i * TILESIZE, null),您可以提取与切换后相同的所有内容并分配一些变量并将其用于更改

    前:

    Object graphic;
    switch (map[y + i][x + j]) {
    case '@': 
        graphic = item;
        break;
    case '#':
        graphic = grass;
        break;
    // etc....
    }
    g.drawImage(graphic, j * TILESIZE, i * TILESIZE, null);
    

    【讨论】:

      【解决方案4】:

      使用 switch/case(不是映射),因为编译器将有更多空间进行优化,因为它知道您要打开的 char 值的确切集合:

      ...
      switch(map[y+i][x+j]) {
          case: '@': image = item; break;
          case: ' ': image = ground; break;
          ...
      }
      g.drawImage(image, j * TILESIZE, i * TILESIZE, null);
      ...
      

      【讨论】:

      • ALSO:最快的解决方案是,如果你确定你永远不会得到除了你正在测试的值之外的值,那么你可以创建一个大小为 255 的 array,分配像tile_array['@'] = item;,然后用 single 行替换所有代码:g.drawImage(tile_array[map[y+i][x+j]], j * TILESIZE, i * TILESIZE, null);
      【解决方案5】:

      您可以使用带有 char 值的开关,这样可能会更清晰。此外,第二个、第三个和第四个参数总是相同的,因此可以在开关中设置一个 var 并在外部调用该方法。一点伪代码:

      for() {
        for() {
           Image obj;
           switch (map[y+i][x +j]) {
             case '@':
               Obj = item;
               break;
           // other cases
             default:
             //default or error handling
         }
         g.drawImage(obj, j * TILESIZE, i * TILESIZE, null);
       }
      }
      

      【讨论】:

        猜你喜欢
        • 2022-10-25
        • 1970-01-01
        • 1970-01-01
        • 2022-06-17
        • 1970-01-01
        • 2019-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多