我正在努力制作类似马里奥兄弟或陷阱的SpriteKit游戏。在这个游戏中,有动物园饲养员在水平方向上来回移动,即沿着x坐标轴。动物园管理员走在被称为平台节点的基地上。当动物园管理员与他们前面的平台碰撞时,例如箱子或动物园笼子,动物园饲养员转向并走另一条路。预计动物园饲养员将在地面上移动。游戏使用内置的物理属性。动物园管理员的赔偿金为1.0。我以一种小冲动开始动物园管理员。在更新功能中,我在y方向上将速度设置为零,并将x速度设置为当前动物园饲养员x速度,使得动物园饲养员不会在y方向上反弹并继续以任何x速度/方向进行移动。我将y速度设置为零,这样如果动物园饲养员走出更高级别的平台,我不希望它们在y方向上反弹。动物园饲养员在他的每日轮次中开始并向右移动穿过8个地面平台单元,从箱子上弹起,转身并开始向另一个方向行走。虽然在返回途中经过3个地面平台单元后,动物园管理员意外地与他之前已经走过并转过身的地面平台相撞。每次我在xCode中重新运行游戏时,碰撞可能发生在不同的地方,虽然一旦运行,碰撞一直发生在同一个地方。如果我给动物园管理员更多的初始冲动,问题就会消失,尽管我的动物园管理员移动的速度太快了。地面节点的大小都相同,并且在相同的y位置放置一个for循环。下面是一个动物园管理员(CharacterNode)步行(接触)在转向并接触地面节点(PlatformNode)之前将节点移动(接触)的示例,该地面节点将节点转动,但不应该。
走过的节点(之前):
打印contact._bodyA的说明: type:representObject:[name:'Platform'position:{974.613037109375,24.98663330078125} scale:{1.00,1.00} accumulationFrame:{{962.11297607421875,12.487000465393066},{25,25}}] 打印contact._bodyB的说明: type:representObject:[name:'ZooKeeper'position:{1000.2339477539062,62.757087707519531} scale:{1.00,1.00} accumulationFrame:{{987.7340087890625,37.756999969482422},{25,50}}]
导致意外阻止的地面节点:
打印contact._bodyA的说明: type:representObject:[name:'Platform'position:{774.5714111328125,24.986606597900391} scale:{1.00,1.00} accumulationFrame:{{762.07098388671875,12.487000465393066},{25,25}}] 打印contact._bodyB的说明: type:representObject:[name:'ZooKeeper'position:{749.27301025390625,62.757034301757812} scale:{1.00,1.00} accumulationFrame:{{736.77301025390625,37.756999969482422},{25,50}}]
以下是我认为相关的代码。我通过从excel文件中读取整数x,y坐标的文件来创建平台和动物园饲养员,缩放对象并使用skspritenodes将它们放置在sknodes中。平台的“模式”可以是1个地块,2个,3个,10个,阶梯图案等。地面图案是10个连续的框。所有平台的大小完全相同(25x25)。虽然如果您查看打印说明,但精度似乎略有偏差。
平台逻辑:地面节点的模式是一组10个并排放置的单个地面单元,即相同的y坐标,在x方向上间隔1个单位。
let kScenePositionScale: CGFloat = 25 // scale all scene positions read from a file by this factor
let kPlatformSizeScale:CGFloat = 0.5
let kCharacterSizeScale:CGFloat = 0.25
for platform in platformArray {
for patternItem in platform.pattern.patternItemArray {
let positionX = platform.xCoordinate + patternItem.xCoordinate
let positionY = platform.yCoordinate + patternItem.yCoordinate
let platformNode = SceneObject.createPlatformAtPosition(CGPoint(x: positionX, y: positionY), ofType: PlatformType(rawValue: patternItem.imageName)!)
foregroundNode.addChild(platformNode)
}
}
class func createPlatformAtPosition(position: CGPoint, ofType type: PlatformType) -> PlatformNode {
let node = PlatformNode()
node.position = position
node.name = kPlatformNodeName
node.platformType = type
var sprite: SKSpriteNode
sprite = SKSpriteNode(imageNamed: type.rawValue)
sprite.setScale(kPlatformSizeScale)
node.addChild(sprite)
node.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.size)
node.physicsBody?.dynamic = false
node.physicsBody?.categoryBitMask = PhysicsCategoryBitmask.Platform
node.physicsBody?.collisionBitMask = 0
return node
}
Zoo Keeper:我只使用接触位掩码来打印导致意外转身功能的触点。对于动物园饲养员来说,这种模式在这一点上是无关紧要的。模式为0,0
// for each item in the character array
for character in characterArray {
for patternItem in character.pattern.patternItemArray {
let positionX = character.xCoordinate + patternItem.xCoordinate
let positionY = character.yCoordinate + patternItem.yCoordinate
let characterNode = Character.createCharacterAtPosition(CGPoint(x: positionX, y: positionY), ofType: CharacterType(rawValue: patternItem.imageName)!, ofMotionType: character.motionType)
foregroundNode.addChild(characterNode)
characterNode.physicsBody?.applyImpulse(CGVectorMake(1.0, 0.0))
}
}
class func createCharacterAtPosition(position: CGPoint, ofType type: CharacterType, ofMotionType motionType: CharacterMotionType) -> CharacterNode {
let node = CharacterNode()
node.position = position
node.name = type.rawValue // named after the character type
node.characterMotionType = motionType
node.textureArray = loadPrimaryAtlas(type.rawValue)
var sprite: SKSpriteNode
sprite = SKSpriteNode(texture: node.textureArray[0])
// anchor at the feet
sprite.setScale(kCharacterSizeScale)
node.sprite = sprite
node.addChild(sprite)
node.physicsBody = SKPhysicsBody(rectangleOfSize: sprite.frame.size)
node.physicsBody?.dynamic = true
node.physicsBody?.allowsRotation = false
node.physicsBody?.restitution = 1.0 // bounciness
node.physicsBody?.friction = 0.0 // keep the character moving if needed
node.physicsBody?.angularDamping = 0.0
node.physicsBody?.linearDamping = 0.0
node.physicsBody?.categoryBitMask = PhysicsCategoryBitmask.Character
node.physicsBody?.collisionBitMask = PhysicsCategoryBitmask.Platform //Collision will occur when hero hits land
node.physicsBody?.contactTestBitMask = PhysicsCategoryBitmask.Platform //Contact will be detected when make a contact with land and fruit
return node
}