You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java RPG战斗菜单KeyPress事件单次触发异常问题求助

Java RPG战斗菜单按键异常问题

按下键(确认键)打开魔法子菜单时,此次按键会同时触发子菜单中法术的选择逻辑,而非仅用于打开子菜单。

相关代码

KeyPressed事件处理代码

public void combatState(int code) {

    if (code == KeyEvent.VK_W) {
        if (gp.ui.commandNum > 0 && !gp.ui.magicMenu) {
            gp.ui.commandNum--;
            System.out.println(gp.ui.commandNum);
        } else if (!gp.ui.magicMenu) {
            gp.ui.commandNum = 4;
        }
    }

    if (code == KeyEvent.VK_S) {
        if (gp.ui.commandNum < 4 && !gp.ui.magicMenu) {
            gp.ui.commandNum++;
            System.out.println(gp.ui.commandNum);
        } else if (!gp.ui.magicMenu) {
            gp.ui.commandNum = 0;
        }
    }

    if (code == KeyEvent.VK_Z) {
        if (gp.ui.commandNum == 0) {
            gp.battleSystem.attack();
        }
        if (gp.ui.commandNum == 1) {
            gp.ui.magicMenu = true;
        }
        if (gp.ui.commandNum == 2) {
            // Use Items Aun sin Implementar
        }
        if (gp.ui.commandNum == 3) {
            gp.battleSystem.defend();
        }
        if (gp.ui.commandNum == 4) {
            // Flee Aun sin Implementar
        }
    }
    // Aquí obtenemos la cantidad de hechizos disponibles
    int numSpells = gp.player.numberOfSpells();
    if (gp.ui.commandNum == 1 && gp.ui.magicMenu) {

        if (code == KeyEvent.VK_W) {
            if (gp.ui.commandNum2 > 0) {
                gp.ui.commandNum2--;
                System.out.println(gp.ui.commandNum2);
            } else {
                gp.ui.commandNum2 = numSpells - 1; // Ir al último hechizo
            }
        }
        if (code == KeyEvent.VK_S) {
            if (gp.ui.commandNum2 < numSpells - 1) {
                gp.ui.commandNum2++;
                System.out.println(gp.ui.commandNum2);
            } else {
                gp.ui.commandNum2 = 0; // Volver al primer hechizo
            }
        }
        // Verificar si estamos dentro del submenu de magia antes de activar el hechizo
        if (code == KeyEvent.VK_Z) {
                // Aquí activa el hechizo seleccionado (sin pasar una variable)
                gp.battleSystem.useMagic();
        }

        if(code == KeyEvent.VK_ESCAPE){
            gp.ui.commandNum2 = 0;
            gp.ui.magicMenu = false;
        }
    }
}

useMagic()方法代码

public void useMagic() {
    // Obtener el hechizo seleccionado por el jugador
    ArrayList<superMagic> playerSpells = player.getSpells();
    if (gp.ui.commandNum2 >= 0 && gp.ui.commandNum2 < playerSpells.size()) {
        superMagic selectedSpell = playerSpells.get(gp.ui.commandNum2);

        // Verificar si el jugador tiene suficiente MP para lanzar el hechizo
        if (player.PLAYERstats.mp >= selectedSpell.mpCost) {
            // Restar el costo de MP al jugador
            player.PLAYERstats.mp -= selectedSpell.mpCost;

            // Realizar cálculos de daño o efectos del hechizo según sea necesario
            int damage = selectedSpell.damage;
            // Puedes agregar lógica adicional aquí para diferentes tipos de hechizos

            // Aplicar los efectos del hechizo al enemigo (monstruo)
            if (turn == 0) {
                monster.health -= damage;
                System.out.println(monster.name + " has recived " + damage + " damage from " + selectedSpell.name);
            }
            // Aplicar los efectos del hechizo al jugador
            else if (turn == 1) {
                player.PLAYERstats.hp -= damage;
                System.out.println("Player has recived " + damage + " damage from " + selectedSpell.name);
            }

            // Actualizar la interfaz de usuario para reflejar los cambios
            // Puedes agregar código aquí para mostrar mensajes o actualizaciones visuales

            // Cambiar al siguiente turno
            nextTurn();
        } else {
            System.out.println("Not enough MP to cast " + selectedSpell.name);
        }
    }
}

尝试过的解决方法

  • 添加布尔变量确认是否处于子菜单后再执行法术选择逻辑,但仍会直接触发法术使用;
  • 多次调试,确认按键仅被触发一次,但问题依旧;
  • 尝试使用thread.sleep(),但无效果。

解决方案

问题根源:同一按键事件中,先执行主菜单逻辑将gp.ui.magicMenu设为true,后续魔法子菜单逻辑检测到同一Z键事件,直接触发了法术使用。

方案一:调整代码执行顺序

将魔法子菜单的输入逻辑移到主菜单按键处理之前,利用else让两者互斥。当按下Z键打开魔法菜单时,此时magicMenu仍为false,只会执行主菜单逻辑设置magicMenu为true,不会触发子菜单的法术逻辑。

修改后的代码:

public void combatState(int code) {
    // 先处理魔法子菜单输入
    int numSpells = gp.player.numberOfSpells();
    if (gp.ui.commandNum == 1 && gp.ui.magicMenu) {
        if (code == KeyEvent.VK_W) {
            if (gp.ui.commandNum2 > 0) {
                gp.ui.commandNum2--;
                System.out.println(gp.ui.commandNum2);
            } else {
                gp.ui.commandNum2 = numSpells - 1;
            }
        }
        if (code == KeyEvent.VK_S) {
            if (gp.ui.commandNum2 < numSpells - 1) {
                gp.ui.commandNum2++;
                System.out.println(gp.ui.commandNum2);
            } else {
                gp.ui.commandNum2 = 0;
            }
        }
        if (code == KeyEvent.VK_Z) {
            gp.battleSystem.useMagic();
        }
        if(code == KeyEvent.VK_ESCAPE){
            gp.ui.commandNum2 = 0;
            gp.ui.magicMenu = false;
        }
    } else {
        // 再处理主菜单按键
        if (code == KeyEvent.VK_W) {
            if (gp.ui.commandNum > 0) {
                gp.ui.commandNum--;
                System.out.println(gp.ui.commandNum);
            } else {
                gp.ui.commandNum = 4;
            }
        }
        if (code == KeyEvent.VK_S) {
            if (gp.ui.commandNum < 4) {
                gp.ui.commandNum++;
                System.out.println(gp.ui.commandNum);
            } else {
                gp.ui.commandNum = 0;
            }
        }
        if (code == KeyEvent.VK_Z) {
            if (gp.ui.commandNum == 0) {
                gp.battleSystem.attack();
            }
            if (gp.ui.commandNum == 1) {
                gp.ui.magicMenu = true;
            }
            if (gp.ui.commandNum == 2) {
                // Use Items Aun sin Implementar
            }
            if (gp.ui.commandNum == 3) {
                gp.battleSystem.defend();
            }
            if (gp.ui.commandNum == 4) {
                // Flee Aun sin Implementar
            }
        }
    }
}

方案二:添加按键处理标记

在主菜单处理Z键打开魔法菜单时,设置一个标记变量,子菜单的法术触发逻辑仅在标记为false时执行,避免同一按键触发两次逻辑。

修改后的代码:

public void combatState(int code) {
    boolean menuToggled = false;

    if (code == KeyEvent.VK_W) {
        if (gp.ui.commandNum > 0 && !gp.ui.magicMenu) {
            gp.ui.commandNum--;
            System.out.println(gp.ui.commandNum);
        } else if (!gp.ui.magicMenu) {
            gp.ui.commandNum = 4;
        }
    }

    if (code == KeyEvent.VK_S) {
        if (gp.ui.commandNum < 4 && !gp.ui.magicMenu) {
            gp.ui.commandNum++;
            System.out.println(gp.ui.commandNum);
        } else if (!gp.ui.magicMenu) {
            gp.ui.commandNum = 0;
        }
    }

    if (code == KeyEvent.VK_Z) {
        if (gp.ui.commandNum == 0) {
            gp.battleSystem.attack();
        }
        if (gp.ui.commandNum == 1) {
            gp.ui.magicMenu = true;
            menuToggled = true;
        }
        if (gp.ui.commandNum == 2) {
            // Use Items Aun sin Implementar
        }
        if (gp.ui.commandNum == 3) {
            gp.battleSystem.defend();
        }
        if (gp.ui.commandNum == 4) {
            // Flee Aun sin Implementar
        }
    }

    int numSpells = gp.player.numberOfSpells();
    if (gp.ui.commandNum == 1 && gp.ui.magicMenu) {
        if (code == KeyEvent.VK_W) {
            if (gp.ui.commandNum2 > 0) {
                gp.ui.commandNum2--;
                System.out.println(gp.ui.commandNum2);
            } else {
                gp.ui.commandNum2 = numSpells - 1;
            }
        }
        if (code == KeyEvent.VK_S) {
            if (gp.ui.commandNum2 < numSpells - 1) {
                gp.ui.commandNum2++;
                System.out.println(gp.ui.commandNum2);
            } else {
                gp.ui.commandNum2 = 0;
            }
        }
        // 仅当未触发菜单切换时,才执行法术逻辑
        if (code == KeyEvent.VK_Z && !menuToggled) {
            gp.battleSystem.useMagic();
        }

        if(code == KeyEvent.VK_ESCAPE){
            gp.ui.commandNum2 = 0;
            gp.ui.magicMenu = false;
        }
    }
}

内容的提问来源于stack exchange,提问作者Alejandrol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:57:02