![](/img/trans.png)
[英]iOS - SpriteKit : ApplyImpulse not working on SKSpriteNode
[英]SpriteKit applyImpulse not affecting sprite
我有一個類型為Skier的播放器節點,我想通過觸摸和拖動來繞x軸移動,類似於本教程 。 我將播放器節點添加到場景中,並且它的物理主體將isDynamic設置為true,但是由於某些原因,當我觸摸並拖動播放器時,它不會移動。 我究竟做錯了什么? 這是我的GameScene和我的Skier課程:
滑雪者:
class Skier: SKSpriteNode {
let playerTexture = SKTexture(imageNamed: "snowmanFancy_NE")
let playerSize = CGSize(width: 24, height: 40)
init () {
super.init(texture: playerTexture, color: UIColor.clear, size: playerSize)
self.name = "player"
setPhysics()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setPhysics(){
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.physicsBody? = SKPhysicsBody(rectangleOf: size)
self.physicsBody?.categoryBitMask = PhysicsCategory.player
self.physicsBody?.contactTestBitMask = PhysicsCategory.tree |
PhysicsCategory.rock | PhysicsCategory.cabin | PhysicsCategory.snowman |
PhysicsCategory.marker
self.physicsBody?.collisionBitMask = 0
self.physicsBody?.allowsRotation = false
self.physicsBody?.angularDamping = 0
self.physicsBody?.isDynamic = true
}
}
GameScene:
class GameScene: SKScene, SKPhysicsContactDelegate {
var lastTouch: CGPoint? = nil
var world = SKNode()
var cam = SKCameraNode()
var player = Skier()
let playerDefaultYInset : CGFloat = 350
var sceneVelocity = CGVector(dx: 0, dy: -170)
var zPositionCounter: CGFloat = 0
override func didMove(to view: SKView) {
//Set up the scene
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
backgroundColor = SKColor.white
//Add top-level world node to the scene
self.addChild(world)
self.physicsWorld.contactDelegate = self
//Add player to scene
spawnPlayer()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in: self) {
lastTouch = location
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in: self) {
lastTouch = location
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
lastTouch = nil
}
override func update(_ currentTime: TimeInterval) {
// Only add an impulse if there's a lastTouch stored
if let touch = lastTouch {
let impulseVector = CGVector(dx: touch.x - player.position.x, dy: 0)
// If myShip starts moving too fast or too slow, you can multiply impulseVector by a constant or clamp its range
player.physicsBody?.applyImpulse(impulseVector)
}
}
func spawnPlayer() {
player.position = CGPoint(x: 0, y: (-self.frame.height / 2) + playerDefaultYInset)
player.zPosition = CGFloat(Int.min)
world.addChild(player)
}
}
我發現自己在做什么錯。 當我為“滑雪者”課程設置物理身體時,我為該物理身體分配了以下可選內容:
self.physicsBody? = SKPhysicsBody(rectangleOf: size)
因此實際上並未將物理主體分配給該子畫面。 我將其更改為:
self.physicsBody = SKPhysicsBody(rectangleOf: playerSize)
現在它可以完美運行了。 話雖這么說,對於任何其他嘗試通過手指拖動精靈在場景中移動來達到類似效果的人,我最終都提出了一個簡單得多的解決方案。 我的touchesMoved方法中有以下內容:
let touch = touches.first
if let location = touch?.location(in: self) {
let prev = touch?.previousLocation(in: self)
let impulse = CGVector(dx: 0.02 * (location.x - (prev?.x)!), dy: 0)
player.physicsBody?.applyImpulse(impulse)
}
它的工作原理完全不必擔心更新,touchesBegan或touchesEnded方法。 變得越來越簡單。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.