如何在Java中移动球

时间:2014-05-14 19:50:21

标签: 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{


    }


}}

上面提到的是我的代码。球的x和y坐标用随机数初始化。现在当执行代码时,球应该下降(即,y坐标应该增加)。但问题是球落下但却无法落下。在循环运行fallball()之后,球似乎在最后一点。那我怎么能让这个球移动呢?

2 个答案:

答案 0 :(得分:1)

你永远不会等待。这一切都发生得和计算机可能做到的一样快(而且非常快)。

最简单的事情是将Thread.sleep(100);每次循环。然后从那里获得更高级。

这可能看起来像这样

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

这将在每次更新之间进行100毫秒的休眠。 Aka它每秒会更新10次。

这段代码在任何想象中都不是,但是它会让你朝着正确的方向前进,而自己做的只是学习过程的一半。这里还有一些需要考虑的事情:

  • 球的速度取决于帧速率,考虑将速度乘以帧的实际时间以获得y的变化
  • Thread.sleep(100);请求睡眠时间为100毫秒,但它可能无法获得。考虑测量您的实际睡眠时间
  • 您正在使用for循环模拟while循环。请改用while循环

      while(y1<=250){
            this.y1+=5;
            repaint();
            Thread.sleep(100);
       }
    
  • Thread.sleep()在Swing中并不理想,请考虑使用Swing Timer

  • 这绝不是物理上的现实,但我想你知道这一点。

答案 1 :(得分:0)

你的基本问题是你从未在“堕落”循环中加入任何延迟,这意味着它几乎立即更新。

Swing可以将多个repaint请求压缩为一个调用,以减少开销并优化绘制过程。

你很有可能阻止事件调度线程,这意味着,即使使用Thread.sleep,也可能看起来球在一个点开始并且突然(通常在延迟之后)出现在终点。

虽然可以使用Thread来实现这一目标,但更安全的方法是使用Swing Timer

此外,您应该调用super.paintComponent以确保正确维护绘制链。

例如......

Ball

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);
        }
    }

}