2016-11-03 8 views
0

私はブロックが簡単に一緒にスナップすることができる種類のパズルインターフェイスを作成しようとしています。より多くのブロックが内部に収まる必要がある場合は、ブロックが拡張可能でなければならないという点で、インタフェースはMIT scratchのようなものになります。私はこれを行う良い方法が何か、あるいは類似のものがすでに存在するかどうか疑問に思っていましたか?MITスクラッチのようなパズルピース

これまでの実装方法は、ユーザーがドラッグできるUIViewだけをブロックにすることです。彼らがお互いに近づくと、私はそれらを一緒にスナップさせます。拡大部分は少し厄介ですが、それらのブロックを3つのビューで構成することができます。より多くのスペースが必要なときは、中間セクションとギャップを広げてブロックをフィットさせることができます。とにかくこれは実装するのが非常に面倒だと思われ、正直なところ、効率的ではないようです。既存のオブジェクト/オープンソースライブラリはありませんか?これを簡単にするために私はピギーバックできますか?

+0

を試すことができ、ユーザーのUI要素とのやりとりがCPUに課税されないためです。 – NRitH

答えて

0

魔法のようにこのライブラリを使用することはできませんが、ブロックやピースが収まるように開いている接続のリストがあります。マウスボタンを放すと、最も近い位置に行くことを選んだ(ピタゴラスの定理を使って距離を見つける)。ブロックが実際に所定の位置に収まらない限界距離があるかもしれません。はい、拡大はやや難しいでしょうが、最終的には何かが関数に置かれたときに再描画されるCGPathを使うことができます。

ここは少しの例です。

extension CGPoint { 
    func distanceTo(_ other:CGPoint) -> CGFloat { 
     return CGFloat(sqrt((pow(other.x - self.x, 2) + pow(other.y - self.y, 2)))) 
    } 
} 

私はほとんどのプログラムに貼り付けた距離関数です。

var pieces:[NSView]!//The Pieces on the board/screen 
var SelectedPiece:NSView!//the piece you are holding, could also be an index. 
override func mouseUp(with event: NSEvent) { 
    var spaces:[CGPoint] = [] 
    for piece in pieces { 
     spaces.append(CGPoint(x: piece.frame.origin.x, y: piece.frame.origin.y + 20))//change 20 to whatever 
     spaces.append(CGPoint(x: piece.frame.origin.x, y: piece.frame.origin.y - 20)) 
     //if you are actually making a puzzle you might want pieces on the sides. 
    } 
    var ClosestDist:CGFloat? 
    var ClosestIndex:Int? 
    for space in spaces { 
     let dist = space.distanceTo(SelectedPiece.frame.origin) 
     if closestDist != nil { 
      if dist < closestDist { 
       ClosestDist = dist 
       ClosestIndex = spaces.index(of:space) 
      } 
     }else { 
      ClosestDist = dist 
      ClosestIndex = spaces.index(of:space) 
     } 
    } 
    if ClosestDist! < 15 { 
     SelectedPiece.frame.origin = spaces[ClosestIndex] 
    } 
} 

これは明らかに不完全ですが、これが役立つことを願っています。

関連する問題