Анимация прямоугольника в Java - PullRequest
1 голос
/ 03 апреля 2012

Я пытался заставить этот прямоугольник двигаться, который я создал, используя цикл for.Все, что происходит с этим кодом, заключается в том, что существует оригинальный прямоугольник, а затем новый рядом с этим прямоугольником.Анимация не происходит, только эти два прямоугольника отображаются в окне.Какими методами можно оживить этот прямоугольник?

import java.awt.*;
import javax.swing.*;

public class Gunman extends JComponent {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public int x = 10;
    public int y = 10;
    public int width = 8;
    public int height = 10;
    public void paint(Graphics g) {
        g.setColor(Color.red);
        g.drawRect (x, y, width, height);  
        g.fillRect (x, y, width, height);
        for(int i = 0; i<=1024; i++){
            g.setColor(Color.red);
            g.drawRect(x++, y, width, height);
            g.fillRect(x++, y, width, height);
        }
    }
}

Ответы [ 3 ]

10 голосов
/ 03 апреля 2012

Нет программной логики в методе paint или paintComponent, и под логикой я подразумеваю цикл for с «движением», поскольку он просто не будет работать.Вы хотите

  • Почти никогда не рисовать в методе рисования JComponent, а в его методе paintComponent.
  • Не забудьте также вызвать метод super.paintComponent(g), часто как первый вызов метода в переопределении paintComponent(g).
  • Используйте таймер Swing для поэтапного изменения x и yзначения
  • вызовите repaint() на JComponent после внесения изменений

Например

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Gunman extends JComponent {

   private static final long serialVersionUID = 1L;
   private static final int PREF_W = 900;
   private static final int PREF_H = 700;
   private static final int TIMER_DELAY = 30;
   public int rectX = 10;
   public int rectY = 10;
   public int width = 8;
   public int height = 10;

   public Gunman() {
      new Timer(TIMER_DELAY, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent actEvt) {
            if (rectX < PREF_W && rectY < PREF_H) {
               rectX++;
               rectY++;
               repaint();
            } else {
               ((Timer)actEvt.getSource()).stop();
            }
         }
      }).start();
   }


   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(Color.red);
      g.drawRect(rectX, rectY, width, height);
      g.fillRect(rectX, rectY, width, height);
   }

   public int getRectX() {
      return rectX;
   }

   public void setRectX(int rectX) {
      this.rectX = rectX;
   }

   public int getRectY() {
      return rectY;
   }

   public void setRectY(int rectY) {
      this.rectY = rectY;
   }

   private static void createAndShowGui() {
      Gunman mainPanel = new Gunman();

      JFrame frame = new JFrame("Gunman");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }

}
0 голосов
/ 03 апреля 2012

Есть множество способов оживить.Вот еще один пример.Обратите внимание на расположение repaint () внутри фонового потока.Это рисует непосредственно на JFrame.Используйте paintComponent () при рисовании на JPanels.

public static void main(String args[]) throws Exception {
new JFrame("Draw a red box") {
  Point pointStart = new Point(50,50);
  Point pointEnd   = new Point(200,200);
  public void paint(Graphics g) {
    super.paint(g);
    if (pointStart != null) {
      g.setColor(Color.RED);
      g.drawRect(pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);
    }}{
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setSize(300, 300);
    setLocation(300, 300);
    setVisible(true);
    Thread t = new Thread(new Runnable() {
      public void run() {
        while (pointEnd.x > 0 && pointEnd.y > 0) {
          pointEnd = new Point(--pointEnd.x, --pointEnd.y);
          repaint();
          try {
            Thread.sleep(22);
          } catch (InterruptedException e) {
            e.printStackTrace();
        }}
        pointStart = null;
        pointEnd = null;
    }});
    t.setDaemon(true);
    t.start();
  }};}
0 голосов
/ 03 апреля 2012

ОБНОВЛЕНИЕ: Хорошо, предыдущий ответ был не очень хорош со старой памяти, вот самый быстрый, самый дешевый и самый грязный способ получить анимацию, вы можете скопировать и скомпилировать код как есть:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class Test extends JFrame {

    public Gunman g = new Gunman();

    public static void main( String[] args ) {
        Test t = new Test();
        t.setSize( 800, 600 );
        t.setVisible( true );
        t.getContentPane().add( t.g );

        while ( true ) {
            t.g.x = t.g.x + 1;
            t.g.y = t.g.y + 1;
            t.repaint();
            try {
                Thread.sleep( 100 );
            } catch ( InterruptedException e ) {
            }
        }
    }

    public void paintComponent( Graphics g ) {
        g.clearRect( 0, 0, 800, 600 );
    }
}


class Gunman extends JComponent {

    private static final long serialVersionUID = 1L;
    public int x = 10;
    public int y = 10;
    public int width = 8;
    public int height = 10;

    public void paintComponent( Graphics g ) {
        g.setColor( Color.red );
        g.fillRect( x, y, width, height );
    }
}

В этом, как сказал Hovercraft of Eels, есть ОЧЕНЬ много ярлыков, это не «идеальный» способ сделать это, но он имеет базовую структуру. У вас есть холст (я использовал JFrame, опять же не очень рекомендуется), и вы добавляете к нему компонент. Вы должны переопределить paintComponent (если вы используете Swing, что я рекомендую вам сделать), и это будет рисовать ваш компонент.
Затем вам нужно каким-то образом изменить положение вашего компонента (порекомендовать правильный вызов метода для объекта, который это делает) и попросить холст перерисовать себя.
Я включил ожидание, чтобы вы могли видеть, что происходит, но если вы думаете о программировании игры, вам следует заняться созданием игрового цикла, чтобы справиться с этим, я рекомендую программирование игр Killer в java, вы можете получить бесплатную версию книги с быстрый поиск в Google.

...