teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

追記

2020/04/13 10:59

投稿

TsukubaDepot
TsukubaDepot

スコア5086

answer CHANGED
@@ -8,4 +8,91 @@
8
8
 
9
9
  ただ、この時はドラッグ直前まで累積させていた加速度成分`vx`, `vy`が残っていますので、これをリセットするなどの処理が必要でしょうし、ドラッグを解除した瞬間の加速度をどのようにして計算するのかなど考える必要がありそうです。
10
10
 
11
- この辺りは、個々のメソッドの使い方というよりも、むしろ得られている重力加速度などの値をいかに加工するのかといったテクニックの見せ所のようにも思えます(物理法則に従わせることよりも、見せ方かも)。
11
+ この辺りは、個々のメソッドの使い方というよりも、むしろ得られている重力加速度などの値をいかに加工するのかといったテクニックの見せ所のようにも思えます(物理法則に従わせることよりも、見せ方かも)。
12
+
13
+ #追記
14
+
15
+ たとえば、こんな感じでコードを変更すれば、それなりにそれっぽい処理ができます。
16
+ 必要なところだけ抜粋しているので、処理の流れをよく考えてオリジナルに追加してみてください。
17
+
18
+ ```swift
19
+ import UIKit
20
+ import CoreMotion
21
+
22
+ class ViewController: UIViewController {
23
+ // 略
24
+
25
+ // ここから追加
26
+ // リングバッファ
27
+ // 過去10回分のドラッグ履歴を残す
28
+ var index = 0
29
+ var maxIndex = 10
30
+ var dX: [CGFloat] = []
31
+ var dY: [CGFloat] = []
32
+ // ここまで
33
+
34
+ // 値を書き換えるので、let -> var に変更
35
+ var mag: Double = 20.0
36
+
37
+ override func viewDidLoad() {
38
+ super.viewDidLoad()
39
+
40
+ // ここから追加
41
+ // 配列の初期化
42
+ // dX = [0.0, 0.0, ..(全部で10回繰り返し), 0.0] と同じ
43
+ dX = Array(repeating: CGFloat(0.0), count: maxIndex)
44
+ dY = Array(repeating: CGFloat(0.0), count: maxIndex
45
+ // ここまで。
46
+
47
+ // 以下略
48
+ }
49
+
50
+ // 略
51
+ override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
52
+ // dx, dy を表示 -> デバッグのため。本質的な処理ではない
53
+ for i in 0..<dX.count {
54
+ print("dx[(i)]: (dX[i]), dy[(i)]: (dY[i])")
55
+ }
56
+
57
+ // ここからが本質的な処理
58
+ // 新しい加速度(vx, vy)を計算
59
+ // ドラッグした値の変化からドラッグ後の加速度を計算する
60
+ // 過去10回分の変位(dX, dY)から加速度を求める -> 実際は過去10回分の平均を求めているだけ
61
+ let amp = 5.0 // 倍率。適切に決める
62
+ // 簡潔に書くため reduce を使っているが、計算は for 文を使って配列全ての要素を足して、最後に要素数で割る処理と同じ
63
+ vx = Double(dX.reduce(0.0) { $0 + $1 } / CGFloat(dX.count)) * amp
64
+ vy = Double(dY.reduce(0.0) { $0 + $1 } / CGFloat(dY.count)) * amp
65
+
66
+ print("vx: ", vx!, "vy: ", vy!)
67
+ // ここまで
68
+ startGame()
69
+ }
70
+
71
+ override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
72
+ print("touchesMoved", touches.count)
73
+ // タッチイベントを取得.
74
+ // 途中略
75
+
76
+ // ドラッグで移動したx, y距離をとる.
77
+ let deltaX: CGFloat = location.x - prevLocation.x
78
+ let deltaY: CGFloat = location.y - prevLocation.y
79
+
80
+ // ここから追加
81
+ // deltaX, deltaY をリングバッファに保存
82
+ dX[index] = deltaX
83
+ dY[index] = deltaY
84
+ // リングバッファの現在のインデックス(配列の要素)を一つ進める
85
+ index += 1
86
+ // インデックスが maxIndex を超えた場合には 0 に戻す(剰余の計算)
87
+ index %= maxIndex
88
+ // ここまで追加
89
+
90
+ // 移動した分の距離をmyFrameの座標にプラスする.
91
+ myFrame.origin.x += deltaX
92
+ myFrame.origin.y += deltaY
93
+ // 以下略
94
+ }
95
+
96
+ // 以下略
97
+ }
98
+ ```