有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java当我按下鼠标按钮时,如何向屏幕添加对象?

我目前正在制作一个基于瓷砖的游戏。到目前为止一切正常。但是,我希望玩家能够在按下鼠标按钮时将石头或木头等物体添加到屏幕上。我自己也尝试过,但不起作用。以下是我所做的,但不起作用:

这是我的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);
  }

}

纹理。stoneArray[0]就是我想要添加到屏幕上的图像。 瓷砖。(实例变量,如x、y、TILEWIDTH和TILEHEIGHT)只是一个平铺类,它包含平铺(草、石等)的所有渲染方法。如果有任何不清楚的地方,我会澄清,或者如果您需要提供任何代码,那么我会添加它

注意-ArrayList只是我脑海中的一个想法,如果有更有效的方法或更好的想法,我愿意接受所有这些想法

这是我放鼠标听筒的地方。我在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) 个答案

  1. # 1 楼答案

    也许回答这个问题的最好方法就是举个小例子

    基本上,需要发生以下情况(假设我对问题的理解是正确的):

    1. 用户单击JComponent/JPanel以确定放置Tile的位置。这将导致需要监听和处理的MouseEvent
    2. JComponent/JPanel需要一个MouseListener实现,它将创建一个新的Tile对象,并将其添加到Tile对象的List中。完成后JComponent/JPanel需要知道repaint()。您不重写repaint(),而是重写paintComponent(Graphics g),它最终将被repaint()调用
    3. paintComponent(Graphics g)方法将迭代ListTile对象,使用组件的Graphics上下文将它们绘制到JComponent/JPanel

    为了说明这一点,我简化了你的问题。注意,这不是解决问题的最佳方法,因为模型(游戏逻辑)和GUI应该分开,理想情况下使用模型-视图-控制器/观察者模式

    首先也是最重要的是GamePanel类,它扩展了JPanel。在本例中,它的唯一作用是以图形方式显示游戏并处理鼠标单击。i、 e.处理上述任务清单

    游戏面板

    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{}是静态的,这种情况可能不会发生,因为它属于类,而不是类的特定实例