我正在尝试制作一个非常简单的平铺RPG。在第一次测试中,瓷砖位于正确的位置,但是当我重构程序并创建了名为map和tile.map的类来存储和显示地图和瓷砖以存储瓷砖的pos和img以及用于碰撞检测时,它是错误的放置图像。
该类的结构包括一个Main类“Frame”,它保存存储在字符串数组中的映射,然后创建一个map类并放置字符串数组,草和水纹理,以及tile高度和宽度以及Graphics对象( init在paint方法中调用soo我会得到一个图形对象而不是null)。
地图使用基于字符串数组的tile类创建了一个二维数组。磁贴获取图形对象并将img绘制到它上面。现在,当我运行它时,它将瓷砖放在错误的位置。
代码链接:
修改:添加了整个代码:
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);
}
}
答案 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;
}
}