如何防止 Sprite 节点相互推挤?
Posted
技术标签:
【中文标题】如何防止 Sprite 节点相互推挤?【英文标题】:How to prevent Sprite Nodes from pushing each other? 【发布时间】:2019-03-02 14:51:17 【问题描述】:3 个 Sprite 节点以不同的速度级别向上移动。你看到大猩猩喜欢休息,但龙虾却在慢慢向上推。预期的行为是,当大猩猩再次开始移动时,龙虾也会休息并继续向上移动。使用 .isDynamic = false 不起作用 - Sprite 节点正在覆盖,并且 lobster 完全忽略了刺猬和大猩猩的身体。
我的游乐场场景录制:https://youtu.be/l47kaJiJvkM
视频截图:
代码:
import SpriteKit
public class WalkingScene: SKScene
public override func didMove(to view: SKView)
backgroundColor = .white
view.showsPhysics = true
let hedgehog = SKSpriteNode(imageNamed: "hedgehog")
hedgehog.size = CGSize(width: 64, height: 64)
hedgehog.position = CGPoint(x: size.width/2, y: 400)
hedgehog.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 80, height: 80))
hedgehog.physicsBody?.affectedByGravity = false
hedgehog.physicsBody?.allowsRotation = false
let gorilla = SKSpriteNode(imageNamed: "gorilla")
gorilla.size = CGSize(width: 64, height: 64)
gorilla.position = CGPoint(x: size.width/2, y: 140)
gorilla.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 80, height: 80))
gorilla.physicsBody?.affectedByGravity = false
gorilla.physicsBody?.allowsRotation = false
let lobster = SKSpriteNode(imageNamed: "lobster")
lobster.size = CGSize(width: 64, height: 64)
lobster.position = CGPoint(x: size.width/2, y: 20)
lobster.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 80, height: 80))
lobster.physicsBody?.affectedByGravity = false
lobster.physicsBody?.allowsRotation = false
// hedgehog.physicsBody?.isDynamic = false
// gorilla.physicsBody?.isDynamic = false
// lobster.physicsBody?.isDynamic = false
// hedgehog.physicsBody?.usesPreciseCollisionDetection = true
// hedgehog.physicsBody?.collisionBitMask = 0
// gorilla.physicsBody?.usesPreciseCollisionDetection = true
// gorilla.physicsBody?.collisionBitMask = 0
// lobster.physicsBody?.usesPreciseCollisionDetection = true
// lobster.physicsBody?.collisionBitMask = 0
self.addChild(lobster)
self.addChild(hedgehog)
self.addChild(gorilla)
self.moveGorilla(gorilla)
self.moveLobster(lobster)
self.moveHedgeHog(hedgehog)
func moveGorilla(_ passenger: SKSpriteNode)
let moveLeft = CGVector(dx: 0, dy: 200)
let aYYY = CGVector(dx: 200, dy: 0)
let moving = SKAction.move(by: moveLeft, duration: 1)
let turnAYY = SKAction.move(by: aYYY, duration: 1)
let chill = SKAction.wait(forDuration: 3)
passenger.run(SKAction.sequence([moving, chill, moving, chill, turnAYY]))
print("Gorilla arrived")
func moveLobster(_ passenger: SKSpriteNode)
let moveLeft = CGVector(dx: 0, dy: 200)
let moving = SKAction.move(by: moveLeft, duration: 1.2)
passenger.run(SKAction.sequence([moving, moving, moving, moving, moving, moving, moving, moving, moving]))
print("Lobster arrived")
func moveHedgeHog(_ passenger: SKSpriteNode)
let moveLeft = CGVector(dx: 0, dy: 200)
let moving = SKAction.move(by: moveLeft, duration: 1)
let chill = SKAction.wait(forDuration: 2)
passenger.run(SKAction.sequence([chill, moving, moving, moving]))
print("Hedgehog arrived")
【问题讨论】:
它们是否设置为运动学?我对isDynamic
设置感到困惑,因为物理体可以是以下三种类型之一:静态、动态或运动。
它的 SpriteKit,不是 SceneKit
SpriteKit 没有运动学物理体?
【参考方案1】:
您可以这样设置这些动态:
hedgehog.physicsBody?.isDynamic = true
gorilla.physicsBody?.isDynamic = false
lobster.physicsBody?.isDynamic = true
通过这种策略,您可以将此示例扩展到其他情况。
如果isDynamic = true
被视为0,而isDynamic = false
,即static
,被视为无穷大,
有一些东西可以通过物理物体的质量来控制。
hedgehog.physicsBody?.isDynamic = false. (mass = Infinity)
gorilla.physicsBody?.isDynamic = true. (mass = big)
lobster.physicsBody?.isDynamic = true (mass = 0)
gorilla.physicsBody?.mass = 1000
【讨论】:
但是,大猩猩正在推刺猬。如果我将它们设置为 false/false/true,那么刺猬和大猩猩就会重叠。如果我将它们设置为 false/false/false,龙虾将忽略所有(如上所述) 好的,谢谢你成功了!问题是,如果每个节点都设置为 .isDynamic = false,为什么它不起作用?是不是因为一个拥有无限质量的节点可以推另一个拥有邀请质量的节点? 是的,如果 dynamic 是 true ,因为三个对象具有相同的默认质量,1.0 并且模拟器只是随机化优先级,这可能会导致一些不需要的行为。如果动态为假,模拟器将忽略物理行为并可能产生其他意想不到的结果。 那么如果我想在队列中添加另一个节点,质量应该低于前一个节点? 是的。它是从上到下递减的。也许每个文件夹之间有大约 10 个文件夹。以上是关于如何防止 Sprite 节点相互推挤?的主要内容,如果未能解决你的问题,请参考以下文章