本文適合SpriteKit初心者 源碼:https://github.com/jamesdouble/JDGamePaddlenode
16年,MOBA手遊市場打得可火熱(這裏咱不幫任何遊戲背書),擼瑟如我也是在16年開始玩SpriteKit,也就是蘋果自制的2D遊戲框架。 有玩過MOBA手遊的,必定十分熟悉遊戲裏咱們是如何移動主人公的吧?沒玩過的......我們不囉唆,先上圖。 git
這樣想不起來的也想起來了唄,由於SpriteKit自己並無提供像搖桿這樣元件(有提供反而奇怪),爲了以防朋友們採坑(也沒有不少坑),我就寫了一個簡易的搖桿Lib,SKScene,SKView(SpriteKit的UIView), UIView皆可直接加上。github
一開始若把問題想得太複雜,那歪路確定會走的特別的多,咱們就照着上面的圖來刻吧,外面一個圓圈,嗯,裏面一個小圓.....好,結束了 ,就從拉出兩個圓來出發吧!!swift
For SpriteKit初心者: UIKit裏每一個元件幾乎都是UIView的子類別,而SpriteKit裏的每一個元件幾乎都是SKNode的子類別。app
那SKShapeNode又是什麼?它是SKNode的子類別,如果你不是要用圖片來初始化一個物件而是純幾何形狀或是線條的話,使用它來作Node會快上許多,看它的建構值就能知道,真的很「幾何」。框架
來吧!第一步!兩個圓形!ide
MovingPing = SKShapeNode(circleOfRadius: paddleSize.width * 0.18)
MovingPing?.fillColor = UIColor.black //內圓黑色實心
PaddleBorder = SKShapeNode(circleOfRadius: paddleSize.width * 0.5 )
PaddleBorder?.fillColor = UIColor.clear //外圓中間空心
PaddleBorder?.strokeColor = UIColor.black
複製代碼
Hmm.... We almost here, right? 不過如今你無論怎麼撥弄它,它都不會移動的,在SpriteKit裏常作的處理點擊方式是實做覆寫UIResponder你們常見的Method。post
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first!
touching = true
let position = touch.location(in: self)
if((PaddleBorder!.contains(position))) //如果手指還在邊界內
{
MovingPing?.position = touch.location(in: self) //內圓移到手指位置
}
didMove()
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first!
let postion = touch.location(in: self)
if((PaddleBorder!.contains(postion)))
{
MovingPing?.position = postion
}
/* 略 */
}
複製代碼
結束了嗎?執行起來試試吧。看起來聽生硬的對吧,如果有MOBA手遊只作到這邊,主人公必定是腳抽了筋。會發生這樣的杯具是在touchesMoved只判斷是否手指在外圈內,而忽略瞭如果使用者從內圈滑到外圈的狀況。ui
讓咱們把上面那段註解換成else{
movingpaddleSmoothly(position: postion)
}
//算出邊界外手指跟中心連成一線後,跟邊界的交點。
func movingpaddleSmoothly(position:CGPoint)
{
let centerPoint = PaddleBorder!.position
let radius = self.frame.width * 0.5
var distance:CGFloat = 0
let diffx:CGFloat = (centerPoint.x - position.x) * (centerPoint.x - position.x)
let diffy:CGFloat = (centerPoint.y - position.y) * (centerPoint.y - position.y)
distance = sqrt(diffx + diffy)
let ratio:CGFloat = radius/distance
let newPostition:CGPoint = CGPoint(x: position.x * ratio, y: position.y * ratio)
MovingPing?.position = newPostition
}
複製代碼
最後咱們再每次移動搖桿時,回傳一個通過正規化的CGVector出去給委任,以便使用者能隨着滑動搖桿,作出適當的迴應。spa