Objective-C状态机传入参数



我饶有兴趣地阅读了StackOverflow上的这篇文章:如何在Objective-C中制作一个基本的有限状态机

我将此作为构建一个简单足球游戏的状态机的基础。我的状态有防御,攻击,停止,中立。我已经创建了状态机,它会打印出NSLog"现在进入状态防御"等。

现在我想把对足球队的引用传递给状态机,这样我就可以让我的球队根据状态做一些事情。例如,如果是防御,我可以让我的玩家站在对手旁边。

我尝试了很多不同的方法,但都以语法错误告终。如果你能朝正确的方向推动我,我会很感激的。

TeamState.h注意我在注释中得到的错误

@class TeamState;
#import <Foundation/Foundation.h>
#import "FootballTeam.h"
@protocol TeamStateProt 
-(void) enterTeamState:(TeamState*)team;
-(void) executeTeamState:(TeamState*)team;
-(void) exitTeamState:(TeamState*)team;
@end

@interface TeamState : NSObject{
    id<TeamStateProt> currentTeamState;
    id<TeamStateProt> Stoppage;
    id<TeamStateProt> Neutral;
    id<TeamStateProt> Defend;
    id<TeamStateProt> Attack;
    FootballTeam *footballTeam;  //ERROR Unknown Type name FootballTeam 
}
@property (nonatomic, retain) id<TeamStateProt> currentTeamState;
@property (nonatomic, retain) id<TeamStateProt> Stoppage;
@property (nonatomic, retain) id<TeamStateProt> Neutral;
@property (nonatomic, retain) id<TeamStateProt> Defend;
@property (nonatomic, retain) id<TeamStateProt> Attack;
- (id)initWithFootBallTeam:(FootballTeam*) team; //Error Expected a Type
-(void)update;
-(void)changeState:(id<TeamStateProt>) newState;
-(void)executeState:(id<TeamStateProt>) State;
@end

TeamState.m

#import "TeamState.h"
#import "FootballTeam.h"
#import "Stoppage_TS.h"
#import "Neutral_TS.h"
#import "Defend_TS.h"
#import "Attack_TS.h"

@implementation TeamState 
@synthesize currentTeamState;
@synthesize Stoppage, Neutral, Defend, Attack;
- (id)init
{
    self = [super init];
     if (self) {
        // Initialization code here.
        id<TeamStateProt>  s = [[Stoppage_TS alloc] init];
        self.Stoppage = s;
        id<TeamStateProt>  n = [[Neutral_TS alloc] init];
        self.Neutral = n;
        id<TeamStateProt>  d = [[Defend_TS alloc] init];
        self.Defend = d;
        id<TeamStateProt>  a = [[Attack_TS alloc] init];
        self.Attack = a;
        self.currentTeamState = n;
        [self.currentTeamState enterTeamState:self];
        [self executeState:self.currentTeamState];
    }
    return self;
}
- (id)initWithFootBallTeam:(FootballTeam*) team
{
    self = [super init];
    if (self) {
        // Initialization code here.
        id<TeamStateProt>  s = [[Stoppage_TS alloc] init];
        self.Stoppage = s;

        id<TeamStateProt>  n = [[Neutral_TS alloc] init];
        self.Neutral = n;
        id<TeamStateProt>  d = [[Defend_TS alloc] init];
        self.Defend = d;
        id<TeamStateProt>  a = [[Attack_TS alloc] init];
        self.Attack = a;
        self.currentTeamState = n;
        [self.currentTeamState enterTeamState:self];
        [self executeState:self.currentTeamState];
        footballTeam = team;
    }
    return self;
}
-(void)changeState:(id<TeamStateProt>) newState{
    NSLog(@"Changing State");
    if (newState != nil) {
        NSLog(@"Changing a state which isn't nil");
        [self.currentTeamState exitTeamState:self];
        self.currentTeamState = newState;
        [self.currentTeamState enterTeamState:self];
        [self executeState:self.currentTeamState];
    }
}
-(void)executeState:(id<TeamStateProt>) State{
    [self.currentTeamState executeTeamState:self];
}
// Each update, execute the execute state on the current team state
-(void)update{
    [self executeState:self.currentTeamState];
}
@end

FootballTeam.h

#import <Foundation/Foundation.h>
#import "Player.h"
#import "TeamState.h"
#import "Football.h"
typedef enum  {
    Home,
    Away
} TeamType;
@interface FootballTeam : NSObject{
    Player *ReceivingPlayer;    //Player to receive the ball
    Player *ClosestToBall;      //Player closest to the ball
    Player *ControllingPlayer;  //Player who has the ball can be NULL
    Player *SupportingPlayer;   //Player in a position to receive the ball
    NSMutableArray *players;    //Array of all the Players on this team
    TeamState *state;           //Current state of the teams state machine
    TeamType type;              //Defines if Home team or Away team
}
@property (nonatomic) TeamType type;
@property(nonatomic, retain) TeamState *state;
-(void) sendPlayersToHome;
-(Player*) playerClosestToBall:(Football*) ball;
-(BOOL) areAllPlayersAtHome;
@end

你有循环引用。您将在FootballTeam.h中导入TeamState.h,反之亦然。

为了避免这种情况,只导入。m文件中的。h文件,并在。h文件中添加forward声明。

因此,在TeamState.h:

@class FootballTeam;

并将导入移动到TeamState.m

在FootballTeam中也是如此。

最新更新