Objective-C/Common/AAPLGameView.m
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
The view displaying the game scene, including the 2D overlay. |
*/ |
@import SpriteKit; |
#import "AAPLGameView.h" |
@implementation AAPLGameView { |
SKNode *_overlayNode; |
SKNode *_congratulationsGroupNode; |
SKLabelNode *_collectedPearlCountLabel; |
NSMutableArray<SKSpriteNode *> *_collectedFlowerSprites; |
} |
#pragma mark - 2D Overlay |
#if TARGET_OS_IOS || TARGET_OS_TV |
- (void)awakeFromNib { |
[super awakeFromNib]; |
[self setup2DOverlay]; |
} |
- (void)layoutSubviews { |
[super layoutSubviews]; |
[self layout2DOverlay]; |
} |
#else |
- (void)viewDidMoveToWindow { |
[super viewDidMoveToWindow]; |
[self setup2DOverlay]; |
} |
- (void)setFrameSize:(NSSize)newSize { |
[super setFrameSize:newSize]; |
[self layout2DOverlay]; |
} |
#endif |
- (void)layout2DOverlay { |
_overlayNode.position = CGPointMake(0.0, self.bounds.size.height); |
_congratulationsGroupNode.position = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5); |
_congratulationsGroupNode.xScale = 1.0; |
_congratulationsGroupNode.yScale = 1.0; |
CGRect currentBbox = [_congratulationsGroupNode calculateAccumulatedFrame]; |
CGFloat margin = 25.0; |
CGRect maximumAllowedBbox = CGRectInset(self.bounds, margin, margin); |
CGFloat top = CGRectGetMaxY(currentBbox) - _congratulationsGroupNode.position.y; |
CGFloat bottom = _congratulationsGroupNode.position.y - CGRectGetMinY(currentBbox); |
CGFloat maxTopAllowed = CGRectGetMaxY(maximumAllowedBbox) - _congratulationsGroupNode.position.y; |
CGFloat maxBottomAllowed = _congratulationsGroupNode.position.y - CGRectGetMinY(maximumAllowedBbox); |
CGFloat left = _congratulationsGroupNode.position.x - CGRectGetMinX(currentBbox); |
CGFloat right = CGRectGetMaxX(currentBbox) - _congratulationsGroupNode.position.x; |
CGFloat maxLeftAllowed = _congratulationsGroupNode.position.x - CGRectGetMinX(maximumAllowedBbox); |
CGFloat maxRightAllowed = CGRectGetMaxX(maximumAllowedBbox) - _congratulationsGroupNode.position.x; |
CGFloat topScale = top > maxTopAllowed ? maxTopAllowed / top : 1; |
CGFloat bottomScale = bottom > maxBottomAllowed ? maxBottomAllowed / bottom : 1; |
CGFloat leftScale = left > maxLeftAllowed ? maxLeftAllowed / left : 1; |
CGFloat rightScale = right > maxRightAllowed ? maxRightAllowed / right : 1; |
CGFloat scale = MIN(topScale, MIN(bottomScale, MIN(leftScale, rightScale))); |
_congratulationsGroupNode.xScale = scale; |
_congratulationsGroupNode.yScale = scale; |
} |
- (void)setup2DOverlay { |
CGFloat w = self.bounds.size.width; |
CGFloat h = self.bounds.size.height; |
_overlayNode = [[SKNode alloc] init]; |
_collectedFlowerSprites = [[NSMutableArray alloc] init]; |
// Setup the game overlays using SpriteKit. |
SKScene *skScene = [SKScene sceneWithSize:CGSizeMake(w, h)]; |
skScene.scaleMode = SKSceneScaleModeResizeFill; |
[skScene addChild:_overlayNode]; |
_overlayNode.position = CGPointMake(0.0, h); |
// The Max icon. |
SKSpriteNode *characterNode = [SKSpriteNode spriteNodeWithImageNamed:@"MaxIcon.png"]; |
characterNode.position = CGPointMake(50, -50); |
characterNode.xScale = 0.5; |
characterNode.yScale = 0.5; |
[_overlayNode addChild:characterNode]; |
// The flowers. |
for (NSUInteger i = 0; i < 3; i++) { |
SKSpriteNode *flowerNode = [SKSpriteNode spriteNodeWithImageNamed:@"FlowerEmpty.png"]; |
flowerNode.position = CGPointMake(110 + i * 40, -50); |
flowerNode.xScale = 0.25; |
flowerNode.yScale = 0.25; |
[_overlayNode addChild:flowerNode]; |
[_collectedFlowerSprites addObject:flowerNode]; |
} |
// The pearl icon and count. |
SKSpriteNode *pearlNode = [SKSpriteNode spriteNodeWithImageNamed:@"ItemsPearl.png"]; |
pearlNode.position = CGPointMake(110, -100); |
pearlNode.xScale = 0.5; |
pearlNode.yScale = 0.5; |
[_overlayNode addChild:pearlNode]; |
_collectedPearlCountLabel = [[SKLabelNode alloc] initWithFontNamed:@"Chalkduster"]; |
_collectedPearlCountLabel.text = @"x0"; |
_collectedPearlCountLabel.position = CGPointMake(152, -113); |
[_overlayNode addChild:_collectedPearlCountLabel]; |
// The virtual D-pad |
#if TARGET_OS_IOS |
CGRect virtualDPadBounds = self.virtualDPadBoundsInScene; |
SKSpriteNode *dpadSprite = [SKSpriteNode spriteNodeWithImageNamed:@"dpad.png"]; |
dpadSprite.anchorPoint = CGPointMake(0.0, 0.0); |
dpadSprite.position = virtualDPadBounds.origin; |
dpadSprite.size = virtualDPadBounds.size; |
[skScene addChild:dpadSprite]; |
#endif |
// Assign the SpriteKit overlay to the SceneKit view. |
self.overlaySKScene = skScene; |
skScene.userInteractionEnabled = NO; |
} |
- (void)setCollectedPearlsCount:(NSUInteger)collectedPearlsCount { |
_collectedPearlsCount = collectedPearlsCount; |
if (_collectedPearlsCount == 10) { |
_collectedPearlCountLabel.position = CGPointMake(158, _collectedPearlCountLabel.position.y); |
} |
_collectedPearlCountLabel.text = [NSString stringWithFormat:@"x%d", (uint32_t)collectedPearlsCount]; |
} |
- (void)setCollectedFlowersCount:(NSUInteger)collectedFlowersCount { |
_collectedFlowerSprites[collectedFlowersCount - 1].texture = [SKTexture textureWithImageNamed:@"FlowerFull.png"]; |
} |
#pragma mark - Congratulating the Player |
- (void)showEndScreen { |
// Congratulation title |
SKSpriteNode *congratulationsNode = [SKSpriteNode spriteNodeWithImageNamed:@"congratulations.png"]; |
// Max image |
SKSpriteNode *characterNode = [SKSpriteNode spriteNodeWithImageNamed:@"congratulations_pandaMax.png"]; |
characterNode.position = CGPointMake(0.0, -220.0); |
characterNode.anchorPoint = CGPointMake(0.5, 0.0); |
_congratulationsGroupNode = [[SKNode alloc] init]; |
[_congratulationsGroupNode addChild:characterNode]; |
[_congratulationsGroupNode addChild:congratulationsNode]; |
SKScene *overlayScene = self.overlaySKScene; |
[overlayScene addChild:_congratulationsGroupNode]; |
// Layout the overlay |
[self layout2DOverlay]; |
// Animate |
congratulationsNode.alpha = 0.0; |
congratulationsNode.xScale = 0.0; |
congratulationsNode.yScale = 0.0; |
[congratulationsNode runAction:[SKAction group:@[[SKAction fadeInWithDuration:0.25], |
[SKAction sequence:@[[SKAction scaleTo:1.22 duration:0.25], [SKAction scaleTo:1.0 duration:0.1]]]]]]; |
characterNode.alpha = 0.0; |
characterNode.xScale = 0.0; |
characterNode.yScale = 0.0; |
[characterNode runAction:[SKAction sequence:@[[SKAction waitForDuration:0.5], [SKAction group:@[[SKAction fadeInWithDuration:0.5], |
[SKAction sequence:@[[SKAction scaleTo:1.22 duration:0.25], [SKAction scaleTo:1.0 duration:0.1]]]]]]]]; |
} |
#pragma mark - Mouse and Keyboard Events |
#if !(TARGET_OS_IOS || TARGET_OS_TV) |
- (void)mouseDown:(NSEvent *)theEvent { |
if (!_eventsDelegate || [_eventsDelegate mouseDown:self event:theEvent] == NO) { |
[super mouseDown:theEvent]; |
} |
} |
- (void)mouseDragged:(NSEvent *)theEvent { |
if (!_eventsDelegate || [_eventsDelegate mouseDragged:self event:theEvent] == NO) { |
[super mouseDragged:theEvent]; |
} |
} |
- (void)mouseUp:(NSEvent *)theEvent { |
if (!_eventsDelegate || [_eventsDelegate mouseUp:self event:theEvent] == NO) { |
[super mouseUp:theEvent]; |
} |
} |
- (void)keyDown:(NSEvent *)theEvent { |
if (!_eventsDelegate || [_eventsDelegate keyDown:self event:theEvent] == NO) { |
[super keyDown:theEvent]; |
} |
} |
- (void)keyUp:(NSEvent *)theEvent { |
if (!_eventsDelegate || [_eventsDelegate keyUp:self event:theEvent] == NO) { |
[super keyUp:theEvent]; |
} |
} |
#endif |
#pragma mark - Virtual D-pad |
#if TARGET_OS_IOS |
- (CGRect)virtualDPadBoundsInScene { |
return CGRectMake(10.0, 10.0, 150.0, 150.0); |
} |
- (CGRect)virtualDPadBounds { |
CGRect virtualDPadBounds = [self virtualDPadBoundsInScene]; |
virtualDPadBounds.origin.y = self.bounds.size.height - virtualDPadBounds.size.height + virtualDPadBounds.origin.y; |
return virtualDPadBounds; |
} |
#endif |
@end |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-09-13