You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpriteKit中如何实现单条线跟随触摸而非无限绘制线条

问题根因

你当前的touchesMoved回调每次触发时都会调用drawLine方法新建一个SKShapeNode节点并添加到场景中,没有复用已有的线条实例,所以会随着触摸移动生成大量线条。

修复方案

将线条节点声明为全局属性,仅在首次触发绘制时创建并添加节点,后续触摸移动时仅更新线条的路径即可,修改后代码如下:

import SpriteKit
import GameplayKit

class WireDrawTest: SKScene{
    var redBox = SKSpriteNode()
    var redBoxPoint = CGPoint(x: 445, y: 800)
    var redBoxTouched:Int = -1
    // 新增全局线条属性,复用同一条线
    var currentLine: SKShapeNode?
    
    override func didMove(to view: SKView) {
        redBox = self.childNode(withName: "redBox") as! SKSpriteNode
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print(redBoxTouched)
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else { return }
        let location = touch.location(in: self)
        let nodesArray = self.nodes(at: location)
        
        if nodesArray.first?.name == "redBox" && redBoxTouched == -1 {
            redBoxTouched = 1
        }
        
        guard redBoxTouched == 1 else { return }
        // 如果还没有创建线条就先创建
        if currentLine == nil {
            let line = SKShapeNode()
            line.strokeColor = .yellow
            line.lineWidth = 13
            addChild(line)
            currentLine = line
        }
        // 直接更新线条路径
        let path = CGMutablePath()
        path.addLines(between: [redBoxPoint, location])
        currentLine?.path = path
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print(redBoxTouched)
        redBoxTouched = -1
        // 如果需要结束后保留线条就注释掉下面两行,不需要保留就保留代码
        // currentLine?.removeFromParent()
        // currentLine = nil
    }
}

内容的提问来源于stack exchange,提问作者Trent Carlock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:24:04