2017-09-19 6 views
1

私はSpriteKitを使って簡単なプラットフォームゲームを作っています。ゲームがfunc didBeginで地面に当たったときにゲームが検出されますが、何らかの理由でbooleanのplayerTouchingGround(Playerクラス内)がtrueに変更されていません。私はvar playerTouchingGroundをtrueに初期化し、プレーヤーは一度ジャンプすることができますが、再びジャンプすることはできません。アウトプットコンソールは、「ヒットグラウンド、左グラウンド、ヒットグラウンド」を印刷します。私は何が間違っているのか分かりません。私はおそらく単純なものを探しています。ここでスプライトを素早く地上に飛ばせるにはどうすればよいですか?

はここに私のGameSceneコード

import SpriteKit 
import GameplayKit 

class GameScene: SKScene{ 

let player: Player! 
let ground: Ground! 
let controller: ControllerNode! 

let contactManager = Player() 


// MARK: - Init 


override init(size: CGSize) { 

    player = Player() 
    ground = Ground(size: size) 
    controller = ControllerNode(position: CGPoint(x:0, y: 0)) 

    super.init(size: size) 

    self.physicsWorld.contactDelegate = contactManager 

    setup() 

} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 



// MARK: - Setup 

func setup() { 


    // Background Color 
    self.backgroundColor = UIColor.white 


    // Adding Player 
    addChild(player) 
    player.position.x = size.width/2 
    player.position.y = size.height/2 


    // Adding Ground 
    addChild(ground) 
    ground.position.x = size.width/2 
    ground.position.y = size.height/4 


    // Adding ControllerNode 
    addChild(controller) 

} 


override func update(_ currentTime: TimeInterval) { 
    // Called before each frame is rendered 
    player.movement(directions: self.controller!.pressedDirections()) 

} 
} 

はここに私のプレーヤーのクラスコード

import SpriteKit 
enum CharacterMovement : Int { 

case Up 
case Right 
case Down 
case Left 

} 

enum ColliderType: UInt32 { 

case player = 1 
case ground = 2 
} 

class Player: SKSpriteNode, SKPhysicsContactDelegate { 


var tick = 0 


var currentMovement: CharacterMovement? 


var lastMovement: CharacterMovement? 


var contactMask: Int = 0 

var playerTouchingGround = true 

// MARK: - Init 

init() { 



    let playerSize = CGSize(width: 30, height: 60) 

    super.init(texture: nil, color: UIColor.cyan, size: playerSize) 

    lastMovement = .Right 

    self.zPosition = 10 

    setup() 

} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 


// MARK: - Setup 

func setup() { 


    physicsBody = SKPhysicsBody(rectangleOf: size) 
    physicsBody?.usesPreciseCollisionDetection = true 
    physicsBody?.categoryBitMask = ColliderType.player.rawValue 
    physicsBody?.collisionBitMask = ColliderType.ground.rawValue 
    physicsBody?.contactTestBitMask = ColliderType.ground.rawValue 
    physicsBody?.allowsRotation = false 
    physicsBody?.restitution = 0 
    physicsBody?.isDynamic = true 

} 

func didBegin(_ contact: SKPhysicsContact) { 

    print("hit ground") 
    playerTouchingGround = true 


} 




func movement(directions: [ControllerInput]) { 



    // if (directions.index(of: .Up) != nil) && (touchingGround == true){ 

    if (directions.index(of: .Up) != nil) && (playerTouchingGround) { 


     physicsBody?.applyImpulse(CGVector(dx: 0, dy: 30)) 
     playerTouchingGround = false 
     currentMovement = .Up 
     print("left ground") 
    } 

    if directions.index(of: .Right) != nil { 

     physicsBody?.applyImpulse(CGVector(dx: 1, dy: 0)) 
     currentMovement = .Right 
    } 

    if directions.index(of: .Left) != nil { 

     physicsBody?.applyImpulse(CGVector(dx: -1, dy: 0)) 
     currentMovement = .Left 
    } 

    if currentMovement != nil { 
     lastMovement = currentMovement 
    } 

    if !directions.isEmpty && self.currentMovement != nil { 
     // Player Animations 
    } 
    else { 
     currentMovement = nil 
    } 

    tick += 1 
    if tick > 60 { 
     tick = 0 
    } 

} 

} 

であることは私のグランドクラスコードは、あなたの問題は、あなたが複数のプレイヤーを作成しているある

import SpriteKit 

class Ground: SKSpriteNode { 


// MARK: - Init 

init(size: CGSize) { 

    let groundSize = CGSize(width: size.width, height: 20) 

    super.init(texture: nil, color: UIColor.black, size: groundSize) 

    setup() 
} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 


// MARK: - Setup 

func setup() { 

    physicsBody = SKPhysicsBody(rectangleOf: size) 
    physicsBody?.categoryBitMask = ColliderType.ground.rawValue 
    physicsBody?.usesPreciseCollisionDetection = true 
    physicsBody?.isDynamic = false 
    physicsBody?.restitution = 0 
    physicsBody?.categoryBitMask = ColliderType.ground.rawValue 
    physicsBody?.collisionBitMask = ColliderType.player.rawValue 
    physicsBody?.contactTestBitMask = ColliderType.player.rawValue 

} 
} 

答えて

1

ですオブジェクト。

Player()に電話するたびに、新しいプレーヤーを作成します。

これはcontactManagerplayerは私が迅速に比較的新しいです

let contactManager = Player() //<---Alright a player 


// MARK: - Init 


override init(size: CGSize) { 

    player = Player()// <-----Uh oh, a new player, need to fix this 
    ground = Ground(size: size) 
    controller = ControllerNode(position: CGPoint(x:0, y: 0)) 

    super.init(size: size) 

    self.physicsWorld.contactDelegate = contactManager 

    setup() 

} 
+0

同じインスタンスではないことを意味します。私のプレーヤークラスを私のcontactDelegateにすることは良い考えですか?私は私のgameSceneにすべてのプレイヤーの動きのコードを入れたくないのですが、複数のPlayerオブジェクトを作成せずにSKPhysicsContactDelegateを自分のプレーヤークラスに初期化する方法はわかりません。 – TommyC

+0

実際には、衝突する唯一のことがプレイヤーでない限り、シーンに残されたほうがいいです。 – Knight0fDragon

+0

私はSkPhysicsContactDelegateを設定し、私のGameSceneにdidBegin(連絡先)を設定しました。次に、GameSceneクラスとPlayerクラスの両方からアクセスできるブール値変数を持つGlobalVariableクラスを作成しました。これを行う最も効率的な方法であるかどうかはわかりませんが、今はゲームが完璧に実行されています。ご協力ありがとうございますKnightOfDragon。 – TommyC

関連する問題