簡體   English   中英

在Java中創建我自己的繪畫方法

[英]Creating my own paint method in java

我想創建一個在面板上創建5個球的方法。 有人可以幫助我使用paint組件方法或創建自己的draw方法來解決此問題。 正如您在下面看到的那樣,我有一個帶有for循環的paint component方法,該方法將循環5並在一個隨機位置創建一個球,但是不幸的是,僅創建了一個球。

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

public class AllBalls extends JPanel {
    int Number_Ball=5;
    int x,y;
    Graphics g;
    AllBalls(){
        Random r = new Random();
        x=r.nextInt(320);
        y=r.nextInt(550);
    }
public static JFrame frame;
    public static void main(String[] args) {
        AllBalls a= new AllBalls();
        frame= new JFrame("Bouncing Balls");
        frame.setSize(400,600);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.add(a);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for(int i=0;i<Number_Ball;i++){
            g.fillOval(x, y, 30, 30);
        }
        repaint();
    }

}

在我的paintComponent方法中,我創建了一個for循環,其中希望創建5個球,但是在屏幕上只創建了一個。

根據我的意見的建議:

  1. 擺脫Graphics g變量,因為這只會傷害您。
  2. 考慮創建一個非GUI Ball類,該類不擴展任何Swing組件並具有自己的paint(Graphics)方法。
  3. 如果需要5個球,請在AllBalls類中創建一個Ball對象數組。
  4. 在paintComponent中,通過調用其paint或draw方法(無論您使用哪種方法)來遍歷Balls繪畫每個對象。
  5. 如果需要移動球,請在Swing計時器中移動球,然后調用repaint()。 無論做什么,都不要在paintComponent方法內調用repaint() ,因為這會導致方法的混用,並導致完全不受控制的動畫。 此方法應僅用於繪畫,而不能用於動畫或代碼邏輯。 請改用Swing計時器。
  6. 另外,不要在paintComponent中隨機放置球的位置,這是現已刪除的答案中提出的另一項建議。 同樣,paintComponent應該僅用於繪畫,而不能用於程序邏輯或更改類的狀態。 隨機化應該在您的Swing Timer或游戲循環中。

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;

@SuppressWarnings({"serial", "unused"})
public class BallImages extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = PREF_W;
   private static final int BALL_COUNT = 15;
   private static final Color[] COLORS = { Color.RED, Color.BLACK, Color.BLUE,
         Color.CYAN, Color.GREEN, Color.ORANGE, Color.PINK, Color.WHITE,
         Color.MAGENTA, Color.YELLOW };
   private static final int MIN_SPEED = 2;
   private static final int MAX_SPEED = 10;
   private static final int MIN_WIDTH = 10;
   private static final int MAX_WIDTH = 30;
   private static final int TIMER_DELAY = 15;
   private List<Ball> balls = new ArrayList<>();
   private Random random = new Random();

   public BallImages() {
      for (int i = 0; i < BALL_COUNT; i++) {
         int ballWidth = MIN_WIDTH + random.nextInt(MAX_WIDTH - MIN_WIDTH);
         Color ballColor = COLORS[random.nextInt(COLORS.length)];
         int ballX = ballWidth / 2 + random.nextInt(PREF_W - ballWidth / 2);
         int ballY = ballWidth / 2 + random.nextInt(PREF_H - ballWidth / 2);
         double direction = 2 * Math.PI * Math.random();
         double speed = MIN_SPEED + random.nextInt(MAX_SPEED - MIN_SPEED);
         Ball ball = new Ball(ballWidth, ballColor, ballX, ballY, direction,
               speed);
         balls.add(ball);
      }

      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      for (Ball ball : balls) {
         ball.draw(g2);
      }
   }

   @Override
   // set the component's size in a safe way
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         if (!BallImages.this.isDisplayable()) {
            ((Timer) e.getSource()).stop();
         }
         for (Ball ball : balls) {
            ball.move(PREF_W, PREF_H);
         }
         repaint();
      }
   }

   private class Ball {
      private int width;
      private Color color;
      private double x;
      private double y;
      private double direction;
      private double speed;
      private double deltaX;
      private double deltaY;

      public Ball(int width, Color color, int x, int y, double direction,
            double speed) {
         this.width = width;
         this.color = color;
         this.x = x;
         this.y = y;
         this.direction = direction;
         this.speed = speed;

         deltaX = speed * Math.cos(direction);
         deltaY = speed * Math.sin(direction);
      }

      public int getWidth() {
         return width;
      }

      public Color getColor() {
         return color;
      }

      public double getX() {
         return x;
      }

      public double getY() {
         return y;
      }

      public double getDirection() {
         return direction;
      }

      public double getSpeed() {
         return speed;
      }

      public void draw(Graphics2D g2) {
         g2.setColor(color);
         int x2 = (int) (x - width / 2);
         int y2 = (int) (y - width / 2);
         g2.fillOval(x2, y2, width, width);
      }

      public void move(int containerWidth, int containerHeight) {
         double newX = x + deltaX;
         double newY = y + deltaY;

         if (newX - width / 2 < 0) {
            deltaX = Math.abs(deltaX);
            newX = x + deltaX;
         }
         if (newY - width / 2 < 0) {
            deltaY = Math.abs(deltaY);
            newY = y + deltaY;
         }

         if (newX + width / 2 > containerWidth) {
            deltaX = -Math.abs(deltaX);
            newX = x + deltaX;
         }
         if (newY + width / 2 > containerHeight) {
            deltaY = -Math.abs(deltaY);
            newY = y + deltaY;
         }

         x = newX;
         y = newY;

      }
   }

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

      JFrame frame = new JFrame("BallImages");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.setResizable(false);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM