/
ControlView.swift
119 lines (93 loc) · 3.71 KB
/
ControlView.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import UIKit
/**
`ControlView` is responsible for displaying the controls
such as jump button and joystick.
*/
class ControlView: UIView {
var joystickView: JoystickView?
let buttonMargin: CGFloat = 50
let buttonSize: CGFloat = 100
let joystickBackgroundWidth: CGFloat = 256
let panThreshold: CGFloat = 15
var controlViewDelegate: ControlViewDelegate?
func setupSubviews() {
setupMovementControls()
setupActionControls()
setupGestureRecognizers()
}
// MARK: Private methods for setup
private func setupMovementControls() {
let joystickY = frame.height - buttonSize - buttonMargin
let joystickView = JoystickView(frame: CGRect(
x: buttonMargin,
y: joystickY,
width: joystickBackgroundWidth,
height: buttonSize
))
joystickView.setupSubviews()
addSubview(joystickView)
self.joystickView = joystickView
}
private func setupActionControls() {
let jumpButton = UIButton(type: .custom)
let buttonX = frame.width - buttonSize - buttonMargin
let buttonY = frame.height - buttonSize - buttonMargin
jumpButton.frame = CGRect(x: buttonX, y: buttonY, width: buttonSize, height: buttonSize)
jumpButton.addTarget(self, action: #selector(jumpButtonTapped), for: .touchUpInside)
jumpButton.setImage(#imageLiteral(resourceName: "JumpButton"), for: .normal)
jumpButton.setImage(#imageLiteral(resourceName: "JumpButtonDown"), for: .highlighted)
addSubview(jumpButton)
}
private func setupGestureRecognizers() {
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
addGestureRecognizer(panGesture)
}
// MARK: Gesture handler methods
@objc
func jumpButtonTapped() {
controlViewDelegate?.jumpButtonPressed()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
guard let joystickView = joystickView,
let firstTouch = touches.first,
firstTouch.location(in: self).x < self.frame.width / 2,
touches.count == 1 else {
return
}
if shouldSendMoveEvent(location: firstTouch.location(in: self)) {
let isLeft = firstTouch.location(in: joystickView).x < joystickView.center.x
controlViewDelegate?.joystickMoved(toLeft: isLeft)
}
joystickView.moveJoystick(location: firstTouch.location(in: joystickView))
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
guard let firstTouch = touches.first?.location(in: self),
firstTouch.x < self.frame.width / 2 else {
return
}
controlViewDelegate?.joystickReleased()
joystickView?.returnJoystick()
}
@objc
func handlePan(_ gesture: UIPanGestureRecognizer) {
guard let joystickView = self.joystickView else {
return
}
let location = gesture.location(in: self)
if gesture.state == .ended {
controlViewDelegate?.joystickReleased()
joystickView.returnJoystick()
} else if location.x < self.frame.width / 2 {
joystickView.moveJoystick(location: gesture.location(in: joystickView))
if shouldSendMoveEvent(location: location) {
let isLeft = gesture.location(in: joystickView).x < joystickView.center.x
controlViewDelegate?.joystickMoved(toLeft: isLeft)
}
}
}
private func shouldSendMoveEvent(location: CGPoint) -> Bool {
true
}
}