图像显示在错误的地方

时间:2011-09-26 19:12:07

标签: java swing jframe

我正在尝试制作一个非常简单的平铺RPG。在第一次测试中,瓷砖位于正确的位置,但是当我重构程序并创建了名为map和tile.map的类来存储和显示地图和瓷砖以存储瓷砖的pos和img以及用于碰撞检测时,它是错误的放置图像。

该类的结构包括一个Main类“Frame”,它保存存储在字符串数组中的映射,然后创建一个map类并放置字符串数组,草和水纹理,以及tile高度和宽度以及Graphics对象( init在paint方法中调用soo我会得到一个图形对象而不是null)。

地图使用基于字符串数组的tile类创建了一个二维数组。磁贴获取图形对象并将img绘制到它上面。现在,当我运行它时,它将瓷砖放在错误的位置。

代码链接:

  1. (主要课程)框架:pastebin.com/dephCtfg
  2. 地图:pastebin.com/hKitArsf
  3. 平铺:pastebin.com/aagDjEWp
  4. 修改:添加了整个代码:

    import java.awt.*;
    import java.awt.event.*;
    import java.util.ArrayList;
    import javax.swing.*;
    
    public class UsersFrame extends JFrame {
       // images
       private Image imgs[] = new Image[2];
       private int tileH = 25;
       private int tileW = 25;
       // map1
       private Map map1;
       String map1St[] = { 
             "0000000000000000000000000",
             "0111111110011111111000000",
             "0111111110011111111000000",
             "0111111110011111111000000",
             "0111000110011100011000000",
             "0110000110011000011000000",
             "0111001110011100111000000",
             "0111101110011110111000000",
             "0111111110011111111000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000001000000000000000",
             "0000000010000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000",
             "0000000000000000000000000", };
    
       public UsersFrame() {
          loadPics();
       }
    
       public void paint(Graphics gg) {
          map1 = new Map(map1St, tileW, tileH, imgs, gg);
          map1.drawMap();
       }
    
       public static void main(String s[]) {
          JFrame frame = new UsersFrame();
          frame.setTitle("RPG");
          // Add a window listner for close button
          frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
          // This is an empty content area in the frame
          JLabel jlbempty = new JLabel("");
          jlbempty.setPreferredSize(new Dimension(600, 625));
          frame.getContentPane().add(jlbempty, BorderLayout.CENTER);
          frame.setResizable(false);
          frame.pack();
          frame.setVisible(true);
       }
    
       private void loadPics() {
          Image grass = new ImageIcon("/Users/olek/RESOURCES/RPG/grass.jpg")
                .getImage();
          Image water = new ImageIcon("/Users/olek/RESOURCES/RPG/water.jpg")
                .getImage();
          imgs[0] = grass;
          imgs[1] = water;
       }
    }
    
    class Map {
       // TODO: fix images not showing
       // position
       private int dx = 0;
       private int dy = 0;
       // position on the frame
       private int tx = 0;
       private int ty = 0;
       private int tileH;
       private int tileW;
       private int mapW = 25;
       private int mapH = 25;
       private Image imgs[] = { null, null };
       private Graphics g;
       Tile map[][] = new Tile[mapW][mapH];
       String mapSt[];
       private boolean doneDrawing = false;
    
       public Map(String mapSt[], int tileW, int tileH, Image imgs[], Graphics g) {
          this.mapSt = mapSt;
          this.tileW = tileW;
          this.tileH = tileH;
          dx = 0;
          dy = 0;
          tx = 0;
          ty = 0;
          this.imgs = imgs;
          doneDrawing = false;
          this.g = g;
          System.out.print(g.toString());
       }
    
       public void drawMap() {
          if (g == null) {
             System.out.print("g is null");
             return;
          }
          char currTile = mapSt[dy].charAt(dx);
          System.out.print(currTile + "\n");
          if (currTile == '0') {
             System.out.print("drawing water at " + tx + " , " + ty + "\n");
             map[dx][dy] = new Tile(imgs[1], tileW, tileH, tx, ty, true, false, g);
          }
          if (currTile == '1') {
             System.out.print("drawing grass at " + tx + " , " + ty + "\n");
             map[dx][dy] = new Tile(imgs[0], tileH, tileH, tx, ty, false, false, g);
          }
          calcPlacePos();
          if (!doneDrawing) {
             drawMap();
          }
       }
    
       private void calcPlacePos() {
          if (dx != (mapW - 1)) {
             // System.out.print(dx+" != ("+mapW+"-1)\n");
             dx++;
          }
          // System.out.print(dx+" == ("+mapW+"-1) && "+dy+" != ("+mapH+"-1)\n");
          if (dx == (mapW - 1) && dy != (mapH - 1)) {
             dx = 0;
             dy++;
          }
          if (dx == (mapW - 1) && dy == (mapH - 1)) {
             doneDrawing = true;
             System.out.print("done");
          }
          tx = dx * tileW;
          ty = dy * tileH;
       }
    }
    
    class Tile {
       private Image img;
       private int tileH;
       private int tileW;
       private int posX;
       private int posY;
       private boolean isWall;
       private boolean front;
       private Graphics gr;
    
       public Tile(Image i, int w, int h, int pX, int pY, boolean wall,
             boolean inFront, Graphics g) {
          img = i;
          tileH = h;
          tileW = w;
          posX = pX;
          posY = pY;
          isWall = wall;
          front = inFront;
          gr = g;
          drawTile();
       }
    
       public boolean isWall() {
          return isWall;
       }
    
       public boolean isInFront() {
          return front;
       }
    
       public Image getImage() {
          return img;
       }
    
       public void setImage(Image i) {
          if (i != null) {
             img = i;
          } else {
             System.out.print("Could not assign image to Tile object becouse \n" +
                    " gotten image is null");
          }
       }
    
       private void drawTile() {
          Graphics2D g2d = (Graphics2D) gr;
          g2d.translate(0, 22);
          g2d.drawImage(img, posX, posX, null);
          System.out.print(posX + " , " + posY);
       }
    
       public Dimension getDimension() {
          return new Dimension(tileW, tileH);
       }
    }
    

2 个答案:

答案 0 :(得分:1)

在Tile.drawTile()中,您必须执行以下操作:

private void drawTile() {
    Graphics2D g2d = (Graphics2D) gr;
    AffineTransform oldTransform = g2d.getTransform(); //new
    g2d.translate(0, 22);
    g2d.drawImage(img, posX, posY, null);
    g2d.setTransform(oldTransform); //new
    System.out.print(posX+" , "+posY);
}

然而,那里有很多次优代码,但随着你的进展你会学到的!

答案 1 :(得分:1)

不要直接在JFrame中绘制,也不要在绘制方法中绘制,也不应该在paint或paintComponent方法中创建对象并初始化它们。

为什么不简单地将瓷砖图像显示为JLabels持有的ImageIcons? JFrame的contentPane可以将JLabel保存在GridLayout中,使其变得非常容易。

你还想在Swing Graphics上查看一两个教程,因为它可能会变得棘手(至少对我而言),并且在学习这种类型的时候我们常常会抛出许多先入为主的假设。编码

再次,只是为了看看JLabels有多容易(因为我无法访问您的图像文件而简化了图像):

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class UsersFrame2 extends JFrame {
   private static final int TILE_H = 25;
   private static final int TILE_W = 25;
   private static final String MAP_1_ST[] = { 
         "0000000000000000000000000",
         "0111111110011111111000000",
         "0111111110011111111000000",
         "0111111110011111111000000",
         "0111000110011100011000000",
         "0110000110011000011000000",
         "0111001110011100111000000",
         "0111101110011110111000000",
         "0111111110011111111000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000001000000000000000",
         "0000000010000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000",
         "0000000000000000000000000", };
   private ImageIcon grassIcon;
   private ImageIcon waterIcon;
   private JLabel[][] labelGrid = new JLabel[MAP_1_ST.length][MAP_1_ST[0].length()];

   public UsersFrame2() {
      loadPics();
   }

   public static void main(String s[]) {
      JFrame frame = new UsersFrame2();
      frame.setTitle("RPG");
      frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
      //frame.setResizable(false);
      frame.pack();
      frame.setVisible(true);
   }

   private void loadPics() {
      // TODO: uncomment this:
      // Image grass = new ImageIcon("/Users/olek/RESOURCES/RPG/grass.jpg").getImage();
      // Image water = new ImageIcon("/Users/olek/RESOURCES/RPG/water.jpg").getImage();
      Image grass = createImage(Color.green); // TODO: delete this
      Image water = createImage(Color.blue); // TODO: delete this
      grassIcon = new ImageIcon(grass);
      waterIcon = new ImageIcon(water);

      setLayout(new GridLayout(labelGrid.length, labelGrid[0].length));
      for (int row = 0; row < labelGrid.length; row++) {
         for (int col = 0; col < labelGrid[row].length; col++) {
            ImageIcon icon = MAP_1_ST[row].charAt(col) == '0' ? grassIcon
                  : waterIcon;
            labelGrid[row][col] = new JLabel(icon);
            add(labelGrid[row][col]);
         }
      }
   }

   // TODO: delete this:
   private Image createImage(Color color) {
      BufferedImage bImg = new BufferedImage(TILE_W, TILE_H, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = bImg.createGraphics();
      g2.setBackground(color);
      g2.clearRect(0, 0, TILE_W, TILE_H);
      g2.dispose();
      return bImg;
   }

}