Ios 在Swift中未检测到触摸

Ios 在Swift中未检测到触摸,ios,swift,xcode,Ios,Swift,Xcode,我一直在用Swift开发一个简单的游戏,以增加我对语言语法和概念的了解。我目前面临一个问题,在游戏应用程序中没有检测到触摸。该应用程序使用动作作为关键方法来启动游戏,但不幸的是,当我点击屏幕时,SKSpriteNodes并不是从屏幕顶部生成的(至少在视觉上)。我已经进入了一些打印状态,以查看代码是否达到了某些方法,但问题的原因似乎在触摸方法内,因为触摸方法未执行打印行。有人能帮我确定我的错误是什么,以及如何防止这种情况发生吗 出于参考目的,我将课程包括: import SpriteKit imp

我一直在用Swift开发一个简单的游戏,以增加我对语言语法和概念的了解。我目前面临一个问题,在游戏应用程序中没有检测到触摸。该应用程序使用动作作为关键方法来启动游戏,但不幸的是,当我点击屏幕时,SKSpriteNodes并不是从屏幕顶部生成的(至少在视觉上)。我已经进入了一些打印状态,以查看代码是否达到了某些方法,但问题的原因似乎在触摸方法内,因为触摸方法未执行打印行。有人能帮我确定我的错误是什么,以及如何防止这种情况发生吗

出于参考目的,我将课程包括:

import SpriteKit
import GameplayKit
class GameScene: SKScene {
    private var counter: Int = 0
    private var level: Int = 0
    private var debug: SKLabelNode?

    // Here we set initial values of counter and level. Debug label is created here as well.

    override func didMove(to view: SKView) {
        counter = 0
        level = 1
        backgroundColor = SKColor.gray
        debug = SKLabelNode(fontNamed: "ArialMT")
        debug?.fontColor = SKColor.purple
        debug?.fontSize = 30.0
        debug?.position = CGPoint(x: frame.midX, y: frame.midY)
        debug?.text = "Counter : [ \(counter) ], Level [ \(level) ]"
        if let aDebug = debug {
            addChild(aDebug)
        }
        print(action(forKey: "counting") == nil)
    }

    //Method to start a timer. SKAction is used here to track a time passed and to maintain the current level
    func startTimer() {
        print("TIMER STARTED...")
        weak var weakSelf: GameScene? = self
        //make a weak reference to scene to avoid retain cycle
        let block = SKAction.run({
            weakSelf?.counter = (weakSelf?.counter ?? 0) + 1
            //Maintaining level
            if (weakSelf?.counter ?? 0) < 5 {
                //level 1
                weakSelf?.level = 1
            } else if (weakSelf?.counter ?? 0) >= 5 && (weakSelf?.counter ?? 0) < 10 {
                //level 2
                weakSelf?.level = 2
            } else {
                //level 3
                weakSelf?.level = 3
            }
            weakSelf?.debug?.text = "Counter : [ \(Int(weakSelf?.counter ?? 0)) ], Level [ \(Int(weakSelf?.level ?? 0)) ]"
        })
        run(SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration: 1), block])), withKey: "counting")
    }

    //Method for stopping the timer and reset everything to the default state.
    func stopTimer() {
         print("TIMER STOPPED.")
        if action(forKey: "counting") != nil {
            removeAction(forKey: "counting")
        }
        counter = Int(0.0)
        level = 1
        debug?.text = "Counter : [ \(counter) ], Level [ \(level) ]"
    }

    //Get current speed based on time passed (based on counter variable)
    func getCurrentSpeed() -> CGFloat {
        if counter < 5 {
            //level 1
            return 1.0
        } else if counter >= 5 && counter < 10 {
            //level 2
            return 2.0
        } else {
            //level 3
            return 3.0
        }
    }

    //Method which stops generating stones, called in touchesBegan

    func stopGeneratingStones() {
         print("STOPPED GENERATING STONES...")
        if action(forKey: "spawning") != nil {
            removeAction(forKey: "spawning")
        }
    }

    func randomFloatBetween(_ smallNumber: CGFloat, and bigNumber: CGFloat) -> CGFloat {
        let diff: CGFloat = bigNumber - smallNumber
        //return (CGFloat(arc4random_uniform(UInt32(CGFloat(RAND_MAX) + 1 / CGFloat(RAND_MAX) * diff )))) + smallNumber
         return CGFloat(arc4random() % (UInt32(RAND_MAX) + 1)) / CGFloat(RAND_MAX) * diff + smallNumber
    }

    //Method for generating stones, you run this method when you want to start spawning nodes (eg. didMoveToView or when some button is clicked)
    func generateStones() {
         print("GENERATING STONES...")
        let delay = SKAction.wait(forDuration: 2, withRange: 0.5)
        //randomizing delay time
        weak var weakSelf: GameScene? = self
        //make a weak reference to scene to avoid retain cycle
        let block = SKAction.run({
            let stone: SKSpriteNode? = weakSelf?.spawnStone(withSpeed: weakSelf?.getCurrentSpeed() ?? 0.0)
            stone?.zPosition = 20
            if let aStone = stone {
                weakSelf?.addChild(aStone)
            }
        })
        run(SKAction.repeatForever(SKAction.sequence([delay, block])), withKey: "spawning")
    }

    //Returns stone with moving action added. Inside, you set standard things, like size, texture, physics body, name and position of a stone

    func spawnStone(withSpeed stoneSpeed: CGFloat) -> SKSpriteNode? {
        print("SPAWNNING STONES...")
        let stoneSize = CGSize(width: 30, height: 30) //size of shape.
        //you can randomize size here
        let stonePosition = CGPoint(x: randomFloatBetween(0.0, and: frame.size.width), y: frame.maxY) //initial position
        //you can randomize position here
        let stone = SKSpriteNode(color: SKColor.green, size: stoneSize) //setting size and color.
        stone.name = "stone" //named shape so we can check collision.
        //this helps if you want to enumerate all stones by name later on in your game
        stone.position = stonePosition //set position.
        let move = SKAction.moveBy(x: 0, y: -200, duration: 3.25)
        //one way to change speed
        move.speed = stoneSpeed
        let moveAndRemove = SKAction.sequence([move, SKAction.removeFromParent()])
        stone.run(moveAndRemove, withKey: "moving")
        //access this key if you want to stop movement
        return stone
    }

    func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        /* Called when a touch begins */
        //just a simple way to start and stop a game
        /**
         TOUCH METHOD NOT WORKING.
        */
        if action(forKey: "counting") == nil {
            print("HERE")
            startTimer()
            generateStones()
        } else {
            print("OR HERE")
            stopTimer()
            stopGeneratingStones()
        }
    }

}
导入SpriteKit
导入游戏工具包
类游戏场景:SKScene{
专用变量计数器:Int=0
私有变量级别:Int=0
私有变量调试:SKLabelNode?
//这里我们设置计数器和级别的初始值。调试标签也在这里创建。
覆盖func didMove(到视图:SKView){
计数器=0
级别=1
backgroundColor=SKColor.gray
debug=SKLabelNode(名称为:“ArialMT”)
调试?.fontColor=SKColor.purple
调试?.fontSize=30.0
调试?.position=CGPoint(x:frame.midX,y:frame.midY)
调试?.text=“计数器:[\(计数器)],级别[\(级别)]”
如果让aDebug=debug{
addChild(aDebug)
}
打印(操作(forKey:“计数”)==nil)
}
//方法启动计时器。此处使用SKAction跟踪经过的时间并保持当前水平
func startTimer(){
打印(“计时器已启动…”)
弱var弱自我:游戏场景?=自我
//对场景进行弱引用以避免重复
让block=SKAction.run({
weakSelf?计数器=(weakSelf?计数器0)+1
//维持水平
如果(弱自我?.counter±0)<5{
//一级
weakSelf?.level=1
}否则,如果(弱自?计数器0)>=5&(弱自?计数器0)<10{
//二级
weakSelf?.level=2
}否则{
//三级
弱自我?.level=3
}
weakSelf?.debug?.text=“计数器:[\(Int(weakSelf?.Counter±0))],级别[\(Int(weakSelf?.Level±0))]”
})
运行(SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration:1),block]),键为:“计数”)
}
//方法停止计时器并将所有内容重置为默认状态。
函数停止计时器(){
打印(“计时器停止”)
如果操作(forKey:“计数”)!=nil{
移除操作(forKey:“计数”)
}
计数器=Int(0.0)
级别=1
调试?.text=“计数器:[\(计数器)],级别[\(级别)]”
}
//根据经过的时间获取当前速度(基于计数器变量)
func getCurrentSpeed()->CGFloat{
如果计数器<5{
//一级
返回1.0
}否则,如果计数器>=5&&计数器<10{
//二级
返回2.0
}否则{
//三级
返回3.0
}
}
//停止生成石头的方法,在ToucheSStart中调用
func stopGeneratingStones(){
打印(“停止生成石头…”)
如果操作(forKey:“产卵”)!=nil{
removeAction(福基:“产卵”)
}
}
func randomFloatBeween(uSmallNumber:CGFloat和bigNumber:CGFloat)->CGFloat{
设diff:CGFloat=bigNumber-smallNumber
//返回值(CGFloat(arc4random_uniform)(UInt32(CGFloat(RAND_MAX)+1/CGFloat(RAND_MAX)*diff))+smallNumber
返回CGFloat(arc4random()%(UInt32(RAND_MAX)+1))/CGFloat(RAND_MAX)*diff+smallNumber
}
//方法,您可以在希望开始生成节点时运行此方法(例如didMoveToView或单击某个按钮)
func generatestone(){
打印(“生成石头…”)
让延迟=SKAction.wait(持续时间:2,范围:0.5)
//随机延迟时间
弱var弱自我:游戏场景?=自我
//对场景进行弱引用以避免重复
让block=SKAction.run({
let stone:SKSpriteNode?=weakSelf?.spawnStone(速度:weakSelf?.getCurrentSpeed()?0.0)
石头?.zPosition=20
如果让阿斯顿=石头{
懦夫?.addChild(阿斯顿)
}
})
运行(SKAction.repeatForever(SKAction.sequence([delay,block])),键为:“繁殖”)
}
//返回添加了移动动作的石头。在里面,你可以设置标准的东西,比如大小、纹理、物理实体、石头的名称和位置
func spawnStone(速度:CGFloat)->SKSpriteNode{
打印(“产卵石…”)
让stoneSize=CGSize(宽:30,高:30)//形状的大小。
//你可以在这里随机化大小
设stonePosition=CGPoint(x:random介于(0.0和:frame.size.width)之间),y:frame.maxY)//初始位置
//你可以在这里随机化位置
让stone=SKSpriteNode(颜色:SKColor.green,大小:stoneSize)//设置大小和颜色。
stone.name=“stone”//命名形状,以便检查碰撞。
//这有助于你以后在游戏中按名称列举所有石头
stone.position=stonePosition//设置位置。
让move=SKAction.moveBy(x:0,y:-200,持续时间:3.25)
//改变速度的一种方法
移动速度
让moveAndRemove=SKAction.sequence([move,SKAction.removeFromParent()]))
石头。奔跑(移动和移动,按键:“移动”)
//如果要停止移动,请访问此键
返回石
}
func touchsbegined(touchs:Set,带有事件:UIEvent){
/*当触摸开始时调用*/
//只是
func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
    /* Called when a touch begins */
    //just a simple way to start and stop a game
    /**
     TOUCH METHOD NOT WORKING.
    */
    if action(forKey: "counting") == nil {
        print("HERE")
        startTimer()
        generateStones()
    } else {
        print("OR HERE")
        stopTimer()
        stopGeneratingStones()
    }
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        /* Called when a touch begins */
        //just a simple way to start and stop a game
        /**
         TOUCH METHOD NOT WORKING.
        */
        if action(forKey: "counting") == nil {
            print("HERE")
            startTimer()
            generateStones()
        } else {
            print("OR HERE")
            stopTimer()
            stopGeneratingStones()
        }
    }