重复使用java.swingTimer动画 [英] repeating animation using java.swingTimer

查看:221
本文介绍了重复使用java.swingTimer动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写游戏豆芽机(高尔顿盒)的使用动画图形code。
我使用swing.Timer使红球移动,通过让Timer对象取一个ActionListener。

I am writing the code of Game bean machine (Galton box) using animated graphics. I am using swing.Timer to make the red ball move, by letting the Timer object take an ActionListener.

下面是输出:
这里的红球是随机移动:
http://imgur.com/J9Xq0t5&HIv1udp
在这里,它到达底部:
http://imgur.com/J9Xq0t5&HIv1udp#1

问题是,我想让几个球不仅1动,但我却不能,我试图把Timer对象在一个循环中,但它只是加快了球的运动。

The problem is that I want to make several balls moving not only 1 but I actually cannot, I tried to put the Timer object in a loop but it only speeded up the ball motion.

下面是code我写的:

Here is the code I wrote:

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


public class GameBean extends JFrame{
private int nSlots;
private int balls;

public GameBean (int nSlots, int balls){
    this.balls=balls;
    this.nSlots=nSlots;
    Timer timer=new Timer(500,new RandomListener());

    timer.start();

    JPanel panel = new JPanel();

    this.add(canvas); 
}

Ball canvas = new Ball();


 public static void main(String[] args) {

    Scanner input=new Scanner(System.in);

    System.out.println("Please enter number of slots: ");
    int nSlots=input.nextInt();

    JFrame frame = new GameBean (nSlots, 5);

    frame.setTitle("Bean Game Machine");
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.setSize(300, 500);
    frame.setVisible(true);

   }
 class RandomListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
         canvas.moveRandom();
    }
}


class Ball extends JPanel{
    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;


    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setColor(Color.RED);

        g.fillOval(getWidth()/2 -raduis/2  + R + L, 0 + D , moveRaduis, moveRaduis);

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

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

            }

        }


        int o=1;
        for(i=1;i<=nSlots-2;i++){
            int k=2;
            for(int j=i;j<=nSlots-2;j++){
                g.fillOval(space+((i+k)*15)-raduis/2, getHeight()-(balls*raduis)-(30*o)-raduis/2, raduis, raduis); 
                k=k+2;   
             }o++;
        }

      }

    public void moveRandom(){

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

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

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

            }

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

                if(D==31*15)D-=15;
                D=D;

            }

        }

    }
    } 

    }

任何帮助,请!
感谢所有..

Any HELP please ! Thanks all..

推荐答案

下面有一个建议。

不要让每个扩展的JP​​anel 。只是让一个类来/操作/图纸的状态。

Don't make each ball extends JPanel. Just make it a class for holding/manipulating/drawing the state.

Ball.java(注意Java命名约定)

Ball.java (notice Java naming convention)

public class Ball {
    int x, y; // and whatever other state you need

    public Ball(int x, int y {}  // or however you want to construct the ball

    public void draw(Graphics g) {
        // draw ball here
    }
    public void move() {
        // do calculations to move here
    }
}

然后,只需具有延伸的JP​​anel 有一个 BallPanel 类,做画在那里。只需拿着一个列表&LT;球&GT; 中的类,你可以调用每个画()方法在的paintComponent ,每个定时>移动()方法。你甚至可以动态地添加到动画球只需添加一个新的到列表中。类似

Then just have one BallPanel class that extends JPanel and do the painting there. Just hold a List<Ball> in the class and you can call each Ball's draw() method in the paintComponent and each Ball's move() method in the Timer. You could even dynamically add balls to be animated by just adding a new Ball to the list. Something like

public class BallPanel extends JPanel {
    private List<Ball> balls;  // create the list

    public BallPanel() {
        Timer timer = new Timer(40, new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                for (Ball ball: balls) {
                    ball.move();
                }
                repaint();
            }
        });
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Ball ball : balls) {
            ball.draw(g);
        }
    }
}

这样,您就不必担心上述独立的定时器和层次感的面板。

This way you don't have to worry above separate timers and layering panels.

看到一堆完整的例子,使用这种技术,这里和的这里 href=\"http://stackoverflow.com/a/21534549/2587435\">和的here 这里和的这里

See a bunch of complete example, using this technique, here and here and here and here and here and here.

这篇关于重复使用java.swingTimer动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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