我正在做一个游戏,你必须使用一个线程悬挂的蜘蛛捕捉糖果,正如我在这个链接中所示:Game screenshot(我是新来的,所以我还不能发布图像) 。我已经从左到右进行了蜘蛛的运动,并且我能够使用SKAction通过'Y'来捕捉糖果,我唯一的问题是我没弄明白但是如何知道蜘蛛是不是' t捕获任何糖果,在他的运动过程中,我尝试在动作完成时使用allContactedBodies函数,但返回的数组的计数始终为零。有什么建议吗?
以下是代码:
class GameScene: SKScene, SKPhysicsContactDelegate {
private var rope = SKSpriteNode(imageNamed: "rope")
private var anchor = SKSpriteNode(imageNamed: "anchor")
private var currentCharacter: SKSpriteNode!
private var candy: SKSpriteNode!
var direction : String = "backward"
var lastCandyAdded: TimeInterval = 0
let candyVelocity: CGFloat = 4.0
let characterBitMask : UInt32 = 0x1 << 1
let candyBitMask: UInt32 = 0x1 << 2
let characterVelocity: CGFloat = 18.0
var direction : String = "backward"
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
self.addAnchor()
self.addRope()
self.addCharacter()
let jointOneFixed = SKPhysicsJointFixed.joint(withBodyA: anchor.physicsBody!, bodyB: rope.physicsBody!, anchor: anchor.position)
self.physicsWorld.add(jointOneFixed);
let jointTwoFixed = SKPhysicsJointFixed.joint(withBodyA: rope.physicsBody!, bodyB: currentCharacter.physicsBody!, anchor: currentCharacter.position)
self.physicsWorld.add(jointTwoFixed);
}
func addAnchor(){
anchor.position = CGPoint(x: self.size.width / 2, y: self.size.height + 1)
anchor.anchorPoint = CGPoint(x: 0.5, y: 0.5)
anchor.setScale(1)
anchor.zPosition = 2
anchor.name = "anchor"
anchor.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: anchor.size.width, height: anchor.size.height))
anchor.physicsBody?.affectedByGravity = false
anchor.physicsBody?.friction = 0;
anchor.physicsBody?.linearDamping = 0;
anchor.physicsBody?.mass = 10;
self.addChild(anchor)
}
func addCharacter() {
let characterName: String = UserDefaults.standard.string(forKey: "current_character")!
currentCharacter = SKSpriteNode(imageNamed: characterName);
currentCharacter.position = CGPoint(x: self.size.width / 2, y: self.size.height - 400)
currentCharacter.anchorPoint = CGPoint(x: 0.5, y: 0.5)
currentCharacter.setScale(0.43)
currentCharacter.zPosition = 2
currentCharacter.name = "character"
currentCharacter.physicsBody = SKPhysicsBody(rectangleOf: currentCharacter.size)
currentCharacter.physicsBody?.categoryBitMask = characterBitMask
currentCharacter.physicsBody?.contactTestBitMask = candyBitMask
currentCharacter.physicsBody?.collisionBitMask = candyBitMask;
currentCharacter.physicsBody?.affectedByGravity = false;
currentCharacter.physicsBody?.friction = 0;
currentCharacter.physicsBody?.linearDamping = 0;
currentCharacter.physicsBody?.mass = 20;
self.addChild(currentCharacter)
}
func addRope() {
rope.position = CGPoint(x: anchor.position.x, y: anchor.position.y - 70)
rope.setScale(0.65)
rope.zPosition = 1
rope.name = "rope"
rope.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: rope.size.width, height: rope.size.height))
rope.physicsBody?.affectedByGravity = false;
rope.physicsBody?.friction = 0;
rope.physicsBody?.linearDamping = 0;
rope.physicsBody?.mass = 5;
rope.physicsBody?.allowsRotation = false
self.addChild(rope)
}
func addCandy() {
let number = Int.random(min: 1, max: 24)
let candyWord = "candie"
let candyTexture = SKTexture(imageNamed: "\(candyWord)\(number)")
candy = SKSpriteNode(texture: candyTexture)
candy.zPosition = 3
candy.setScale(0.40)
candy.physicsBody = SKPhysicsBody(circleOfRadius: max(candy.size.width / 2, candy.size.height / 2))
candy.physicsBody?.isDynamic = true
candy.name = "candy"
candy.physicsBody?.categoryBitMask = candyBitMask
candy.physicsBody?.contactTestBitMask = characterBitMask
candy.physicsBody?.collisionBitMask = characterBitMask
candy.physicsBody?.affectedByGravity = false
candy.position = CGPoint(x: self.frame.size.width + 20, y: self.frame.size.height / 2 + 150)
self.addChild(candy)
}
func moveCandy() {
self.enumerateChildNodes(withName: "candy", using: {(node, stop) -> Void in
if let candy = node as? SKSpriteNode {
candy.position = CGPoint(x: candy.position.x - self.candyVelocity, y: candy.position.y)
if candy.position.x < 0 {
candy.removeFromParent()
}
}
})
}
override func update(_ currentTime: TimeInterval) {
self.moveCandy()
self.moveCharacter()
if currentTime - self.lastCandyAdded > 0.75 {
self.lastCandyAdded = currentTime + Double.random(min: 0.00, max: 0.60)
self.addCandy()
}
}
func collisionBetween(candy: SKNode, object: SKNode) {
let moveUp = SKAction.moveBy(x: 0, y: 100, duration:0.0)
let shrinkRope = SKAction.animate(with: [SKTexture(imageNamed: "rope")], timePerFrame: 0)
let moveUpBlock = SKAction.run({
self.anchor.run(moveUp)
})
let shrinkRopeBlock = SKAction.run({
self.rope.run(shrinkRope)
})
let sequence = SKAction.sequence([SKAction.wait(forDuration: 0.07), shrinkRopeBlock, moveUpBlock])
self.run(sequence)
candy.removeFromParent()
}
func didBegin(_ contact: SKPhysicsContact) {
guard let nodeA = contact.bodyA.node else { return }
guard let nodeB = contact.bodyB.node else { return }
if nodeA.name == "candy" && nodeB.name == "character" {
collisionBetween(candy: nodeA, object: nodeB)
} else if nodeA.name == "character" && nodeB.name == "candy" {
collisionBetween(candy: nodeB, object: nodeA)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
let moveDown = SKAction.moveBy(x: 0, y: -100, duration:0.0)
let stretchRope = SKAction.animate(with: [SKTexture(imageNamed: "rope_stretch")], timePerFrame: 0)
let moveDownBlock = SKAction.run({
self.anchor.run(moveDown, completion: {
var physicBodies = self.currentCharacter.physicsBody?.allContactedBodies();
// This count is always zero
print(physicBodies?.count)
})
})
let stretchRopeBlock = SKAction.run({
self.rope.run(stretchRope)
})
let sequence = SKAction.sequence([moveDownBlock, stretchRopeBlock])
self.run(sequence)
}
func moveCharacter(){
self.enumerateChildNodes(withName: "anchor", using: {(node, stop) -> Void in
if let anchorNode = node as? SKSpriteNode {
if anchorNode.position.x < 120 {
anchorNode.position = CGPoint(x: anchorNode.position.x + self.characterVelocity, y: anchorNode.position.y)
self.direction = "forward"
} else if anchorNode.position.x > self.size.width - 120 {
anchorNode.position = CGPoint(x: anchorNode.position.x - self.characterVelocity, y: anchorNode.position.y)
self.direction = "backward"
} else if self.direction == "forward" {
anchorNode.position = CGPoint(x: anchorNode.position.x + self.characterVelocity, y: anchorNode.position.y)
self.direction = "forward"
} else {
anchorNode.position = CGPoint(x: anchorNode.position.x - self.characterVelocity, y: anchorNode.position.y)
self.direction = "backward"
}
}
})
}
}
答案 0 :(得分:0)
首先,你在这个问题上有很多代码......太多了,这使得很难专注于真正发生的事情。您还缺少moveCharacter()的代码块。
你应该强烈考虑为你的玩家,绳子和(大多数)糖果创建子类。我还会考虑最初创建一个糖果数组,这样你就不会在运行时动态创建物理对象。
至于你的问题,不如在你的班级中创建几个变量那么简单
private var isMoving = false
private var didGetCandy = false
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//prevent the user from firing the move while in the middle of a move
guard !isMoving else { return }
isMoving = true
let moveDownBlock = SKAction.run({
self.anchor.run(moveDown) {
//this is an appreviated form of a 'completion' block
self.isMoving = false
print("did I get a candy \(didGetCandy)")
}
})
}
func collisionBetween(candy: SKNode, object: SKNode) {
didGetCandy = true
}