Я пытался понять это навсегда, но я не могу понять это.

Я хотел бы отобразить более одного изображения на экране в одной и той же JPanel, но по какой-то причине он отображает только последнее изображение из компонента рисования

Я пытаюсь сделать игру в стиле фруктового ниндзя и хотел бы вытащить фрукты из кадра до начала анимации.

У кого-нибудь есть идеи, как это сделать? Любая помощь будет принята с благодарностью ...

import javax.swing.*;//imports JPanel class
import java.awt.*;//imports the Graphics class

public class FruitNinja extends JPanel {

   private Image dojo;
   private Image apple;
   private Image orange;
   private Image pineapple;
   private Image strawberry;
   private Image banana;

   private Timer timer;
   private int x, y;

   public FruitNinja() { // a constructor to set up graphics windo
      super();
      setBackground(Color.WHITE);
      loadImage();
      x = 25;
      y = 25;


   }



   private void loadImage() {
      ImageIcon ii = new ImageIcon("Dojo.jpg");
      dojo = ii.getImage();

      ImageIcon oo = new ImageIcon("Orange.ico");
      orange = oo.getImage();

      ImageIcon ss = new ImageIcon("Strawberry.png");
      strawberry = ss.getImage();

      ImageIcon bb = new ImageIcon("Banana.png");
      banana = bb.getImage();

      ImageIcon pp = new ImageIcon("Pineapple.png");
      pineapple = pp.getImage();

      ImageIcon aa = new ImageIcon("Apple.png");
      apple = aa.getImage();


   }

   public void paintComponent(Graphics g){ // draw graphics in the panel

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(dojo, 0,0, this);
      //draws out dojo


      super.paintComponent(g);// to make panel display correctly
      g.drawImage(apple, 0,0, this);

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(orange, 0,0, this);

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(pineapple, 0,0, this);

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(banana, 0,0, this);

      super.paintComponent(g);// to make panel display correctly
      g.drawImage(strawberry, 0,0, this);

      //draws out the fruits somewhere
   }

  /* 
   @Override
    public void actionPerformed(ActionEvent e) {

      x += 5;
      y += 5;

      if (y > getHeight()) {
         y = 25;
         x = 25;
      }
      repaint();
   }
*/

   public static void main(String[] args) { 

      FruitNinja panel = new FruitNinja(); // window for drawing  
      JFrame f = new JFrame(); // the program itself
      f.setTitle("Fruit Ninja");
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//when the X button is clicked, the program quits
      f.setSize(1280,800);//size of the frame
      Container pane = f.getContentPane();//pane refers to the interior of the JFrame

      FruitNinja p1 = new FruitNinja();

      pane.add(p1);//add the FacePanel object to the interior of the frame
      f.setVisible(true);

   }
}

Также не имеет отношения к этому текущему вопросу, так как я пытаюсь сделать игру, похожую на FruitNinja, как мне сделать так, чтобы код регистрировал, что моя мышь там (так что он нарезает фрукты, когда моя мышь наводится над фруктами) ) ? это mouseListenter?

2
Martin 28 Май 2017 в 09:14

2 ответа

Лучший ответ

Я бы посоветовал взглянуть на рисование в AWT и Swing, чтобы понять почему у вас проблема

Одно из заданий, которое paintComponent выполняет, подготавливает контекст Graphics для рисования компонента, обычно оно делает это, заполняя его цветом фона компонента

Итак, основываясь на вашем коде, можно предположить, что вам нужно вызывать paintComponent один раз, в начале метода

public void paintComponent(Graphics g){ // draw graphics in the panel

  super.paintComponent(g);// to make panel display correctly
  g.drawImage(dojo, 0,0, this);
  //draws out dojo
  g.drawImage(apple, 0,0, this);
  g.drawImage(orange, 0,0, this);
  g.drawImage(pineapple, 0,0, this);
  g.drawImage(banana, 0,0, this);
  g.drawImage(strawberry, 0,0, this);
  //draws out the fruits somewhere
}

Итак, теперь все изображения должны быть нарисованы друг на друге

Также не имеет отношения к этому текущему вопросу, так как я пытаюсь сделать игру FruitNinja, как мне сделать так, чтобы код регистрировал, что моя мышь там (так что он разрезает фрукты, когда моя мышь наводится над фруктами)? это mouseListenter?

Вы, вероятно, ищете MouseMotionListener, посмотрите на Как написать слушателя мыши для более подробной информации

3
Andrew Thompson 28 Май 2017 в 09:05

Вы расширили JPanel, и в этом JPanel вы нарисовали те же x и y, что 0. А также в переопределенном методе paintComponent() вы вызываете метод класса super несколько раз. Из-за этого вы можете видеть только последний нарисованный рисунок.

Изменить это:

  super.paintComponent(g);
  g.drawImage(apple, 0,0, this);

  super.paintComponent(g);
  g.drawImage(orange, 0,0, this);

  super.paintComponent(g);
  g.drawImage(pineapple, 0,0, this);

  super.paintComponent(g);
  g.drawImage(banana, 0,0, this);

  super.paintComponent(g);
  g.drawImage(strawberry, 0,0, this);

Кому:

  super.paintComponent(g);

  g.drawImage(apple, 0,0, this);
  g.drawImage(orange, 0,0, this);
  g.drawImage(pineapple, 0,0, this);
  g.drawImage(banana, 0,0, this);
  g.drawImage(strawberry, 0,0, this);

Тем не менее, вы не можете видеть другие изображения, потому что все изображения находятся друг над другом. Чтобы избежать этого, вы можете сделать что-то вроде этого:

  super.paintComponent(g);

  g.drawImage(dojo, x,0, this);
  g.drawImage(apple, x,100, this);
  g.drawImage(orange, 300,100, this);
  g.drawImage(pineapple, x,300, this);
  g.drawImage(banana, 300,0, this);
  g.drawImage(strawberry, 300,300, this);

Вы можете изменить x и y по своему усмотрению. Но все же это сбивает с толку и раздражает, и это занимает много времени. Ну, есть лучший способ сделать это. Это диспетчер макетов.

Подумайте, как использовать Менеджер макетов в своей программе. Эти ссылки могут помочь вам:

В последней части вашего вопроса вы упоминаете о

как мне сделать так, чтобы код регистрировал, что моя мышь там

Вам необходимо получить текущую позицию указателя (x и y).

это mouseListenter?

Нет, если только у вас не так много событий. mouseListenter для событий мыши (нажмите, отпустите, щелкните, введите и выйдите) в компоненте.

Что вам нужно, это MouseMotionListener согласно приведенному выше утверждению. Это для событий движения мыши на компоненте.

ОБНОВЛЕНИЕ (согласно комментарию):

Я не совсем уверен, как вы используете MouseMotionListener? Я был в состоянии оживить фрукты / изображения, таким образом, это летит вокруг моей структуры теперь. Как я могу использовать MouseMotionListener, чтобы убрать этот фрукт с фрейма, когда я наведу на него курсор?

Это выходит за рамки вопроса, но в качестве справки,

Ну, для этого вам нужно добавить все изображения в JLabel, иначе вы можете добавить слушателя на панель. Поскольку существует несколько изображений, вы должны создавать ярлыки. Для этого я создал новый метод, код должен выглядеть так:

public void moveImage(ImageIcon icon){
    JLabel dojoLabel = new JLabel();
    dojoLabel.setIcon(icon);
    this.add(dojoLabel);

    dojoLabel.addMouseMotionListener(new MouseMotionAdapter() {
        public void mouseMoved(MouseEvent evt){
            dojoLabel.setLocation(0,0);
            repaint();
        }
    });
}

Теперь внутри вашего loadImage() вызовите этот метод для анализа ImageIcon. Невозможно добавить тип Image к JLabel. Вот почему вам нужно добавить ImageIcon.

private void loadImage() {
      ImageIcon ii = new ImageIcon("Dojo.jpg");
      dojo = ii.getImage();
      //.....
      //move method here
      moveImage(ii);
}
1
Blasanka 28 Май 2017 в 12:16