我正在制作顶级王牌类型的纸牌游戏 - 但我在其中一个控件上遇到了麻烦。在这个问题上我一直在用头撞墙——这很奇怪,因为它似乎是最简单的解决方法
这是一个基本的决策树,只有 3 个步骤,但由于某些原因它不起作用。
handleAction
和renderActionButtons
或renderSlotButtons
之间的东西坏了:(
上下文
轮到任何玩家都可以采取两种行动:[将牌添加到牌组]或[攻击]
[将卡添加到牌组] - 这将打开一个选项列表,用于将卡添加到牌组中的位置 - 点击该选项将执行操作。 这很好用/
[攻击] - 这应该打开三个连续的选项集。
(注意 XYZ 不在代码中 - 仅用于说明目的)
但实际上它显示我(粗体表示选择)
问题
1.[Attack from [Y]] 从来没有真正渲染过:它显示了我 [Attack [x]] 两次 2.第 3 步向我展示了决策树的两个步骤 - 应该一次只向我展示一个
---代码
// Controls.Js - this is the logic for rendering the controls
import React, { useState } from 'react';
import './Controls.css';
import { slotNames } from '../constants';
const Controls = ({ onAction, currentPlayer }) => {
const [currentAction, setCurrentAction] = useState(null);
const [selectedSlot, setSelectedSlot] = useState(null);
const handleActionChoice = (action) => {
setCurrentAction(action);
};
const handleSlotChoice = (slot) => {
if (currentAction === 'addCard') {
onAction({ type: 'ADD_CARD_TO_BATTLE_DECK', payload: { playerId: currentPlayer, slot } });
setCurrentAction(null);
} else {
setSelectedSlot(slot);
}
};
const handleAttributeChoice = (attribute) => {
onAction({
type: 'ATTACK',
payload: { playerId: currentPlayer, attackerSlot: selectedSlot, defenderSlot: selectedSlot, attribute },
});
setCurrentAction(null);
setSelectedSlot(null);
};
const renderActionButtons = () => {
if (!currentAction) {
return (
<>
<button onClick={() => handleActionChoice('addCard')}>Add Card to Deck</button>
<button onClick={() => handleActionChoice('attack')}>Attack</button>
</>
);
}
};
const renderSlotButtons = () => {
if (currentAction) {
return (
<>
<button className="back-button" onClick={() => setCurrentAction(null)}>{`←`}</button>
{slotNames.map((slotName, index) => (
<button key={`slot-${index}`} onClick={() => handleSlotChoice(index + 1)}>
{currentAction === 'attack' ? 'Attack ' : 'Add Card to '}
{slotName}
</button>
))}
</>
);
}
};
const renderAttributeButtons = () => {
if (currentAction === 'attack' && selectedSlot) {
return (
<>
<button onClick={() => setSelectedSlot(null)}>{`←`}</button>
{['force', 'magic', 'stealth', 'luck'].map((attribute) => (
<button key={`attribute-${attribute}`} onClick={() => handleAttributeChoice(attribute)}>
Attack with {attribute}
</button>
))}
</>
);
}
};
return (
<div className={`controls controls-player${currentPlayer}`}>
{renderActionButtons()}
{renderSlotButtons()}
{renderAttributeButtons()}
</div>
);
};
export default Controls;
//Handle action - contained in GameContainer.js - to handle game state
const handleAction = useCallback((action) => {
// Verify active player
if (action.payload.playerId !== currentPlayer) {
return;
}
// Clone gameState and get player states
const newGameState = { ...gameState };
const currentPlayerState = newGameState[`player${action.payload.playerId}`];
const opponentPlayerState = newGameState[`player${action.payload.playerId === 1 ? 2 : 1}`];
// Process actions based on type
switch (action.type) {
case 'ADD_CARD_TO_BATTLE_DECK':
// Remove card from reserveDeck
const cardToAdd = currentPlayerState.reserveDeck.shift();
// Add card to battleDeck
currentPlayerState.battleDeck[action.payload.slot - 1].push(cardToAdd);
// Notify user
showNotification('Card added to deck');
break;
case 'ATTACK':
// Get attacker and defender slots
const attackerSlot = currentPlayerState.battleDeck[action.payload.attackerSlot - 1];
const defenderSlot = opponentPlayerState.battleDeck[action.payload.defenderSlot - 1];
// Get top cards from slots
const attackerCard = attackerSlot[attackerSlot.length - 1];
const defenderCard = defenderSlot[defenderSlot.length - 1];
// Get attribute for comparison
const attribute = action.payload.attribute;
// Compare cards and update graveyard
if (attackerCard && defenderCard && attackerCard[attribute] > defenderCard[attribute]) {
opponentPlayerState.graveyard.push(defenderCard);
defenderSlot.pop();
showNotification(`Player ${action.payload.playerId} victorious`);
} else if (attackerCard && defenderCard && attackerCard[attribute] < defenderCard[attribute]) {
currentPlayerState.graveyard.push(attackerCard);
attackerSlot.pop();
showNotification(`Attack was parried`);
} else {
showNotification(`Player ${action.payload.playerId} turn`);
}
// Check for game win condition
if (opponentPlayerState.graveyard.length === 24) {
showNotification(`Player ${action.payload.playerId} wins the game!`);
}
break;
default:
break;
}
// Update gameState with new state
setGameState(newGameState);
我尝试多次重写 RenderslotCards 和 HandleAction,但它最终破坏了一个东西,然后又破坏了另一个
实际上可能是显示了正确的选项,但标记错误(但仍然一次显示 2