java - 基于带整数的文件在 Canvas 上平铺绘图

标签 java awt paintcomponent tile

所以我试图根据一个包含整数的文件制作 map

1111111111
1000000001
1000000001
1000000001
1111111111

所以我得到的代码是显示 1 的草地 block (32x32) 和 0 的土 block 。

这是我用于加载和区分 2 的代码。

protected void loadMapFile(String string) throws Exception {
    // TODO Load Map, Put into int array
    File f = new File(string);
    BufferedReader in = new BufferedReader(new FileReader(f));
    String line = in.readLine();

    cols = line.length();
    rows = count(string) + 1;
    System.out.println(rows);

    lines = new String[rows];
    map = new Image[cols][rows];
    mapMask = new int[cols][rows];

    while (line != null) {
        lines[counter] = line;
        counter++;
        line = in.readLine();
    }

    for (int y = 0; y < rows; y++) {
        for (int x = 0; x < cols; x++) {
            mapMask[x][y] = Integer.parseInt(lines[y].substring(x, x + 1));
            System.out.print(mapMask[x][y]);
            setImageContent(x, y);

        }
        System.out.println("");
    }
    mapCreated = true;

}




private void setImageContent(int x, int y) {
    switch (mapMask[x][y]) {
    case 0:// dirt
        map[x][y] = Images.DirtTile.getImage();
        break;
    case 1:// grass
        map[x][y] = Images.GrassTile.getImage();
        break;
    }
}

在我的绘画方法中,我是这样画的:

public void paintComponent(Graphics g) {
    if (mapCreated) {
        for (int y = 0; y < endRows; y++) {
            for (int x = 0; x < endCols; x++) {
                g.drawImage(map[x][y], 0 + (x * 32), 0 + (y * 32),
                        32 + (x * 32), 32 + (y * 32), 0, 0, 32, 32, this);
            }
        }
    }

}

我的问题是,你们会推荐这个吗?还有没有更简单的方法可以将 Tiles 渲染到屏幕上?

最佳答案

  • 您应该使用 for 循环将图 block 最初绘制到更大的 BufferedImage 并将 BufferedImage 保存到类字段。
  • 然后使用 drawImage 在 paintComponent(...) 中绘制单个 BufferedImage。这将使绘图更加高效。
  • 当然,除非您的瓷砖快速连续变化。

另一种方法是将图 block 放入 ImageIcons,将图标放入 JLabel 数组。例如:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class GridExample extends JPanel {
   public static final int[][] MAP = {
      {1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2},
      {1, 1, 0, 0, 2, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2},
      {1, 1, 0, 0, 0, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2},
      {1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2},
      {1, 1, 1, 1, 1, 0, 0, 0, 2, 2, 2},
      {1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 2}
   };

   public static final Color[] COLORS = {};
   private JLabel[][] labelGrid = new JLabel[MAP.length][MAP[0].length];

   public GridExample() {
      setLayout(new GridLayout(MAP.length, MAP[0].length));
      for (int r = 0; r < labelGrid.length; r++) {
         for (int c = 0; c < labelGrid[r].length; c++) {
            labelGrid[r][c] = new JLabel();
            labelGrid[r][c].setIcon(Ground.getGround(MAP[r][c]).getIcon());
            add(labelGrid[r][c]);            
         }
      }
   }

   private static void createAndShowGui() {
      GridExample mainPanel = new GridExample();

      JFrame frame = new JFrame("GridExample");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

enum Ground {
   DIRT(0, new Color(205,133, 63)), GRASS(1, new Color(0, 107, 60)), 
   WATER(2, new Color(29, 172, 214));
   private int value;
   private Color color;
   private Icon icon;

   private Ground(int value, Color color) {
      this.value = value;
      this.color = color;

      icon = createIcon(color);
   }

   private Icon createIcon(Color color) {
      int width = 24; // how to use const in enum? 
      BufferedImage img = new BufferedImage(width, width, BufferedImage.TYPE_INT_ARGB);
      Graphics g = img.getGraphics();
      g.setColor(color);
      g.fillRect(0, 0, width, width);
      g.dispose();
      return new ImageIcon(img);
   }

   public int getValue() {
      return value;
   }

   public Color getColor() {
      return color;
   }

   public Icon getIcon() {
      return icon;
   }

   public static Ground getGround(int value) {
      for (Ground ground : Ground.values()) {
         if (ground.getValue() == value) {
            return ground;
         }
      }
      return null;
   }

}

示例 2:可以通过鼠标按下来更改图标的 Grid:

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class GridExample extends JPanel {
   private Ground[][] groundMap = {
         { Ground.GRASS, Ground.DIRT, Ground.DIRT, Ground.WATER, Ground.WATER,
               Ground.WATER, Ground.WATER, Ground.WATER, Ground.WATER,
               Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.DIRT, Ground.WATER,
               Ground.WATER, Ground.WATER, Ground.WATER, Ground.WATER,
               Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.WATER,
               Ground.WATER, Ground.WATER, Ground.WATER, Ground.WATER,
               Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.DIRT,
               Ground.WATER, Ground.WATER, Ground.WATER, Ground.WATER,
               Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.GRASS, Ground.GRASS, Ground.DIRT,
               Ground.WATER, Ground.WATER, Ground.WATER, Ground.WATER,
               Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.DIRT,
               Ground.DIRT, Ground.WATER, Ground.WATER, Ground.WATER,
               Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.DIRT, Ground.DIRT,
               Ground.WATER, Ground.WATER, Ground.WATER, Ground.WATER,
               Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.DIRT,
               Ground.DIRT, Ground.WATER, Ground.WATER, Ground.WATER,
               Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.GRASS, Ground.GRASS,
               Ground.GRASS, Ground.DIRT, Ground.DIRT, Ground.DIRT,
               Ground.DIRT, Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.GRASS, Ground.GRASS,
               Ground.GRASS, Ground.DIRT, Ground.DIRT, Ground.DIRT,
               Ground.WATER, Ground.WATER, Ground.WATER },
         { Ground.GRASS, Ground.GRASS, Ground.GRASS, Ground.GRASS,
               Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.DIRT,
               Ground.DIRT, Ground.WATER, Ground.WATER }, };

   private JLabel[][] labelGrid = new JLabel[groundMap.length][groundMap[0].length];

   public GridExample() {
      setLayout(new GridLayout(groundMap.length, groundMap[0].length));
      for (int r = 0; r < labelGrid.length; r++) {
         for (int c = 0; c < labelGrid[r].length; c++) {
            labelGrid[r][c] = new JLabel();
            labelGrid[r][c].setIcon(groundMap[r][c].getIcon());
            add(labelGrid[r][c]);
         }
      }

      addMouseListener(new MyMouseListener());
   }

   private class MyMouseListener extends MouseAdapter {
      @Override
      public void mousePressed(MouseEvent mEvt) {
         Component comp = getComponentAt(mEvt.getPoint());
         for (int row = 0; row < labelGrid.length; row++) {
            for (int col = 0; col < labelGrid[row].length; col++) {
               if (labelGrid[row][col] == comp) {
                  Ground ground = groundMap[row][col];
                  int mapCode = ground.getValue();
                  mapCode++;
                  mapCode %= Ground.values().length;
                  groundMap[row][col] = Ground.values()[mapCode];
                  labelGrid[row][col].setIcon(groundMap[row][col].getIcon());
               }
            }
         }
      }
   }

   private static void createAndShowGui() {
      GridExample mainPanel = new GridExample();

      JFrame frame = new JFrame("GridExample");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

enum Ground {
   DIRT(0, new Color(205, 133, 63)), GRASS(1, new Color(0, 107, 60)), WATER(2,
         new Color(29, 172, 214));
   private int value;
   private Color color;
   private Icon icon;

   private Ground(int value, Color color) {
      this.value = value;
      this.color = color;

      icon = createIcon();
   }

   private Icon createIcon() {
      int width = 24;
      BufferedImage img = new BufferedImage(width, width,
            BufferedImage.TYPE_INT_ARGB);
      Graphics g = img.getGraphics();
      g.setColor(color);
      g.fillRect(0, 0, width, width);
      g.dispose();
      return new ImageIcon(img);
   }

   public int getValue() {
      return value;
   }

   public Color getColor() {
      return color;
   }

   public Icon getIcon() {
      return icon;
   }

   public static Ground getGround(int value) {
      for (Ground ground : Ground.values()) {
         if (ground.getValue() == value) {
            return ground;
         }
      }
      return null;
   }

}

关于java - 基于带整数的文件在 Canvas 上平铺绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17916057/

相关文章:

java - 如何在小程序上绘制图像

Java Swing,看不到错误

java - setFrame、JSlider 错误

java - 如何更改持有 AccountInfo 类型对象的 ListView 上的文本?

java - JTextField super.paintComponent() 在 Linux 上忽略背景颜色

java - 使用java1.1淡入淡出图像

java - 哪里需要调用方法 "super.paint()"

java - Apache Ignite 作为 Hibernate L2 缓存存储重复实体

java - 不知道我的算法使用什么数据结构

java - 使用自定义加载程序出现错误 "Register pair 1/2 contains wrong type"