我饶有兴趣地阅读了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中也是如此。