- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我目前正在制作一款基于图 block 的游戏。到目前为止一切都运行良好。但是,我希望玩家在按下鼠标按钮时能够向屏幕添加物体,例如石头或木头。我自己尝试过,但它不起作用。这是我所做的,但不起作用:
这是我的 KeyInput 类,所有键盘和鼠标事件都在其中发生。
public static ArrayList<StoneTile> sTile = new ArrayList<StoneTile>();
public KeyInput(Handler handler) {
this.handler = handler;
}
public void tick(LinkedList<Square> object) {}
public void mousePressed(MouseEvent e){
int mx = e.getX();
int my = e.getY();
System.out.println("Pressed (X,Y): " + mx + " " + my);
sTile.add(new StoneTile(1,mx,my));
if(sTile.add(new StoneTile(1,mx,my))){
System.out.println("ADDED");
}
}
public void mouseReleased(MouseEvent e){
System.out.println("Released");
}
这是我的 StoneTile 类,这是我要添加到屏幕的内容:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.LinkedList;
public class StoneTile extends Tile {
Textures tex;
public StoneTile(int id,int x,int y) {
super(Textures.stoneArray[0], id);
Tile.x = x;
Tile.y = y;
}
public static void main(String[] args) {
}
public Rectangle getBounds(){
return new Rectangle(x,y,Tile.TILEWIDTH,Tile.TILEHEIGHT);
}
}
Textures.stoneArray[0] 只是我想要添加到屏幕上的图像。Tile.(实例变量,如 x、y、TILEWIDTH 和 TILEHEIGHT)只是一个 Tile 类,其中包含图 block (草、石头等)的所有渲染方法。如果有任何不清楚的地方,我会澄清,或者如果您需要提供任何代码,那么我会添加它。
注意 - ArrayList 只是我想到的一个想法,如果有更有效的方法或任何更好的想法,我愿意接受所有这些。
这是我设置 MouseListener 的地方。我在 init() 方法中设置它,然后在 run() 方法中调用(最后一行):
private void init() {
BufferedImageLoader loader = new BufferedImageLoader();
level = loader.loadImage("level.png");
world = new worldLoader("res/worlds/world1.txt");
handler = new Handler();
WIDTH = getWidth();
HEIGHT = getHeight();
cam = new Camera(handler, Game.WIDTH / 2, Game.HEIGHT / 2);
setWIDTH(getWidth());
setHEIGHT(getHeight());
tex = new Textures();
//backGround = loader.loadImage("/background.jpg");
handler.addObject(new Coin(100, 100, handler, ObjectId.Coin));
handler.addObject(new newStoneTile(20,20,ObjectId.newStoneTile));
handler.addObject(new player_Square(100,100, handler, ObjectId.player_Square));
//handler.addObject(new OneUp(300, 150, handler, ObjectId.OneUp));
this.addKeyListener(new KeyInput(handler));
this.addMouseListener(new KeyInput(handler));
}
jcomponent,这是你的意思吗?
public class Window {
private static final long serialVersionUID = -6482107329548182911L;
static final int DimensionX = 600;
static final int DimensionY = 600;
public Window(int w, int h, String title, Game game) {
game.setPreferredSize(new Dimension(w, h));
game.setMaximumSize(new Dimension(w, h));
game.setMinimumSize(new Dimension(w, h));
JFrame frame = new JFrame();
frame.add(game);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
}
最佳答案
也许尝试回答这个问题的最好方法是举一个小例子。
本质上需要发生的事情如下(假设我对问题的理解是正确的):
JComponent
/JPanel
来确定放置Tile
的位置。这将导致需要监听和处理的 MouseEvent
。JComponent
/JPanel
需要一个 MouseListener
实现,它将创建一个新的 Tile
对象并将其添加到 Tile
对象的 List
中。完成后,JComponent
/JPanel
需要知道repaint()
。您无需重写 repaint()
,而是重写 paintComponent(Graphics g)
,它将由 repaint()
(最终)调用。paintComponent(Graphics g)
方法将迭代 Tile
对象的 List
,并使用组件的 Graphics
上下文将它们绘制到 JComponent
/JPanel
。为了说明这一点,我简化了您的问题。请注意,这不是解决问题的最佳方法,因为模型(游戏逻辑)和 GUI 应该分开,最好使用 Model View Controller /观察者模式。
首先也是最重要的是 GamePanel
类,它扩展了 JPanel
。在此示例中,它的唯一作用是以图形方式显示游戏并处理鼠标单击。即处理上述任务列表。
游戏面板
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<Tile> tiles; // Stores the Tile objects to be displayed
/**
* Sole constructor for GamePanel.
*
* @param width the width of the game panel
* @param height the height of the game panel
*/
public GamePanel(int width, int height) {
tiles = new ArrayList<>();
setPreferredSize(new Dimension(width, height));
// Implement mouse events for when the JPanel is 'clicked', only using the
// mouse released operation in this case.
addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
// On mouse release, add a StoneTile (in this case) to the tiles List
tiles.add(new StoneTile(e.getX(), e.getY()));
// Repaint the JPanel, calling paint, paintComponent, etc.
repaint();
}
@Override
public void mouseClicked(MouseEvent e) {
// Do nothing
}
@Override
public void mousePressed(MouseEvent e) {
// Do nothing
}
@Override
public void mouseEntered(MouseEvent e) {
// Do nothing
}
@Override
public void mouseExited(MouseEvent e) {
// Do nothing
}
});
}
/**
* Draws the Tiles to the Game Panel.
*
* @param g the Graphics context in which to paint
*/
@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 (Tile tile : tiles) {
Rectangle tileRect = tile.getBounds();
g.fillRect(tileRect.x, tileRect.y, tileRect.width, tileRect.height);
}
}
}
第二个是GameFrame
,它扩展了JFrame
。这只是一个基本的 JFrame
,它添加了一个 GamePanel
对象。我还包含了 main
方法,该方法将确保 GUI 在事件调度线程上初始化。
游戏框架
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GameFrame extends JFrame {
private static final String TITLE = "Tile Game"; // Game Frame Window Title
private final JPanel gamePanel;
/**
* Sole constructor for GameFrame.
*
* @param width the width of the game in pixels
* @param height the height of the game in pixels
*/
public GameFrame(int width, int height) {
gamePanel = new GamePanel(width, height);
}
/**
* Performs final configuration and shows the GameFrame.
*/
public void createAndShow() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle(TITLE);
add(gamePanel);
pack();
setVisible(true);
}
/**
* Entry point for the program.
*
* @param args not used
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GameFrame gameFrame = new GameFrame(640, 480);
gameFrame.createAndShow();
}
});
}
}
最后,为了完整性,示例中使用的其他类是 Tile
和 StoneTile
。就我个人而言,我认为在模型中使用 Rectangle 并没有多大好处,但每个都有自己的好处,我希望该示例与您当前的实现有些相似。
平铺
import java.awt.Rectangle;
public abstract class Tile {
private int x, y, width, height;
public Tile(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
}
石砖
public class StoneTile extends Tile {
public StoneTile(int x, int y) {
super(x, y, 100, 100);
}
}
最后一条评论。我注意到您的 sTile
ArrayList
是静态的,但情况可能并非如此,因为它属于该类而不是该类的特定实例。
关于java - 如何在按下鼠标按钮时将对象添加到屏幕上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44858912/
我是一名优秀的程序员,十分优秀!