我怎么能在1之后做几个动画

时间:2017-04-14 02:03:37

标签: java swing timer

我尝试使用动画将jbs中的标签从一个地方移动到另一个地方 摇摆中的计时器,我总是得到计时器发送的最后一个动画 例如:

一个cetrian标签有一个可变的“地方”,每时每刻都有标签的位置 place是0<地方< 101和它的第一个值是1 我还有一个枚举列表,显示所有100点x和y 所以,例如,如果标签位置是52 这样:

label.setposition(pointslist.place.getx(),pointslist.place.gety());

以这种方式设置标签在第52位的位置

public void move_player1{

    timer = new Timer(20, new ActionListener(){  
        @Override
        public void actionPerformed(ActionEvent e){
            //Move 1 px everytime   
            if(player1.getLocation().x<pointslist.values()[place].getx()&&player1.getLocation().y==pointslist.values()[place].gety())
            player1.setLocation(player1.getLocation().x+1, player1.getLocation().y); 
            if(player1.getLocation().x==pointslist.values()[place].getx()&&player1.getLocation().y>pointslist.values()[place].gety())
            player1.setLocation(player1.getLocation().x, player1.getLocation().y-1);
            if(player1.getLocation().x>pointslist.values()[place].getx()&&player1.getLocation().y==pointslist.values()[place].gety())
            player1.setLocation(player1.getLocation().x-1, player1.getLocation().y);
            if(player1.getLocation().x>pointslist.values()[place].getx()&&player1.getLocation().y>pointslist.values()[place].gety())
            player1.setLocation(player1.getLocation().x-1, player1.getLocation().y-1);
            if(player1.getLocation().x<pointslist.values()[place].getx()&&player1.getLocation().y<pointslist.values()[place].gety())
            player1.setLocation(player1.getLocation().x+1, player1.getLocation().y+1);
            if(player1.getLocation().x<pointslist.values()[place].getx()&&player1.getLocation().y>pointslist.values()[place].gety())
            player1.setLocation(player1.getLocation().x-1, player1.getLocation().y-1);
            if(player1.getLocation().x>pointslist.values()[place].getx()&&player1.getLocation().y<pointslist.values()[place].gety())
            player1.setLocation(player1.getLocation().x-1, player1.getLocation().y+1);
            if(player1.getLocation().x<pointslist.values()[place].getx()&&player1.getLocation().y>pointslist.values()[place].gety())
            player1.setLocation(player1.getLocation().x+1, player1.getLocation().y-1);
            if(player1.getLocation().x==pointslist.values()[place].getx()&&player1.getLocation().y==pointslist.values()[place].gety()){
                timer.stop();
            }
        }               
    });
    timer.start();
}

现在可以说在其他功能中我得到一个随机数x 并使标签逐一遍历所有点x次:

int x=*random* (for example 6);
 for(int i=0;i<x;i++)
            {
                place++;
                move_player1();
            }

如果玩家站在第52点,我想在gui中看到 玩家逐点移动直到它到达58 但它不起作用 我在gui中看到玩家直接从52点移动到58点,当时我希望它只能逐一移动1 我怎么解决呢?如何在第一次完成之前停止第二个计时器的运行?

--------编辑: 这是一个可运行的例子

主机:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class mainframe extends JFrame{


    private JPanel gamepanel;
    private JPanel DicePanel;
    private Die Dice;

    private final int WIDTH=850;
    private final int HEIGHT=610;
    private final String BACKGROUNDPATH=".\\images\\lns.png";

    public JButton button;
    public int place;
    JLabel player1;
    Timer timer;

    public mainframe(){


        this.setSize(WIDTH,HEIGHT);     
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);

        gamepanel=new JPanel();
        gamepanel.setBounds(new Rectangle(570,HEIGHT));
        gamepanel.setLayout(new BorderLayout());

        JLabel backgroundimg=new JLabel(new ImageIcon(BACKGROUNDPATH));
        gamepanel.add(backgroundimg);

        player1=new JLabel(new ImageIcon(".\\images\\player1.png"));    
        player1.setBounds(pointslist.POINT1.getx(),pointslist.POINT1.gety(),59,29);
        backgroundimg.add(player1);
        place=1;    


        DicePanel=new JPanel();
        DicePanel.setLayout(new BorderLayout());
        DicePanel.setPreferredSize(new Dimension(WIDTH-gamepanel.getWidth()-15,HEIGHT));
        Dice=new Die();






        //Button
        button = new JButton("ROLL THE DICE !");
        button.setFont(new Font("Arial",Font.BOLD,20));
        button.setPreferredSize(new Dimension(200,100));
        DicePanel.add(button,BorderLayout.SOUTH);
        this.setLayout(new BorderLayout());
        this.add(gamepanel,BorderLayout.CENTER);
        this.add(DicePanel,BorderLayout.LINE_END);


        button.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                Dice.roll();
                int dienum=Dice.getFaceValue();
                System.out.println(dienum);
                for(int i=0;i<dienum;i++)
                {
                    place++;
                    move_player1();
                }
    }

    public void move_player1()
    {

          timer = new Timer(50, new ActionListener(){  
                @Override
                public void actionPerformed(ActionEvent e){
                    //Move 1 px everytime   

                    if(player1.getLocation().x<pointslist.values()[place].getx()&&player1.getLocation().y==pointslist.values()[place].gety())
                        player1.setLocation(player1.getLocation().x+1, player1.getLocation().y); 
                    if(player1.getLocation().x>pointslist.values()[place].getx()&&player1.getLocation().y==pointslist.values()[place].gety())
                        player1.setLocation(player1.getLocation().x-1, player1.getLocation().y);
                    if(player1.getLocation().x==pointslist.values()[place].getx()&&player1.getLocation().y>pointslist.values()[place].gety())
                        player1.setLocation(player1.getLocation().x, player1.getLocation().y-1);
                    if(player1.getLocation().x>pointslist.values()[place].getx()&&player1.getLocation().y>pointslist.values()[place].gety())
                        player1.setLocation(player1.getLocation().x-1, player1.getLocation().y-1);
                    if(player1.getLocation().x<pointslist.values()[place].getx()&&player1.getLocation().y<pointslist.values()[place].gety())
                        player1.setLocation(player1.getLocation().x+1, player1.getLocation().y+1);
                    if(player1.getLocation().x<pointslist.values()[place].getx()&&player1.getLocation().y>pointslist.values()[place].gety())
                        player1.setLocation(player1.getLocation().x-1, player1.getLocation().y-1);
                    if(player1.getLocation().x>pointslist.values()[place].getx()&&player1.getLocation().y<pointslist.values()[place].gety())
                        player1.setLocation(player1.getLocation().x-1, player1.getLocation().y+1);
                    if(player1.getLocation().x<pointslist.values()[place].getx()&&player1.getLocation().y>pointslist.values()[place].gety())
                        player1.setLocation(player1.getLocation().x+1, player1.getLocation().y-1);



                    if(player1.getLocation().x==pointslist.values()[place].getx()&&player1.getLocation().y==pointslist.values()[place].gety())
                        {
                        timer.stop();
                        }

                    }



          });
          timer.start();
    }
});
}

    public static void main(String[] args) {

          mainframe frame = new mainframe();
          frame.setVisible(true);
    }
    }

骰子课程:

class Die{

// Note: If we changed the class definition to "public class Die"
// then we would put this class definition in a separate file Die.java

//  Represents one die (singular of dice) with faces showing values
//  between 1 and 6.

   private final int MAX = 6;  // maximum face value

   private int faceValue;  // current value showing on the die

   //-----------------------------------------------------------------
   //  Constructor: Sets the initial face value.
   //-----------------------------------------------------------------
   public Die()
   {
      faceValue = 1;
   }

   // Alternate Constructor

   public Die(int value)
   {
      faceValue = value;
   }

   //-----------------------------------------------------------------
   //  Rolls the die and returns the result.
   //-----------------------------------------------------------------
   public int roll()
   {
      faceValue = (int)(Math.random() * MAX) + 1;

      return faceValue;
   }

   //-----------------------------------------------------------------
   //  Face value mutator.
   //-----------------------------------------------------------------
   public void setFaceValue (int value)
   {
      faceValue = value;
   }

   //-----------------------------------------------------------------
   //  Face value accessor.
   //-----------------------------------------------------------------
   public int getFaceValue()
   {
      return faceValue;
   }

// Returns a string representation of this die. 
       public String toString() 
      { 
             String result = Integer.toString(faceValue); 
             return result; 
        } 

}

以及所有职位的枚举:

public enum pointslist {


NOPOINT(-10,-10),
POINT1(15,500),
POINT2(70,500),
POINT3(125,500),
POINT4(180,500),
POINT5(230,500),
POINT6(285,500),
POINT7(338,500),
POINT8(390,500),
POINT9(445,500),
POINT10(500,500),

POINT11(500,450),
POINT12(445,450),
POINT13(390,450),
POINT14(338,450),
POINT15(285,450),
POINT16(230,450),
POINT17(180,450),
POINT18(125,450),
POINT19(70,450),
POINT20(15,450),

POINT21(15,395),
POINT22(70,395),
POINT23(125,395),
POINT24(180,395),
POINT25(230,395),
POINT26(285,395),
POINT27(338,395),
POINT28(390,395),
POINT29(445,395),
POINT30(500,395),

POINT31(500,342),
POINT32(445,342),
POINT33(390,342),
POINT34(338,342),
POINT35(285,342),
POINT36(230,342),
POINT37(180,342),
POINT38(125,342),
POINT39(70,342),
POINT40(15,342),

POINT41(15,290),
POINT42(70,290),
POINT43(125,290),
POINT44(180,290),
POINT45(230,290),
POINT46(285,290),
POINT47(338,290),
POINT48(390,290),
POINT49(445,290),
POINT50(500,290),

POINT51(500,235),
POINT52(445,235),
POINT53(390,235),
POINT54(338,235),
POINT55(285,235),
POINT56(230,235),
POINT57(180,235),
POINT58(125,235),
POINT59(70,235),
POINT60(15,235),

POINT61(15,180),
POINT62(70,180),
POINT63(125,180),
POINT64(180,180),
POINT65(230,180),
POINT66(285,180),
POINT67(338,180),
POINT68(390,180),
POINT69(445,180),
POINT70(500,180),

POINT71(500,130),
POINT72(445,130),
POINT73(390,130),
POINT74(338,130),
POINT75(285,130),
POINT76(230,130),
POINT77(180,130),
POINT78(125,130),
POINT79(70,130),
POINT80(15,130),

POINT81(15,75),
POINT82(70,75),
POINT83(125,75),
POINT84(180,75),
POINT85(230,75),
POINT86(285,75),
POINT87(338,75),
POINT88(390,75),
POINT89(445,75),
POINT90(500,75),

POINT91(500,20),
POINT92(445,20),
POINT93(390,20),
POINT94(338,20),
POINT95(285,20),
POINT96(230,20),
POINT97(180,20),
POINT98(125,20),
POINT99(70,20),
POINT100(15,20);



private final int x;
private final int y;

pointslist(int x,int y)
{
    this.x=x;
    this.y=y;
}
public int getx(){return x;};
public int gety(){return y;};

}

the game board : lns.png

the player icon : player1.png

请注意,例如玩家需要移动 从8平方到14平方,它需要很短的路程 而不是经历所有9 10 11 12 13 我不想要它我希望它一直到一个certian广场

1 个答案:

答案 0 :(得分:0)

首先从move_player1() ...

中移除对for-loop的来电
@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    Dice.roll();
    int dienum = Dice.getFaceValue();
    System.out.println(dienum);
    for (int i = 0; i < dienum; i++) {
        place++;
    }
    move_player1();
}

这会创建n次,只会混淆你将来再做的任何事情。

接下来,在repaint Timer中添加对ActionListener的来电,以触发新的绘画周期

timer = new Timer(50, new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        //...
        player1.getParent().repaint();
    }

});
  

它并没有解决我的问题,因为我说当玩家不需要注意当标签需要到达上面的一个正方形而不需要&#34;长时,玩家会通过这些线。方式&#34;它只是跳到那里,我想要的是玩家逐个广场,直到它到达目的地。

     你知道我想做什么吗?我只是不希望玩家直接到某一点,我希望它以前的方式通过所有的方块。例如,如果您可以从骰子获得数字99,那么第一次尝试的地方将是100,然后标签动画将直接从1到100(通过1,20,21,40,41,60,61,80) ,81,100)我不希望它像我希望它通过所有99个方格之前

所以,基本上你真正想要的是某种时间线/关键帧动画

请参阅:

对于其他概念,您还可以查看Can't move JLabel on JPanel

  我已经看了他们所有,我不明白它怎么能帮助我我不做螺旋或方形运动我的运动更接近蛇运动我也没有问题标签飞出屏幕我刚试过了解它是如何工作的,我没有得到时间轴类所需的角色

好的,你还有时间表。每个点都是关键帧。基本上,您希望从电路板上的一个索引点移动到另一个索引点,每个索引点都有一个关联点。

所以,我有一个简单的Mover类,它采用from索引和to索引。然后我有一个模型,给定index点将返回关联的Point。这意味着我的Mover类只需要递增索引点(直到达到目标点),它向观察者报告该位置已更新,然后更新播放器在屏幕上的位置。 ..

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test1 {

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

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

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public interface Positioner {

        public void movePlayerTo(int to);

        public void playerStoppedAt(int at);
    }

    public class TestPane extends JPanel implements Positioner {

        private BufferedImage background;
        private Player player;
        private PointList pointList = new PointList();

        private int currentPoint = 0;

        public TestPane() throws IOException {
            background = ImageIO.read(getClass().getResource("/Board.png"));
            setLayout(null);
            player = new Player();
            add(player);

            movePlayerTo(currentPoint);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    int roll = (int) ((Math.random() * 6) + 1);
                    System.out.println(currentPoint + " + " + roll);
                    Mover mover = new Mover(currentPoint, currentPoint + roll, TestPane.this);
                    mover.start();
                }
            });
        }

        @Override
        public void playerStoppedAt(int at) {
            // Does the player need to move directly to a new
            // location, ie slide down or climb up
            Integer next = pointList.nextPoint(at);
            if (next != null) {
                // Move direclty to next position
            }
        }

        @Override
        public void movePlayerTo(int to) {
            currentPoint = to;
            player.setLocation(pointList.pointAt(currentPoint));
            repaint();
        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.drawImage(background, 0, 0, this);
                g2d.dispose();
            }
        }

    }

    public class Mover {

        private int point;
        private int from;
        private int to;
        private Positioner positioner;
        private Timer timer;

        public Mover(int from, int to, Positioner positioner) {
            this.from = from;
            this.to = to;
            this.positioner = positioner;
        }

        public void start() {
            point = from;
            timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    point++;
                    if (point >= to) {
                        point = to;
                        timer.stop();
                        positioner.playerStoppedAt(point);
                    } else {
                        positioner.movePlayerTo(point);
                    }
                }
            });
            timer.start();
        }

    }

    public class Player extends JPanel {

        private BufferedImage background;

        public Player() throws IOException {
            setOpaque(false);
            background = ImageIO.read(getClass().getResource("/Player.png"));
            setSize(getPreferredSize());
        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.drawImage(background, 0, 0, this);
                g2d.dispose();
            }
        }

    }

    public class PointList {

        private List<Point> points = new ArrayList<>(100);
        private Map<Integer, Integer> nextPoint = new HashMap<>();

        public PointList() {
            points.add(new Point(15, 500));
            points.add(new Point(70, 500));
            points.add(new Point(125, 500));
            points.add(new Point(180, 500));
            points.add(new Point(230, 500));
            points.add(new Point(285, 500));
            points.add(new Point(338, 500));
            points.add(new Point(390, 500));
            points.add(new Point(445, 500));
            points.add(new Point(500, 500));
            points.add(new Point(500, 450));
            points.add(new Point(445, 450));
            points.add(new Point(390, 450));
            points.add(new Point(338, 450));
            points.add(new Point(285, 450));
            points.add(new Point(230, 450));
            points.add(new Point(180, 450));
            points.add(new Point(125, 450));
            points.add(new Point(70, 450));
            points.add(new Point(15, 450));
            points.add(new Point(15, 395));
            points.add(new Point(70, 395));
            points.add(new Point(125, 395));
            points.add(new Point(180, 395));
            points.add(new Point(230, 395));
            points.add(new Point(285, 395));
            points.add(new Point(338, 395));
            points.add(new Point(390, 395));
            points.add(new Point(445, 395));
            points.add(new Point(500, 395));
            points.add(new Point(500, 342));
            points.add(new Point(445, 342));
            points.add(new Point(390, 342));
            points.add(new Point(338, 342));
            points.add(new Point(285, 342));
            points.add(new Point(230, 342));
            points.add(new Point(180, 342));
            points.add(new Point(125, 342));
            points.add(new Point(70, 342));
            points.add(new Point(15, 342));
            points.add(new Point(15, 290));
            points.add(new Point(70, 290));
            points.add(new Point(125, 290));
            points.add(new Point(180, 290));
            points.add(new Point(230, 290));
            points.add(new Point(285, 290));
            points.add(new Point(338, 290));
            points.add(new Point(390, 290));
            points.add(new Point(445, 290));
            points.add(new Point(500, 290));
            points.add(new Point(500, 235));
            points.add(new Point(445, 235));
            points.add(new Point(390, 235));
            points.add(new Point(338, 235));
            points.add(new Point(285, 235));
            points.add(new Point(230, 235));
            points.add(new Point(180, 235));
            points.add(new Point(125, 235));
            points.add(new Point(70, 235));
            points.add(new Point(15, 235));
            points.add(new Point(15, 180));
            points.add(new Point(70, 180));
            points.add(new Point(125, 180));
            points.add(new Point(180, 180));
            points.add(new Point(230, 180));
            points.add(new Point(285, 180));
            points.add(new Point(338, 180));
            points.add(new Point(390, 180));
            points.add(new Point(445, 180));
            points.add(new Point(500, 180));
            points.add(new Point(500, 130));
            points.add(new Point(445, 130));
            points.add(new Point(390, 130));
            points.add(new Point(338, 130));
            points.add(new Point(285, 130));
            points.add(new Point(230, 130));
            points.add(new Point(180, 130));
            points.add(new Point(125, 130));
            points.add(new Point(70, 130));
            points.add(new Point(15, 130));
            points.add(new Point(15, 75));
            points.add(new Point(70, 75));
            points.add(new Point(125, 75));
            points.add(new Point(180, 75));
            points.add(new Point(230, 75));
            points.add(new Point(285, 75));
            points.add(new Point(338, 75));
            points.add(new Point(390, 75));
            points.add(new Point(445, 75));
            points.add(new Point(500, 75));
            points.add(new Point(500, 20));
            points.add(new Point(445, 20));
            points.add(new Point(390, 20));
            points.add(new Point(338, 20));
            points.add(new Point(285, 20));
            points.add(new Point(230, 20));
            points.add(new Point(180, 20));
            points.add(new Point(125, 20));
            points.add(new Point(70, 20));
            points.add(new Point(15, 20));

            nextPoint.put(38, 4);
            nextPoint.put(33, 10);
            nextPoint.put(16, 36);
            nextPoint.put(40, 80);
            nextPoint.put(46, 74);
            nextPoint.put(31, 69);
            nextPoint.put(56, 24);
            nextPoint.put(65, 96);
            nextPoint.put(99, 77);
            nextPoint.put(91, 68);
        }

        public Point pointAt(int index) {
            index = Math.abs(index % points.size());
            return points.get(index);
        }

        public Integer nextPoint(int index) {
            return nextPoint.get(index);
        }

    }
}

现在,我确实设置了一个检查以确定玩家是否应该从新位置向上/向下移动,但我没有设置移动代码,这是从一开始就移动对象所必需的{ {1}}到结尾Point,而不是通过索引点移动;)