Common/AAPLFlockScene.m
/* |
Copyright (C) 2015 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Demonstrates flocking behavior -- a combination of separation, alignment, and cohesion goals. Click (OS X) or touch (iOS) and drag and the flock of agents follows the mouse/touch location together. |
*/ |
#import "AAPLFlockScene.h" |
#import "AAPLAgentNode.h" |
@interface AAPLFlockScene () |
@property NSArray<AAPLAgentNode *> *flock; |
@property GKGoal *seekGoal; |
@end |
@implementation AAPLFlockScene |
- (NSString *)sceneName { |
return @"FLOCKING"; |
} |
- (void)didMoveToView:(nonnull SKView *)view { |
[super didMoveToView:view]; |
// Create a flock of similar agents. |
NSMutableArray<GKAgent2D *> *agents = [NSMutableArray arrayWithCapacity:20]; |
NSInteger agentsPerRow = 4; |
for (NSInteger i = 0; i < agentsPerRow*agentsPerRow; i++) { |
CGFloat x = CGRectGetMidX(self.frame) + i % agentsPerRow * 20; |
CGFloat y = CGRectGetMidY(self.frame) + i / agentsPerRow * 20; |
AAPLAgentNode *boid = [[AAPLAgentNode alloc] initWithScene:self |
radius:10 |
position:CGPointMake(x, y)]; |
[self.agentSystem addComponent:boid.agent]; |
[agents addObject:boid.agent]; |
boid.drawsTrail = NO; |
} |
self.flock = [agents copy]; |
static const float separationRadius = 0.553f * 50; |
static const float separationAngle = 3 * M_PI / 4.0f; |
static const float separationWeight = 10.0f; |
static const float alignmentRadius = 0.83333f * 50; |
static const float alignmentAngle = M_PI / 4.0f; |
static const float alignmentWeight = 12.66f; |
static const float cohesionRadius = 1.0f * 100; |
static const float cohesionAngle = M_PI / 2.0f; |
static const float cohesionWeight = 8.66f; |
// Separation, alignment, and cohesion goals combined cause the flock to move as a group. |
GKBehavior* behavior = [[GKBehavior alloc] init]; |
[behavior setWeight:separationWeight forGoal:[GKGoal goalToSeparateFromAgents:agents maxDistance:separationRadius maxAngle:separationAngle]]; |
[behavior setWeight:alignmentWeight forGoal:[GKGoal goalToAlignWithAgents:agents maxDistance:alignmentRadius maxAngle:alignmentAngle]]; |
[behavior setWeight:cohesionWeight forGoal:[GKGoal goalToCohereWithAgents:agents maxDistance:cohesionRadius maxAngle:cohesionAngle]]; |
for (GKAgent2D *agent in agents) { |
agent.behavior = behavior; |
} |
// Create the seek goal, but add it to the behavior only in -setSeeking:. |
self.seekGoal = [GKGoal goalToSeekAgent:self.trackingAgent]; |
} |
- (void)setSeeking:(BOOL)seeking { |
[super setSeeking:seeking]; |
for (GKAgent2D *agent in self.agentSystem) { |
if (seeking) { |
[agent.behavior setWeight:1 forGoal:self.seekGoal]; |
} |
else { |
[agent.behavior setWeight:0 forGoal:self.seekGoal]; |
} |
} |
} |
@end |
Copyright © 2015 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2015-09-16