jjzjj

Java Swing 骰子滚动动画

coder 2024-03-31 原文

我正在编写一个 GUI 掷骰子游戏。有一个名为“roll”的 JButton,单击它会为游戏掷骰子。 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);
                }
            }
       }                                    

使用更新的代码进行编辑!!!

这里是定时器和数组声明的地方:

public class NCrapsGUI extends JFrame
{
private Timer timer; 
private int numPlayers;
private int totalIcons = 6;

private ImageIcon imageArray[];`

/* CODE */

这是在 NCrapsGUI 构造函数中填充数组的位置:

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

    initComponents();`

这是整个 rollActionPerformed 方法。我猜定时器启动正确 一开始,但每当我尝试启动它时,我都会遇到很多错误。然而,当我 我单独制作了一个新的 JPanel,并让它实现了 Action 监听器,我没有 错误。我尝试将 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;
    }
}

`

最佳答案

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

  • 您读入图像并制作一次 ImageIcons,可能是在程序开始时。
  • 您将图标放入长度为 7 的 ImageIcon 数组中——但是您会将图标放入 1-6 槽中,而第 0 项为空。
  • 您使用 Swing Timer 以适当的延迟随机交换这些图标,比如 200 或 300 毫秒。
  • 您使用一个 Random 对象获取 1 到 6 之间的随机数,然后将此数字作为您的数组索引,从数组中获取 Icon。
  • 您在 JLabel 中显示 ImageIcons(如果您显示 2 个骰子,则显示两个 JLabel)并通过简单地调用 JLabel 的 setIcon(...) 方法来交换图标。

编辑
您在评论中声明您尝试过:

timer = new Timer(100,this);

这就是您的问题 - 您对 this 的使用。您不应该尝试对所有内容都使用相同的 ActionListner。而是在需要的地方创建一个 ActionListener。类似的东西,

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

关于Java Swing 骰子滚动动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8469941/

有关Java Swing 骰子滚动动画的更多相关文章

  1. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  2. LVGL V8动画 - 2

    动画/*INITIALIZEANANIMATION 初始化一个动画*-----------------------*/lv_anim_ta;lv_anim_init(&a);/*MANDATORYSETTINGS 必选设置*------------------*//*Setthe"animator"function 设置“动画”功能*/lv_anim_set_exec_cb(&a,(lv_anim_exec_xcb_t)lv_obj_set_x);/*Setthe"animator"function*/lv_anim_set_var(&a,obj);/*Lengthoftheanim

  3. ruby - Carrierwave + MiniMagick - 如何将动画 GIF 压缩到第一帧? - 2

    有人知道如何使用Carrierwave+MiniMagick将动画GIF压缩到第一帧吗? 最佳答案 我认为MiniMagick有一些变化,因为我只花了三个小时试图找出为什么Andrey的代码对我不起作用。我收到以下错误:ActiveRecord::RecordInvalid(Validationfailed:ImageFailedtomanipulatewithMiniMagick,maybeitisnotanimage?OriginalError:Command("mogrify-scene/var/folders/0o/0oqN

  4. ruby - 绕过 Element 的方法无法滚动到 View 中 - Watir-webdriver with Ruby - 2

    因此,我们的页面中有以下代码:OnOff这是2个单选按钮。'开和关'。“关闭”是默认值。使用Watir-webdriver和Ruby,我们想要选择“打开”单选按钮。我们这样做:browser.radio(:id=>"HasRegistration_true").set但在这样做时,我们得到以下错误:`WebElement.clickElement':Elementcannotbescrolledintoview:[objectHTMLInputElement](Selenium::WebDriver::Error::MoveTargetOutOfBoundsError)我们知道Sele

  5. 华为OD机试 -旋转骰子(Python) | 机试题算法思路 【2023】 - 2

    最近更新的博客华为OD机试-卡片组成的最大数字(Python)|机试题算法思路华为OD机试-网上商城优惠活动(一)(Python)|机试题算法思路华为OD机试-统计匹配的二元组个数(Python)|机试题算法思路华为OD机试-找到它(Python)|机试题算法思路华为OD机试-九宫格按键输入(Python)|机试算法备考思路华为OD机试-身高排序(Python)|备考思路使用说明参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。华为OD清单查看地址:blog.csdn.net/hihell/catego

  6. ruby-on-rails - 如何在 Ajax 请求处理期间显示动画图标 - Rails 3 - 2

    我正在尝试为每个ajax请求显示一个加载指示器,我在Rails3应用程序中工作。HTML:"loading-indicator",:style=>"display:none")%>CSS:#loading-indicator{position:absolute;left:10px;top:10px;}loading.js:我放在assest/javascripts/$(document).ready(function(){$(document).ajaxSend(function(event,request,settings){$('#loading-indicator').show(

  7. ruby - 如何使用 watir 滚动网页 - 2

    我正在尝试滚动网页以查找并单击滚动页面时延迟加载的内容。我正在使用以下命令require'watir-webdriver'@browser=Watir::new:firefox@browser.send_keys:space我在firefox上使用网络驱动程序,我在ubuntu上,但它不工作。在下面的ruby​​代码中,我试图向下滚动页面,直到找不到带有:id的元素。该元素正在延迟加载。几秒钟后我超时了,不知道下面的代码有什么问题。When/^deal(\d+)isloaded$/do|id|(0..5).eachdo|click|@browser.send_keys:spaceend

  8. ruby - Selenium 滚动元素进入(中心) View - 2

    当一个元素在selenium的View之外并且试图与之交互时,selenium通常会首先隐式地将元素滚动到View中。这很棒,只是烦人的是它通常将元素放入View中。我的意思是,如果元素位于窗口下方,它会向下滚动足够多直到元素刚好与窗口边缘接壤。通常这很好,但是当在周围有边框的网站上工作时,这将导致许多此类错误Selenium::WebDriver::Error::UnknownError:unknownerror:Elementisnotclickableatpoint(438,747).Otherelementwouldreceivetheclick:...因为通常网页的边框都在它

  9. javascript - 在 Fabric js 中的两个对象之间添加动画 - 2

    我有一个非常基本的应用程序,可让您创建形状并用一条线将它们连接起来。为此,您需要执行以下操作。Example1.Clicknewanimation2.addrectangle3.addchild4.addcircle您可以移动形状、拖动和调整大小。我想知道是否可以在两个对象之间添加动画。因此,例如,一个小圆球会在两个物体之间的线上移动。我已经查看了fabricjs动画页面上的演示,但不确定是否可以从对象b执行。这是FIDDLE. 最佳答案 我不知道你是否可以在fabric中使用内置的动画功能,因为正如你所说,这些对象可能会自己移动。

  10. javascript - 在上方和下方添加新内容时锁定滚动 - 2

    我有一个用作新闻提要的meteor.js应用程序,可以发布话题,人们可以实时评论话题。这意味着当您查看帖子时,将在帖子上方和下方添加新评论,并且在上方添加新话题。这会将您正在关注的帖子向下推到视口(viewport)之外,这是意想不到的(除非您已经滚动到顶部)。更新滚动以在添加新内容时保持相同视觉中心的最佳方法是什么? 最佳答案 你可以试试这个方法:保存scrollTop值;在内容前添加内容(即,在关注的帖子上方添加新帖子);将新内容的高度添加到步骤1中保存的值;滚动到新值。这是一个例子:functionrandomString()

随机推荐