Как добавить 30-секундный таймер для завершения игрового раунда?

#swift #scenekit

#swift #scenekit

Вопрос:

В настоящее время я экспериментирую с некоторым кодом, который я нашел в Интернете об игре, в которой вам нужно нажимать на один набор элементов и избегать нажатия на другой. В настоящее время я пытаюсь добавить таймер в игру, чтобы он длился в общей сложности 30 секунд, но я действительно изо всех сил пытаюсь это сделать, поскольку я совершенно неопытен в этом языке программирования.

 import UIKit
import QuartzCore
import SceneKit

class GameViewController: UIViewController, SCNSceneRendererDelegate {

    var gameView:SCNView!
    var SceneGame:SCNScene!
    var NodeCamera:SCNNode!
    var targetCreationTime:TimeInterval = 0


    override func viewDidLoad() {
        super.viewDidLoad()

        View_in()
        initScene()
        initCamera()
    }

    func View_in(){
        gameView = self.view as! SCNView
        gameView.allowsCameraControl = true
        gameView.autoenablesDefaultLighting = true

        gameView.delegate = self
    }

    func initScene (){
        SceneGame = SCNScene()
        gameView.scene = SceneGame

        gameView.isPlaying = true

    }

    func initCamera(){
        NodeCamera = SCNNode()
        NodeCamera.camera = SCNCamera()

        NodeCamera.position = SCNVector3(x:0, y:5, z:10)

        SceneGame.rootNode.addChildNode(NodeCamera)
    }

    func createTarget(){

        let geometry:SCNGeometry = SCNPyramid( width: 1, height: 1, length: 1)

        let randomColor = arc4random_uniform(2
            ) == 0 ? UIColor.green : UIColor.red

        geometry.materials.first?.diffuse.contents = randomColor

        let geometryNode = SCNNode(geometry: geometry)
        geometryNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)


        if randomColor == UIColor.red {
            geometryNode.name = "enemy"
        }else{
            geometryNode.name = "friend"
        }


        SceneGame.rootNode.addChildNode(geometryNode)


        let randomDirection:Float = arc4random_uniform(2) == 0 ? -1.0 : 1.0

        let force = SCNVector3(x: randomDirection, y: 15, z: 0)

        geometryNode.physicsBody?.applyForce(force, at: SCNVector3(x: 0.05, y: 0.05, z: 0.05), asImpulse: true)
    }

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
        if time > targetCreationTime{
            createTarget()
            targetCreationTime = time   0.6
        }

        cleanUp()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first!

        let location = touch.location(in: gameView)

        let hitList = gameView.hitTest(location, options: nil)

        if let hitObject = hitList.first{
            let node = hitObject.node

            if node.name == "friend" {
                node.removeFromParentNode()
                self.gameView.backgroundColor = UIColor.black
            }else {
                node.removeFromParentNode()
                self.gameView.backgroundColor = UIColor.red
            }
        }
    }

    func cleanUp() {
        for node in SceneGame.rootNode.childNodes {
            if node.presentation.position.y < -2 {
                node.removeFromParentNode()
            }
        }
    }

    override var shouldAutorotate: Bool {
        return true
    }

    override var prefersStatusBarHidden: Bool {
        return true
    }

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if UIDevice.current.userInterfaceIdiom == .phone {
            return .allButUpsideDown
        } else {
            return .all
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Release any cached data, images, etc that aren't in use.
    }

}
 

Ответ №1:

Вы могли бы использовать Timer объект, описанный здесь . Просто установите таймер, когда вы хотите, чтобы игра началась, возможно, после завершения всех инициализаций. Когда вы настроите таймер, просто подождите, пока он перезвонит к вашему коду, когда он завершится, и запустите любую логику, которую вы хотите использовать для завершения игры.

Комментарии:

1. Не уверен, почему этот ответ не был принят. пусть checkWaveTime = Timer.scheduledTimer(с интервалом времени: 1.0, повторы: true, блок: { _ в self.subtractValueTakeAction() }) — просто убедитесь, что он выполняется в основном потоке.

Ответ №2:

Редактировать

Создайте переменную, представляющую время, в течение которого вы хотите, чтобы ваша игра закончилась:

     var time: CGFloat = 60
 

Затем добавьте SCNAction в свою сцену, чтобы с каждой секундой это значение переменной уменьшалось, например, в viewDidLoad :

     //One second before decrease the time
    let wait = SCNAction.wait(forDuration: 1)

    //This is the heart of this answer
   // An action that reduce the time and when it is less than 1 (it reached zero) do whatever you want

    let reduceTime = SCNAction.run{ _ in
        self.time -= 1
        if self.time < 1 {
    // Do whatever you want
    // for example show a game over scene or something else
            }
        }
    }

    SceneGame.rootNode.run(SCNAction.repeatForever(SCNAction.sequence([wait,reduceTime])))
 

Если вы хотите, вы можете показать оставшееся время, используя SKLabel на HUD, который SKScene используется как наложение.

Вы можете проверить это руководство о том, как создать HUD

Кроме того, вы можете использовать SCNText , это документация об этом

Комментарии:

1. Привет, я скопировал и вставил бит кода SCNAction в раздел viewDidLoad, но внезапно появилось много ошибок. Не могли бы вы, пожалуйста, помочь мне немного дальше. Кроме того, принадлежат ли ‘var time: CGFloat = 60’ и ‘var timeNode = SCNNode()’ разделу GameViewController?

2. Обе переменные должны принадлежать вашему GameViewController. Что касается ошибок, я попробовал код на игровой площадке без проблем, так что расскажите мне о них подробнее, даже наедине, если хотите.

3. Кроме того, проверьте мое редактирование, вам не нужен узел-призрак «timeNode», вы можете сделать корневой узел своей сцены для запуска действия

4. Привет, да, я хотел бы поговорить с вами наедине, если это возможно, поскольку я все еще ничего не добился. Как мы могли бы поговорить наедине.

5. Давайте попробуем решить эту проблему здесь, чтобы все, кто ищет одно и то же решение, могли легко его найти. В любом случае, если это зайдет слишком далеко, система позволит нам получать личные сообщения. В любом случае, ваш класс должен выглядеть так в ссылке . Выдает ли это какую-либо ошибку?