How can I change the touch offset of a sprite in SpriteKit?

Viewed 86

When I touch the player mallet (Air Hockey), I want to make it so the mallet moves slightly above the touch. This way the mallet will be more visible in the game. I have found some solutions but am having a hard time implementing properly in my function.

Here is a sample of my touchesMoved() function:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
{
    bottomTouchIsActive = true
    var releventTouch:UITouch!
    //convert set to known type
    let touchSet = touches

    //get array of touches so we can loop through them
    let orderedTouches = Array(touchSet)


    for touch in orderedTouches
    {
        //if we've not yet found a relevent touch
        if releventTouch == nil
        {
            //look for a touch that is in the activeArea (Avoid touches by opponent)
            if activeArea.contains(touch.location(in: parent!))
            {
                isUserInteractionEnabled = true
                releventTouch = touch
            }
            else
            {
                releventTouch = nil
            }
        }
    }

    if (releventTouch != nil)
    {
        //get touch position and relocate player
        let location = releventTouch!.location(in: parent!)
        position = location

        //find old location and use pythagoras to determine length between both points
        let oldLocation = releventTouch!.previousLocation(in: parent!)
        let xOffset = location.x - oldLocation.x
        let yOffset = location.y - oldLocation.y
        let vectorLength = sqrt(xOffset * xOffset + yOffset * yOffset)

        //get eleapsed and use to calculate speed6A
        if  lastTouchTimeStamp != nil
        {
            let seconds = releventTouch.timestamp - lastTouchTimeStamp!
            let velocity = 0.01 * Double(vectorLength) / seconds

            //to calculate the vector, the velcity needs to be converted to a CGFloat
            let velocityCGFloat = CGFloat(velocity)

            //calculate the impulse
            let directionVector = CGVector(dx: velocityCGFloat * xOffset / vectorLength, dy: velocityCGFloat * yOffset / vectorLength)

            //pass the vector to the scene (so it can apply an impulse to the puck)
            delegate?.bottomForce(directionVector, fromBottomPlayer: self)
            delegate?.bottomTouchIsActive(bottomTouchIsActive, fromBottomPlayer: self)
        }
        //update latest touch time for next calculation
        lastTouchTimeStamp = releventTouch.timestamp
    }
}
1 Answers

Is the position var, which you take from the touch location, used to set the position of the mallet? If it is, then if you want the mallet above the touch, why not do something like position.y += 50 immediately after position = location to move it up by 50 points?

Alternatively, you might find it more logical to set the mallet's anchorPoint property (https://developer.apple.com/documentation/spritekit/skspritenode/1519877-anchorpoint and https://developer.apple.com/documentation/spritekit/skspritenode/using_the_anchor_point_to_move_a_sprite) to be somewhere other than the default poisition (the centre of the sprite) e.g. the point that corresponds to the part of the handle of the mallet where one would normally hold it.

Related