代码之家  ›  专栏  ›  技术社区  ›  Andy Lebowitz

对象位置不匹配(spritekit)

  •  0
  • Andy Lebowitz  · 技术社区  · 7 年前

    我正在建立一个spritekit游戏,刚刚开始这个项目。我在屏幕上有一个从中心开始的圆,当我把手指从圆向外拖动时,它会显示一条与球相连的虚线/BezierPath,这将帮助用户看到它瞄准球的位置。当用户举起手指时,球将朝着与瞄准线相反的方向射出。(想想足球明星或游泳池之类的比赛)。问题是,当所有的动作都从中间开始时,这个动作第一次起作用:我拖动手指,球向相反的方向射出,然后停止。但当我再次尝试时,瞄准线的位置显示它和球是一样的(它应该是),但是它在屏幕上显示的距离球只有一英寸。我觉得这可能是一个问题,即物体后面的场景可能大小不同?但我很困惑,因为我想我只使用了一个场景。

    游戏视图控制器视图加载:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        if let view = self.view as! SKView? {
            // Load the SKScene from 'GameScene.sks'
            if let scene = SKScene(fileNamed: "GameScene") {
                // Set the scale mode to scale to fit the window
                scene.scaleMode = .aspectFill
                scene.size = view.bounds.size
                //scene.anchorPoint = CGPoint(x: 0.0, y: 0.0)
    
    
                // Present the scene
                view.presentScene(scene)
            }
    
            view.ignoresSiblingOrder = true
    
            view.showsFPS = true
            view.showsNodeCount = true
        }
    }
    

    游戏场景代码(怀疑你是否需要所有的代码,除了什么):

    import SpriteKit
    import GameplayKit
    
    class GameScene: SKScene {
    
        var ball = SKShapeNode(circleOfRadius: 35)
        var touchingBall = false
        var aimLine = SKShapeNode()
    
        var startAimPoint = CGPoint()
        var endAimPoint = CGPoint()
    
        let damping:CGFloat = 0.94
    
        override func didMove(to view: SKView) {
    
            ball.fillColor = SKColor.orange
            ball.name = "ball"
    
            let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
            borderBody.friction = 0
            self.physicsBody = borderBody
            physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)
    
            var physicsBody = SKPhysicsBody(circleOfRadius: 35)
            ball.physicsBody = physicsBody
            ball.physicsBody?.affectedByGravity = false
            ball.physicsBody?.friction = 10.0
    
            ball.position = CGPoint(x: frame.midX, y: frame.midY)
    
            self.addChild(ball)
        }
    
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            print("TOUCHES BEGAN.")
            for touch in touches {
                print("TB: \(touchingBall)")
                let location = touch.location(in: self)
                let node : SKNode = self.atPoint(location)
                if node.name == "ball" {
                    // touched inside node
                    if ball.physicsBody!.angularVelocity <= 0.0{
                        touchingBall = true
    
                        startAimPoint = ball.position
    
                        print(touchingBall)
                    }
                }
            }
    
        }
    
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
            print("TOCUHES MOVED.")
            for touch in touches {
                let location = touch.location(in: self)
                if touchingBall{
                    endAimPoint = location
    
                    assignAimLine(start: startAimPoint, end: endAimPoint)
                    print("Moving touched ball")
    
                }
            }
    
        }
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            print("Touches ended. \(touchingBall)")
            if touchingBall == true{
    
                ball.physicsBody!.applyImpulse(CGVector(dx: -(endAimPoint.x - startAimPoint.x) * 3, dy: -(endAimPoint.y - startAimPoint.y) * 3))
    
            }
    
            touchingBall = false
            aimLine.removeFromParent()
            print(touchingBall)
    
        }
    
        override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            print("Touches cancelled. \(touchingBall)")
            if touchingBall == true{
    
                ball.physicsBody!.applyImpulse(CGVector(dx: -(endAimPoint.x - startAimPoint.x) * 3, dy: -(endAimPoint.y - startAimPoint.y) * 3))
    
            }
    
            touchingBall = false
            aimLine.removeFromParent()
            print(touchingBall)
    
        }
    
    
        override func update(_ currentTime: TimeInterval) {
            // Called before each frame is rendered
    
            print(ball.physicsBody!.velocity)
            let dx2 = ball.physicsBody!.velocity.dx * damping
            let dy2 = ball.physicsBody!.velocity.dy * damping
            ball.physicsBody!.velocity = CGVector(dx: dx2, dy: dy2)
    
    
        }
        func assignAimLine(start: CGPoint, end: CGPoint){
    
            aimLine.removeFromParent()
    
            var bezierPath = UIBezierPath()
            bezierPath.move(to: start)
            bezierPath.addLine(to: shortenedEnd(startPoint: start, endPoint: end))
    
            var pattern : [CGFloat] = [10.0, 10.0]
            let dashed = SKShapeNode(path: bezierPath.cgPath.copy(dashingWithPhase: 2, lengths: pattern))
    
            aimLine = dashed
            aimLine.position = ball.position
    
            aimLine.zPosition = 0
    
            self.addChild(aimLine)
    
    
    
        }
        func hypotenuse(bp: UIBezierPath) -> Double{
            var a2 = bp.cgPath.boundingBox.height * bp.cgPath.boundingBox.height
            var b2 = bp.cgPath.boundingBox.width * bp.cgPath.boundingBox.width
            return Double(sqrt(a2 + b2))
        }
        func hypotenuse(startP: CGPoint, endP: CGPoint) -> Double{
            var bezierPath = UIBezierPath()
            bezierPath.move(to: startP)
            bezierPath.addLine(to: endP)
            return hypotenuse(bp: bezierPath)
        }
        func shortenedEnd(startPoint: CGPoint, endPoint: CGPoint) -> CGPoint{
    
            var endTemp = endPoint
            //while hypotenuse(startP: startPoint, endP: endTemp) > 150{
                    endTemp = CGPoint(x: endTemp.x / 1.01, y: endTemp.y / 1.01)
            //}
            return endTemp
        }
        func addTestPoint(loc: CGPoint, color: UIColor){
            var temp = SKShapeNode(circleOfRadius: 45)
            temp.fillColor = color
            temp.position = loc
            self.addChild(temp)
    
        }
    }
    

    我试着打印场景的帧大小,它显示400到700多个(我正在iPhone6 Plus上测试),它显示uiscreen的大小相同,所以我不知道是什么问题。总的来说,我只需要瞄准线在圆的中心,而不是第一次尝试操作。谢谢。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Knight0fDragon    7 年前

    import SpriteKit
    import GameplayKit
    
    class GameScene: SKScene {
    
        var ball = SKShapeNode(circleOfRadius: 35)
        var touchingBall = false
        var aimLine = SKShapeNode()
    
        var endAimPoint = CGPoint()
    
    
        override func didMove(to view: SKView) {
    
            ball.fillColor = SKColor.orange
            ball.name = "ball"
    
            let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
            borderBody.friction = 0
            self.physicsBody = borderBody
            physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)
            ball.position = CGPoint(x: frame.midX, y: frame.midY)
    
            let physicsBody = SKPhysicsBody(circleOfRadius: 35)
            physicsBody.affectedByGravity = false
            physicsBody.friction = 10.0
            physicsBody.linearDamping = 0.94
            ball.physicsBody = physicsBody
    
            self.addChild(ball)
        }
    
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            print("TOUCHES BEGAN.")
            for touch in touches {
                print("TB: \(touchingBall)")
                let location = touch.location(in: self)
                let node : SKNode = self.atPoint(location)
                if node.name == "ball" {
                    // touched inside node
                    if ball.physicsBody!.angularVelocity <= 0.0{
                        touchingBall = true
                        aimLine.path = nil
                        self.addChild(aimLine)
    
                        print(touchingBall)
                    }
                }
            }
    
        }
    
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
            print("TOCUHES MOVED.")
            for touch in touches {
                let location = touch.location(in: self)
                if touchingBall{
                    endAimPoint = self.convert(location, to: ball)
                    assignAimLine(end: endAimPoint)
                    print("Moving touched ball")
    
                }
            }
    
        }
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            print("Touches ended. \(touchingBall)")
            if touchingBall == true{
                ball.physicsBody!.applyImpulse(CGVector(dx: -(endAimPoint.x) * 3, dy: -(endAimPoint.y) * 3))
            }
    
            touchingBall = false
    
            aimLine.removeFromParent()
            print(touchingBall)
    
        }
    
        override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            print("Touches cancelled. \(touchingBall)")
            if touchingBall == true{
    
                ball.physicsBody!.applyImpulse(CGVector(dx: -(endAimPoint.x) * 3, dy: -(endAimPoint.y) * 3))
    
            }
    
            touchingBall = false
            aimLine.removeFromParent()
            print(touchingBall)
    
        }
    
    
        override func update(_ currentTime: TimeInterval) {
            // Called before each frame is rendered
    
            print(ball.physicsBody!.velocity)
            //let dx2 = ball.physicsBody!.velocity.dx * damping
            //let dy2 = ball.physicsBody!.velocity.dy * damping
            //ball.physicsBody!.velocity = CGVector(dx: dx2, dy: dy2)
    
    
        }
        func assignAimLine(end: CGPoint){
    
    
            let bezierPath = UIBezierPath()
            bezierPath.move(to: CGPoint.zero)
            bezierPath.addLine(to: end)
    
            let pattern : [CGFloat] = [10.0, 10.0]
    
    
            aimLine.position = ball.position
            aimLine.path = bezierPath.cgPath.copy(dashingWithPhase: 2, lengths: pattern)
            aimLine.zPosition = 0
    
    
    
        }
    
        func addTestPoint(loc: CGPoint, color: UIColor){
            var temp = SKShapeNode(circleOfRadius: 45)
            temp.fillColor = color
            temp.position = loc
            self.addChild(temp)
    
        }
    }
    
    推荐文章