2018-01-15 CHAPTER3 - SKAction

昨天一天把SKAction常見的用法都實操過了一遍,基本都實現(xiàn)了sample code中要實現(xiàn)的需求产喉。先總結(jié)如下:

  1. 最基本的SKAction.move(to:)和 SKAction.move(by:)用法

學過英語的都從字面上能理解到move to和move by的區(qū)別矫限,
move to代表具體移動到哪個位置CGPoint彭雾,
而move by的話是指sprite移動的矢量offset(大概可以這樣理解)沪铭。
這個太簡單了,就不舉例了峦朗。

  1. Sequence action

其實sequence action就是將一個SKAction數(shù)組里面的action依次執(zhí)行。首先依次定義好單獨的SKAction排龄,然后通過以下方法將之前定義好單獨的SKAction append進來

let actionSequence:[SKAction] = []

actionSequence.append(action)

然后通過以下方法依次執(zhí)行各個action:

run.SKAction(SKAction.sequence(actionAction))
  1. Wait-for-duration action
    在執(zhí)行sequence的SKAction時波势,有時需要在兩個動作之間有一些間歇時間,我們可以通過以下方法實現(xiàn):
let action1 = SKAction()
        
let action2 = SKAction()
        
let actionWait = SKAction.wait(forDuration: 2.0)
   
zombie.run(SKAction.sequence([action1,actionWait,action2]))

然后action1和action2在執(zhí)行時橄维,中間就會停頓2秒

  1. Run-block action

如果想在sequence里面加一些打log的動作尺铣,可通過以下方法實現(xiàn):

let logMessage = SKAction.run() {
  print("Reached bottom!")
}
  1. Reversing actions
    所謂的reverse,就是把可逆的action進行反向操作争舞,比如move(by:)凛忿,如下圖所示


    image.png

    用法如下:

let reverseMid = actionMidMove.reversed()
  1. Repeat & RepeatForever actions
    前者是指定重復(fù)動作的次數(shù),用法如下:
let repeatAction = SKAction.repeat(SKAction, count: Int)

后者是永遠重復(fù)竞川,用法如下:

let repeatAction = SKAction.repeatForever(SKAction)
  1. 在教程中間店溢,插了一個取最小值與最大值之間隨機數(shù)的算法,如下:
extension CGFloat {
  static func random() -> CGFloat {
//arc4random()是返回UInt32以內(nèi)的一個隨機數(shù)流译,UInt32.max是UInt32內(nèi)的最大值逞怨,前者除以后者得到了一個0-1之間的隨機數(shù)。
    return CGFloat(Float(arc4random()) / Float(UInt32.max))
  }
  static func random(min: CGFloat, max: CGFloat) -> CGFloat {
//首先斷言最小值應(yīng)該小于最大值福澡,然后下面這個公式應(yīng)該就不用贅述了
    assert(min < max)
    return CGFloat.random() * (max - min) + min
  }
}
  1. 在該section中叠赦,sample創(chuàng)建了很多元素,比如僵尸啊,敵人啊除秀,貓貓狗狗之類的糯累,他們都是用了一個spawnXXX()的方法將sprite素材加載出來、初始化位置(可能是固定的册踩,也可能位置是隨機的)泳姐、然后匹配一些初始化的動作。如果場景初始化的時候需要他們出現(xiàn)暂吉,則直接將spawnXXX()的方法在didMove()中進行調(diào)用即可胖秒,比如如下所示的方法:
func spawnEnemy() {
  let enemy = SKSpriteNode(imageNamed: "enemy")
  enemy.position = CGPoint(
    x: size.width + enemy.size.width/2,
    y: CGFloat.random(
      min: playableRect.minY + enemy.size.height/2,
      max: playableRect.maxY - enemy.size.height/2))
  addChild(enemy)
  let actionMove =
    SKAction.moveTo(x: -enemy.size.width/2, duration: 2.0)
  enemy.run(actionMove)
}

9.在創(chuàng)建敵人的時候使用了弱引用weak reference,原文的解釋如下:

Note: You are using a weak reference to self here. Otherwise the closure passed to run(_ block:) will create a strong reference cycle and result in a memory leak.

暫時對內(nèi)存泄漏的了解不是太多慕的,先暫時知其然吧阎肝,后面再來看weak/strong reference的專題文章。

run(SKAction.repeatForever(
  SKAction.sequence([SKAction.run() { [weak self] in
                      self?.spawnEnemy()
                    },
                    SKAction.wait(forDuration: 2.0)])))

10.Remove-from-parent action
這個方法就是不用sprite的時候無情干掉肮街,免得占用內(nèi)存风题,浪費資源,用法如下:

 let actionRemove = SKAction.removeFromParent()
enemy.run(SKAction.sequence([actionMove, actionRemove]))

這個方法removeFromParent()顧名思義就是從他的父節(jié)點中移除他嫉父,不僅適用于SKAction也適用于node節(jié)點的移除

  1. Animation action
    這個就是序列幀素材的動畫action沛硅,用法如下:
// 1
var textures:[SKTexture] = []
// 2
for i in 1...4 {
  textures.append(SKTexture(imageNamed: "zombie\(i)"))
}
// 3
textures.append(textures[2])
textures.append(textures[1])
// 4
zombieAnimation = SKAction.animate(with: textures,
  timePerFrame: 0.1)
//創(chuàng)建好動畫后,就直接在sprite節(jié)點run這個動畫即可
zombie.run(SKAction.repeatForever(zombieAnimation))
  1. Stop animation
    用過一個key介質(zhì)來控制動畫的開始和停止
func startZombieAnimation() {
  if zombie.action(forKey: "animation") == nil {
    zombie.run(
      SKAction.repeatForever(zombieAnimation),
      withKey: "animation")
} }
func stopZombieAnimation() {
  zombie.removeAction(forKey: "animation")
}
  1. Scale actions
    初始化scale
    cat.setScale(0)
    然后就是scale(to:) scale(by:)

  2. Rotate actions
    rotate(byAngle: )
    rotate(toAngle: )
    注:swift中π的用法為Double.pi

  3. Group actions
    之前學到的actions都是串行的绕辖,如果我們想讓多個動作并行摇肌,應(yīng)該怎么做呢?比如sample項目中的小貓引镊,我們要他在rotate的同時朦蕴,也要scale,那么group action的用法就派上用場了弟头,方法如下:

//fullScale為scale的action吩抓, fullWiggle為rotate的action
let group = SKAction.group([fullScale, fullWiggle])

15.Collision detection
因為SK中有強大的物理引擎碰撞檢測,所以我就打算跳過這個不學赴恨,所以此處略(不過還是把sample code貼進來做note),看了一下下面的sample code疹娶,大概的意思就是通過frame.intersects看不同sprite之間的交集,如果交集上了伦连,就算是碰撞了

func zombieHit(cat: SKSpriteNode) {
  cat.removeFromParent()
}
func zombieHit(enemy: SKSpriteNode) {
  enemy.removeFromParent()
}
func checkCollisions() {
  var hitCats: [SKSpriteNode] = []
  enumerateChildNodes(withName: "cat") { node, _ in
    let cat = node as! SKSpriteNode
    if cat.frame.intersects(self.zombie.frame) {
      hitCats.append(cat)
    }
  }
  for cat in hitCats {
    zombieHit(cat: cat)
  }
  var hitEnemies: [SKSpriteNode] = []
  enumerateChildNodes(withName: "enemy") { node, _ in
    let enemy = node as! SKSpriteNode
    if node.frame.insetBy(dx: 20, dy: 20).intersects(
      self.zombie.frame) {
      hitEnemies.append(enemy)
    }
  }
  for enemy in hitEnemies {
    zombieHit(enemy: enemy)
  }

16.Sound actions
播放聲音雨饺,用法如下:

  run(SKAction.playSoundFileNamed("hitCat.wav",
  waitForCompletion: false))

好了,SKAction的筆記大概就記到這了惑淳,本Section后還有三個challenges额港,現(xiàn)在就去完成它們。

PS:中英文夾雜做筆記切換好累啊歧焦,從下一篇起移斩,嘗試使用英文來記了,順便也可以練習丟了很久的英文寫作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末向瓷,一起剝皮案震驚了整個濱河市肠套,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌猖任,老刑警劉巖你稚,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異朱躺,居然都是意外死亡刁赖,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門长搀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乾闰,“玉大人,你說我怎么就攤上這事盈滴。” “怎么了轿钠?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵巢钓,是天一觀的道長。 經(jīng)常有香客問我疗垛,道長症汹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任贷腕,我火速辦了婚禮背镇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泽裳。我一直安慰自己瞒斩,他們只是感情好,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布涮总。 她就那樣靜靜地躺著胸囱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瀑梗。 梳的紋絲不亂的頭發(fā)上烹笔,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天,我揣著相機與錄音抛丽,去河邊找鬼谤职。 笑死,一個胖子當著我的面吹牛亿鲜,可吹牛的內(nèi)容都是我干的允蜈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼陷寝!你這毒婦竟也來了锅很?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凤跑,失蹤者是張志新(化名)和其女友劉穎爆安,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仔引,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡扔仓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了咖耘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翘簇。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖儿倒,靈堂內(nèi)的尸體忽然破棺而出版保,到底是詐尸還是另有隱情,我是刑警寧澤夫否,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布彻犁,位于F島的核電站,受9級特大地震影響凰慈,放射性物質(zhì)發(fā)生泄漏汞幢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一微谓、第九天 我趴在偏房一處隱蔽的房頂上張望森篷。 院中可真熱鬧,春花似錦豺型、人聲如沸仲智。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坎藐。三九已至,卻和暖如春哼绑,著一層夾襖步出監(jiān)牢的瞬間岩馍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工抖韩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛀恩,地道東北人宛畦。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓拓萌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親兴枯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容