Ziehen Drehen Sie einen Knoten um einen festen Punkt


Wurflöffel

Ich versuche, einen drehbaren Knoten zu erstellen, der dem "Preisrad" in dieser Frage ähnelt . Bisher habe ich die Fähigkeit, mit einem UIPanGestureRecognizer, der wirklich gut funktioniert, Winkelimpulse auf einen Physikkörper zu übertragen. Ich kann das Drehen auch mit einer Berührung stoppen.

Jetzt versuche ich, eine Feineinstellung des Rads durch Ziehen oder Wischen zu ermöglichen. Wenn der Spieler mit dem Ergebnis nicht zufrieden ist, kann er es manuell drehen / ziehen / drehen, um die gewünschte Drehung zu erzielen.

Derzeit speichere ich den Ort der Berührung im touchBegan und versuche, die zRotation meines Knotens in der Aktualisierungsschleife zu erhöhen.

Die Rotation folgt nicht meinem Finger und ist ruckartig. Ich bin mir nicht sicher, ob ich die Fingerbewegung genau genug ablesen kann oder ob die Änderungsposition des Fingers nicht genau in Bogenmaß übersetzt wird. Ich vermute, dass es keine gute Lösung ist, die Berührung zu erkennen und sie dann im Update zu behandeln.

Hier ist mein Code.

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent?) {
    if let touch = touches.first as? UITouch {
        var location = touch.locationInView(self.view)
        location = self.convertPointFromView(location)

        mostRecentTouchLocation = location

        let node = nodeAtPoint(location)
        if node.name == Optional("left") && node.physicsBody?.angularVelocity != 0
        {
            node.physicsBody = SKPhysicsBody(circleOfRadius:150)
            node.physicsBody?.applyAngularImpulse(0)
            node.physicsBody?.pinned = true
        }
    }
}

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
        if mostRecentTouchLocation != CGPointZero{
        let node = nodeAtPoint(mostRecentTouchLocation)
        if node.name == Optional("left")
        {
            var positionInScene:CGPoint = mostRecentTouchLocation
            let deltaX:Float = Float(positionInScene.x) - Float(node.position.x)
            let deltaY:Float = Float(positionInScene.y) - Float(node.position.y)
            let angle:CGFloat = CGFloat(atan2f(deltaY, deltaX))
            let maths:CGFloat = angle - (CGFloat(90) * (CGFloat(M_PI) / 180.0))
            node.zRotation += maths
            mostRecentTouchLocation = CGPointZero
        }
    }
}

Ich habe einige der Berechnungen im Update auf mehrere Zeilen verteilt, um das Debuggen etwas zu vereinfachen.

Ich kann den PanGestureRecognizer-Code bei Bedarf hinzufügen, aber ich werde versuchen, ihn vorerst kurz zu halten.

BEARBEITEN Hier ist mein neuester Code, der auf der Empfehlung von GilderMan basiert. Ich denke, es funktioniert besser, aber die Rotation ist alles andere als glatt. Es springt in großen Schritten und folgt dem Finger nicht gut. Bedeutet das, dass mit meiner Winkelberechnung etwas nicht stimmt?

    override func didSimulatePhysics() {
    if mostRecentTouchLocation != CGPointZero {
        let node = nodeAtPoint(mostRecentTouchLocation)
        if node.name == Optional("left")
        {
            var positionInScene:CGPoint = mostRecentTouchLocation
            let deltaX:Float = Float(positionInScene.x) - Float(node.position.x)
            let deltaY:Float = Float(positionInScene.y) - Float(node.position.y)
            let angle:CGFloat = CGFloat(atan2f(deltaY, deltaX))
            node.zRotation += angle
            println(angle)
            mostRecentTouchLocation = CGPointZero
        }
    }
}
0x141E

Der folgende Code simuliert ein Preisrad, das sich je nach Berührung dreht. Wenn sich der Finger des Benutzers bewegt, dreht sich das Rad proportional zur Geschwindigkeit des Fingers. Wenn der Benutzer über das Rad wischt, dreht sich das Rad proportional zur Geschwindigkeit des Wischens. Sie können die angularDampingEigenschaft des Physikkörpers ändern, um die Geschwindigkeit, mit der das Rad zum Stillstand kommt, zu verlangsamen oder zu erhöhen.

class GameScene: SKScene {
    var startingAngle:CGFloat?
    var startingTime:TimeInterval?

    override func didMove(to view: SKView) {
        let wheel = SKSpriteNode(imageNamed: "Spaceship")
        wheel.name = "wheel"
        wheel.setScale(0.5)
        wheel.physicsBody = SKPhysicsBody(circleOfRadius: wheel.size.width/2)
        // Change this property as needed (increase it to slow faster)
        wheel.physicsBody!.angularDamping = 0.25
        wheel.physicsBody?.pinned = true
        wheel.physicsBody?.affectedByGravity = false
        addChild(wheel)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in:self)
            let node = atPoint(location)
            if node.name == "wheel" {
                let dx = location.x - node.position.x
                let dy = location.y - node.position.y
                // Store angle and current time
                startingAngle = atan2(dy, dx)
                startingTime = touch.timestamp
                node.physicsBody?.angularVelocity = 0
            }
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches{
            let location = touch.location(in:self)
            let node = atPoint(location)
            if node.name == "wheel" {
                let dx = location.x - node.position.x
                let dy = location.y - node.position.y

                let angle = atan2(dy, dx)
                // Calculate angular velocity; handle wrap at pi/-pi
                var deltaAngle = angle - startingAngle!
                if abs(deltaAngle) > CGFloat.pi {
                    if (deltaAngle > 0) {
                        deltaAngle = deltaAngle - CGFloat.pi * 2
                    }
                    else {
                        deltaAngle = deltaAngle + CGFloat.pi * 2
                    }
                }
                let dt = CGFloat(touch.timestamp - startingTime!)
                let velocity = deltaAngle / dt

                node.physicsBody?.angularVelocity = velocity

                // Update angle and time
                startingAngle = angle
                startingTime = touch.timestamp
            }
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        startingAngle = nil
        startingTime = nil
    }
}

Verwandte Artikel


So skalieren Sie immer um einen festen Punkt (Kartenmitte)

LaurentP22 Ich erstelle eine Anwendung, in der der Benutzer einen Speicherort auswählen kann (wie in diesem Beispiel: https://docs.mapbox.com/android/maps/examples/location-picker/ ). Wie kann man das Verhalten des ändern standardScaleGestureDetector, damit es

Mathematica: Einen Punkt um einen anderen drehen

RUHE IN FRIEDEN Ich frage mich, ob es möglich ist, einen Punkt in Mathematica um einen anderen vorhandenen Punkt zu drehen. Ich habe versucht, so etwas zu tun: one = Graphics[Point[{1, 1}]]; two = Graphics[Point[{2, 2}]]; two = Rotate[{two}, 60 Degree, {one}]

So drehen Sie ein Bild um einen Punkt in Java

Eduardo Maia: Ich habe mir einige ähnliche Fragen angesehen, aber keine beantwortet genau das, was ich brauche. In den Lösungen, die ich gefunden habe, haben alle das Bild gedreht, ohne sich zu bewegen, aber ich brauche, dass sich dieses Bild um die Ausgangspo

Drehen Sie das Spielermodell, um auf einen Punkt zu zeigen

Konsti Lackner Ich habe den Beitrag von vor drei Jahren gesehen, in dem eine ähnliche Frage gestellt wurde, wie dies erreicht werden glm::lookAtkann, konnte ihn aber nicht ganz auf mein Spiel anwenden. Ich habe ein Kamera- und Spielermodell, das sich auf einer

OpenSCAD: Um einen bestimmten Punkt drehen?

Mark Harrison Der folgende Code dreht den zweiten Würfel um den Ursprung. Wie kann ich stattdessen den zweiten Würfel um seinen Mittelpunkt ([5,5,0]) drehen? cube([10,10,1]); rotate([0,0,45]) cube([10,10,1]); Mark Harrison Dieses Modul führt die gewünschte Dr

Drehen Sie einen Datenrahmen um

Madno Ich arbeite an Databricks mit Python 2. Ich habe einen PySpark-Datenrahmen wie: |Germany|USA|UAE|Turkey|Canada... |5 | 3 |3 |42 | 12.. Wie Sie sehen, besteht es aus Hunderten von Spalten und nur einer einzigen Zeile. Ich möchte es so umdrehen,

JavaScript - eine Form um einen festen Winkel drehen

Great_Raisin Ich möchte eine Form um den Umfang eines Kreises auf der HTML-Leinwand verschieben. Ich verwende die folgende JavaScript-Logik: speed = 0.005; angle = Math.PI/2; angle += speed * direction; var x = cx + (radius * Math.cos(angle)); var y = cy + (r