0

我最近一直在从事一个 ActionScript 3 纸牌游戏项目,我遇到了事件处理程序的问题,我发现这有点复杂。我将尝试解释它:

轮流打牌的玩家数量不定。在他们这样做之后,他们将轮到他们右边的玩家。

function Round(table:Table, lead:Player)/*Table is the list of players. 
Lead is the person that starts the round*/
{
    private var query:int = 0;
    private var roundEnd:Boolean = false;
    private var currentplater:Player = lead;

    while(roundEnd == false)
    {
        query = currentPlayer.hasTurn();/*I'll explain this one later. It's 
        the problematic one*/

        //Game stuff happens.

        currentPlayer = currentPlayer.nextPlayer;/*Once the turn is over,
        it gets assigned to the next player*/
        if(currentPlayer.nextPlayer == lead)
        {
            roundEnd = true;//Everyone has played
        }
    }
}

正如那里评论的那样,复杂的是hasTurn. 该函数必须从 Player 类激活并触发玩家处理事件并返回整数值的权限。

public function hasTurn():int
{
    for each(var cards:Card in hand)
    {
        cards.addEventListener(MouseEvent.CLICK, playCard);
    }
}

在那之后

public function playCard(theCard:Card)
{
    for each(var cards:Card in hand)
    {
        cards.removeEventListener(MouseEvent.CLICK, playCard);
    }

    //More game stuff happens. Not currently relevant.

}

我在这里所做的是允许玩家手中的每张牌都被打出,然后在其中一张牌被打出时取消这些权限,但我永远不会返回值Round,更重要的是,我无法让下一个玩家打出以后玩。我已经在脑海中多次解决这个问题,但似乎无法找到hasTurn返回值或结束其执行的方法,以便Round代码可以继续工作。我是否以错误的方式处理这个问题的逻辑?

4

2 回答 2

0

这是我的 2 美分。

你应该怎么做才能正确处理这个问题。有一个类来管理你的玩家,比如 TurnManager。TurnManager 是一个有两个玩家数组的类。一个是全局玩家数组,另一个是用来轮流然后从这个数组中移除玩家。一旦这个数组为空,这意味着每个玩家都轮到了这一轮,它应该使用全局数组重新填充自己。

public class TurnManager{

    private Array _allPlayers;
    private Array _currentPlayers;

    public void TurnManager(Array players){
        _allPlayers = players;

        foreach(Player player in _allPlayers){
            player.endTurnFunction = this.OnRoundFinished;
        }

        RefillPlayerArray();
        Init();
    }

    public void Init(){
        ActTurn();
    }

    public void ActTurn(){
        if(_currentPlayers.length > 0){
            /*Round isnt finished*/
            Player _currentPlayer = _currentPlayers[0];
            _currentPlayer.PromptForTurnActions();
        } else {
            /*Round is finished*/
            OnRoundFinished();
            RefillPlayerArray();
            /*Restarting round*/
            _currentPlayer.PromptForTurnActions();
        }
    }

    public void RefillPlayerArray(){
        //copy all players from _allPlayer and add them to _currentPlayer
        //make sure to empty _currentPlayer First
    }

    public void OnRoundFinished(){
        //this is called when the round is finished.
    }

    public void PlayerFinishedTurn(Player player){
        ActTurn();
    }
}

在开始时,当 TurnManager 创建自己时,它应该循环遍历所有玩家,以便在他们的回合结束时为他们提供调用函数,以便 TurnManager 可以继续。

就您的卡问题而言。TurnManager 处理转弯、命令和提示玩家采取行动。您还应该有一个处理玩家卡片的 CardManager。当玩家点击手中的卡片时,它将转到 CardManager 并被要求玩家。然后 CardManager 可以要求您的 GUI 播放动画等等。

希望这可以帮助 :)

于 2013-01-23T18:16:59.953 回答
0

如评论中所述:

  • 为游戏动作制作进入帧循环

例如,当用户在其他游戏设置中点击播放时:

addEventListener(Event.ENTER_FRAME, gameLoop, false, 0, true);

protected function gameLoop(e:Event):void
{
    //here the code for game
}

您可以为卡上的 clicikn 注册单个事件,例如通过在卡的容器上注册

cardsHolder.addEventListener(MouseEvent.CLICK, playCard, false, 0, true);

protected function playCard(e:MouseEvent):void
{
    if(e.target is Card)
    {
    //we have clicked on a Card not on another object
    var playedCard:Card = e.target as Card;
    //do whatever with playedCard needs to be done - you can set a flag
    //that it was clicked and next turn is allowed for example
    }
}

处理完点击事件后,您就可以更换播放器了

我认为这是您可以遵循的算法:

  1. 开始游戏 - 洗牌,选择第一个玩家
  2. 让玩家与卡片互动
  3. 评估它——这通常取决于玩家进行有效移动的纸牌游戏类型
  4. 检查完成游戏 - 如果玩家实际上赢了
  5. 未完成然后下一个玩家

此致

于 2013-01-23T20:44:16.590 回答