Sprite Kit教程:初学者
作者:Ray Wenderlich
原文出处:点击打开链接
http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners

转自破船之家,原文:Sprite Kit Tutorial for Beginners





- #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]]];
- }

- static const uint32_t projectileCategory = 0x1 << 0;
- static const uint32_t monsterCategory = 0x1 << 1;
- self.physicsWorld.gravity = CGVectorMake(0,0);
- self.physicsWorld.contactDelegate = self;
- monster.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:monster.size]; // 1
- monster.physicsBody.dynamic = YES; // 2
- monster.physicsBody.categoryBitMask = monsterCategory; // 3
- monster.physicsBody.contactTestBitMask = projectileCategory; // 4
- monster.physicsBody.collisionBitMask = 0; // 5
- projectile.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:projectile.size.width/2];
- projectile.physicsBody.dynamic = YES;
- projectile.physicsBody.categoryBitMask = projectileCategory;
- projectile.physicsBody.contactTestBitMask = monsterCategory;
- projectile.physicsBody.collisionBitMask = 0;
- projectile.physicsBody.usesPreciseCollisionDetection = YES;
- - (void)projectile:(SKSpriteNode *)projectile didCollideWithMonster:(SKSpriteNode *)monster {
- NSLog(@"Hit");
- [projectile removeFromParent];
- [monster removeFromParent];
- }
- - (void)didBeginContact:(SKPhysicsContact *)contact
- {
- // 1
- SKPhysicsBody *firstBody, *secondBody;
- if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
- {
- firstBody = contact.bodyA;
- secondBody = contact.bodyB;
- }
- else
- {
- firstBody = contact.bodyB;
- secondBody = contact.bodyA;
- }
- // 2
- if ((firstBody.categoryBitMask & projectileCategory) != 0 &&
- (secondBody.categoryBitMask & monsterCategory) != 0)
- {
- [self projectile:(SKSpriteNode *) firstBody.node didCollideWithMonster:(SKSpriteNode *) secondBody.node];
- }
- }
- @interface MyScene () <SKPhysicsContactDelegate>
- @import AVFoundation;
- @interface ViewController ()
- @property (nonatomic) AVAudioPlayer * backgroundMusicPlayer;
- @end
- NSError *error;
- NSURL * backgroundMusicURL = [[NSBundle mainBundle] URLForResource:@"background-music-aac" withExtension:@"caf"];
- self.backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
- self.backgroundMusicPlayer.numberOfLoops = -1;
- [self.backgroundMusicPlayer prepareToPlay];
- [self.backgroundMusicPlayer play];
- [self runAction:[SKAction playSoundFileNamed:@"pew-pew-lei.caf" waitForCompletion:NO]];
- #import <SpriteKit/SpriteKit.h>
- @interface GameOverScene : SKScene
- -(id)initWithSize:(CGSize)size won:(BOOL)won;
- @end
- #import "GameOverScene.h"
- #import "MyScene.h"
- @implementation GameOverScene
- -(id)initWithSize:(CGSize)size won:(BOOL)won {
- if (self = [super initWithSize:size]) {
- // 1
- self.backgroundColor = [SKColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
- // 2
- NSString * message;
- if (won) {
- message = @"You Won!";
- } else {
- message = @"You Lose :[";
- }
- // 3
- SKLabelNode *label = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
- label.text = message;
- label.fontSize = 40;
- label.fontColor = [SKColor blackColor];
- label.position = CGPointMake(self.size.width/2, self.size.height/2);
- [self addChild:label];
- // 4
- [self runAction:
- [SKAction sequence:@[
- [SKAction waitForDuration:3.0],
- [SKAction runBlock:^{
- // 5
- SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
- SKScene * myScene = [[MyScene alloc] initWithSize:self.size];
- [self.view presentScene:myScene transition: reveal];
- }]
- ]]
- ];
- }
- return self;
- }
- @end
- #import "GameOverScene.h"
- SKAction * loseAction = [SKAction runBlock:^{
- SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
- SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:NO];
- [self.view presentScene:gameOverScene transition: reveal];
- }];
- [monster runAction:[SKAction sequence:@[actionMove, loseAction, actionMoveDone]]];
- @property (nonatomic) int monstersDestroyed;
- self.monstersDestroyed++;
- if (self.monstersDestroyed > 30) {
- SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
- SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:YES];
- [self.view presentScene:gameOverScene transition: reveal];
- }
Sprite Kit教程:初学者的更多相关文章
- ios游戏开发 Sprite Kit教程:初学者 1
注:本文译自Sprite Kit Tutorial for Beginners 目录 Sprite Kit的优点和缺点 Sprite Kit vs Cocos2D-iPhone vs Cocos2D- ...
- iOS Sprite Kit教程之滚动场景
iOS Sprite Kit教程之滚动场景 滚动场景 在很多的游戏中,场景都不是静止的,而是滚动的,如在植物大战僵尸的游戏中,它的场景如图2.26所示. 图2.26 植物大战僵尸 在图2.26中,用 ...
- iOS Sprite Kit教程之场景的切换
iOS Sprite Kit教程之场景的切换 Sprite Kit中切换场景 每一个场景都不是单独存在的.玩家可以从一个场景中切换到另外一个场景中.本小节,我们来讲解场景切换.在每一个游戏中都会使用到 ...
- iOS Sprite Kit教程之场景的设置
iOS Sprite Kit教程之场景的设置 Sprite Kit中设置场景 在图2.8所示的效果中,可以看到新增的场景是没有任何内容的,本节将讲解对场景的三个设置,即颜色的设置.显示模式的设置以及测 ...
- iOS Sprite Kit教程之真机测试以及场景的添加与展示
iOS Sprite Kit教程之真机测试以及场景的添加与展示 IOS实现真机测试 在进行真机测试之前,首先需要确保设备已经连在了Mac(或者Mac虚拟机)上,在第1.9.1小节开始,设备就一直连接在 ...
- iOS Sprite Kit教程之申请和下载证书
iOS Sprite Kit教程之申请和下载证书 模拟器虽然可以实现真机上的一些功能,但是它是有局限的.例如,在模拟器上没有重力感应.相机机等.如果想要进行此方面的游戏的开发,进行程序测试时,模拟器显 ...
- iOS Sprite Kit教程之使用帮助文档以及调试程序
iOS Sprite Kit教程之使用帮助文档以及调试程序 IOS中使用帮助文档 在编写代码的时候,可能会遇到很多的方法.如果开发者对这些方法的功能,以及参数不是很了解,就可以使用帮助文档.那么帮助文 ...
- iOS Sprite Kit教程之编写程序以及Xcode的介绍
iOS Sprite Kit教程之编写程序以及Xcode的介绍 Xcode界面介绍 一个Xcode项目由很多的文件组成,例如代码文件.资源文件等.Xcode会帮助开发者对这些文件进行管理.所以,Xco ...
- iOS Sprite Kit教程之编敲代码以及Xcode的介绍
iOS Sprite Kit教程之编敲代码以及Xcode的介绍 Xcode界面介绍 一个Xcode项目由非常多的文件组成,比如代码文件.资源文件等.Xcode会帮助开发人员对这些文件进行管理.所以,X ...
随机推荐
- [LeetCode#241]Different Ways to Add Parentheses
Problem: Given a string of numbers and operators, return all possible results from computing all the ...
- Android TextView setText内嵌html标签
由于得到的数据是保存在数据库里面的,不好对数据的某一部分进行操作.解决办法在数据库里面存数据的时候加上html的标签对, 如data = <中华人名共和国道路交通安全实施条例>第<u ...
- HDOJ1175连连看 DFS
连连看 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- Poj 2887-Big String Splay
题目:http://poj.org/problem?id=2887 Big String Time Limit: 1000MS Memory Limit: 131072K Total ...
- qut训练题解-2016-9-4个人赛
题目链接:http://acm.hust.edu.cn/vjudge/contest/131124#overview 贴了链接这里就不上原题的描述了. A: B: 分析:这里用到简单的拓扑排序的算法. ...
- LOL游戏程序中对一些函数的Hook记录(Win10 x64)
[PC Hunter Standard][League of Legends.exe-->Ring3 Hook]: 108Hooked Object Hook Address and Locat ...
- codeforces 385C Bear and Prime Numbers 预处理DP
题目链接:http://codeforces.com/problemset/problem/385/C 题目大意:给定n个数与m个询问区间,问每个询问区间中的所有素数在这n个数中被能整除的次数之和 解 ...
- java web实现 忘记密码(找回密码)功能及代码
java web实现 忘记密码(找回密码)功能及代码 (一).总体思路 (二).部分截图 (三).部分代码 (一).总体思路: 1.在 找回密码页面 录入 姓名.邮箱和验证码,录入后点击[提交]按钮, ...
- c#委托和事件(上)
C# 中的委托和事件 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真 ...
- 【转】HTML5的语音输入 渐进使用HTML5语言识别, so easy!
转自: 本文地址:http://www.zhangxinxu.com/wordpress/?p=2408 一.本不想写此文 HTML5语音识别(现在一般用在搜索上),目前相关介绍还是挺多的.为何呢?因 ...