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

时间:2017-07-01 08:30:06

标签: java awt

我目前正在制作基于平铺的游戏。到目前为止,一切都很好。但是,我希望玩家能够在他/她按下鼠标按钮时向屏幕添加石头或木头等对象。我自己尝试了这个,但它没有用。这是我所做的,但不起作用:

这是我的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类,它包含了tile(草,石头等)的所有渲染方法。如果有任何不清楚的地方,我会澄清,或者如果您需要提供任何代码,我会将其添加进去。

注意 - 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 个答案:

答案 0 :(得分:0)

尝试回答这个问题的最佳方法可能是举一个小例子。

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

  1. 用户点击JComponent / JPanel以确定Tile的放置位置。这将导致需要收听和处理的MouseEvent
  2. JComponent / JPanel需要MouseListener实施,该实施将创建新的Tile对象,并将其添加到List Tile对象。完成后,JComponent / JPanel需要知道repaint()。您不会覆盖repaint(),而是paintComponent(Graphics g)repaint()(最终)会调用paintComponent(Graphics g)
  3. List方法将遍历Tile JComponentJPanel个对象,使用Graphics上下文将其绘制到GamePanel / JPanel对于组件。
  4. 为了说明这一点,我简化了你的问题。请注意,这不是解决问题的最佳方法,因为模型(游戏逻辑)和GUI应该分开,理想情况下使用模型视图控制器/观察者模式。

    首先也是最重要的是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。在这个例子中,唯一的作用是以图形方式显示游戏并处理鼠标点击。即处理上述任务清单。

    <强>的GamePanel

    JFrame

    第二个是JFrame,它扩展了GamePanel。这只是一个基本的main,它会添加一个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方法,该方法将确保在事件调度线程上初始化GUI。

    <强> GameFrame

    StoneTile

    最后,示例中用于完整性的其他类Rectangleimport 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

    <强> StoneTile

    ArrayList

    最后一条评论。我注意到你的w_cen = (1-1/np.sqrt(2))**2 # Weights w_diag = (1/np.sqrt(2))**2 w_orto = (1-1/np.sqrt(2))*(1/np.sqrt(2)) def bilinear_interpoplation(i_cen, i_diag, i_hor, i_ver): return i_cen*w_cen + i_diag*w_diag + i_hor*w_orto + i_ver*w_orto def circular_neighbourhood(x): [I7, I6, I5] = x[0, :] [I0, Ic, I4] = x[1, :] [I1, I2, I3] = x[2, :] I7i = bilinear_interpolation(Ic, I7, I0, I6) I5i = bilinear_interpolation(Ic, I5, I4, I6) I3i = bilinear_interpolation(Ic, I3, I4, I2) I1i = bilinear_interpolation(Ic, I1, I0, I2) interpolated = np.array([[I7i, I6, I5i], [ I0, Ic, I4], [I1i, I2, I3i]]) return interpolated def binary_pattern(x): return np.where(x >= x[1, 1], 1, 0) def display_lbps(patch): interpolated = circular_neighbourhood(patch) print('Patch =') print(patch) print('LBP of patch =') print(binary_pattern(patch)) print('Interpolated patch =') print(interpolated) print('LBP of interpolated patch =') print(binary_pattern(interpolated)) display_lbps(image[0:3, 0:3]) display_lbps(image[1:4, 1:4]) public function unverified_jobs_page() { $query = "SELECT jd.*, cd.`company_name`, jc.`category_title`, jt.`job_type_title`, cc.`city_name` FROM `job_details` AS jd JOIN `company_details` AS cd ON cd.`company_id`=jd.`company_id` JOIN `job_category` AS jc ON jc.`category_id`=jd.`category_id` JOIN `job_type` AS jt ON jt.`job_type_id`=jd.`job_type_id` JOIN `city` AS cc ON cc.`city_id`=jd.`city_id` WHERE jd.`is_verified`='NO' ORDER BY jd.`date_posted` DESC"; $sql = General_model::rawQuery($query); return view('adminpanel.jobs.unverfied_jobs',compact($sql)); } 是静态的,这可能不是这种情况,因为它属于类而不是类的特定实例。