iOS 7新引入的Sprite Kit類庫算是給iOS游戲開發(fā)者帶來一些福音吧,由于是用底層的東西做開發(fā)秆撮,在效率方面應(yīng)該會有很大的提高四濒。也不單單是在游戲方面,任何需要?jiǎng)赢嬓Ч腶pp也可以利用Sprite Kit來實(shí)現(xiàn)。
每天抽點(diǎn)時(shí)間出來學(xué)習(xí)一下盗蟆,做一下筆記戈二,今天是第一次學(xué)習(xí)筆記,先跟大家總體的介紹一下整個(gè)Sprite Kit框架喳资,接下來會利用官方的例子帶大家進(jìn)入Sprite Kit觉吭。學(xué)過cocos2d的朋友可能會學(xué)得比較快,其實(shí)很多東西都是相通的骨饿,有關(guān)cocos2d的東西就不多說亏栈。
如上圖所示,這是每一幀會做的事情宏赘,更新每一幀的內(nèi)容绒北,然后是場景中的行為,再就是物理系統(tǒng)察署,最后通過SKView進(jìn)行渲染闷游。可以通過一個(gè)UIviewController贴汪,將其view object的class屬性由UIView改為SKView脐往,然后在上面做你想要渲染的東西,可以通過storyboard對其view進(jìn)行修改扳埂,有了SKView之后就需要SKScene了业簿,再場景中添加你要的游戲?qū)ο螅@不難理解吧阳懂。Sprite Kit好像沒有Layer的概念梅尤,可以直接在Scene上面直接畫東西,SKSpriteNode便是你要在Scene上面呈現(xiàn)的精靈岩调,另外添加文本為SKLabelNode巷燥,同樣繼承SKNode,建議大家去了解一下整一個(gè)的Node Tree号枕。
大概的框架邏輯就是缰揪,在Sprite View上添加Sprite Scene,Sprite渲染在Scene上葱淳,Node Tree展示了所有可以出現(xiàn)在Scene上的東西钝腺,node可以執(zhí)行action,Scene上有物理系統(tǒng)
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
SKScene * scene = [SKMainScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
好了蛙紫,有了一個(gè)大概了解之后拍屑,開始用例子了來學(xué)習(xí)Sprite Kit
直接創(chuàng)建一個(gè)工程
配置工程
首先當(dāng)然是建立工程,Xcode8提供了SpriteKit模板坑傅,使用該模板建立新工程,名字就叫做SpriteKitSimpleGame好了。
運(yùn)行后你會看到一靜態(tài)的Hello World
圖片,如下,可以與用戶交互
-
先不用理會里面的源代碼,我們先新創(chuàng)建一個(gè)MyScene繼承自SKScene,里面什么都不用做
將GameViewController.m中的-viewDidLoad:
方法全部替換成下面的-viewDidLoad:
蒜茴。
- (void) viewDidLoad:(BOOL)animated
{
[super viewDidLoad:animated];
// 配置view 你會發(fā)現(xiàn)當(dāng)前的view就是``SKView ``可以在main.storyboard中查看
SKView * skView = (SKView *)self.view;
// 顯示FPS 右下角
skView.showsFPS = YES;
// 顯示節(jié)點(diǎn)數(shù)量 右下角
skView.showsNodeCount = YES;
//創(chuàng)建和配置場景
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// 呈現(xiàn)場景
[skView presentScene:scene];
}
運(yùn)行后你會發(fā)現(xiàn)里面是漆黑一片,就只剩下右下角的nodes 和 fps 了
接著我們要在MyScene做點(diǎn)事情,重寫- (instancetype)initWithSize:(CGSize)size
方法
- (instancetype)initWithSize:(CGSize)size {
self = [super initWithSize:size];
if (self) {
self.backgroundColor = [SKColor whiteColor];
}
return self;
}
運(yùn)行程序你會發(fā)現(xiàn)界面變白了,這樣顯得太單調(diào)了,我們再做點(diǎn)事情,這里我們模仿官方示例程序讓界面顯示Hello World
我們在MyScene 的- (void)didMoveToView:(SKView *)view
方法里這么寫
- (void)didMoveToView:(SKView *)view {
[super didMoveToView:view];
SKLabelNode *labelNode = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
labelNode.text = @"Hello World";
labelNode.fontSize = 40;
labelNode.fontColor = [SKColor redColor]; // 默認(rèn)白色
labelNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
labelNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:labelNode.frame.size];
[self addChild:labelNode];
運(yùn)行后你會發(fā)現(xiàn)如下所示
接下來我們再為文本添加一些動作實(shí)現(xiàn)一下動畫效果星爪,還是在.m文件里,添加如下代碼:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self helloAction];
}
- (void)helloAction {
SKNode *helloNode = [self childNodeWithName:@"helloNode"];
if (helloNode != nil) {
helloNode.name = nil;
SKAction *moveUp = [SKAction moveByX:0 y:100 duration:0.5];
SKAction *zoom = [SKAction scaleTo:2 duration:0.25];
SKAction *pause = [SKAction waitForDuration:0.5];
SKAction *fadeAway = [SKAction fadeOutWithDuration:0.25];
SKAction *remove = [SKAction removeFromParent];
SKAction *moveSequence = [SKAction sequence:@[moveUp, zoom, pause, fadeAway, remove]];
[helloNode runAction:moveSequence];
}
}
這里重寫了-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
函數(shù)粉私,即點(diǎn)擊屏幕便開始播放動畫顽腾。定義一個(gè)動作,上面的代碼寫得很清楚诺核,Sprite Kit自帶的很多種抄肖,我解釋一下上的各個(gè)動作吧,哦窖杀,這里說一下漓摩,可以通過name屬性拿到具有相同name的node,它允許多個(gè)node具有同樣的名字入客。第一個(gè)動作是上升100個(gè)單位管毙,時(shí)間間隔為0.5,第二個(gè)動作是放大2倍桌硫,然后停0.5秒夭咬,接著fadeOut,最后一個(gè)是將labelNode從Scene里面移除铆隘,將這幾個(gè)動作用一個(gè)隊(duì)列連接起來卓舵,它便會一個(gè)接一個(gè)地播放下去,然后runAction就ok了膀钠。
運(yùn)行边器,點(diǎn)擊屏幕,動畫開始執(zhí)行托修,如無意外,整個(gè)HelloWorld會照著我們的動作而行動著恒界,這時(shí)可以觀察一下最下面一行nodes和draws的數(shù)量變化睦刃,動畫執(zhí)行完后我們發(fā)現(xiàn),它停住十酣,只剩下白色的Scene
接下來我們再做一些有意思的事情,往scene中再添加兩個(gè)node
- (void)didMoveToView:(SKView *)view {
[super didMoveToView:view];
SKLabelNode *labelNode = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
labelNode.name = @"helloNode";
labelNode.text = @"Hello World";
labelNode.fontSize = 40;
labelNode.fontColor = [SKColor redColor]; // 默認(rèn)白色
labelNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
labelNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:labelNode.frame.size];
[self addChild:labelNode];
NSLog(@"------%@",NSStringFromCGRect([labelNode calculateAccumulatedFrame]));
//設(shè)置邊界 如果不設(shè)置邊界,我們的精靈就跑到地球的另一邊了
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectMake(self.frame.origin.x, self.frame.origin.y, self.size.width, self.size.height)];
[self planeNode];
}
-(void)planeNode{
// 垃圾代碼,為了省事就先不管了
SKSpriteNode *qqNode = [SKSpriteNode spriteNodeWithImageNamed:@"qq"];
qqNode.position = CGPointMake(self.size.width/2, self.size.height/2);
qqNode.anchorPoint = CGPointMake(0.5, 0.5);
qqNode.zPosition = 1;
qqNode.name = @"qq";
[self addChild:qqNode];
SKSpriteNode *qqNode1 = [SKSpriteNode spriteNodeWithImageNamed:@"qq"];
qqNode1.position = CGPointMake(self.size.width/2+100, self.size.height/2);
qqNode1.anchorPoint = CGPointMake(0.5, 0.5);
qqNode1.zPosition = 1;
qqNode1.name = @"qq1";
[self addChild:qqNode1];
}
運(yùn)行后你會看到如下界面
-
SKNode類中有一個(gè)屬性叫physicsBody,這個(gè)physicsBody屬性就是用來指定對象的物理體的.下面我們就用代碼來給我們的精靈添加矩形物理模型.添加的過程是在touchBegan中實(shí)現(xiàn)的.全部代碼如下.
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self qqAction];
}
- (void)qqAction {
// 根據(jù)node的name取出node
SKSpriteNode *qqNode = (SKSpriteNode *)[self childNodeWithName:@"qq"];
// 設(shè)置node 的 物理邊界
qqNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:qqNode.size];
// 設(shè)置反彈力
qqNode.physicsBody.restitution = 0.1;
// 在物體的(0,0)點(diǎn)上施加一個(gè)拉力
[qqNode.physicsBody applyForce:CGVectorMake(1000, 200) atPoint:CGPointMake(0, 0)];
SKSpriteNode *qqNode1 = (SKSpriteNode *)[self childNodeWithName:@"qq1"];
qqNode1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:qqNode1.size];
qqNode1.physicsBody.restitution = 0;
[qqNode1.physicsBody applyForce:CGVectorMake(1000, 100) atPoint:CGPointMake(0, 0)];
}
然后運(yùn)行程序,哇,變得有意思點(diǎn)了不是嗎