見出し画像

Swiftで行こう!--パズルゲーム(16パズル)2

Swiftで行こう!--パズルゲーム(16パズル)では画像を分割して表示させました。

次はその画像をいろんな位置へ移動させて、ゲームとして成り立つようにしたいですね。

まずスタートボタンを押して画像をシャッフルして、_piece[15]の画像を透明にして見えなくして空マスとします。

 @objc func onClick(sender: UIButton) {
      
       if sender.tag == BTN_START {
           //シャッフルの実行(8)
           _shuffle = 20
           while _shuffle > 0 {
               if movePiece(tx: rand(num:4), ty: rand(num:4)) {_shuffle -= 1}
           }
           for i in 0..<16 {
               let dx: CGFloat = 30+75*CGFloat(i%4)
               let dy: CGFloat = 180+75*CGFloat(i/4)
               _piece[_data[i]].frame =
                   CGRect(x: dx, y: dy, width: 75, height: 75)
           }

        _piece[15].alpha = 0

       }
   }

ピースを移動させます。全体像としては、

func movePiece(tx: Int, ty: Int) -> Bool {
       //空きマスの行番号と列番号を求める(4)
       var fx = 0
       var fy = 0
       for i in 0..<16 {
           if _data[i] == 15 {
               fx = i%4
               fy = Int(i/4)
               break
           }
       }
       if (fx == tx && fy == ty) || (fx != tx && fy != ty) {
           return false
       }
       
       //ピースを上にスライド(5)
       if fx == tx && fy < ty {
           for i in fy..<ty {
               _data[fx+i*4] = _data[fx+i*4+4]
           }
           _data[tx+ty*4] = 15
       }
           //ピースを下にスライド(5)
       else if fx == tx && fy > ty {
           for i in stride(from:fy,to: ty, by: -1) {
               _data[fx+i*4] = _data[fx+i*4-4]
           }
           _data[tx+ty*4] = 15
       }
           //ピースを左にスライド(5)
       else if fy == ty && fx < tx {
           for i in fx..<tx {
               _data[i+fy*4] = _data[i+fy*4+1]
           }
           _data[tx+ty*4] = 15
       }
           //ピースを右にスライド(5)
       else if fy == ty && fx > tx {
           for i in stride(from:fx,to: tx, by: -1) {
               _data[i+fy*4]=_data[i+fy*4-1]
           }
           _data[tx+ty*4] = 15
       }
        var clearCheck = 0
        for i in 0..<16 {
            let dx: CGFloat = 30+75*CGFloat(i%4)
            let dy: CGFloat = 180+75*CGFloat(i/4)
            
            //ピースの移動アニメ
            if _data[i] != 15 {
                UIView.beginAnimations("anime0", context: nil)
                UIView.setAnimationDuration(0.3)
                _piece[_data[i]].frame = CGRect(x: dx, y: dy, width: 75, height: 75)
                UIView.commitAnimations()
            } else {
                _piece[_data[i]].frame = CGRect(x: dx, y: dy, width: 75, height: 75)
            }
            
            //クリアチェック
            if _data[i] == i {clearCheck += 1}
        }

       
       return true
   }

まず

 var fx = 0
       var fy = 0
       for i in 0..<16 {
           if _data[i] == 15 {
               fx = i%4
               fy = Int(i/4)
               break
           }
       }

では空いているマスの行番号、列番号を決めます。ここでは15番目の画像、0から始まるので、画像としては16番目の画像をがどこに位置するかを取得しています。

タッチした場所と、空マスとが同じ場合は

 if (fx == tx && fy == ty) || (fx != tx && fy != ty) {
           return false
       }

で"false"ということで何も起きません。

このコード以下はピースを動かすもので、空マスの方向へスライドします。

あとはクリアのチェックをして全て揃って入れば終了となります。

この動作を画面にタッチすることで次に出てくるタッチした行番号、列番号"tx","ty"を求め実行(movePiece(tx: tx, ty: ty))していきます。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
       if _startButton.alpha != 0 {
           return
       }
       //タッチ位置からピースの列番号と行番号を求める(3)
       let pos = touches.first!.location(in: _gameView)
               if 30 < pos.x && pos.x < 330 && 180 < pos.y && pos.y < 480 {
                   let tx = Int((pos.x-30)/75)
                   let ty = Int((pos.y-180)/75)
                   movePiece(tx: tx, ty: ty)
               }
   }

この記事が気に入ったらサポートをしてみませんか?