Java 在屏幕上放置块第2部分
好的,我已经发布了一个类似的问题,问我如何在点击鼠标时在屏幕上放置块。我已经让它工作了。这是通过一些答案的帮助以及制作一个列表来实现的,当按下鼠标按钮时,一个特定的磁贴被添加到此列表中(每个磁贴都有一个图像),然后重新绘制。现在,由于我在游戏中有多个瓷砖,我显然制作了一张草瓷砖地图。我有一个问题,当我放置一个块时,事件会注册,但它不会显示在地图上,但会显示在默认屏幕上(正常的JFrame窗口上没有任何内容)。这将允许完美的块放置,因此它们不会相互重叠 我的想法不是说当按下鼠标按钮并在鼠标坐标处绘制块时,我想找到一种方法来替换瓷砖。例如,如果我运行我的游戏,我有一个10 x 10的瓷砖地图,它由草瓷砖填充,当我单击草瓷砖时,其中一个草瓷砖将被石头瓷砖替换 我想这样做的方式是-Java 在屏幕上放置块第2部分,java,events,mouse,Java,Events,Mouse,好的,我已经发布了一个类似的问题,问我如何在点击鼠标时在屏幕上放置块。我已经让它工作了。这是通过一些答案的帮助以及制作一个列表来实现的,当按下鼠标按钮时,一个特定的磁贴被添加到此列表中(每个磁贴都有一个图像),然后重新绘制。现在,由于我在游戏中有多个瓷砖,我显然制作了一张草瓷砖地图。我有一个问题,当我放置一个块时,事件会注册,但它不会显示在地图上,但会显示在默认屏幕上(正常的JFrame窗口上没有任何内容)。这将允许完美的块放置,因此它们不会相互重叠 我的想法不是说当按下鼠标按钮并在鼠标坐标处绘
public void mousePressed(MouseEvent e) {
if(MouseEvent.BUTTON1 == Tile.grassTile.id) {
tiles.add(new StoneTile(e.getX() - 16, e.getY() - 16,0));
}
}
我之所以想到这样做,是因为我已经为所有的tile分配了一个id,当e.getX()和e.getY()(鼠标坐标)遇到具有特定id的tile时,然后执行上面if语句中的代码。显然,这不起作用,但它是有意义的,我仍然认为这可能起作用,但我很可能错过了一些东西。我知道这不是唯一的方法,我愿意接受所有比我更好的想法
多谢各位
这是一个模拟我的游戏的可运行程序
游戏框架-
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GameFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final String TITLE = "Tile Game"; // Game Frame Window Title
private final JPanel gamePanel;
public GameFrame(int width, int height) {
gamePanel = new GamePanel(width, height);
}
public void createAndShow() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle(TITLE);
add(gamePanel);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GameFrame gameFrame = new GameFrame(640, 480);
gameFrame.createAndShow();
}
});
}
}
import java.awt.Rectangle;
public abstract class stoneTileAdder {
private int x, y, width, height,id;
public stoneTileAdder(int x, int y, int width, int height,int id) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.id = id;
}
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
游戏面板
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList
import java.util.List;
import javax.swing.JPanel;
public class GamePanel extends JPanel {
private List<stoneTileAdder> tiles; // Stores the Tile objects to be displayed
public GamePanel(int width, int height) {
tiles = new ArrayList<>();
setPreferredSize(new Dimension(width, height));
addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
// Do nothing
}
@Override
public void mousePressed(MouseEvent e) {
tiles.add(new StoneTile(e.getX(), e.getY(),0));
// Repaint the JPanel, calling paint, paintComponent, etc.
repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
// Do nothing
}
@Override
public void mouseExited(MouseEvent e) {
// Do nothing
}
});
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // Make sure you do this
// For this example, using black as the color to draw
g.setColor(Color.BLACK);
// Iterate over the tile list and draw them to the JPanel
for (stoneTileAdder tile : tiles) {
Rectangle tileRect = tile.getBounds();
g.fillRect(tileRect.x, tileRect.y, tileRect.width, tileRect.height);
}
}
}
石头头像-
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GameFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final String TITLE = "Tile Game"; // Game Frame Window Title
private final JPanel gamePanel;
public GameFrame(int width, int height) {
gamePanel = new GamePanel(width, height);
}
public void createAndShow() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle(TITLE);
add(gamePanel);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GameFrame gameFrame = new GameFrame(640, 480);
gameFrame.createAndShow();
}
});
}
}
import java.awt.Rectangle;
public abstract class stoneTileAdder {
private int x, y, width, height,id;
public stoneTileAdder(int x, int y, int width, int height,int id) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.id = id;
}
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
}添加瓷砖的更简单方法是找到鼠标按下的组件,如下所示:
@Override
public void mousePressed(MouseEvent e) {
Component selectedTile = findComponentAt(e.getPoint());
if(MouseEvent.BUTTON1 == Tile.grassTile.id && selectedTile instanceof Tile) {
tiles.add(new StoneTile(selectedTile.getX(), selectedTile.getY(), 0));
}
}
这将获得单击的平铺的坐标,并将一个
石头平铺放置在其正上方。添加平铺的更简单方法是找到鼠标按下的组件,如下所示:
@Override
public void mousePressed(MouseEvent e) {
Component selectedTile = findComponentAt(e.getPoint());
if(MouseEvent.BUTTON1 == Tile.grassTile.id && selectedTile instanceof Tile) {
tiles.add(new StoneTile(selectedTile.getX(), selectedTile.getY(), 0));
}
}
这将获取单击的平铺的坐标,并将一个石头平铺放置在其正上方。只获取单击的平铺位置,而不是鼠标位置,然后将其替换为石头平铺,不是更好吗?另外,请给出一个可编译的示例。不是你的整个程序,只是一个我们可以修复的可运行示例。在你的鼠标压缩方法中:if(MouseEvent.BUTTON1){if(鼠标位置在块的边界内){tiles.add(new StoneTile();}}}}或者更好,只需更改已经存在的块的ID。@KylonTyner我喜欢简单地获取块的边界的想法,但我该如何在if声明中说明这一点。因为获取边界是一个矩形。@CodeLife如果网格大小固定,只需除以网格大小(使用整数除法)。因此,如果网格位于位置(1,2)且网格大小为16,则网格的“像素角点”将位于(16,32)、(16,47)、(31,47)和(31,32)。如果您单击点(18,35)并将两者除以16,您将得到(1,2)。我希望这是有意义的。@CodeLife你能发布你的Tile类吗?这是我唯一能解决你问题的方法。点击瓷砖的位置,而不是鼠标位置,然后用石头瓷砖替换,不是更好吗?另外,请给出一个可编译的示例。不是你的整个程序,只是一个我们可以修复的可运行示例。在你的鼠标压缩方法中:if(MouseEvent.BUTTON1){if(鼠标位置在块的边界内){tiles.add(new StoneTile();}}}}或者更好,只需更改已经存在的块的ID。@KylonTyner我喜欢简单地获取块的边界的想法,但我该如何在if声明中说明这一点。因为获取边界是一个矩形。@CodeLife如果网格大小固定,只需除以网格大小(使用整数除法)。因此,如果网格位于位置(1,2)且网格大小为16,则网格的“像素角点”将位于(16,32)、(16,47)、(31,47)和(31,32)。如果您单击点(18,35)并将两者除以16,您将得到(1,2)。我希望这是有意义的。@CodeLife你能发布你的Tile类吗?这是我解决您问题的唯一方法。“0”指的是互动程序id。我可以问一下centerPanel的功能和功能吗?我测试了你的代码,中心面板用红色下划线。如果我给您一个可运行的示例,您将需要许多类(如果不是全部的话),仅仅提供一个或两个类来运行是不可能的。如果这就是你的意思,对不起,如果我误解了。@CodeLife嘿CodeLife!谢谢你的反馈<代码>中心面板
仅指您将瓷砖放入的任何面板。它是父对象(平铺是子对象)。只需将centerPanel更改为添加瓷砖的位置即可。我刚刚意识到面板名称是tiles
,如果我是正确的话。我已经编辑了我的帖子,现在应该可以了。您可能仍然需要修改它。@CodeLife(cont.)“可运行示例”我不是指程序的缩短版本,只是尝试制作一个针对您的问题的示例程序。只需制作一个可以添加瓷砖且尽可能简单的。要获得更多帮助,请访问:我已经添加了一个可运行的示例,我希望它足够了!谢谢你的帮助@CodeLife表示此行中有错误:Tile selectedfile=(Tile)findComponentAt(e.getPoint())代码>尝试将其更改为Tile selectedTile=findComponentAt(e.getPoint())代码>我还编辑了我的帖子。“0”指的是互动程序id。我可以问一下centerPanel的功能和功能吗?我测试了你的代码,中心面板用红色下划线。如果我给您一个可运行的示例,您将需要许多类(如果不是全部的话),仅仅提供一个或两个类来运行是不可能的。如果这就是你的意思,对不起,如果我误解了。@CodeLife嘿CodeLife!谢谢你的反馈<代码>中心面板
仅指