move a ball one after another

这一生的挚爱 提交于 2019-12-12 02:16:44

问题


I am writing a code of game bean machine(Galton box), its mechanism that one ball fall and move randomly until it get to one of the slots (randomly) and then another ball comes doing the same thing and so on, the problem is that all balls fall at the same time which something I do not want, I want each ball to fall when the current one finishes its travel..can anyone helps me ! Thanks..

here is the code:

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import java.util.Scanner;
import java.lang.Iterable;

import javax.swing.*;


public class BallPanel extends JPanel  {

int x=1, y=1;
Collection <Ball> ball;
public static void main(String [] args){
      // create the list
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
    JFrame frame= new JFrame("Bean game");
    frame.add(new BallPanel());
    frame.setSize(300,500);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
        }
    });    
}

public BallPanel() {

    JPanel panel = new JPanel();
    ball=new ArrayList<>(); 
    for(int i=1;i<=4;i++){
        ball.add(new Ball(x,y));
        x++;
        y++;
    }
     Timer timer = new Timer(400, new ActionListener()
    { 
        public void actionPerformed(ActionEvent e) {
            for (Ball b: ball) {
                  b.move();repaint();
            }

        }
    });
      timer.start();
}

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    int raduis=10;
    int  i=0;
    int width=(getWidth()/8);
    int space=(getWidth()-8*30)/2;
    g.setColor(Color.BLACK);
    for(i=0;i<=8;i++){
        g.drawLine(space+(30*i),getHeight()-5*(raduis) ,space+(30*i) ,getHeight() );
        if(i!=0 && i!=8)
            g.fillOval(space+(30*i)-5, getHeight()-5*(raduis)-5, 10, 10);
        if(i==0){
            g.drawLine(space,getHeight()-5*(raduis) , space+((8)*15)-(raduis/2)-15 , getHeight()-15-(5*raduis)-(30*(8-2))-raduis/2);
            g.drawLine(space+((8)*15)-(raduis/2)-15 , getHeight()-15-(5*raduis)-(30*(8-2))-raduis/2 , space+((8)*15)-(raduis/2)-15 , getHeight()/2-8*8);//vertical line

        }
        if(i==8){
            g.drawLine(space+(30*i), getHeight()-5*(raduis), space+((8)*15)+(raduis/2)+15, getHeight()-15-(5*raduis)-(30*(8-2))-raduis/2);
            g.drawLine(space+((8)*15)+(raduis/2)+15 , getHeight()-15-(5*raduis)-(30*(8-2))-raduis/2 , space+((8)*15)+(raduis/2)+15 , getHeight()/2-8*8);//vertical line

        }

    }


    int o=1;
    for(i=1;i<=8-2;i++){
        int k=2;
        for(int j=i;j<=8-2;j++){
            g.fillOval(space+((i+k)*15)-raduis/2, getHeight()-(5*raduis)-(30*o)-raduis/2, raduis, raduis); 
            k=k+2;   
         }o++;
    }
    for (Ball b : ball) {
         b.draw(g);
    }
}
public class Ball {
    Random rand=new Random();
    private int n;
    private int raduis = 10;
    private int moveRaduis=12;
    private int L = 0;
    private int R = 0;
    private int D = 0;
    int x, y; 

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

    public void draw(Graphics g) {
        g.setColor(Color.RED);
        g.fillOval(getWidth()/2 -raduis/2  + R + L, 0 + D , moveRaduis, moveRaduis);

    }
    public void move() {
        n=1+rand.nextInt(100);
        if(n<=51){
            D+=15;

            if(D<=(getHeight()-15-(5*raduis)-(30*(8-2))-raduis/2))
                L=0;
            else if(D>getHeight()-15-(5*raduis)-(30*(8-2))-raduis/2 && D<getHeight()-5*(raduis))
            {
                D+=15;
                L-=15;

            }
            else if(D>=getHeight()-5*(raduis))
            {
                if(D==31*15)D-=15;
                D=D;

            }

        }
        else if (n>=51 && n<=100){
            D+=15;
            if(D<=getHeight()-15-(5*raduis)-(30*(8-2))-raduis/2)
                R=0;
            else if(D>getHeight()-15-(5*raduis)-(30*(8-2))-raduis/2 && D<getHeight()-5*(raduis))
                {
                D+=15;
                R+=15;
            }
            else if(D>=getHeight()-5*(raduis)){
                if(D==31*15)D-=15;
                D=D;

            }

        }

    }
}
}

回答1:


So, your movement code moves all the balls on each iteration, what you need to do is have an "active" ball, for example...

private Ball activeBall;

Timer timer = new Timer(400, new ActionListener() { 
    public void actionPerformed(ActionEvent e) {
        if (activeBall != null && activeBall.hasCompleted()) {
            activeBall = null;
        }
        if (activeBall == null && ball.size() > 0) {
            activeBall = ball.remove(0);
        }
        if (activeBall != null) {
            activeBall.move();
            repaint();
        }
    }
});

You'll need to add in some kind of check to determine the ball has completed it's run though



来源:https://stackoverflow.com/questions/23964875/move-a-ball-one-after-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!