2012-03-28 50 views
0

我正在进行基于回合的纸牌游戏。主循环很简单,我有这样的结构(这是非常简化为简单):模拟一个人类玩家在回合制游戏中的转向顺序

while (!gameEnded) { 
    for (Player *pl in players) { 
     Action *a = [pl askForAction]; 
     self [manageAction]; 
    } 
    if (some condition...) { 
     gameEnded = TRUE; 
    } 
} 

如果所有玩家的是电脑玩家有没有问题,但如果我想有一个人的球员,在askForAction方法应“暂停”循环并让玩家选择动作(按下按钮或触摸卡...)

我该怎么做?我一直在“谷歌搜索”,但我找不到任何东西。我想这个解决方案应该是使用NSThread(或者NSRunLoop也许...),但我找不到方法。谁能帮我?

预先感谢您

+0

您创建的内容与基于循环的'传统'游戏引擎非常相似。但是由于您在iOS中工作时不需要实时更新,因此改用事件驱动方法是有道理的。 – RonLugge 2012-03-28 23:25:01

回答

3

像亚当说,事件驱动的模式可能是最好的。不过,我只想强调解决这个问题的简单性,并且不需要像NSThreadNSRunLoop这样的任何东西。

您只需停止迭代,当你到一个人的球员,然后再启动,一旦你从他们那里得到一个动作再次迭代:

- (void)nextTurn 
    while (!gameEnded) { 
     Player *pl = [self nextPlayer]; 
     if (pl.isHuman) { 
      break; 
     } else { 
      Action *a = [pl getActionFromComputer]; 
      [self manageAction:a]; 
     } 
    } 
    if (gameEnded) { 
     // game over 
    } else { 
     // Set up your UI so it can get an action from the player. 
     // Your UI should be set up so that once it gets an action, 
     // it does [self manageAction:uiAction] then [self nextTurn] 
    } 
} 
3

我会做它的方式(可能有更好的答案)是使用事件驱动的模型而不是在循环中运行。

在代表(或任何地方),跟踪当前玩家(玩家数组中的索引)。致电[[players objectAtIndex:currentPlayer] askForActionWithDelegate:self];

在代表中,有一个接收器(您可以使用manageAction),并且当用户执行该操作时,请致电manageAction。在manageAction中,检查胜利条件并提前currentPlayer

0

对不起。我已经应用了这种方法,这就是我想要的。我做了它的方式如下:

- (void)consumeTurn:(int)idPlayer { 
    if (![gameEnded]) { 
     Player *p = [getPlayer:idPlayer]; 
     if (![p isHuman]) { 
      /** Do some stuff **/ 
      consumeTurn:[getNextPlayer]; 
     } else { 
      /** Show UIView with buttons for human player interaction **/ 
     } 
    } else { 
     /** Game is ended... **/ 
    } 
} 

然后在每一个按钮,与每个按钮的动作是:

- (IBAction)playerAction { 
    /** Do some stuff **/ 
    consumeTurn:[getNextPlayer]; 
} 

我把我的主视图控制器“consumeTurn”的方法( viewDidLoad中)。

谢谢各位的帮助