gpt4 book ai didi

ios - SpriteKit applyImpulse 不影响 Sprite

转载 作者:行者123 更新时间:2023-11-28 07:30:47 25 4
gpt4 key购买 nike

我有一个 Skier 类型的播放器节点,我想通过触摸和拖动围绕 x 轴移动,类似于 this tutorial .我将我的播放器节点添加到场景中,它有一个 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
}
}

游戏场景:

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)
}
}

最佳答案

我发现我做错了什么。当我为 Skier 类设置我的物理体时,我像这样分配了一个可选的物理体:

self.physicsBody? = SKPhysicsBody(rectangleOf: size)

所以物理体实际上并没有分配给 sprite。我通过将其更改为此来修复它:

self.physicsBody = SKPhysicsBody(rectangleOf: playerSize)

现在它完美运行了。话虽这么说,对于任何其他试图通过手指拖动在场景中移动 Sprite 来实现类似效果的人来说,我最终想出了一个更简单的解决方案。我的 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 方法。更简单、更容易。

关于ios - SpriteKit applyImpulse 不影响 Sprite ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54780380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com