gpt4 book ai didi

java - 如何在按下鼠标按钮时将对象添加到屏幕上?

转载 作者:太空宇宙 更新时间:2023-11-04 11:21:28 25 4
gpt4 key购买 nike

我目前正在制作一款基于图 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();




}

}

最佳答案

也许尝试回答这个问题的最好方法是举一个小例子。

本质上需要发生的事情如下(假设我对问题的理解是正确的):

  1. 用户单击JComponent/JPanel来确定放置Tile的位置。这将导致需要监听和处理的 MouseEvent
  2. JComponent/JPanel 需要一个 MouseListener 实现,它将创建一个新的 Tile 对象并将其添加到 Tile 对象的 List 中。完成后,JComponent/JPanel 需要知道repaint()。您无需重写 repaint(),而是重写 paintComponent(Graphics g),它将由 repaint() (最终)调用。
  3. 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();
}
});
}

}

最后,为了完整性,示例中使用的其他类是 TileStoneTile。就我个人而言,我认为在模型中使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com