Spritekit学习

sprite kit学习总结,以下简称sk

sk中所有的动画,渲染都由skview对象执行

在skview绘制需要的内容,需要通过另一个继承于sknode(不会绘制内容)的对象skscene

skscene的所有内容是通过它来组织的,用场景来描述各种内容如:主菜单、结束画面、游戏画面等等,通过skview实现 场景的切换或者呈现

sk使用SkView加载scene


加载过渡动画场景

[self.viewpresentScene:scenetransition:transition ];

scene中重要的方法

-didmovetoview场景呈现完调用的方法

- didChangeSize:当场景大小发生改变时调用该方法

- (void)didMoveToView:(SKView *)view参数view:持有该场景的视图返回值论述这个方法通常会被子类重写。执行动画循环

- (void)update:(NSTimeInterval)currentTime参数currentTime:已经过去的时间,保证单调递增返回值不要直接调用这个方法,它每一帧会被调用一次

- (void)didSimulatePhysics它每一帧会被调用一次。场景子类应该重写这个方法,并执行一些需要的更新这是对场景变化更改最晚的一个方法

sk所有的内容都是以节点树的形式呈现,一切节点都继承与sknode

常用的精灵:

skspritenode   可以用于创建一个带纹理的精灵

对于纹理的理解,现在不是很深,相当于图片,但是它不同一般的图片,这样的精灵能有更多的属性比如精灵可以再次绘制变色或者其他阴影效果

[SKSpriteNodespriteNodeWithImageNamed:@"background"]

sklabelnode   文本节点

skvideonode  视频节点,用法和avfoundation里面的类似

skemitternode   创建渲染粒子的节点(很酷炫)

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;

//限定产生多少粒子,它会自动停下来

emitternode.numParticlesToEmit=40;

//使用序列改变粒子的随时间尺度属性;

SKKeyframeSequence*scalesequence=[[SKKeyframeSequencealloc]initWithKeyframeValues:@[@0.2,@0.7,@0.1]times:@[@0.0,@0.5,@0.7]];

emitternode.particleScaleSequence=scalesequence;

各种节点在添加时有个默认锚点,也就是精灵的左下角(0,0)  横向0-1垂直方向0-1

锚点也就是对精灵的定位在哪里(比如旋转,放大缩小是以精灵那个部位作为基准的)。。。计算各种碰撞检测,添加内容到场景需要注意

添加节点内容到场景[node  add children:anode];

制作可以拉伸的精灵

gameplaynode.centerRect=CGRectMake(12/28,12/28,2/28,2/28);

表示4个角分别占12 个像素,中间扣出宽度为2像素的矩形2*2像素大小

这个的效果很有用,比如制作一个对话框,内容很多的时候,他的背景图片只有那么大

强行放大会模糊不清,效果不好标准化的做法就是需要讲图片的某个部分进行像素扩充

通常是中间的部分抠出来去扩充他不够的地方,这里只需要设置centerrect属性就可以满足了

这样你的size发生变化 ,精灵四周不会变化

对于一个需要角色帧动画的实现使用纹理图册来加载会更有效

SKTextureAtlas*atlas=[SKTextureAtlasatlasNamed:@"monster.alas"];

SKTexture*t1=[atlastextureNamed:@"monster"];

SKTexture*t2=[atlastextureNamed:@"monster"];

SKTexture*t3=[atlastextureNamed:@"monster"];

NSArray*a=@[t1,t2,t3];

序列按时动作的使用

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

//为防止多次点击,运行动画不完全,需要将动画移除

SKAction* actionMoveDone = [SKActionremoveFromParent];

一个可以同时进行的序列动作

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

节点树的绘制顺序

场景渲染的标准行为遵循以下一对简单的规则:?父节点先绘制自身的内容再渲染子节点。?子节点以它们在子节点数组中的顺序依次渲染。

每个节点拥有一个zpostion的标记让父节点知道先绘制渲染哪个节点使用的节点的深度来确定节点在屏幕上移动的速度。通过增加不同深度的节点,你可以模拟视差滚动,比如离我们远的东西他看着跑的慢一些,近一些的要快一些

节点树的搜索

[sknode childnodewithname:@“name”];

[sknode enumeratechildnodewithname:@“name” usingblock^{

//将搜索出的节点进行操作

}];

物理表现形式

hul.physicsBody=[SKPhysicsBodybodyWithRectangleOfSize:hul.size];

hul.physicsBody.dynamic=YES;

hul.physicsBody.velocity=CGVectorMake(1,1);//左上角为坐标原点,向右x增加,向下Y越大

mass属性决定力是如何影响主体,以及当主体参与碰撞时它有多大的动量。

page87image17728.png ¬

•friction属性决定了主体表面的粗糙度。它被用来计算一个主体沿其他主体表面移动时产生的摩擦力。

•linearDamping和angularDamping属性是用来计算主体在世界中移动时的摩擦。例如,它可能用于模拟空气或水的摩擦。

•restitution属性决定主体在碰撞过程中保持能多少能量,即它的弹力。其他的属性被用来决定模拟在主体本身上如何进行:

•dynamic属性决定该主体是否由物理子系统来模拟。

•affectedByGravity属性决定模拟是否对主体产生重力。关于物理世界的更多信息,请参阅“配置物理世界”。

•allowsRotation属性决定力是否能对主体传递角速度(angular velocity)

•gravity属性对模拟中基于体积的主体施加加速度。静态体和affectedByGravity属性设置为NO的物理体则不受影响。

•speed属性决定了模拟的运行速率。

碰撞效果及检测

遵守协议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];

//游戏结束负责写这里的逻辑

}

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;

}

}

物理联合效果

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使用方法类似

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 197,737评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,103评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 144,710评论 0 326
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,909评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,794评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,557评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,939评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,572评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,852评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,871评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,692评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,490评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,939评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,114评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,409评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,971评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,176评论 2 339

推荐阅读更多精彩内容

  • 作为北方人,松树是我们最爱的树种,寒风凛冽的漫长冬季,如果没有松树的绿意,北方的冬天不知该有多荒凉。松树的生长需要...
    元初阅读 3,722评论 0 0
  • XMPPFramework框架的导入有两种方式1.通过cocopods进行配置,比较方便,但某些时候可能会配置不成...
    音符上的码字员阅读 734评论 1 3
  • 读的什么书:《所有人走的路》 阅读有效时间:一个小时 阅读中遇到了什么困难:静不下来 阅读有什么收获:新的观...
    嘟梦冉阅读 112评论 0 0