【问题标题】:Returning values from events in ActionScript 3从 ActionScript 3 中的事件返回值
【发布时间】:2013-01-06 14:22:24
【问题描述】:

我最近一直在从事一个 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 代码可以继续工作。我是否以错误的方式处理这个问题的逻辑?

【问题讨论】:

  • 注意:我不确定这个问题是否足够清楚。我已尽最大努力传达此类特定问题的性质,但请告诉我是否必须编辑帖子。谢谢
  • 你正在做的事情是完全错误的——你不能使用 while 或其他循环来进行游戏执行循环(它不是 JAVA)——仅仅是因为在 flash 循环中停止执行/渲染所有内容,直到它完成。它可能会起作用 - 循环 - 如果它是一个输入帧循环。
  • @Lukasz'Severiaan'Grela 有趣。我会调查的。我可以使用什么路径来解决这个不涉及循环的问题?
  • 现在进入游戏 - 在您的示例中,theCard 不是来自任何东西,循环建议它应该在那里填充它的值,其次是对于您没有在每张卡上注册它的卡的点击事件作为点击气泡,可以由单个听众咳嗽。您不必在每个循环中注册它,除非单击后您打算取消注册。从事件处理程序中,您不能返回任何值,但您可以为另一个将从 playCard 分派的事件注册。 hasTurn 在你的例子中并没有做太多,但它是一个简单的函数,所以它可以返回值
  • @Lukasz'Severiaan'Grela theCard 是卡片。已经解决了。除此之外,嗯......我知道这个逻辑有问题。这就是我问的原因。我的主要目标是至少留下足够好的伪代码让人们理解我的目标......

标签: actionscript-3 events event-handling logic return


【解决方案1】:

这是我的 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 播放动画等等。

希望这会有所帮助:)

【讨论】:

  • 你在 TurnManager 中有一个变量设置为当前玩家,如果玩家点击一张牌来玩你应该检查他是否能够玩它,通过查看 TurnManager 中的当前玩家变量,另外这根本没有递归性。
  • 你可以删除不相关的cmets :)
【解决方案2】:

如 cmets 中所述:

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

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

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. 下一个玩家未完成

最好的问候

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    相关资源
    最近更新 更多