如何在 Java 中绘制以不同速度移动的多个对象? [英] How do I paint multiple objetcs that move at different speeds in Java?

查看:23
本文介绍了如何在 Java 中绘制以不同速度移动的多个对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做课堂作业,但很晚了,因为尽管我正在做所有研究,但我似乎无法理解材料.我是初学者,对java的方式了解不多.另外,这是我的第一篇文章,所以当你阅读这篇文章时请原谅.

I am working on homework for class, and its late because I can't seem to understand the material despite all the research that I am doing. I am a beginner and do not know much in the way of java. Also, this is my first post so please be forgiving when you are reading this.

我正在构建我的教科书中的源代码,我最近更新了过去的作业,但现在我正在尝试生成一个类来绘制多个正方形并以不同的速度独立地移动这些对象.他们都需要从墙上反弹.我按照说明创建了两个数组,这些数组将保存 1 到 10 之间的随机 x 和 y 值.但是,我在处理数组方面遇到了困难,而且我确信我没有正确执行此操作.所以,我希望得到一些反馈,看看我是否正确设置了它.

I am building on source code from my textbook, which I updated recently for past homework, but now I am trying to generate a class that draws multiple squares and moves those objects independently and at different speeds. They will all need to rebound off the walls as well. I followed the instructions and created two arrays that will hold the random x and y values between 1 and 10. However, I struggle with arrays and I am sure that I am not doing it correctly. So, I would love some feedback to see if I have it set up correctly.

我有一个 jpanel 拉起来画画,只要有 1 个正方形,它就可以很好地从墙上弹开,但是当我画一个以上时,情况就会发生变化.它们不会独立移动,它们也具有相同的速度.有些甚至不时消失.这真的让我失望了.感谢您的帮助!

I have a the jpanel pulling up and drawing, and as long as there is 1 square it is working fine bouncing off the walls, but things change when I draw more than one. The do not move independently and they also share the same speed. Some even disappear from time to time. This has really thrown me off. I appreciate any help!

简而言之,我正在尝试绘制以不同方向和不同速度行进的新方块.根据说明,我们假设创建并使用两个数组来处理 x 和 y 值.

In short, I am trying to paint new squares that all travel in different directions and at different speeds. Per the instructions we are suppose create and use a two arrays that handle the x and y values.

这是我目前所拥有的:

public class DotsPanel extends JPanel
{
private int delay = 15;
private final int SIZE = 7, IMAGE_SIZE = 3;  // radius of each dot
private Timer timer;
private int x, y, i;
private ArrayList<Point> pointList;
static int [] xarray = new int [1000];
static int [] yarray = new int [1000];
Random rand = new Random();
   //-----------------------------------------------------------------
   //  Constructor: Sets up this panel to listen for mouse events.
   //-----------------------------------------------------------------
   public DotsPanel()
   {
      pointList = new ArrayList<Point>();
      int [] xarray = new int [1000];
      int [] yarray = new int [1000];

      timer = new Timer(delay, new ReboundListener());
      addMouseListener (new DotsListener());
      addMouseMotionListener (new DotsListener());

      setBackground(Color.gray);
      setPreferredSize(new Dimension(700, 500));
      for(int i = 0; i < xarray.length; i++)
      {   
      xarray[i] = rand.nextInt(7);
      yarray[i] = rand.nextInt(7);
      }
      timer.start();          
   }

   //-----------------------------------------------------------------
   //  Draws all of the dots stored in the list.
   //-----------------------------------------------------------------
   public void paintComponent(Graphics page)
   {
      super.paintComponent(page);
      page.setColor(Color.BLUE); 

      for (Point spot : pointList)
      {  
        page.fillRect(spot.x-SIZE, spot.y-SIZE, 25, 25);
        page.drawString("Count: " + pointList.size(), 5, 15);
      }
   }



//*****************************************************************
   //  Represents the listener for mouse events.
   //*****************************************************************
   private class DotsListener implements MouseListener, MouseMotionListener
   {
      //--------------------------------------------------------------
      //  Adds the current point to the list of points and redraws
      //  the panel whenever the mouse button is pressed.
      //--------------------------------------------------------------
      public void mousePressed(MouseEvent event)
      {
            pointList.add(event.getPoint());    
            repaint();
      }
      public void mouseDragged(MouseEvent event)
      {
        // initially I had two xarray and yarray in here just like in 
        // mouseClicked
        // but it did not change anything when removed  
      }
      //--------------------------------------------------------------
      //  Provide empty definitions for unused event methods.
      //--------------------------------------------------------------
      public void mouseClicked(MouseEvent event) 
      { 
          xarray[i] = rand.nextInt(7);
          yarray[i] = rand.nextInt(7);            
      }
      public void mouseReleased(MouseEvent event) {}
      public void mouseEntered(MouseEvent event) {}
      public void mouseExited(MouseEvent event) {}
      public void mouseMoved(MouseEvent e) {}
   }
   private class ReboundListener implements ActionListener
   {
      //--------------------------------------------------------------
      //  Updates the position of the image and possibly the direction
      //  of movement whenever the timer fires an action event.
      //--------------------------------------------------------------
      public void actionPerformed(ActionEvent event)
      {


            for (Point spot : pointList) 
            {   
                spot.x += xarray[i];
                spot.y += yarray[i];
                if (spot.x <= 0 || spot.x >= 700)
                    xarray[i] = xarray[i] * -1;
                if (spot.y <= 0 || spot.y >= 500)
                    yarray[i] = yarray[i] * -1;
                repaint();  
            }
      }
    }   
}   

推荐答案

但是,我在处理数组方面很挣扎,而且我确信我没有正确地做.

However, I struggle with arrays and I am sure that I am not doing it correctly.

我不会使用数组.

相反,让一个 Ball 对象管理它自己的状态.然后你可以为每个 Ball 设置不同的颜色、速度、大小等.然后当 Timer 触发时,您只需计算新位置并重新绘制 Ball.

Instead, have a Ball object manage its own state. Then you can have different color, speed, size etc for each Ball. Then when the Timer fires you just calculate the new position and repaint the Ball.

这是一个让您入门的示例:

Here is an example to get you started:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class BallAnimation4
{
    private static void createAndShowUI()
    {
        BallPanel panel = new BallPanel();

        JFrame frame = new JFrame("BallAnimation4");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( panel );
        frame.setSize(800, 600);
        frame.setLocationRelativeTo( null );
        //frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setVisible( true );

        panel.addBalls(5);
        panel.startAnimation();
    }

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

class BallPanel extends JPanel implements ActionListener
{
    private ArrayList<Ball> balls = new ArrayList<Ball>();

    public BallPanel()
    {
        setLayout( null );
        setBackground( Color.BLACK );
    }

    public void addBalls(int ballCount)
    {
        Random random = new Random();

        for (int i = 0; i < ballCount; i++)
        {
            Ball ball = new Ball();
            ball.setRandomColor(true);
            ball.setLocation(random.nextInt(getWidth()), random.nextInt(getHeight()));
            ball.setMoveRate(32, 32, 1, 1, true);
//          ball.setMoveRate(16, 16, 1, 1, true);
            ball.setSize(32, 32);
            balls.add( ball );
        }
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        for (Ball ball: balls)
        {
            ball.draw(g);
        }
    }

    public void startAnimation()
    {
        Timer timer = new Timer(75, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        move();
        repaint();
    }

    private void move()
    {
        for (Ball ball : balls)
        {
            ball.move(this);
        }
    }


    class Ball
    {
        public Color color = Color.BLACK;

        public int x = 0;
        public int y = 0;
        public int width  = 1;
        public int height = 1;

        private int moveX = 1;
        private int moveY = 1;
        private int directionX = 1;
        private int directionY = 1;
        private int xScale = moveX;
        private int yScale = moveY;

        private boolean randomMove = false;
        private boolean randomColor = false;
        private Random myRand = null;

        public Ball()
        {
            myRand = new Random();
            setRandomColor(randomColor);
        }

        public void move(JPanel parent)
        {
            int iRight = parent.getSize().width;
            int iBottom = parent.getSize().height;

            x += 5 + (xScale * directionX);
            y += 5 + (yScale * directionY);

            if (x <= 0)
            {
                x = 0;
                directionX *= (-1);
                xScale = randomMove ? myRand.nextInt(moveX) : moveX;
                if (randomColor) setRandomColor(randomColor);
            }

            if (x >= iRight - width)
            {
                x = iRight - width;
                directionX *= (-1);
                xScale = randomMove ? myRand.nextInt(moveX) : moveX;
                if (randomColor) setRandomColor(randomColor);
            }

            if (y <= 0)
            {
                y = 0;
                directionY *= (-1);
                yScale = randomMove ? myRand.nextInt(moveY) : moveY;
                if (randomColor) setRandomColor(randomColor);
            }

            if (y >= iBottom - height)
            {
                y = iBottom - height;
                directionY *= (-1);
                yScale = randomMove ? myRand.nextInt(moveY) : moveY;
                if (randomColor) setRandomColor(randomColor);
            }
        }

        public void draw(Graphics g)
        {
            g.setColor(color);
            g.fillOval(x, y, width, height);
        }

        public void setColor(Color c)
        {
            color = c;
        }

        public void setLocation(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public void setMoveRate(int xMove, int yMove, int xDir, int yDir, boolean randMove)
        {
            this.moveX = xMove;
            this.moveY = yMove;
            directionX  = xDir;
            directionY  = yDir;
            randomMove  = randMove;
        }

        public void setRandomColor(boolean randomColor)
        {
            this.randomColor = randomColor;

            switch (myRand.nextInt(3))
            {
                case 0:  color = Color.BLUE;
                         break;
                case 1:  color = Color.GREEN;
                         break;
                case 2:  color = Color.RED;
                         break;
                default: color = Color.BLACK;
                         break;
            }
        }

        public void setSize(int width, int height)
        {
            this.width  = width;
            this.height = height;
        }
    }
}

由于您的数组仅包含您要绘制的点,因此您没有关于每个点应以何种速度移动的速度的任何信息.您可以做的最好的事情是创建一个随机量,每次更改其位置时每个点都应移动.这会导致不稳定的移动,因为每次移动一个点时,距离都是随机的.

Since your Arrays only contain the Point you want to paint you don't have any information about the speed each point should be moved at. The best you could do is create a random amount each point should be moved each time its location is changed. This would give erratic movement as each time you move a point the distance would be random.

如果你想要更恒定的速度,那么你需要创建第二个数组来包含每个点每次应该移动的距离.

If you want more constant speed then you would need to create a second Array to contain the distance each point should move every time.

每当您希望新属性对于您要绘制的对象是唯一的时,创建一个新数组就开始变得混乱.这就是创建具有多个属性的自定义对象的方法更易于管理的原因.

This starts to get messy creating a new Array every time you want a new property to be unique for the object you want to paint. That is why the approach to create a custom Object with multiple properties is easier to manage.

这篇关于如何在 Java 中绘制以不同速度移动的多个对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆