提问者:小点点

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


我尝试通过使用定时器在摇摆中的动画将jframe中的标签从一个地方移动到另一个地方,并且我总是得到定时器发送的最后一个动画,例如:

cetrian标签有一个变量“place”,它保存标签的位置,每时每刻位置都是0的变量

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

}

游戏板:lns. png

播放器图标:player1. png

请注意,例如,如果玩家需要从第8方格移动到第14方格,它会走捷径,而不是穿过所有的9 10 11 12 13我不想要它,我想让它一直走到一个特定的方格


共1个答案

匿名用户

首先从for循环中删除对move_player1()的调用…

@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的次数,这只会在将来再次破坏您所做的任何事情。

接下来,在TimerActionListener中添加对repaint的调用以触发新的绘制周期

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

});

它并没有解决我的问题,因为我说的事实是,玩家在不需要注意的情况下通过线路,当标签需要到达上行的一个正方形时,它不需要“很长的路”,它只是跳到那里,我想要的是玩家一个正方形一个正方形地走,直到它到达目的地。

例如,如果你可以从骰子中得到数字99,那么这个地方将在第一次尝试100,然后标签动画将直接从1到100(通过1,20,21,40,41,60,61,80,81,100),我不希望它像这样,我希望它通过之前所有的99个方块

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

见:

  • 在java中以螺旋方式移动图像
  • JPanel图像从屏幕上飞出
  • 将JLabel移动到其他JLabel-GUI

有关其他概念,您还可以查看JPanel上的无法移动JLabel

我看了它们,我不知道它能帮我什么,我不做螺旋或方形运动,我的运动更接近蛇运动,我也没有问题,标签从屏幕上飞出,我只是试图理解它是如何工作的,我没有得到时间线类的角色

好的,你还有一个时间线。每个点都是关键帧。基本上,你想从板上的一个索引点移动到另一个索引点,每个索引点都有一个关联点。

所以,我有一个简单的Mover类,它从索引和索引获取。然后我有一个模型,给定一个索引点将返回关联的。这意味着我的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);
        }

    }
}

现在,我确实设置了一个检查,看看玩家是否应该从新位置向上/向下移动,但是我没有设置移动代码,这将需要将对象从开始移动到结束,而不是通过索引点移动;)