函数仅适用于第一个生成的精灵,而不适用于另一个

Posted

技术标签:

【中文标题】函数仅适用于第一个生成的精灵,而不适用于另一个【英文标题】:Function only works on the first spawned sprite and not the other 【发布时间】:2016-04-04 22:57:30 【问题描述】:

我是编程新手,但仍在学习很多东西。我刚刚遇到了一个问题。我遇到问题的部分是 SharkWall() 函数,它使“SHARKNODE”-sprite 以各种方式到达屏幕末端时转身并朝相反的方向前进。 “鲨鱼节点”每 0.75 秒产生一次,在 Y 方向上有一个计时器。这就是问题所在。 SharkWall() 函数似乎只在第一个生成的“SHARKNODE”-sprite 上工作,而不是在 Y 轴上更高处生成的其他精灵上工作。值得一提的是,第一个生成的精灵是唯一在屏幕上可见的精灵,直到玩家在 Y 轴上的位置更高,并且其他“SHARKNODE”精灵出现在屏幕上。当然,我想要的是让 SharkWall() 函数适用于所有“SHARKNODE”精灵。 任何对在这里做什么有想法并可以解释的人?提前致谢。

GameScene.swift:

class GameScene: SKScene, SKPhysicsContactDelegate 


var background:SKNode!
var midground:SKNode!
var foreground:SKNode!

var buttonPressed = 0

 var leftButtonFirst: UIButton!
 var rightButtonFirst: UIButton!

var hud: SKNode!
var scaleX = 0
var sharkSprite = SKSpriteNode()

var counter = 1
var player: SKNode!

var scaleFactor:CGFloat!

var startButton = SKSpriteNode(imageNamed: "TapToStart")

var endOfGamePosition = 0

let montionManager = CMMotionManager()

var xAcceleration:CGFloat = 1

var scoreLabel: SKLabelNode!
var flowerLabel: SKLabelNode!

var playersMaxY:Int!

var GameOver = false

required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)

    

override init(size: CGSize)
    super.init(size: size)

    backgroundColor =  UIColor(red: (57/255.0), green: (214/255.0), blue: (255/255.0), alpha: 1.0)

    scaleFactor = self.size.width / 200


    background = createBackground()
    addChild(background)

    midground = createMidground()
    addChild(midground)

    foreground = SKNode()
    addChild(foreground)

    player = createPlayer()
    foreground.addChild(player)



    var bubbleTimer = NSTimer.scheduledTimerWithTimeInterval(0.75, target: self, selector: #selector(GameScene.bubbleMaker), userInfo: nil, repeats: true)

    var sharkTimer = NSTimer.scheduledTimerWithTimeInterval(0.75, target: self, selector: #selector(GameScene.sharkMaker), userInfo: nil, repeats: true)


    physicsWorld.gravity = CGVector(dx: 0, dy: -3)
    physicsWorld.contactDelegate = self

   



func bubbleMaker() 
    let randomXPos = arc4random_uniform(172) + 15
    let yPosition = CGRectGetMidY(self.frame) + 200 * CGFloat(counter)
    counter += 1
    let platformNode = createPlatformAtPosition(CGPoint(x: CGFloat(randomXPos), y: yPosition - 180), ofType: PlatformType.normalBubble)
    foreground.addChild(platformNode)





func sharkMaker() 
let randomXPos = arc4random_uniform(170) + 10
let yPosition = CGRectGetMidY(self.frame) + 200 * CGFloat(counter)
counter += 1
let shark = createSharkAtPosition(CGPoint(x: CGFloat(randomXPos), y: yPosition - 180), ofType: SharkType.normalShark)
foreground.addChild(shark)




override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) 

    if player.physicsBody!.dynamic 
        return
    

    player.physicsBody?.dynamic = true
    player.physicsBody?.velocity.dy = CGFloat(500)
    createLeftButton()
    createRightButton()

    createLeftButtonFirst()
    createRightButtonFirst()



override func didSimulatePhysics() 

    if player.position.x < -10 
        player.physicsBody?.applyImpulse(CGVectorMake(3, 0))
    else if (player.position.x > self.size.width + 10) 
          player.physicsBody?.applyImpulse(CGVectorMake(-3, 0))
    
    sharkWall()



func didBeginContact(contact: SKPhysicsContact) 
    var otherNode:SKNode!

    if contact.bodyA.node != player 
        otherNode = contact.bodyA.node
     else 
        otherNode = contact.bodyB.node
    

    (otherNode as! GenericNode).collisionWithPlayer(player)



override func update(currentTime: CFTimeInterval) 





    foreground.enumerateChildNodesWithName("PLATFORMNODE") (node, stop) -> Void in
        let platform = node as! PlatformNode
        platform.shoudRemoveNode(self.player.position.y)
    

    if player.position.y > 200 
        background.position = CGPoint(x: 0, y: -((player.position.y - 200)/10))
        midground.position = CGPoint(x: 0, y: -((player.position.y - 200)/4))
        foreground.position = CGPoint(x: 0, y: -((player.position.y) - 200))
    



func sharkWall()
if foreground.childNodeWithName("SHARKNODE")?.position.x < -10 
        foreground.childNodeWithName("SHARKNODE")?.xScale =  -1
        foreground.childNodeWithName("SHARKNODE")?.physicsBody?.velocity.dx = CGFloat(50)
    else if (foreground.childNodeWithName("SHARKNODE")?.position.x > self.size.width + 10) 
            foreground.childNodeWithName("SHARKNODE")?.xScale = 1
            foreground.childNodeWithName("SHARKNODE")?.physicsBody?.velocity.dx = CGFloat(-50)
    




func createLeftButton () 
    let button = UIButton();
    button.frame = CGRectMake(self.frame.width - self.frame.width, 0, self.frame.width / 2, self.frame.height) // X, Y, width, height

    button.addTarget(self, action: #selector(GameScene.buttonPressedRight(_:)), forControlEvents: .TouchUpInside)
    self.view!.addSubview(button)
    button.layer.zPosition = -1



func createRightButton () 

    let buttonRight = UIButton();

    buttonRight.frame = CGRectMake(self.frame.width / 2, 0, self.frame.width / 2, self.frame.height) // X, Y, width, height

    buttonRight.addTarget(self, action: #selector(GameScene.buttonPressedLeft(_:)), forControlEvents: .TouchUpInside)
    self.view!.addSubview(buttonRight)
    buttonRight.layer.zPosition = -1


func createLeftButtonFirst () 
    leftButtonFirst = UIButton()
    leftButtonFirst.frame = CGRectMake(self.frame.width - self.frame.width, 0, self.frame.width / 2, self.frame.height) // X, Y, width, height

    leftButtonFirst.addTarget(self, action: #selector(GameScene.buttonPressedLeftFirst(_:)), forControlEvents: .TouchUpInside)
    self.view!.addSubview(leftButtonFirst)
    leftButtonFirst.layer.zPosition = 1


func createRightButtonFirst () 

    rightButtonFirst = UIButton()
    rightButtonFirst.frame = CGRectMake(self.frame.width / 2, 0, self.frame.width / 2, self.frame.height) // X, Y, width, height
    rightButtonFirst.addTarget(self, action: #selector(GameScene.buttonPressedRightFirst(_:)), forControlEvents: UIControlEvents.TouchUpInside)
    self.view!.addSubview(rightButtonFirst)
    rightButtonFirst.userInteractionEnabled = true
    rightButtonFirst.layer.zPosition = 1




func buttonPressedRight(sender: UIButton!) 

    if player.physicsBody?.velocity.dx > 0 
       player.physicsBody?.velocity = CGVector(dx: -200, dy:  player.physicsBody!.velocity.dy)
 

    player.xScale = -1

func buttonPressedLeft(sender: UIButton!) 
    if player.physicsBody?.velocity.dx < 0 
        player.physicsBody?.velocity = CGVector(dx: 200, dy:  player.physicsBody!.velocity.dy)
    
    player.xScale = 1


func buttonPressedLeftFirst(sender: UIButton!) 
    player.physicsBody?.velocity = CGVector(dx: -200, dy:  player.physicsBody!.velocity.dy)

    player.xScale = -1

    rightButtonFirst.hidden = true
    leftButtonFirst.hidden = true


func buttonPressedRightFirst(sender: UIButton!) 
    player.physicsBody?.velocity = CGVector(dx: 200, dy:  player.physicsBody!.velocity.dy)
    player.xScale = 1

    rightButtonFirst.hidden = true
    leftButtonFirst.hidden = true


GameElements.swift:

 import SpriteKit

 extension GameScene 


func createBackground() -> SKNode
    let backgroundNode = SKNode()
    let spacing = 32 * scaleFactor

    for index in 0 ... 20 

        let node = SKSpriteNode(imageNamed: String(format: "Background/Background%02d", index + 1))
        node.setScale(scaleFactor)
        node.anchorPoint = CGPoint(x: 0.5, y: 0)
        node.position = CGPoint(x: self.size.width / 2, y:spacing * CGFloat(index))
        node.size.width = self.frame.width

        backgroundNode.addChild(node)
    

    return backgroundNode



func createMidground () -> SKNode

let midgroundNode = SKNode()
var anchor: CGPoint!
var xPos: CGFloat!

for index in 0 ... 250 
    var name: String

    let randomNumber = arc4random() % 2

    if randomNumber > 0 
        name = "whale"
        anchor = CGPoint(x: 0, y: 0.5)
        xPos = CGFloat(arc4random_uniform(170) + 15)
     else
        name = "whale"
        anchor = CGPoint(x: 1, y: 0.5)
        xPos = CGFloat(arc4random_uniform(170) + 15)
    
    let cloudNode = SKSpriteNode(imageNamed: name)
    cloudNode.alpha = 0.3
    cloudNode.anchorPoint = anchor
    cloudNode.position = CGPoint(x: xPos, y: 500 + 500 * CGFloat(index))
    midgroundNode.addChild(cloudNode)


    return midgroundNode



func createPlayer() -> SKNode 

let playerNode = SKNode()
    playerNode.position = CGPoint(x: self.size.width / 2, y: 80)

    let sprite = SKSpriteNode(imageNamed: "Player")
    playerNode.addChild(sprite)

    playerNode.physicsBody = SKPhysicsBody(circleOfRadius: sprite.size.width / 2)

    playerNode.physicsBody?.dynamic = false
    playerNode.physicsBody?.allowsRotation = false

    playerNode.physicsBody?.restitution = 1
    playerNode.physicsBody?.friction = 0
    playerNode.physicsBody?.angularDamping = 0
    playerNode.physicsBody?.linearDamping = 0

    playerNode.physicsBody?.usesPreciseCollisionDetection = true

    playerNode.physicsBody?.categoryBitMask = CollisionBitMask.Player

    playerNode.physicsBody?.collisionBitMask = 0
    playerNode.physicsBody?.contactTestBitMask = CollisionBitMask.Bubble | CollisionBitMask.Shark

    return playerNode





func createSharkAtPosition (position:CGPoint, ofType type:SharkType) -> SharkNode 

    let shark = SharkNode()
    let position = CGPoint(x: position.x * scaleFactor, y: position.y)
    shark.position = position
    shark.name = "SHARKNODE"
    shark.sharkType = type

    let spriteTexture1 = SKTexture(imageNamed: "shark1")
    let spriteTexture2 = SKTexture(imageNamed: "shark2")
    let spriteTexture3 = SKTexture(imageNamed: "shark3")

    let sharkAnimation = SKAction.animateWithTextures([spriteTexture1, spriteTexture2, spriteTexture3], timePerFrame: 0.2)
    let makeSharkFlap = SKAction.repeatActionForever(sharkAnimation)

    sharkSprite = SKSpriteNode(texture: spriteTexture1)
    sharkSprite.runAction(makeSharkFlap)
    shark.addChild(sharkSprite)


    shark.physicsBody = SKPhysicsBody(rectangleOfSize: sharkSprite.size)
    shark.physicsBody?.dynamic = true
    shark.physicsBody?.affectedByGravity = false
    shark.physicsBody?.categoryBitMask = CollisionBitMask.Shark
    shark.physicsBody?.collisionBitMask = 0
    shark.physicsBody?.velocity = CGVectorMake(-60, 0)

    return shark




func createPlatformAtPosition (position:CGPoint, ofType type:PlatformType) -> PlatformNode 

    let node = PlatformNode()
    let position = CGPoint(x: position.x * scaleFactor, y: position.y)
    node.position = position
    node.name = "PLATFORMNODE"
    node.platformType = type
    var sprite:SKSpriteNode

    sprite = SKSpriteNode(imageNamed: "bubble")

    node.addChild(sprite)

    node.physicsBody = SKPhysicsBody(circleOfRadius: sprite.size.height / 2)
    node.physicsBody?.dynamic = false
    node.physicsBody?.categoryBitMask = CollisionBitMask.Bubble
    node.physicsBody?.collisionBitMask = 0

    return node

【问题讨论】:

有人知道如何解决这个问题吗? 【参考方案1】:

childNodeWithName只调用第一个有名字的子节点,需要全部枚举出来

func sharkWall()
    foreground.enumerateChildNodesWithName("SHARKNODE")
        node, stop in 
        if node.position.x < -10 
            node.xScale =  -1
            node.physicsBody?.velocity.dx = CGFloat(50)
        else if (node.position.x > self.size.width + 10) 
            node.xScale = 1
            node.physicsBody?.velocity.dx = CGFloat(-50)
        
    

【讨论】:

以上是关于函数仅适用于第一个生成的精灵,而不适用于另一个的主要内容,如果未能解决你的问题,请参考以下文章

uitableview didselectrowatindex 仅适用于第一个表视图而不适用于同一视图控制器中的第二个表视图?

我的 foreach 仅适用于第一个实例 [重复]

Ajax 调用仅适用于表的第一行,不适用于下一行

MySQL - WHERE 子句中的 NOT IN 查询具有相同的结构,适用于第一个表但不适用于第二个表

变异只适用于第一列的值

JQuery.Dirty 字段不适用于第一个“updateFormState”,但适用于第二个