Java Swing骰子滚动动画

Java Swing骰子滚动动画,java,swing,animation,Java,Swing,Animation,我正在编写一个GUI游戏。有一个称为“掷骰子”的按钮,单击该按钮可以掷骰子。然后,GUI显示使用jpeg的模具面滚动的内容 一切都很好,除了我现在应该添加一个动画到GUI。我的想法是使用相同的jpeg显示方法,在短时间内快速显示不同的面值(模拟“滚动”)。然而,我相信你们都知道,这是行不通的 我很熟悉EDT和Timer类的概念,但我不确定如何使用它们。基本上,我希望这个动画在我点击“滚动”按钮时发生,当动画完成时,我希望它像以前一样显示实际滚动的内容 任何帮助都将不胜感激。以下是迄今为止我掌握的

我正在编写一个GUI游戏。有一个称为“掷骰子”的按钮,单击该按钮可以掷骰子。然后,GUI显示使用jpeg的模具面滚动的内容

一切都很好,除了我现在应该添加一个动画到GUI。我的想法是使用相同的jpeg显示方法,在短时间内快速显示不同的面值(模拟“滚动”)。然而,我相信你们都知道,这是行不通的

我很熟悉EDT和Timer类的概念,但我不确定如何使用它们。基本上,我希望这个动画在我点击“滚动”按钮时发生,当动画完成时,我希望它像以前一样显示实际滚动的内容

任何帮助都将不胜感激。以下是迄今为止我掌握的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


/* This is the GUI declaration */
public class NCrapsGUI extends JFrame {
     //code...   
/* Action when "roll" is clicked */
    private void rollActionPerformed(java.awt.event.ActionEvent evt){                                         
        game.rollDice();
            //Rolls both die
            sumOfDice.setText(Integer.toString(game.getSum()));
            //Displays the sum of the die
            numRolls.setText(Integer.toString(game.getNumRolls()));
            //Displays the number of rolls in each game
            // <editor-fold defaultstate="collapsed" desc="Die JPEG's">
            // If statements display the die face based on the number rolled
            if (game.getDie1Value() == 1) {
                 die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face1.jpg")));
            }
            if (game.getDie1Value() == 2) {
                die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face2.jpg")));
            }
            if (game.getDie1Value() == 3) {
                die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face3.jpg")));
            }
            if (game.getDie1Value() == 4) {
                die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face4.jpg")));
            }
            if (game.getDie1Value() == 5) {
                die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face5.jpg")));
            }
            if (game.getDie1Value() == 6) {
                die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face6.jpg")));
            }
            if (game.getDie2Value() == 1) {
                die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face1.jpg")));
            }
            if (game.getDie2Value() == 2) {
                die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face2.jpg")));
            }
            if (game.getDie2Value() == 3) {
                die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face3.jpg")));
            }
            if (game.getDie2Value() == 4) {
                die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face4.jpg")));
            }
            if (game.getDie2Value() == 5) {
                die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face5.jpg")));
            }
            if (game.getDie2Value() == 6) {
                die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face6.jpg")));
            }
            //</editor-fold>
            /* 
             * If the game is beyond the first roll, it checks to see if the sum of the
             * values rolled equal 7 or the point value for a loss or win respectively.
             * If it is a win, it adds a win. Likewise for a loss.
             */
            if (game.getGameStatus() == 2) {
                if (game.getSum() == game.getPoint()) {
                    game.addWin();
                    numWins.setText(Integer.toString(game.getWins()));
                    game.setGameStatus(1);
                    game.setPoint(0);
                    game.resetRolls();
                    return;
                }
                if (game.getSum() == 7) {
                    game.addLoss();
                    numLosses.setText(Integer.toString(game.getLosses()));
                    game.setGameStatus(1);
                    game.setPoint(0);
                    game.resetRolls();
                    return;
                }
            }

            /*
             * This checks to see if the game is on the first roll. If it is, it checks 
             * if the sum of the die is 7 or 11 for a win, or 2, 3, or 12 for a loss. If
             * not, it passes it on to the next roll and sets the point value to the sum
             */
            if (game.getGameStatus() == 1) {
                game.setPoint(game.getSum());
                dieSum.setText(Integer.toString(game.getPoint()));

                if (((game.getSum() == 7) || ((game.getSum() == 11)))) {
                    game.addWin();
                    numWins.setText(Integer.toString(game.getWins()));
                    game.setPoint(0);
                    dieSum.setText(Integer.toString(game.getPoint()));
                    game.resetRolls();
                    return;
                }

                if (((game.getSum() == 2) || ((game.getSum()) == 3)) || (game.getSum()) == 12) {
                    game.addLoss();
                    numLosses.setText(Integer.toString(game.getLosses()));
                    game.setPoint(0);
                    dieSum.setText(Integer.toString(game.getPoint()));
                    game.resetRolls();
                    return;
                } else {
                    game.setGameStatus(2);
                }
            }
       }                                    
这里是数组在NCrapsGUI构造函数中填充的位置:

imageArray = new ImageIcon[totalIcons];
   for (int i = 0; i < 6 ;i++)
    {
        int temp = i + 1;
        imageArray[i] = new ImageIcon("face" + temp + ".jpg");
    }

    initComponents();`
imageArray=newimageicon[totalIcons];
对于(int i=0;i<6;i++)
{
内部温度=i+1;
imageArray[i]=新的图像图标(“面”+temp+.jpg”);
}
初始化组件()`
这是整个rollActionPerformed方法。我猜计时器启动得对 刚开始的时候,但每当我尝试启动它时,我都会遇到很多错误。然而,当我 我单独制作了一个新的JPanel,并让它实现了action listener,我没有 错误。我尝试将implements ActionListner添加到此声明中,但NetBeans实际上是 不让我输入任何东西

private void rollActionPerformed(java.awt.event.ActionEvent evt) {                                     



game.rollDice();
//Rolls both die

sumOfDice.setText(Integer.toString(game.getSum()));
//Displays the sum of the die

numRolls.setText(Integer.toString(game.getNumRolls()));
//Displays the number of rolls in each game

// <editor-fold defaultstate="collapsed" desc="Die JPEG's">
// If statements display the die face based on the number rolled
if (game.getDie1Value() == 1) 
{
    die1Disp.setIcon(imageArray[0]);
}

if (game.getDie1Value() == 2) 
{
    die1Disp.setIcon(imageArray[1]);
}

if (game.getDie1Value() == 3)
{
    die1Disp.setIcon(imageArray[2]);
}

if (game.getDie1Value() == 4) {
    die1Disp.setIcon(imageArray[3]);
}

if (game.getDie1Value() == 5) {
    die1Disp.setIcon(imageArray[4]);
}

if (game.getDie1Value() == 6) 
{
    die1Disp.setIcon(imageArray[5]);
}

if (game.getDie2Value() == 1) 
{
    die2Disp.setIcon(imageArray[0]);
}

if (game.getDie2Value() == 2) 
{
    die2Disp.setIcon(imageArray[1]);
}


if (game.getDie2Value() == 3) 
{
    die2Disp.setIcon(imageArray[2]);
}

if (game.getDie2Value() == 4)
{
    die2Disp.setIcon(imageArray[3]);
}

if (game.getDie2Value() == 5) 
{
    die2Disp.setIcon(imageArray[4]);
}

if (game.getDie2Value() == 6) 
{
    die2Disp.setIcon(imageArray[5]);
}

//</editor-fold>

/* 
 * If the game is beyond the first roll, it checks to see if the sum of the
 * values rolled equal 7 or the point value for a loss or win respectively.
 * If it is a win, it adds a win. Likewise for a loss.
 */

if (game.getGameStatus() == 2) {
    if (game.getSum() == game.getPoint()) {
        game.addWin();
        numWins.setText(Integer.toString(game.getWins()));
        game.setGameStatus(1);
        game.setPoint(0);
        game.resetRolls();
        return;
    }

    if (game.getSum() == 7) {
        game.addLoss();
        numLosses.setText(Integer.toString(game.getLosses()));
        game.setGameStatus(1);
        game.setPoint(0);
        game.resetRolls();
        return;
    }
}
private void rollActionPerformed(java.awt.event.ActionEvent evt){
game.rollDice();
//两个辊都有模
sumOfDice.setText(Integer.toString(game.getSum());
//显示模具的总和
numRolls.setText(Integer.toString(game.getNumRolls());
//显示每场比赛的掷骰数
// 
//If语句根据轧制数量显示模具表面
if(game.getDie1Value()==1)
{
die1Disp.setIcon(imageArray[0]);
}
if(game.getDie1Value()==2)
{
die1Disp.setIcon(图像阵列[1]);
}
if(game.getDie1Value()==3)
{
die1Disp.setIcon(图像阵列[2]);
}
if(game.getDie1Value()==4){
die1Disp.setIcon(图像阵列[3]);
}
if(game.getDie1Value()==5){
die1Disp.setIcon(图像阵列[4]);
}
if(game.getDie1Value()==6)
{
die1Disp.setIcon(图像阵列[5]);
}
if(game.getDie2Value()==1)
{
die2Disp.setIcon(imageArray[0]);
}
if(game.getDie2Value()==2)
{
die2Disp.setIcon(图像阵列[1]);
}
if(game.getDie2Value()==3)
{
die2Disp.setIcon(图像阵列[2]);
}
if(game.getDie2Value()==4)
{
die2Disp.setIcon(imageArray[3]);
}
if(game.getDie2Value()==5)
{
die2Disp.setIcon(imageArray[4]);
}
if(game.getDie2Value()==6)
{
die2Disp.setIcon(图像阵列[5]);
}
//
/* 
*如果游戏超出了第一轮,它会检查
*值分别等于7或输赢的分值。
*如果这是一场胜利,它将增加一场胜利。同样,对于一场失败。
*/
if(game.getGameStatus()==2){
if(game.getSum()==game.getPoint()){
game.addWin();
numWins.setText(Integer.toString(game.getWins());
游戏。设置游戏状态(1);
游戏设定点(0);
game.resetRolls();
返回;
}
if(game.getSum()==7){
game.addLoss();
numLosses.setText(Integer.toString(game.getloss());
游戏。设置游戏状态(1);
游戏设定点(0);
game.resetRolls();
返回;
}
}

`

我认为,你在动画背后的基本想法很好,但它是否有效,当然取决于实现细节。我建议

  • 您在图像中读取并制作图像图标一次,可能是在程序开始时
  • 将图标放入长度为7的ImageIcon数组中,但将图标放入1-6个插槽中,第0项为空
  • 使用Swing计时器以适当的延迟(例如200或300毫秒)随机交换这些图标
  • 使用随机对象获取1到6之间的随机数,然后将该数字作为数组索引,从数组中取出图标
  • 您可以在一个JLabel中显示图像图标(如果您正在显示2个骰子,则显示两个JLabel)并通过调用JLabel的
    setIcon(…)
    方法交换图标
编辑
您在评论中表示已尝试:

timer = new Timer(100,this);
这就是你的问题——你对
这个
的使用。你不应该尝试对所有事情都使用相同的ActionListner。相反,在你需要的地方创建一个ActionListener。比如

  timer = new Timer(100, new ActionListener() {
     public void actionPerformed(ActionEvent actionEvt) {
        // ... put your ActionListener's code here 
     }
  });

不确定是谁投了你的反对票,或者为什么(一次驾车的反对票),但我投了你反对票。为了发布+1+1建议。我还将首先考虑解决渲染单个骰子的问题。我是否将所有这些代码都放在我的rollActionPerformed方法中?除了填充数组之外。你将在构造函数中创建图像图标。rollActionPerformed可能由一个按钮启动,并将从计时器有自己的ActionListener,在那里你可以随机交换图标,直到它重复x次(你会给它一个int计数器变量,你可以递增并检查)。好的。我有数组。但是,每当我尝试在“rollActionPerformed”中启动计时器时,我得到一个错误。这是否意味着我需要让rollActionPerformed实现ActionListener?我使用NetBeans中的Swing接口创建了GUI,它不允许我手动编辑声明。@SkankinJake:我使用了ActionListener持有的计数器变量,该变量在actionPerformed方法中递增。一旦它达到set值,我在计时器上调用
stop()
  timer = new Timer(100, new ActionListener() {
     public void actionPerformed(ActionEvent actionEvt) {
        // ... put your ActionListener's code here 
     }
  });