Как я могу изменить свой код, чтобы мой спрайт, который вращается по круговой орбите, перепрыгивал вверх и вниз, когда пользователь касался экрана? - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь заставить мой оранжевый спрайт, который вращается по кругу, прыгать в точке муравья при его вращении и снова падать вниз, когда пользователь касается экрана, но не может понять, что я Я делаю неправильно. Пожалуйста, помогите.

Я пытался воспользоваться советом к похожему посту, но безуспешно.

class GameScene: SKScene {
    let sprite = SKSpriteNode(imageNamed: "circle")

    let player = SKSpriteNode(imageNamed: "player")
    var node2AngularDistance: CGFloat = 0

    override func didMove(to view: SKView) {
        backgroundColor = SKColor(red: 94.0/255, green: 63.0/255, blue: 107.0/255, alpha: 1)

        physicsWorld.gravity = CGVector(dx: 0, dy: 0)
        sprite.size = CGSize(width: 150, height: 150)
        sprite.position = CGPoint(x: 0,y: 0)
        sprite.physicsBody = SKPhysicsBody(circleOfRadius: 10)
        player.size = CGSize(width: 100, height: 100)
        player.position = CGPoint(x: 0+50, y: 0)
        player.physicsBody = SKPhysicsBody(circleOfRadius: 10)
        self.addChild(sprite)
        self.addChild(player)
    }

    //dont touch blue lines that discard code and don't allow you to undo

    override func update(_ currentTime: TimeInterval) {
        let dt: CGFloat = 1.0/60.0 //Delta Time
        let period: CGFloat = 3 //Number of seconds it takes to complete 1 orbit.
        let orbitPosition = sprite.position //Point to orbit.
        let orbitRadius = CGPoint(x: 150, y: 150) //Radius of orbit.

        let normal = CGVector(dx:orbitPosition.x + CGFloat(cos(self.node2AngularDistance))*orbitRadius.x ,dy:orbitPosition.y + CGFloat(sin(self.node2AngularDistance))*orbitRadius.y);
        self.node2AngularDistance += (CGFloat(Double.pi)*2.0)/period*dt;
        if (abs(self.node2AngularDistance)>CGFloat(Double.pi)*2) {
            self.node2AngularDistance = 0
        }
        player.physicsBody!.velocity = CGVector(dx:(normal.dx-player.position.x)/dt ,dy:(normal.dy-player.position.y)/dt);



        //func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
        //sprite.position = (touches.first! as! UITouch).location(in: self)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { self.touchDown(atPoint: t.location(in: self)) }
    }

    func touchDown(atPoint pos: CGPoint) {
        jump()
    }

    func jump() {
        player.texture = SKTexture(imageNamed: "player")
        player.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 500))
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for t in touches { self.touchUp(atPoint: t.location(in: self)) }
    }

    func touchUp(atPoint pos: CGPoint) {
        player.texture = SKTexture(imageNamed: "player")
    }
}

Ожидаемым результатом будет спрайт с маленьким кругом, называемый игроком, который вращается по круговой орбите вокруг большего круга, называемого спрайтом, и когда пользователь касается экрана, игрок (маленький круг) будет подпрыгивать, а затем опускаться вниз в любой точке своего круга. Орбита. Фактические результаты заключаются в том, что круг вращается вокруг большего круга, но не поднимается, когда я нажимаю на экран в симуляторе iPhone.

1 Ответ

0 голосов
/ 12 января 2019

Состояние сброса необходимо записать как: isJumpping. Если isJumpping, обновление не будет выполняться, если это то, что вам нужно.

Второй вопрос: после поднятия игрок возвращается на орбиту. Здесь приведена простая математика, когда игрок прямо падает на круг.

Но если ситуация сложная, вы можете использовать PhysicsField для имитации ситуации.

Это работает в Xcode 10 и игровая площадка

import UIKit
import PlaygroundSupport
import SpriteKit
import simd

class GameScene: SKScene {
let sprite = SKSpriteNode(imageNamed: "circle")

let player = SKSpriteNode(imageNamed: "player")
var node2AngularDistance: CGFloat = 0

override func didMove(to view: SKView) {
    print(100)
  //  backgroundColor = SKColor(red: 94.0/255, green: 63.0/255, blue: 107.0/255, alpha: 1)
     backgroundColor = SKColor.black

    physicsWorld.gravity = CGVector(dx: 0, dy: 0)
    sprite.size = CGSize(width: 150, height: 150)
    sprite.position = CGPoint(x: 0,y: 0)
    sprite.physicsBody = SKPhysicsBody(circleOfRadius: 10)
    player.size = CGSize(width: 100, height: 100)
    player.position = CGPoint(x: 0+50, y: 0)
    player.physicsBody = SKPhysicsBody(circleOfRadius: 10)
    self.anchorPoint = CGPoint.init(x: 0.5, y: 0.5)
    self.addChild(sprite)
    self.addChild(player)
}

//dont touch blue lines that discard code and don't allow you to undo

override func update(_ currentTime: TimeInterval) {

    guard  !isJumpping else {

        return
    }

    let dt: CGFloat = 1.0/60.0 //Delta Time
    let period: CGFloat = 3 //Number of seconds it takes to complete 1 orbit.
    let orbitPosition = sprite.position //Point to orbit.
    let orbitRadius = CGPoint(x: 150, y: 150) //Radius of orbit.


   let currentDistance = distance(double2(x: Double(orbitPosition.x), y: Double(orbitPosition.y)), double2(x: Double(player.position.x), y: Double(player.position.y)))
    if (  currentDistance > 150){

        player.physicsBody!.velocity = CGVector(dx:(orbitPosition.x - player.position.x) ,dy:(orbitPosition.y - player.position.y));

        let x = Double(player.position.x) - Double(orbitPosition.x)
        let y = Double(player.position.y) - Double(orbitPosition.y)
        self.node2AngularDistance = CGFloat(acos(x/currentDistance))

   if y < 0 {

    self.node2AngularDistance = 2 * CGFloat.pi -  self.node2AngularDistance }

        return;
    }



    let normal = CGVector(dx:orbitPosition.x + CGFloat(cos(self.node2AngularDistance))*orbitRadius.x ,dy:orbitPosition.y + CGFloat(sin(self.node2AngularDistance))*orbitRadius.y);


    self.node2AngularDistance += (CGFloat(Double.pi)*2.0)/period*dt;
    if (abs(self.node2AngularDistance)>CGFloat(Double.pi)*2) {
        self.node2AngularDistance = 0
    }

    player.physicsBody!.velocity = CGVector(dx:(normal.dx-player.position.x)/dt ,dy:(normal.dy-player.position.y)/dt);



    //func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    //sprite.position = (touches.first! as! UITouch).location(in: self)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}

func touchDown(atPoint pos: CGPoint) {
    jump()
}
private var isJumpping : Bool = false
func jump() {
    isJumpping.toggle()
    player.texture = SKTexture(imageNamed: "player")
    player.physicsBody?.applyImpulse(CGVector(dx: (self.player.position.x - self.sprite.position.x) / 100.0, dy: (self.player.position.y - self.sprite.position.y) / 100.0))
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

    for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}

func touchUp(atPoint pos: CGPoint) {
    isJumpping.toggle()
    player.texture = SKTexture(imageNamed: "player")
}
}




class GameViewCointroller: UIViewController{

    var skview: SKView!



  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    skview = SKView.init(frame: view.bounds)
    let scene = GameScene.init(size: view.frame.size)
    skview.presentScene(scene)
    view.addSubview(skview)
   }


}

PlaygroundPage.current.liveView = GameViewCointroller()
...