简体   繁体   中英

How to move a ball in Java

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Game extends JFrame{
     int x1=(int)( Math.random()*10),x2=(int)(Math.random()*45),x3=(int)(Math.random()*35);
 int y1=(int)( Math.random()*10),y2=(int)(Math.random()*45),y3=(int)(Math.random()*35);
 int temp=0;
Game(){

    this.setBounds(100,100,200,300);
    this.setTitle("LEVEL 1:");
    Container c=this.getContentPane();
    c.setVisible(true);
    this.setVisible(true);
    add(new g());

    for(int loop=0;loop<=10;loop++){
        System.out.print("abc");
        ballfall();}
}
    protected void ballfall(){
        if(temp==0){
            for( ;y1<=250;y1++){
                this.y1+=5;
                repaint();
            }


        }

    }
    class g extends JPanel{
        protected void paintComponent(Graphics g){
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, 200, 300);
            g.setColor(Color.PINK);
            g.fillOval(x1,y1,15,15);
            g.setColor(Color.YELLOW);
            g.fillOval(x2,y2,15,15);
            g.setColor(Color.RED);
            g.fillOval(x3,y3,15,15);
            g.setColor(Color.RED);
            g.fillArc(80, 230, 50, 30, 180, 180);


        }

    class ml extends MouseAdapter{


    }


}}

Above mentioned is my code. x and y coordinates of balls are initialized with random numbers. Now when the code is executed a ball should fall (ie, y coordinate should increase) . But the problem is that the ball falls but it can't be seen falling. After the loop is run of fallball(), ball appears to be at the final point. So how can i make this ball move?

You never wait. It all happens as fast as the computer can possibly do it (and thats VERY fast).

The simplest thing to do is put Thread.sleep(100); each time through the loop. Then get more advanced from there.

This might look like this

  for( ;y1<=250;){
       this.y1+=5;
       repaint();
       Thread.sleep(100);
  }

This will put a 100ms sleep between each update. Aka it will update 10 times a second.

This code is not good by any stretch of the imagination but it'll move you in the right direction and doing it yourself is half the learning process. Here are a few more things to consider however:

  • The balls speed depends on the frame rate, consider multiplying a velocity by the actual time of the frame to get the change in y
  • Thread.sleep(100); requests a sleep of 100ms, but it might not get it. Consider measuring the actual time you sleep for
  • You are simulating a while loop with a for loop. Use a while loop instead

      while(y1<=250){ this.y1+=5; repaint(); Thread.sleep(100); } 
  • Thread.sleep() isn't ideal within Swing, consider using a Swing Timer .

  • This is in no way physically realistic, but I assume you know that.

Your basic problem is that you never put any kind of delay in "fall" loop, this means that it updates almost immediately.

Swing can compress multiple repaint requests into a single call, in order to reduce the overhead and optimise the painting process.

You are in serious danger of blocking the Event Dispatching Thread, meaning that, even with the use Thread.sleep , it could appear that the ball starts at one point and suddenly (usually after a delay), appears at the end point.

While this could be achived using a Thread , a safer method would be to use a Swing Timer

Also, you should be calling super.paintComponent to ensure that the paint chain is correctly maintained.

For example...

球

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Game {

    public static void main(String[] args) {
        new Game();
    }

    public Game() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new BallPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class BallPane extends JPanel {

        int x1 = (int) (Math.random() * 10), x2 = (int) (Math.random() * 45), x3 = (int) (Math.random() * 35);
        int y1 = (int) (Math.random() * 10), y2 = (int) (Math.random() * 45), y3 = (int) (Math.random() * 35);
        int temp = 0;

        public BallPane() {
            Timer timer = new Timer(40, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    if (y1 < getHeight()) {
                        y1 += 5;
                    } else {
                        ((Timer)e.getSource()).stop();
                    }
                    repaint();
                }
            });
            timer.start();
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, 200, 300);
            g.setColor(Color.PINK);
            g.fillOval(x1, y1, 15, 15);
            g.setColor(Color.YELLOW);
            g.fillOval(x2, y2, 15, 15);
            g.setColor(Color.RED);
            g.fillOval(x3, y3, 15, 15);
            g.setColor(Color.RED);
            g.fillArc(80, 230, 50, 30, 180, 180);
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM