sprite kit學(xué)習(xí)總結(jié),以下簡稱sk
在sk中所有的動(dòng)畫,渲染都由skview對(duì)象執(zhí)行
在skview繪制需要的內(nèi)容,需要通過另一個(gè)繼承于sknode(不會(huì)繪制內(nèi)容)的對(duì)象skscene
skscene的所有內(nèi)容是通過它來組織的,用場景來描述各種內(nèi)容如:主菜單、結(jié)束畫面、游戲畫面等等,通過skview實(shí)現(xiàn) 場景的切換或者呈現(xiàn)
sk使用SkView加載scene
加載過渡動(dòng)畫場景
[self.viewpresentScene:scenetransition:transition ];
scene中重要的方法
-didmovetoview場景呈現(xiàn)完調(diào)用的方法
- didChangeSize:當(dāng)場景大小發(fā)生改變時(shí)調(diào)用該方法
- (void)didMoveToView:(SKView *)view參數(shù)view:持有該場景的視圖返回值論述這個(gè)方法通常會(huì)被子類重寫。執(zhí)行動(dòng)畫循環(huán)
- (void)update:(NSTimeInterval)currentTime參數(shù)currentTime:已經(jīng)過去的時(shí)間,保證單調(diào)遞增返回值不要直接調(diào)用這個(gè)方法,它每一幀會(huì)被調(diào)用一次
- (void)didSimulatePhysics它每一幀會(huì)被調(diào)用一次。場景子類應(yīng)該重寫這個(gè)方法,并執(zhí)行一些需要的更新這是對(duì)場景變化更改最晚的一個(gè)方法
在sk中所有的內(nèi)容都是以節(jié)點(diǎn)樹的形式呈現(xiàn),一切節(jié)點(diǎn)都繼承與sknode
常用的精靈:
skspritenode ??可以用于創(chuàng)建一個(gè)帶紋理的精靈
對(duì)于紋理的理解,現(xiàn)在不是很深,相當(dāng)于圖片,但是它不同一般的圖片,這樣的精靈能有更多的屬性比如精靈可以再次繪制變色或者其他陰影效果
[SKSpriteNodespriteNodeWithImageNamed:@"background"]
sklabelnode ??文本節(jié)點(diǎn)
skvideonode ?視頻節(jié)點(diǎn),用法和avfoundation里面的類似
skemitternode ??創(chuàng)建渲染粒子的節(jié)點(diǎn)(很酷炫)
NSString*path=[[NSBundlemainBundle]pathForResource:@"snow"ofType:@"sks"];
SKEmitterNode*emitternode=[NSKeyedUnarchiverunarchiveObjectWithFile:path] ;
emitternode.particleScaleRange=0.2;
emitternode.particleLifetimeRange=0.3;
emitternode.particleBirthRate=4;
emitternode.particleSpeed=0.4;
//scale美妙0.1速度減小
emitternode.particleScaleSpeed=-0.1;
//限定產(chǎn)生多少粒子,它會(huì)自動(dòng)停下來
emitternode.numParticlesToEmit=40;
//使用序列改變粒子的隨時(shí)間尺度屬性;
SKKeyframeSequence*scalesequence=[[SKKeyframeSequencealloc]initWithKeyframeValues:@[@0.2,@0.7,@0.1]times:@[@0.0,@0.5,@0.7]];
emitternode.particleScaleSequence=scalesequence;
各種節(jié)點(diǎn)在添加時(shí)有個(gè)默認(rèn)錨點(diǎn),也就是精靈的左下角(0,0) ?橫向0-1垂直方向0-1
錨點(diǎn)也就是對(duì)精靈的定位在哪里(比如旋轉(zhuǎn),放大縮小是以精靈那個(gè)部位作為基準(zhǔn)的)。。。計(jì)算各種碰撞檢測,添加內(nèi)容到場景需要注意
添加節(jié)點(diǎn)內(nèi)容到場景[node ?add children:anode];
制作可以拉伸的精靈
gameplaynode.centerRect=CGRectMake(12/28,12/28,2/28,2/28);
表示4個(gè)角分別占12 個(gè)像素,中間扣出寬度為2像素的矩形2*2像素大小
這個(gè)的效果很有用,比如制作一個(gè)對(duì)話框,內(nèi)容很多的時(shí)候,他的背景圖片只有那么大
強(qiáng)行放大會(huì)模糊不清,效果不好標(biāo)準(zhǔn)化的做法就是需要講圖片的某個(gè)部分進(jìn)行像素?cái)U(kuò)充
通常是中間的部分摳出來去擴(kuò)充他不夠的地方,這里只需要設(shè)置centerrect屬性就可以滿足了
這樣你的size發(fā)生變化 ,精靈四周不會(huì)變化
對(duì)于一個(gè)需要角色幀動(dòng)畫的實(shí)現(xiàn)使用紋理圖冊(cè)來加載會(huì)更有效
SKTextureAtlas*atlas=[SKTextureAtlasatlasNamed:@"monster.alas"];
SKTexture*t1=[atlastextureNamed:@"monster"];
SKTexture*t2=[atlastextureNamed:@"monster"];
SKTexture*t3=[atlastextureNamed:@"monster"];
NSArray*a=@[t1,t2,t3];
序列按時(shí)動(dòng)作的使用
SKSpriteNode*hul=[SKSpriteNodespriteNodeWithImageNamed:@"rocket"];
SKAction*hover=[SKActionsequence:@[
[SKActionwaitForDuration:0.5],
[SKActionmoveToX:25duration:0.5],
[SKActionwaitForDuration:0.5],
[SKActionmoveToX:CGRectGetMidX(self.frame)duration:0.5],
//顏色變化
[SKActioncolorizeWithColor:[UIColorredColor]colorBlendFactor:0.7duration:1],
[SKActionwaitForDuration:1.0],
[SKActionmoveToX:CGRectGetMaxX(self.frame)-hul.frame.size.width/2duration:0.5],
[SKActionwaitForDuration:0.5],
[SKActioncolorizeWithColor:[UIColorwhiteColor]colorBlendFactor:0.7duration:0.5],
[SKActionmoveToX:CGRectGetMaxX(self.frame)/2duration:0.5]
]
];
[hulrunAction:[SKActionrepeatActionForever:hover]];
//為防止多次點(diǎn)擊,運(yùn)行動(dòng)畫不完全,需要將動(dòng)畫移除
SKAction* actionMoveDone = [SKActionremoveFromParent];
一個(gè)可以同時(shí)進(jìn)行的序列動(dòng)作
SKAction*move=[SKActionmoveByX:600y:200duration:2];
SKAction*scale=[SKActionscaleBy:2duration:1];
SKAction*rotation=[SKActionrotateByAngle:M_1_PIduration:2];
SKAction*scaleog=[SKActionscaleBy:1duration:1];
[self.playerrunAction:[SKActiongroup:@[move,scale,rotation,scaleog]]];
節(jié)點(diǎn)樹的繪制順序
場景渲染的標(biāo)準(zhǔn)行為遵循以下一對(duì)簡單的規(guī)則:?父節(jié)點(diǎn)先繪制自身的內(nèi)容再渲染子節(jié)點(diǎn)。?子節(jié)點(diǎn)以它們?cè)谧庸?jié)點(diǎn)數(shù)組中的順序依次渲染。
每個(gè)節(jié)點(diǎn)擁有一個(gè)zpostion的標(biāo)記讓父節(jié)點(diǎn)知道先繪制渲染哪個(gè)節(jié)點(diǎn)使用的節(jié)點(diǎn)的深度來確定節(jié)點(diǎn)在屏幕上移動(dòng)的速度。通過增加不同深度的節(jié)點(diǎn),你可以模擬視差滾動(dòng),比如離我們遠(yuǎn)的東西他看著跑的慢一些,近一些的要快一些
節(jié)點(diǎn)樹的搜索
[sknode childnodewithname:@“name”];
[sknode enumeratechildnodewithname:@“name” usingblock^{
//將搜索出的節(jié)點(diǎn)進(jìn)行操作
}];
物理表現(xiàn)形式
hul.physicsBody=[SKPhysicsBodybodyWithRectangleOfSize:hul.size];
hul.physicsBody.dynamic=YES;
hul.physicsBody.velocity=CGVectorMake(1,1);//左上角為坐標(biāo)原點(diǎn),向右x增加,向下Y越大
mass屬性決定力是如何影響主體,以及當(dāng)主體參與碰撞時(shí)它有多大的動(dòng)量。
page87image17728.png ?
?friction屬性決定了主體表面的粗糙度。它被用來計(jì)算一個(gè)主體沿其他主體表面移動(dòng)時(shí)產(chǎn)生的摩擦力。
?linearDamping和angularDamping屬性是用來計(jì)算主體在世界中移動(dòng)時(shí)的摩擦。例如,它可能用于模擬空氣或水的摩擦。
?restitution屬性決定主體在碰撞過程中保持能多少能量,即它的彈力。其他的屬性被用來決定模擬在主體本身上如何進(jìn)行:
?dynamic屬性決定該主體是否由物理子系統(tǒng)來模擬。
?affectedByGravity屬性決定模擬是否對(duì)主體產(chǎn)生重力。關(guān)于物理世界的更多信息,請(qǐng)參閱“配置物理世界”。
?allowsRotation屬性決定力是否能對(duì)主體傳遞角速度(angular velocity)
?gravity屬性對(duì)模擬中基于體積的主體施加加速度。靜態(tài)體和affectedByGravity屬性設(shè)置為NO的物理體則不受影響。
?speed屬性決定了模擬的運(yùn)行速率。
碰撞效果及檢測
遵守協(xié)議SKPhysicsContactDelegate
staticconstuint32_tzidancategory=0x1;
staticconstuint32_tmostercategory=0x2;
staticconstuint32_tplayercategory=0x3;
_player.physicsBody=[SKPhysicsBodybodyWithRectangleOfSize:_player.size];
_player.physicsBody.dynamic=NO;
_player.physicsBody.contactTestBitMask=zidancategory;
_player.physicsBody.categoryBitMask=playercategory;
_player.physicsBody.collisionBitMask=0;
moster.physicsBody=[SKPhysicsBodybodyWithRectangleOfSize:moster.size];
moster.physicsBody.dynamic=YES;
moster.physicsBody.contactTestBitMask=zidancategory;
moster.physicsBody.categoryBitMask=mostercategory;
moster.physicsBody.collisionBitMask=4;
moster.physicsBody.usesPreciseCollisionDetection=YES;
zidan.physicsBody=[SKPhysicsBodybodyWithRectangleOfSize:zidan.size];
zidan.physicsBody.dynamic=NO;
zidan.physicsBody.contactTestBitMask=mostercategory;
zidan.physicsBody.categoryBitMask=zidancategory;
zidan.physicsBody.collisionBitMask=0;
zidan.physicsBody.usesPreciseCollisionDetection=YES;
- (void)didBeginContact:(SKPhysicsContact*)contact
{
SKPhysicsBody*a;
SKPhysicsBody*b;
if(contact.bodyA.categoryBitMask==playercategory||contact.bodyB.categoryBitMask==playercategory) {
a=contact.bodyA;
b=contact.bodyB;
[selfremovecontactnode:a.nodeandmonster:b.node];
//游戲結(jié)束負(fù)責(zé)寫這里的邏輯
}
elseif(contact.bodyA.categoryBitMask==zidancategory||contact.bodyB.categoryBitMask==zidancategory)
{
a=contact.bodyA;
b=contact.bodyB;
[selfremovecontactnode:a.nodeandmonster:b.node];
SKLabelNode*lavb=(SKLabelNode*)[selfchildNodeWithName:@"score"];
record+=4;
score=[NSStringstringWithFormat:@"score:%d分",record];
lavb.text=score;
}
}
物理聯(lián)合效果
spring
[selfaddChild:rec1];
[selfaddChild:rec2];
SKPhysicsJointSpring*joint=[SKPhysicsJointSpringjointWithBodyA:rec1.physicsBodybodyB:rec2.physicsBodyanchorA:CGPointMake(0.5,0.5)anchorB:CGPointMake(0.5,0.5)];
[self.physicsWorldaddJoint:joint];
rope ???pin ????fixed ??sliding使用方法類似