在 do-while 循环中更新计时器上的 JButton [英] Updating JButton on a timer in a do-while loop

查看:22
本文介绍了在 do-while 循环中更新计时器上的 JButton的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 do-while 循环中让 JButton 重复更新(与计时器一起使用)时遇到了一些麻烦.我正在开发一个简单的游戏,在一个 10 * 10 的瓷砖对象网格上玩,这些对象对应于具有 100 个按钮的 JButton arrayList.

程序的这一部分处理简单的寻路(即,如果我点击角色,然后点击一个空方块,角色将在前往目的地的途中穿过每个方块).每一步之间都有一段延迟,因此用户可以看到角色的进度.

在目前的情况下,移动是正确的,但JButton仅在角色到达目的地时更新,而不是在中间步骤.

public void move(int terrainTile){int currentPosition = actorList.get(selectedActor).getPosition();int 运动值 = 0;int 目的地 = 地形瓦片;int 目的地X = 目的地/10;int 目的地Y = 目的地% 10;做{currentPosition = actorList.get(selectedActor).getPosition();//获取PC的当前位置(移动前)System.out.println("旧位置为" + currentPosition);int currentX = currentPosition/10;int currentY = 当前位置 % 10;if(actorList.get(selectedActor).getCurrentAP() > 0){运动值 = 0;如果(目的地X>当前X){运动值 += 10;}如果(目的地X <当前X){运动值 -= 10;}if(destinationY > currentY){运动值 += 1;}如果(目的地Y <当前Y){运动值 -= 1;}int nextStep = 当前位置 + 运动值;myGame.setActorIdInTile(currentPosition, -1);//将PC当前图块中的ActorId改回-1擦洗瓷砖(当前位置);actorList.get(selectedActor).setPosition(nextStep);//在actor对象中设置新位置System.out.println("Actor " + selectedActor + " " + actorList.get(selectedActor).getName() + " 位置已经更新为 " + nextStep);myGame.setActorIdInTile(nextStep, selectedActor);//设置 ActorId 移动到 TileSystem.out.println("Tile " + nextStep + " actorId 已更新为 " + selectedActor);button.get(nextStep).setIcon(new ImageIcon(actorList.get(selectedActor).getImageName()));//如果正交移动 AP-4如果(运动值 == 10 || 运动值 == -10 || 运动值 == 1 || 运动值 == -1){actorList.get(selectedActor).reduceAP(4);}//如果对角线移动 AP-6别的{actorList.get(selectedActor).reduceAP(6);}System.out.println(actorList.get(selectedActor).getName() + " has " + actorList.get(selectedActor).getCurrentAP() + " AP剩余");尝试{线程睡眠(500);//一秒}捕获(异常 e){}button.get(nextStep).repaint();}别的{System.out.println(actorList.get(selectedActor).getName() + "AP 不够移动");休息;}}而(目的地!=(当前位置+运动值));

我尝试过的:

  1. buttons.get(nextStep).repaint();(尝试在设置 imageIcon 后放置一个命令来重新绘制按钮.没有变化.

  2. buttons.get(nextStep).revalidate();(不能 100% 确定这是做什么的 - 它作为一个潜在的解决方案出现,但不起作用.

  3. 步骤 1 &2 组合

  4. Looked into the swing timer class - movement doesn't occur everytime an actionEvent is fired, (only if character is selected and target tile is empty) so not sure how I could get this to work

任何帮助将不胜感激!

解决方案

我真的不知道你在评论中想知道什么,尽管对上面的答案 +1,在我看来这才是真正的原因.看看这个示例程序,只需将您的调用添加到 timerAction 中的 move(...) 方法,似乎可以为您工作.在这里试试这个代码:

import java.awt.*;导入 java.awt.event.*;导入 javax.swing.*;公共类 GridExample{私有静态最终 int SIZE = 36;私人 JButton[] 按钮;private int presentPos;私人 int 期望Pos;私人定时器定时器;私人图标 infoIcon =UIManager.getIcon("OptionPane.informationIcon");private ActionListener timerAction = new ActionListener(){public void actionPerformed(ActionEvent ae){按钮[presentPos].setIcon(null);如果(desiredPos 

presentPos){现在Pos++;按钮[presentPos].setIcon(infoIcon);}否则如果(desiredPos == presentPos){定时器停止();按钮[presentPos].setIcon(infoIcon);}}};公共网格示例(){按钮 = 新 JButton[SIZE];当前位置 = 0;期望位置 = 0;}私有无效 createAndDisplayGUI(){JFrame frame = new JFrame("网格游戏");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel contentPane = new JPanel();contentPane.setLayout(new GridLayout(6, 6, 5, 5));for (int i = 0; i

I'm having some trouble getting a JButton to update repeatedly (used with a timer) in a do-while loop. I'm working on a simple game, played on a 10 * 10 grid of tile objects which correspond to a JButton arrayList with 100 buttons.

This part of the program handles simple pathfinding (i.e. if I click on character, then an empty tile, the character will move through each tile on its way to the destination). There is a delay between each step so the user can see the character's progress.

In the current state of things, the movement is correct, but the JButton is only updated when the character reaches the destination, not on intermediate steps.

public void move(int terrainTile)
{
    int currentPosition = actorList.get(selectedActor).getPosition();
    int movementValue = 0;
    int destination = terrainTile;
    int destinationX = destination / 10;
    int destinationY = destination % 10;

    do
    {
        currentPosition = actorList.get(selectedActor).getPosition();  // Gets PC's current position (before move)
        System.out.println("Old position is " + currentPosition);
        int currentX = currentPosition / 10;
        int currentY = currentPosition % 10;


        if(actorList.get(selectedActor).getCurrentAP() > 0)
        {
            movementValue = 0;

            if(destinationX > currentX)
            {
                movementValue += 10;
            }

            if(destinationX < currentX)
            {
                movementValue -= 10;
            }

            if(destinationY > currentY)
            {
                movementValue += 1;
            }

            if(destinationY < currentY)
            {
                movementValue -= 1;
            }

            int nextStep = currentPosition + movementValue;

            myGame.setActorIdInTile(currentPosition, -1);  //Changes ActorId in PC current tile back to -1
            scrubTiles(currentPosition);

            actorList.get(selectedActor).setPosition(nextStep);  //  Sets new position in actor object
            System.out.println("Actor " + selectedActor + " " + actorList.get(selectedActor).getName() + " position has been updated to " + nextStep);

            myGame.setActorIdInTile(nextStep, selectedActor); // Sets ActorId in moved to Tile
            System.out.println("Tile " + nextStep + " actorId has been updated to " + selectedActor);

            buttons.get(nextStep).setIcon(new ImageIcon(actorList.get(selectedActor).getImageName()));

            // If orthagonal move AP-4
            if(movementValue == 10 || movementValue == -10 || movementValue == 1 || movementValue == -1)
            {
                actorList.get(selectedActor).reduceAP(4);
            }
            // If diagonal move AP-6
            else
            {
                actorList.get(selectedActor).reduceAP(6);
            }

            System.out.println(actorList.get(selectedActor).getName() + " has " + actorList.get(selectedActor).getCurrentAP() + " AP remaining");

            try
            {
                Thread.sleep(500);    // one second
            }
            catch (Exception e){} 

            buttons.get(nextStep).repaint();

        }

        else
        {
            System.out.println(actorList.get(selectedActor).getName() + " has insufficient AP to move");
            break;
        }

    }while(destination != (currentPosition + movementValue));

What I've tried:

  1. buttons.get(nextStep).repaint(); (Tried putting a command to repaint the button after setting the imageIcon. No change.

  2. buttons.get(nextStep).revalidate(); (No 100% sure what this does - it came up as a potential solution, but doesn't work.

  3. Steps 1 & 2 combined

  4. Looked into the swing timer class - movement doesn't occur everytime an actionEvent is fired, (only if character is selected and target tile is empty) so not sure how I could get this to work

Any help would be greatly appreciated!

解决方案

I really dont' know exactly what you wanted to know in your comments, though +1 to the answer above, seems to me that's the real cause. Have a look at this example program, simply add your call to the move(...) method inside the timerAction, seems like that can work for you. Here try this code :

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

public class GridExample
{
    private static final int SIZE = 36;
    private JButton[] buttons;
    private int presentPos;
    private int desiredPos;
    private Timer timer;
    private Icon infoIcon = 
                UIManager.getIcon("OptionPane.informationIcon");

    private ActionListener timerAction = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            buttons[presentPos].setIcon(null);
            if (desiredPos < presentPos)
            {
                presentPos--;
                buttons[presentPos].setIcon(infoIcon);
            }
            else if (desiredPos > presentPos)
            {
                presentPos++;
                buttons[presentPos].setIcon(infoIcon);
            }
            else if (desiredPos == presentPos)
            {
                timer.stop();
                buttons[presentPos].setIcon(infoIcon);
            }
        }
    };

    public GridExample()
    {
        buttons = new JButton[SIZE];
        presentPos = 0;
        desiredPos = 0;
    }

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("Grid Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setLayout(new GridLayout(6, 6, 5, 5));
        for (int i = 0; i < SIZE; i++)
        {
            final int counter = i;
            buttons[i] = new JButton();
            buttons[i].setActionCommand("" + i);
            buttons[i].addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent ae)
                {
                    desiredPos = Integer.parseInt(
                                    (String) buttons[counter].getActionCommand());
                    timer.start();              
                }
            });
            contentPane.add(buttons[i]);
        }
        buttons[presentPos].setIcon(infoIcon);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        timer = new Timer(1000, timerAction);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new GridExample().createAndDisplayGUI();
            }
        });
    }
}

这篇关于在 do-while 循环中更新计时器上的 JButton的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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