Sie sind auf Seite 1von 9

//

//
//
//
//
//
//

DRGameView.m
Dragon Rider
Created by iAdmin on 7/28/14.
Copyright (c) 2014 Ride That Wave. All rights reserved.

#import "DRGameView.h"
#define TIME 1.5
#define MINIMUM_SWORD_HEIGHT 75.0f
#define GAP_BETWEEN_TOP_AND_BOTTOM_SWORD 50
@interface DRGameView()
@property
@property
@property
@property
@property
@property
@property
@property
@property
@property
@property

BOOL sceneCreated;
SKLabelNode* scoreLabel;
NSTimeInterval deltaTime;
float bottomScrollerHeight;
int score;
(nonatomic) NSTimeInterval lastUpdateTimeInterval;
(nonatomic) NSTimeInterval lastSpawnTimeInterval;
NSArray* flappyDragonFrames;
SKSpriteNode* dragon;
BOOL isGameStarted;
BOOL isGameOver;

@end
@implementation DRGameView
static const uint32_t dragonPlayerCategory = 0x1 << 0;
static const uint32_t swordPillarCategory = 0x1 << 1;
static const uint32_t bottomScrollerCategory = 0x1 << 2;
static const float BG_VELOCITY = (TIME * 60);
static inline CGPoint CGPointAdd(const CGPoint num1, const CGPoint num2)
{
return CGPointMake(num1.x + num2.x, num1.y + num2.y);
}
static inline CGPoint CGPointMultiplyScalar(const CGPoint number, const CGFloat
scalar)
{
return CGPointMake(number.x * scalar, number.y * scalar);
}
- (void)didMoveToView:(SKView *)view
{
if (!self.sceneCreated)
{
self.physicsWorld.gravity = CGVectorMake(0.0, -5.0);
[self playBackgroundMusic];
[self addChild:[self createBackgroundNode]];
[self initializeScrollingBackground];
[self addChild:[self createDragon]];

[self addChild:[self createScoreLabel]];


_isGameStarted = YES;
_isGameOver = NO;
[self initGameScene];
self.physicsWorld.contactDelegate = self;
self.sceneCreated = YES;
}
}
- (void) initGameScene
{
NSMutableArray* dragonWingFrames = [NSMutableArray array];
SKTextureAtlas* dragonAtlas = [SKTextureAtlas atlasNamed:@"dragon"];
for (int index = 1; index <= 2; index++)
{
NSString* texture = [NSString stringWithFormat:@"Dragon%d", index];
[dragonWingFrames addObject:[dragonAtlas textureNamed:texture]];
}
self.flappyDragonFrames = dragonWingFrames;
SKAction* animateWingFlap = [SKAction animateWithTextures:self.flappyDragonF
rames timePerFrame:0.17];
SKAction* repeatWingFlap = [SKAction repeatActionForever:animateWingFlap];
[_dragon runAction:repeatWingFlap];
}
- (void) playBackgroundMusic
{
NSString* soundFilePath = [[NSBundle mainBundle]pathForResource:@"GameOfThro
nesThemeMusic" ofType:@"mp3"];
NSURL* audioURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
AVAudioPlayer* musicPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:aud
ioURL error:nil];
self.backgroundMusicPlayer = musicPlayer;
[self.backgroundMusicPlayer prepareToPlay];
self.backgroundMusicPlayer.numberOfLoops = -1;
self.backgroundMusicPlayer.volume = 10;
[self.backgroundMusicPlayer play];
}
- (SKSpriteNode*) createBackgroundNode
{
SKSpriteNode* background = [SKSpriteNode spriteNodeWithImageNamed:@"iamsicko
fbackgrounds.png"];
background.name = @"background";
background.size = self.size;
background.anchorPoint = self.anchorPoint;
background.zPosition = DrawingOrderBackground;
return background;
}
- (SKSpriteNode*) createDragon
{
_dragon = [SKSpriteNode spriteNodeWithImageNamed:@"Dragon1.png"];

_dragon.name = @"dragon";
_dragon.size = CGSizeMake(30.0f, 30.0f);
_dragon.position = CGPointMake(CGRectGetMidX(self.frame) / 2, CGRectGetMidY(
self.frame));
_dragon.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(20.0
f, 10.0f)];
_dragon.physicsBody.usesPreciseCollisionDetection = YES;
_dragon.physicsBody.categoryBitMask = dragonPlayerCategory;
_dragon.physicsBody.contactTestBitMask = swordPillarCategory | bottomScrolle
rCategory;
_dragon.physicsBody.dynamic = YES;
_dragon.physicsBody.allowsRotation = NO;
_dragon.zPosition = DrawingOrderDragonPlayer;
return _dragon;
}
- (SKLabelNode*)createScoreLabel
{
NSString* score = [NSString stringWithFormat:@"%d", _score];
_scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"GameofThrones"];
_scoreLabel.name = @"score";
_scoreLabel.position = CGPointMake(160, 3);
_scoreLabel.text = score;
_scoreLabel.fontSize = 20.0f;
_scoreLabel.zPosition = 100;
return _scoreLabel;
}
- (void) initializeScrollingBackground
{
for (int index = 0; index < 2; index++)
{
SKSpriteNode* scrollingBottom = [SKSpriteNode spriteNodeWithImageNamed:@
"ScrollingBottom.png"];
scrollingBottom.zPosition = DrawingOrderBottomScroller;
scrollingBottom.position = CGPointMake((index * scrollingBottom.size.wid
th) + (scrollingBottom.size.width * 0.5f + 1.0f) - 1, scrollingBottom.size.heigh
t - 100.0f);
scrollingBottom.name = @"Scrolling_Background";
scrollingBottom.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:scr
ollingBottom.size];
scrollingBottom.physicsBody.categoryBitMask = bottomScrollerCategory;
scrollingBottom.physicsBody.contactTestBitMask = dragonPlayerCategory;
scrollingBottom.physicsBody.affectedByGravity = NO;
scrollingBottom.physicsBody.dynamic = NO;
[self addChild:scrollingBottom];
}
}
- (void) scrollBackground
{
[self enumerateChildNodesWithName:@"Scrolling_Background" usingBlock: ^(SKNo
de* node, BOOL *stop)
{

SKSpriteNode* scrollingBackground = (SKSpriteNode*)node;


CGPoint backgroundVelocity = CGPointMake(-BG_VELOCITY, 0);
CGPoint amountToMoveBackground = CGPointMultiplyScalar(backgroundVeloci
ty, _deltaTime);
scrollingBackground.position = CGPointAdd(scrollingBackground.position,
amountToMoveBackground);
if (scrollingBackground.position.x + scrollingBackground.size.width * 0
.5f <= 0)
{
scrollingBackground.position = CGPointMake(scrollingBackground.size
.width * 2 - (scrollingBackground.size.width * 0.5f) - 2, scrollingBackground.po
sition.y);
}
}];
}
- (void)flappyDragonCollidedWithBottomScroller:(SKSpriteNode*)dragon
{
SKAction* fadeAway = [SKAction fadeOutWithDuration:0.5];
SKAction* wait = [SKAction waitForDuration:0.1f];
[self runAction:wait completion:^{[self runAction:fadeAway completion:^{SKSc
ene* mainMenu = [[DRMainMenu alloc]initWithSize:self.size]; SKTransition* doorTr
ansition = [SKTransition doorsCloseHorizontalWithDuration:1.0]; [self.view prese
ntScene:mainMenu transition:doorTransition];}];}];
_dragon.physicsBody.velocity = CGVectorMake(0, 0);
[_backgroundMusicPlayer stop];
self.sceneCreated = NO;
self.userInteractionEnabled = NO;
//Make Dragon Bleed
NSString* bloodPath = [[NSBundle mainBundle]pathForResource:@"Blood" ofType:
@"sks"];
SKEmitterNode* dragonBlood = [NSKeyedUnarchiver unarchiveObjectWithFile:bloo
dPath];
dragonBlood.position = _dragon.position;
[self addChild:dragonBlood];
//Update the high score
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber* storedHighScore = [defaults valueForKey:@"high_score"];
if(storedHighScore != nil)
{
NSNumber* scoreNS = [NSNumber numberWithInt:_score / 2];
if([storedHighScore compare:scoreNS] == NSOrderedAscending)
{
[defaults setObject:[NSNumber numberWithInt:_score / 2] forKey:@"hig
h_score"];
[defaults synchronize];
}
}
else
{
[defaults setObject:[NSNumber numberWithInt:_score / 2] forKey:@"high_sc
ore"];
[defaults synchronize];
}

}
- (void)flappyDragonCollidedWithASword:(SKSpriteNode*)dragon
{
SKAction* fadeAway = [SKAction fadeOutWithDuration:0.1];
SKAction* wait = [SKAction waitForDuration:0.1f];
[self runAction:wait completion:^{[self runAction:fadeAway completion:^{SKSc
ene* mainMenu = [[DRMainMenu alloc]initWithSize:self.size]; SKTransition* doorTr
ansition = [SKTransition doorsCloseHorizontalWithDuration:1.0]; [self.view prese
ntScene:mainMenu transition:doorTransition];}];}];
_dragon.physicsBody.velocity = CGVectorMake(0, 0);
[_backgroundMusicPlayer stop];
self.sceneCreated = NO;
self.userInteractionEnabled = NO;
//Make Dragon Bleed
NSString* bloodPath = [[NSBundle mainBundle]pathForResource:@"Blood" ofType:
@"sks"];
SKEmitterNode* dragonBlood = [NSKeyedUnarchiver unarchiveObjectWithFile:bloo
dPath];
dragonBlood.position = _dragon.position;
[self addChild:dragonBlood];
//Update the high score
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber* storedHighScore = [defaults valueForKey:@"high_score"];
if(storedHighScore != nil)
{
NSNumber* scoreNS = [NSNumber numberWithInt:_score / 2];
if([storedHighScore compare:scoreNS] == NSOrderedAscending)
{
[defaults setObject:[NSNumber numberWithInt:_score / 2] forKey:@"hig
h_score"];
[defaults synchronize];
}
}
else
{
[defaults setObject:[NSNumber numberWithInt:_score / 2] forKey:@"high_sc
ore"];
[defaults synchronize];
}
}
- (void)didBeginContact:(SKPhysicsContact*)contact
{
SKPhysicsBody* firstBody;
if(((contact.bodyA.categoryBitMask == dragonPlayerCategory) && contact.bodyB
.categoryBitMask ==bottomScrollerCategory) || ((contact.bodyA.categoryBitMask ==
bottomScrollerCategory) && (contact.bodyB.categoryBitMask == dragonPlayerCatego
ry)))
{
[self flappyDragonCollidedWithBottomScroller:(SKSpriteNode *)firstBody.n
ode];
}

if(((contact.bodyA.categoryBitMask == dragonPlayerCategory) && contact.bodyB


.categoryBitMask ==swordPillarCategory) || ((contact.bodyA.categoryBitMask == sw
ordPillarCategory) && (contact.bodyB.categoryBitMask == dragonPlayerCategory)))
{
[self flappyDragonCollidedWithASword:(SKSpriteNode*)firstBody.node];
}
}
- (void) update:(NSTimeInterval)currentTime
{
if (_isGameOver == NO)
{
if (self.lastUpdateTimeInterval)
{
_deltaTime = currentTime - _lastUpdateTimeInterval;
}
else
{
_deltaTime = 0;
}
CFTimeInterval timeSinceLastUpdate = currentTime - self.lastUpdateTimeIn
terval;
self.lastUpdateTimeInterval = currentTime;
if (timeSinceLastUpdate > TIME)
{
timeSinceLastUpdate = 1.0 / (TIME * 60.0);
self.lastUpdateTimeInterval = currentTime;
}
[self scrollBackground];
[self updateScore];
if (_isGameStarted) {
[self updateWithTimeSinceLastUpdate:timeSinceLastUpdate];
}
}
}
- (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast
{
self.lastSpawnTimeInterval += timeSinceLast;
if (self.lastSpawnTimeInterval > TIME)
{
self.lastSpawnTimeInterval = 0;
[self addASword];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
_dragon.physicsBody.velocity = CGVectorMake(0, 0);
[_dragon.physicsBody applyImpulse:CGVectorMake(0, 1.5f)];
if (_dragon.position.y > self.frame.size.height)
{
SKAction* fadeAway = [SKAction fadeOutWithDuration:0.5];
SKAction* wait = [SKAction waitForDuration:0.1f];

[self runAction:wait completion:^{[self runAction:fadeAway completion:^{


SKScene* mainMenu = [[DRMainMenu alloc]initWithSize:self.size]; SKTransition* do
orTransition = [SKTransition doorsCloseHorizontalWithDuration:1.0]; [self.view p
resentScene:mainMenu transition:doorTransition];}];}];
_dragon.physicsBody.velocity = CGVectorMake(0, 0);
[_backgroundMusicPlayer stop];
self.sceneCreated = NO;
self.userInteractionEnabled = NO;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (_dragon.position.y > self.frame.size.height)
{
SKAction* fadeAway = [SKAction fadeOutWithDuration:0.5];
SKAction* wait = [SKAction waitForDuration:0.1f];
[self runAction:wait completion:^{[self runAction:fadeAway completion:^{
SKScene* mainMenu = [[DRMainMenu alloc]initWithSize:self.size]; SKTransition* do
orTransition = [SKTransition doorsCloseHorizontalWithDuration:1.0]; [self.view p
resentScene:mainMenu transition:doorTransition];}];}];
_dragon.physicsBody.velocity = CGVectorMake(0, 0);
[_backgroundMusicPlayer stop];
self.sceneCreated = NO;
self.userInteractionEnabled = NO;
}
}
- (SKSpriteNode*) createSwordWithUpwardDirection:(BOOL) isUpwards
{
NSString* swordImageName = nil;
if (isUpwards) {
swordImageName = @"iceUp.png";
}
else {
swordImageName = @"iceDown.png";
}
SKSpriteNode* sword = [SKSpriteNode spriteNodeWithImageNamed:swordImageName]
;
sword.name = @"Sword";
sword.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:sword.size];
sword.physicsBody.usesPreciseCollisionDetection = YES;
sword.physicsBody.categoryBitMask = swordPillarCategory;
sword.physicsBody.contactTestBitMask = dragonPlayerCategory;
sword.physicsBody.collisionBitMask = 0;

sword.physicsBody.affectedByGravity = NO;
[self addChild:sword];
return sword;
}
- (void) addASword
{
//Upward sword
SKSpriteNode* upwardSword = [self createSwordWithUpwardDirection:YES];
int minY = MINIMUM_SWORD_HEIGHT;
int maxY = (self.frame.size.height - GAP_BETWEEN_TOP_AND_BOTTOM_SWORD - 25.0
f);
int rangeY = maxY - minY;
float upwardSwordY = ((arc4random() % rangeY) + minY) - upwardSword.size.hei
ght;
upwardSwordY += _bottomScrollerHeight;
upwardSwordY += upwardSword.size.height * 0.5f;
upwardSword.position = CGPointMake(self.frame.size.width + upwardSword.size.
width/2, upwardSwordY);
//Downward sword
SKSpriteNode* downwardSword = [self createSwordWithUpwardDirection:NO];
float downwardSwordY = upwardSwordY + upwardSword.size.height + GAP_BETWEEN_
TOP_AND_BOTTOM_SWORD;
downwardSword.position = CGPointMake(upwardSword.position.x, downwardSwordY)
;
//Up action
SKAction* upwardSwordActionMove = [SKAction moveTo:CGPointMake(-upwardSword.
size.width/2, upwardSwordY) duration:(TIME * 2)];
SKAction* upwardSwordActionMoveComplete = [SKAction removeFromParent];
[upwardSword runAction:[SKAction sequence:@[upwardSwordActionMove,upwardSwor
dActionMoveComplete]]];
//Move upwardSword up and down action definitions
SKAction* moveUpwardSwordUp = [SKAction moveToY:upwardSwordY + 15 duration:T
IME];
SKAction* moveUpwardSwordDown = [SKAction moveToY:upwardSwordY - 15 duration
:TIME];
//Move downwardSword up and down action definitions
SKAction* moveDownwardSwordUp = [SKAction moveToY:downwardSwordY + 15 durati
on:TIME];
SKAction* moveDownwardSwordDown = [SKAction moveToY:downwardSwordY - 15 dura
tion:TIME];
//Down action
SKAction* downwardSwordActionMove = [SKAction moveTo:CGPointMake(-downwardSw
ord.size.width/2, downwardSwordY) duration:(TIME * 2)];
SKAction* downwardSwordActionMoveComplete = [SKAction removeFromParent];
[downwardSword runAction:[SKAction sequence:@[downwardSwordActionMove, downw
ardSwordActionMoveComplete]]];
//Move both swords up and down
[upwardSword runAction:[SKAction sequence:@[moveUpwardSwordUp, moveUpwardSwo

rdDown]]];
[downwardSword runAction:[SKAction sequence:@[moveDownwardSwordUp, moveDownw
ardSwordDown]]];
}
- (void) updateScore
{
[self enumerateChildNodesWithName:@"Sword" usingBlock:^(SKNode* node, BOOL*
stop)
{
if(_dragon.position.x > node.position.x)
{
node.name = @"";
++_score;
if (_score % 2 == 0)
{
_scoreLabel.text = [NSString stringWithFormat:@"%d", _score / 2
];
}
*stop = YES;
}
}];
}
@end