- #import "MyScene.h"
- // 1
- @interface MyScene ()
- @property (nonatomic) SKSpriteNode * player;
- @end
- @implementation MyScene
- -(id)initWithSize:(CGSize)size {
- if (self = [super initWithSize:size]) {
- // 2
- NSLog(@"Size: %@", NSStringFromCGSize(size));
- // 3
- self.backgroundColor = [SKColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
- // 4
- self.player = [SKSpriteNode spriteNodeWithImageNamed:@"player"];
- self.player.position = CGPointMake(100, 100);
- [self addChild:self.player];
- }
- return self;
- }
- @end
- SpriteKitSimpleGame[3139:907] Size: {320, 568}
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Configure the view.
- SKView * skView = (SKView *)self.view;
- skView.showsFPS = YES;
- skView.showsNodeCount = YES;
- // Create and configure the scene.
- SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
- scene.scaleMode = SKSceneScaleModeAspectFill;
- // Present the scene.
- [skView presentScene:scene];
- }
- - (void)viewWillLayoutSubviews
- {
- [super viewWillLayoutSubviews];
- // Configure the view.
- SKView * skView = (SKView *)self.view;
- if (!skView.scene) {
- skView.showsFPS = YES;
- skView.showsNodeCount = YES;
- // Create and configure the scene.
- SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
- scene.scaleMode = SKSceneScaleModeAspectFill;
- // Present the scene.
- [skView presentScene:scene];
- }
- }
- self.player.position = CGPointMake(self.player.size.width/2, self.frame.size.height/2);
- - (void)addMonster {
- // Create sprite
- SKSpriteNode * monster = [SKSpriteNode spriteNodeWithImageNamed:@"monster"];
- // Determine where to spawn the monster along the Y axis
- int minY = monster.size.height / 2;
- int maxY = self.frame.size.height - monster.size.height / 2;
- int rangeY = maxY - minY;
- int actualY = (arc4random() % rangeY) + minY;
- // Create the monster slightly off-screen along the right edge,
- // and along a random position along the Y axis as calculated above
- monster.position = CGPointMake(self.frame.size.width + monster.size.width/2, actualY);
- [self addChild:monster];
- // Determine speed of the monster
- int minDuration = 2.0;
- int maxDuration = 4.0;
- int rangeDuration = maxDuration - minDuration;
- int actualDuration = (arc4random() % rangeDuration) + minDuration;
- // Create the actions
- SKAction * actionMove = [SKAction moveTo:CGPointMake(-monster.size.width/2, actualY) duration:actualDuration];
- SKAction * actionMoveDone = [SKAction removeFromParent];
- [monster runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];
- }
- @property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
- @property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
- - (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
- self.lastSpawnTimeInterval += timeSinceLast;
- if (self.lastSpawnTimeInterval > 1) {
- self.lastSpawnTimeInterval = 0;
- [self addMonster];
- }
- }
- - (void)update:(NSTimeInterval)currentTime {
- // Handle time delta.
- // If we drop below 60fps, we still want everything to move the same distance.
- CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
- self.lastUpdateTimeInterval = currentTime;
- if (timeSinceLast > 1) { // more than a second since last update
- timeSinceLast = 1.0 / 60.0;
- self.lastUpdateTimeInterval = currentTime;
- }
- [self updateWithTimeSinceLastUpdate:timeSinceLast];
- }
- static inline CGPoint rwAdd(CGPoint a, CGPoint b) {
- return CGPointMake(a.x + b.x, a.y + b.y);
- }
- static inline CGPoint rwSub(CGPoint a, CGPoint b) {
- return CGPointMake(a.x - b.x, a.y - b.y);
- }
- static inline CGPoint rwMult(CGPoint a, float b) {
- return CGPointMake(a.x * b, a.y * b);
- }
- static inline float rwLength(CGPoint a) {
- return sqrtf(a.x * a.x + a.y * a.y);
- }
- // Makes a vector have a length of 1
- static inline CGPoint rwNormalize(CGPoint a) {
- float length = rwLength(a);
- return CGPointMake(a.x / length, a.y / length);
- }
- -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- // 1 - Choose one of the touches to work with
- UITouch * touch = [touches anyObject];
- CGPoint location = [touch locationInNode:self];
- // 2 - Set up initial location of projectile
- SKSpriteNode * projectile = [SKSpriteNode spriteNodeWithImageNamed:@"projectile"];
- projectile.position = self.player.position;
- // 3- Determine offset of location to projectile
- CGPoint offset = rwSub(location, projectile.position);
- // 4 - Bail out if you are shooting down or backwards
- if (offset.x <= 0) return;
- // 5 - OK to add now - we've double checked position
- [self addChild:projectile];
- // 6 - Get the direction of where to shoot
- CGPoint direction = rwNormalize(offset);
- // 7 - Make it shoot far enough to be guaranteed off screen
- CGPoint shootAmount = rwMult(direction, 1000);
- // 8 - Add the shoot amount to the current position
- CGPoint realDest = rwAdd(shootAmount, projectile.position);
- // 9 - Create the actions
- float velocity = 480.0/1.0;
- float realMoveDuration = self.size.width / velocity;
- SKAction * actionMove = [SKAction moveTo:realDest duration:realMoveDuration];
- SKAction * actionMoveDone = [SKAction removeFromParent];
- [projectile runAction:[SKAction sequence:@[actionMove, actionMoveDone]]];
- }