简体   繁体   中英

How do I allow MULTIPLE images to be moved using touch in SpriteKit?

so I am making this game in Swift and I have included the code of what I have done on the 'GameScene.swift' file. I have 4 different objects that will need to be recreated at run time after every 0.2 seconds (don't even know how to do that :/), however using the code I currently have, if I try to move the 'coin20', 'coin100', or 'coin50' image, they don't move, only 'coin10' gets moved to their location and is far too sensitive so it just moves around like crazy whilst the other images are static. I hope this question is specific enough since my past questions weren't well received by answerers, if not please let me know how to improve, i'm just a beginner in programming. Thank you

Code:

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {

var coin10 = SKSpriteNode(imageNamed: "10S.png")
var coin100 = SKSpriteNode(imageNamed: "100S.png")
var coin50 = SKSpriteNode(imageNamed: "50S.png")
var coin20 = SKSpriteNode(imageNamed: "20S.png")
var wall1 = SKSpriteNode(imageNamed: "Wall1.png")
var wall2 = SKSpriteNode(imageNamed: "Wall2.png")
var bar = SKSpriteNode(imageNamed: "Bar.png")

var scorelabel = SKLabelNode()
var score = 0

var touchPoint: CGPoint = CGPoint()
var touching: Bool = false

enum ColliderType:UInt32 {
    case coin = 1
    case wall = 2

}

override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    //Adding coin10
    coin10.position = CGPointMake(self.size.width / 2, self.size.height / 5)
    coin10.physicsBody = SKPhysicsBody(circleOfRadius: coin10.size.width/2)
    coin10.physicsBody!.affectedByGravity = false
    coin10.physicsBody!.categoryBitMask = ColliderType.coin.rawValue
    coin10.physicsBody!.contactTestBitMask = ColliderType.wall.rawValue
    coin10.physicsBody!.collisionBitMask = ColliderType.wall.rawValue
    coin10.physicsBody!.dynamic = true
    self.addChild(coin10)

    //Adding coin100
    coin100.position = CGPointMake(self.size.width / 1.7, self.size.height / 5.1)
    coin100.physicsBody = SKPhysicsBody(circleOfRadius: coin100.size.width/2)
    coin100.physicsBody!.affectedByGravity = false
    coin100.physicsBody!.categoryBitMask = ColliderType.coin.rawValue
    coin100.physicsBody!.contactTestBitMask = ColliderType.wall.rawValue
    coin100.physicsBody!.collisionBitMask = ColliderType.wall.rawValue
    coin100.physicsBody!.dynamic = true
    self.addChild(coin100)

    //Adding coin50
    coin50.position = CGPointMake(self.size.width / 2.2, self.size.height / 4.9)
    coin50.physicsBody = SKPhysicsBody(circleOfRadius: coin50.size.width/2)
    coin50.physicsBody!.affectedByGravity = false
    coin50.physicsBody!.categoryBitMask = ColliderType.coin.rawValue
    coin50.physicsBody!.contactTestBitMask = ColliderType.wall.rawValue
    coin50.physicsBody!.collisionBitMask = ColliderType.wall.rawValue
    coin50.physicsBody!.dynamic = true
    self.addChild(coin50)

    //Adding coin20
    coin20.position = CGPointMake(self.size.width / 2.4, self.size.height / 5)
    coin20.physicsBody = SKPhysicsBody(circleOfRadius: coin20.size.width/2)
    coin20.physicsBody!.affectedByGravity = false
    coin20.physicsBody!.categoryBitMask = ColliderType.coin.rawValue
    coin20.physicsBody!.contactTestBitMask = ColliderType.wall.rawValue
    coin20.physicsBody!.collisionBitMask = ColliderType.wall.rawValue
    coin50.physicsBody!.dynamic = true
    self.addChild(coin20)

    //Adding wall1
    wall1.position = CGPointMake(self.size.width / 1.72, self.size.height / 1.07)
    wall1.physicsBody = SKPhysicsBody(rectangleOfSize: wall1.frame.size )
    wall1.physicsBody!.affectedByGravity = false
    wall1.physicsBody!.categoryBitMask = ColliderType.wall.rawValue
    wall1.physicsBody!.contactTestBitMask = ColliderType.coin.rawValue
    wall1.physicsBody!.collisionBitMask = ColliderType.coin.rawValue
    wall1.physicsBody!.dynamic = false
    self.addChild(wall1)

    //Adding wall2
    wall2.position = CGPointMake(self.size.width / 2.5, self.size.height / 1.07)
    wall2.physicsBody = SKPhysicsBody(rectangleOfSize: wall2.frame.size )
    wall2.physicsBody!.affectedByGravity = false
    wall2.physicsBody!.categoryBitMask = ColliderType.wall.rawValue
    wall2.physicsBody!.contactTestBitMask = ColliderType.coin.rawValue
    wall2.physicsBody!.collisionBitMask = ColliderType.coin.rawValue
    wall2.physicsBody!.dynamic = false
    self.addChild(wall2)

    //Adding bar
    bar.position = CGPointMake(self.size.width / 2, self.size.height / 1)
    bar.physicsBody = SKPhysicsBody(rectangleOfSize: wall2.frame.size)
    bar.physicsBody!.affectedByGravity = false
    bar.physicsBody!.categoryBitMask = ColliderType.wall.rawValue
    bar.physicsBody!.contactTestBitMask = ColliderType.coin.rawValue
    bar.physicsBody!.collisionBitMask = ColliderType.coin.rawValue
    bar.physicsBody!.dynamic = false
    self.addChild(bar)

    //Adding physics world properties
    self.physicsWorld.contactDelegate = self
    var scenebody = SKPhysicsBody(edgeLoopFromRect: self.frame)
    scenebody.friction = 0
    self.physicsBody = scenebody
    self.physicsWorld.gravity = CGVectorMake(0, -0.3)

    //Scoreboard
    scorelabel = SKLabelNode(text: "0")
    scorelabel.position.y = (self.size.height/2)
    scorelabel.position.x = (self.size.height/2.3)
    addChild(scorelabel)

}

func didBeginContact(contact: SKPhysicsContact) {

}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    /* Called when a touch begins */

    let touch = touches.first as! UITouch

    for touch in (touches as! Set<UITouch>) {
        let location = touch.locationInNode(self)

        if coin10.containsPoint(location){
            touchPoint = location
            touching = true
        }
        else if coin100.containsPoint(location){
            touchPoint = location
            touching = true
        }
        else if coin20.containsPoint(location){
            touchPoint = location
            touching = true
        }
        else if coin50.containsPoint(location){
            touchPoint = location
            touching = true
        }
    }
}

override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {

    let touch = touches.first as! UITouch

    for touch in (touches as! Set<UITouch>) {
        let location = touch.locationInNode(self)

        if coin10.containsPoint(location){
            touchPoint = location
        }
        else if coin100.containsPoint(location){
            touchPoint = location
        }
        else if coin50.containsPoint(location){
            touchPoint = location
        }
        else if coin20.containsPoint(location){
            touchPoint = location
        }

    }
}

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    touching = false
}

override func update(currentTime: CFTimeInterval) {

        if touching {

            let dt: CGFloat = 1.0/60.0
            let distance = CGVector(dx: touchPoint.x-coin10.position.x, dy: touchPoint.y-coin10.position.y)
            let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
            coin10.physicsBody!.velocity = velocity
    }
  }
}

First, add this instance variable

var touchedCoin:SKSpriteNode?

Then, in touchesBegan , set touchedCoin to the coin that was touched:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    for touch in (touches as! Set<UITouch>) {
        let location = touch.locationInNode(self)
        if coin10.containsPoint(location) {
            touchPoint = location
            touching = true
            touchedCoin = coin10
        }
        else if coin100.containsPoint(location){
            touchPoint = location
            touching = true
            touchedCoin = coin100
        }
        else if coin20.containsPoint(location){
            touchPoint = location
            touching = true
            touchedCoin = coin20
        }
        else if coin50.containsPoint(location){
            touchPoint = location
            touching = true
            touchedCoin = coin50
        }
    }
}

Lastly, move the coin that was touched

override func update(currentTime: CFTimeInterval) {
    if touching {
        let dt: CGFloat = 1.0/60.0
        let distance = CGVector(dx: touchPoint.x-touchedCoin!.position.x, dy: touchPoint.y-touchedCoin!.position.y)
        let velocity = CGVector(dx: distance.dx/dt, dy: distance.dy/dt)
        touchedCoin!.physicsBody!.velocity = velocity
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM