返回
iOS SpriteKit打造简单手游虚拟摇杆(通用组件)
IOS
2023-11-25 01:29:24
写在前面
2016年,MOBA手游市场可谓是火爆异常(此处不为任何游戏站台),笔者也是在同年开始接触SpriteKit,即苹果专为2D游戏开发打造的框架。
对于MOBA手游的爱好者而言,游戏中的角色移动方式一定再熟悉不过了。而对于未曾接触过MOBA手游的读者,咱们也不绕圈子,直接上图。
(图片展示:MOBA手游中的虚拟摇杆)
怎么样,现在想起来了嘛?因为……
触控虚拟摇杆的实现
1. 创建组件
首先,我们创建一个自定义组件,命名为VirtualJoystick
,代码如下:
import SpriteKit
class VirtualJoystick: SKSpriteNode {
// 摇杆的背景图片
private let backgroundImage: SKSpriteNode
// 摇杆的控制按钮
private let controlImage: SKSpriteNode
// 摇杆的最大移动范围
private let maxRadius: CGFloat
// 摇杆的当前位置
private var currentPosition: CGPoint
// 摇杆事件委托
weak var delegate: VirtualJoystickDelegate?
init(backgroundImageName: String, controlImageName: String, maxRadius: CGFloat) {
self.backgroundImage = SKSpriteNode(imageNamed: backgroundImageName)
self.controlImage = SKSpriteNode(imageNamed: controlImageName)
self.maxRadius = maxRadius
self.currentPosition = .zero
super.init(texture: nil, color: .clear, size: backgroundImage.size)
addChild(backgroundImage)
addChild(controlImage)
controlImage.position = .zero
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - 触控处理
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let location = touch.location(in: self)
if controlImage.contains(location) {
currentPosition = location
delegate?.virtualJoystickDidBeginDragging(self)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let location = touch.location(in: self)
// 计算偏移量,限制摇杆移动范围
let offset = location - currentPosition
let length = offset.length()
if length > maxRadius {
let normalizedOffset = offset.normalized() * maxRadius
currentPosition = currentPosition + normalizedOffset
controlImage.position = normalizedOffset
} else {
currentPosition = location
controlImage.position = offset
}
delegate?.virtualJoystickDidMove(self, offset: offset)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
// 手指离开屏幕时,摇杆复位
controlImage.position = .zero
currentPosition = .zero
delegate?.virtualJoystickDidEndDragging(self)
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
// 手指离开屏幕时,摇杆复位
controlImage.position = .zero
currentPosition = .zero
delegate?.virtualJoystickDidEndDragging(self)
}
}
// MARK: - 摇杆事件代理
protocol VirtualJoystickDelegate: AnyObject {
// 摇杆开始拖动
func virtualJoystickDidBeginDragging(_ virtualJoystick: VirtualJoystick)
// 摇杆拖动中
func virtualJoystickDidMove(_ virtualJoystick: VirtualJoystick, offset: CGPoint)
// 摇杆停止拖动
func virtualJoystickDidEndDragging(_ virtualJoystick: VirtualJoystick)
}
2. 使用组件
在游戏场景中,添加VirtualJoystick
组件并设置其代理:
// 创建虚拟摇杆
let joystick = VirtualJoystick(backgroundImageName: "joystick_background", controlImageName: "joystick_control", maxRadius: 100)
joystick.position = CGPoint(x: 100, y: 100)
joystick.delegate = self
addChild(joystick)
3. 实现代理方法
在游戏场景中,实现VirtualJoystickDelegate
代理方法,处理摇杆事件:
extension GameScene: VirtualJoystickDelegate {
func virtualJoystickDidBeginDragging(_ virtualJoystick: VirtualJoystick) {
// 摇杆开始拖动时的处理
}
func virtualJoystickDidMove(_ virtualJoystick: VirtualJoystick, offset: CGPoint) {
// 摇杆拖动中的处理
}
func virtualJoystickDidEndDragging(_ virtualJoystick: VirtualJoystick) {
// 摇杆停止拖动时的处理
}
}
结语
通过上述步骤,我们就可以在SpriteKit中实现一个简单的虚拟摇杆。这个组件支持拖动控制,并且可以设置摇杆的移动范围和外观。
希望本教程对您有所帮助。如果您有任何问题或建议,欢迎在评论区留言。