所有设备左上角的分数标签

时间:2015-12-18 02:58:12

标签: ios swift sprite-kit label

我是编程新手,最近我做了一个我在网上找到的教程,制作了一个无尽的蛙游戏。教程人员没有告诉我如何做分数标签,我已经无休止地尝试找到一个视频教程,它将告诉我如何在左上角放置一个分数标签。我尝试过使用此代码:

label.horizontalAlignmentMode = .Left
label.position = CGPoint(x:0.0, y:self.size.height)

但我没有运气,它没有出现在左上角。所以我尝试了另一种方法让它定位在角落里,我玩弄了这些值,最后得到了这个

scoreLabel.position = CGPointMake(frame.size.width / -2.231, frame.size.height / 2.29)

将它完美地定位在模拟器屏幕的角落,但不是所有设备。我有一个单独的swift文件,我的分数标签就在这里:

导入基金会 导入SpriteKit 导入UIKit

class Score: SKLabelNode {

var number = 0

init (num: Int) {

    super.init()

    fontColor = UIColor.whiteColor()
    fontName = "Helvetica"
    fontSize = 150.0

    number = num
    text = "\(num)"

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func addOneToScore() {

    number++
    text = "\(number)"
   }
}

我有一个世界节点,里面有一个播放器,摄像机位置集中在播放器上。我已经提供了我的游戏场景课程供您查看。我想要的是能够在屏幕的左上角或右上角为所有设备定位分数标签。

import SpriteKit


enum BodyType:UInt32 {

case player = 1
case roadObject = 2
case waterObject = 4
case water = 8
case road = 16


}

enum LevelType:UInt32 {

case road, water

}


class GameScene: SKScene, SKPhysicsContactDelegate {

//recongises swipe and tap gestures
let TapUpRec = UITapGestureRecognizer()

let swipeRightRec = UISwipeGestureRecognizer()
let swipeLeftRec = UISwipeGestureRecognizer()
let swipeDownRec = UISwipeGestureRecognizer()

//defines the attributes for level units.
var levelUnitCounter:CGFloat = 1    // Not sure, i think it starts the frog further up.
var levelUnitWidth:CGFloat = 0      //will be screenwidth
var levelUnitHeight:CGFloat = 50    // changes the height of the level units
var initialUnits:Int = 10           // tells how many level units will be spawned as you climb.


//defines the world node for the scene & defines the player image in a constant.
var screenWidth:CGFloat = 0
var screenHeight:CGFloat = 0
let worldNode:SKNode = SKNode()
let thePlayer:Player = Player(imageNamed: "Frog")
var increment:CGFloat = 0

// variables with boolean values to check if the player is on certain types of levels or objects.
var onLilyPad:Bool = false
var onWater:Bool = false
var onRoad:Bool = false

//same variable that checks if the player is dead.
var isDead:Bool = false

//variable that links with the swift file called object and (maybe passes it through :(  )
var waterObject:Object?

//creates a constant that will be the starting point of the player
let startingPosition:CGPoint = CGPointMake(0, 0)

var direction:CGFloat = 1

// var nodeToMove:Object?
// var moveInProgress:Bool = false

override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    // Defines the view as the target defines the direction and calls the function (in red)
    swipeRightRec.addTarget(self, action:"swipedRight")
    swipeRightRec.direction = .Right
    self.view!.addGestureRecognizer(swipeRightRec)

    swipeLeftRec.addTarget(self, action: "swipedLeft")
    swipeLeftRec.direction = .Left
    self.view!.addGestureRecognizer(swipeLeftRec)

    TapUpRec.addTarget(self, action: "tapUp")
    self.view!.addGestureRecognizer(TapUpRec)

    swipeDownRec.addTarget(self, action: "swipedDown")
    swipeDownRec.direction = .Down
    self.view!.addGestureRecognizer(swipeDownRec)

    //makes the background colour black and defines the screenWidth variable as sk view boundry
    self.backgroundColor = SKColor.greenColor()
    screenWidth = self.view!.bounds.width
    screenHeight = self.view!.bounds.height

    //makes the world able to have objects that can collide (I Think)
    physicsWorld.contactDelegate = self

    //physicsWorld.gravity = CGVector(dx:0.3, dy:0.0)

    //creates the world node point to be in the middle of the screen
    self.anchorPoint = CGPointMake(0.5, 0.5)
    addChild(worldNode)


    let scoreLabel = Score(num: 0)
    scoreLabel.horizontalAlignmentMode = .Left
    scoreLabel.position = CGPoint(x:0.0, y:self.size.height)
    addChild(scoreLabel)

    //scoreLabel.position = CGPointMake(frame.size.width / -2.231, frame.size.height / 2.29)

    // let highscoreLabel = Score(num: 0)

    //adds a child node to the world node (so the player is playing within the world node)
    worldNode.addChild(thePlayer)
    thePlayer.position = startingPosition
    thePlayer.zPosition = 500                // zPosition is the order the player will be displayed.

    addLevelUnits()         //runs the func that addds levelUnits.

}

func addScoreLabels(){

}

// this function along with the next three run the swipe and tap gesture actions.
func swipedRight(){

    let amountToMove:CGFloat = levelUnitHeight

    let move:SKAction = SKAction.moveByX(amountToMove, y: 0, duration: 0.1)

    thePlayer.runAction(move) // links the action with the players

}

func swipedLeft(){

    let amountToMove:CGFloat = levelUnitHeight

    let move:SKAction = SKAction.moveByX(-amountToMove, y: 0, duration: 0.1)

    thePlayer.runAction(move)

}

func swipedDown(){

    let amountToMove:CGFloat = levelUnitHeight

    let move:SKAction = SKAction.moveByX(0, y: -amountToMove, duration: 0.1)

    thePlayer.runAction(move)

    // clearNodes()

}

func tapUp(){

    let amountToMove:CGFloat = levelUnitHeight

    let move:SKAction = SKAction.moveByX(0, y: amountToMove, duration: 0.1)

    thePlayer.runAction(move)

    clearNodes()

}

func resetLevel(){

    //searches the world node for child nodes that have the name "levelUnit"
    worldNode.enumerateChildNodesWithName("levelUnit") {
        node, stop in

        //removes all the child nodes from the parent.
        node.removeFromParent()


    }

    levelUnitCounter = 1
    addLevelUnits()

}

func addLevelUnits() {

    for (var i = 0; i < initialUnits; i++ ) {

        createLevelUnit()

    }

}

func createLevelUnit() {

    if (direction == 1) {

        direction = -1
    } else {

        direction = 1
    }

    print(direction )


    let levelUnit:LevelUnit = LevelUnit()
    worldNode.addChild(levelUnit)
    levelUnit.zPosition = -1
    levelUnit.levelUnitWidth = screenWidth
    levelUnit.levelUnitHeight = levelUnitHeight
    levelUnit.direction = direction
    levelUnit.setUpLevel()

    levelUnit.position = CGPointMake( 0 ,  levelUnitCounter * levelUnitHeight)      // counts the level unit and multiplies it so t goes above the last level unit.

    levelUnitCounter++                                                              //constantly makes the level units appear.

}

func clearNodes(){


    var nodeCount:Int = 0

    worldNode.enumerateChildNodesWithName("levelUnit") {
        node, stop in


        let nodeLocation:CGPoint = self.convertPoint(node.position, fromNode: self.worldNode)   //converts cordinates of level units with the world node.

        if ( nodeLocation.x < -(self.screenWidth / 2) - self.levelUnitWidth ) { // checks to see if the node is off the screen.

            node.removeFromParent()

            print("levelUnit was removed", terminator: "")

        } else {

            nodeCount++

        }

    }

    print( "levelUnits in the scene is \(nodeCount)")

}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */

    worldNode.enumerateChildNodesWithName("levelUnit"){
        node, stop in

        let levelUnit:LevelUnit = node as! LevelUnit  //cast as an actual LevelUnit class


        levelUnit.enumerateChildNodesWithName("obstacle"){
            node, stop in

            let obstacle:Object = node as! Object   //cast as an actual Object class
            obstacle.update()


            let obstacleLocation:CGPoint = self.convertPoint(obstacle.position, fromNode: levelUnit)

            let buffer:CGFloat = 150


            if (obstacleLocation.x < -(self.screenWidth / 2) - buffer) {                                    //changes the speed of object when it reaches middle of the screen.

                levelUnit.changeSpeed()

                obstacle.position = CGPointMake(obstacle.position.x + (self.screenWidth + (buffer * 2))  , obstacle.position.y)


            } else if (obstacleLocation.x > (self.screenWidth / 2) + buffer  ) {                            //changes the speed of the object again.

                levelUnit.changeSpeed()

                obstacle.position = CGPointMake(obstacle.position.x - (self.screenWidth + (buffer * 2))  , obstacle.position.y)
            }

        }

    }

    // creates new level units if always centering horizontally

    let nextTier:CGFloat = (levelUnitCounter * levelUnitHeight) - (CGFloat(initialUnits) * levelUnitHeight)

    if (thePlayer.position.y > nextTier) {

        createLevelUnit()
    }

    //deal with the players location....

    let playerLocation:CGPoint = self.convertPoint(thePlayer.position, fromNode: worldNode)

    var repositionPlayer:Bool = false

    if ( playerLocation.x < -(screenWidth / 2)) {

        repositionPlayer = true

    } else  if ( playerLocation.x > (screenWidth / 2)) {

        repositionPlayer = true

    } else if ( playerLocation.y < 0) {

        repositionPlayer = true

    } else if ( playerLocation.y > screenHeight) {

        repositionPlayer = true

    }

    if (repositionPlayer == true) {

        /* great code for reference later */

        killPlayer()

        thePlayer.physicsBody?.velocity = CGVector(dx: 0, dy: 0)

    }

}

// this function centers the world node on teh player.
override func didSimulatePhysics() {



    self.centerOnNode(thePlayer)


    if (onLilyPad == true) {

        thePlayer.position = CGPointMake(thePlayer.position.x + waterObject!.xAmount , thePlayer.position.y)

    }

}

//centers the camera on the node world.
func centerOnNode(node:SKNode) {

    let cameraPositionInScene:CGPoint = self.convertPoint(node.position, fromNode: worldNode)
    worldNode.position = CGPoint(x: worldNode.position.x , y:worldNode.position.y - cameraPositionInScene.y  )

}

func didBeginContact(contact: SKPhysicsContact) {

    //  Defines the contact between objects.

    /// lily pad
    if (contact.bodyA.categoryBitMask == BodyType.player.rawValue && contact.bodyB.categoryBitMask == BodyType.waterObject.rawValue ) {

        waterObject = contact.bodyB.node!.parent as? Object
        onLilyPad = true

        self.removeActionForKey("checkOnLilyPad")

        let waterObjectLocation:CGPoint = self.convertPointToView(waterObject!.position)
        thePlayer.position = self.convertPointFromView(waterObjectLocation)

    } else if (contact.bodyA.categoryBitMask == BodyType.waterObject.rawValue  && contact.bodyB.categoryBitMask == BodyType.player.rawValue ) {

        waterObject = contact.bodyA.node!.parent as? Object
        onLilyPad = true
        self.removeActionForKey("checkOnLilyPad")

        let waterObjectLocation:CGPoint = self.convertPointToView(waterObject!.position)
        thePlayer.position = self.convertPointFromView(waterObjectLocation)

    }

    //// check on water

    if (contact.bodyA.categoryBitMask == BodyType.player.rawValue  && contact.bodyB.categoryBitMask == BodyType.water.rawValue ) {

        onRoad = false
        onWater = true

        waitAndThenCheckOnLilyPad()


    } else if (contact.bodyA.categoryBitMask == BodyType.water.rawValue  && contact.bodyB.categoryBitMask == BodyType.player.rawValue ) {

        onRoad = false
        onWater = true

        waitAndThenCheckOnLilyPad()

    }

    //// cars

    if (contact.bodyA.categoryBitMask == BodyType.player.rawValue  && contact.bodyB.categoryBitMask == BodyType.roadObject.rawValue ) {

        killPlayer()


    } else if (contact.bodyA.categoryBitMask == BodyType.roadObject.rawValue  && contact.bodyB.categoryBitMask == BodyType.player.rawValue ) {

        killPlayer()


    }

    //// check on road

    if (contact.bodyA.categoryBitMask == BodyType.player.rawValue  && contact.bodyB.categoryBitMask == BodyType.road.rawValue ) {

        onRoad = true
        onWater = false
        onLilyPad = false

    } else if (contact.bodyA.categoryBitMask == BodyType.road.rawValue  && contact.bodyB.categoryBitMask == BodyType.player.rawValue ) {

        onRoad = true
        onWater = false
        onLilyPad = false

    }

}

func waitAndThenCheckOnLilyPad() {

    let wait:SKAction = SKAction.waitForDuration(0.1)
    let check:SKAction = SKAction.runBlock(checkIfOnLilyPad)
    let seq:SKAction = SKAction.sequence([wait, check])
    self.runAction(seq, withKey:"checkOnLilyPad")

}

func checkIfOnLilyPad() {


    if ( onRoad == false) {

        if ( onWater == true && onLilyPad == false) {


            killPlayer()

        } else if ( onWater == true && onLilyPad == true) {

            print("safely on water")
            // maybe play sound here
        }

    }

}

func didEndContact(contact: SKPhysicsContact) {


    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

    switch (contactMask) {

    case BodyType.waterObject.rawValue | BodyType.player.rawValue:

        onLilyPad = false
        waterObject = nil
        onWater = true

        waitAndThenCheckOnLilyPad()

    default:
        return

    }
}


func killPlayer() {


    if ( isDead == false) {

        isDead = true

        let fadeOut:SKAction = SKAction.fadeAlphaTo(0, duration: 0.2)
        let move:SKAction = SKAction.moveTo(startingPosition, duration: 0.2)
        let block:SKAction = SKAction.runBlock(revivePlayer)
        let seq:SKAction = SKAction.sequence([fadeOut, move, block])

        thePlayer.runAction(seq)

    }

}

func revivePlayer() {

    isDead = false
    onRoad = false
    onWater = false
    onLilyPad = false


    let fadeOut:SKAction = SKAction.fadeAlphaTo(0, duration: 0.2)
    let block:SKAction = SKAction.runBlock(resetLevel)
    let fadeIn:SKAction = SKAction.fadeAlphaTo(1, duration: 0.2)
    let seq:SKAction = SKAction.sequence([fadeOut, block, fadeIn])
    worldNode.runAction(seq)

    let wait:SKAction = SKAction.waitForDuration(1)
    let fadeIn2:SKAction = SKAction.fadeAlphaTo(1, duration: 0.2)
    let seq2:SKAction = SKAction.sequence([wait , fadeIn2])
    thePlayer.runAction(seq2)

}

}

2 个答案:

答案 0 :(得分:0)

我认为你走在正确的轨道上:

    let scoreLabel = Score(num: 0)
    scoreLabel.horizontalAlignmentMode = .Left
    scoreLabel.position = CGPoint(x:0.0, y:self.size.height)
    addChild(scoreLabel)

但我认为你还需要添加

scoreLabel.verticalAlignmentMode = .Top

作为默认的is.Baseline,它会导致它从屏幕上消失得最多。

答案 1 :(得分:0)

如果其他解决方案不起作用,您可以尝试这样的事情:

import UIKit
var screenSize = UIScreen.mainscreen().bounds
var screenWidth = screenSize.width
var screenHeight = screenSize.height

这将获得屏幕的尺寸并将它们存储在screenHeight和screenWidth变量中。 然后,当你打电话给scoreLabel.position时,你可以说

scoreLabel.position = CGPoint(x: screenWidth / 10, y: screenHeight / 15)

或类似的东西,但试验数学,直到它处于正确的位置。

如果这不起作用,您可能还需要声明尺寸或scoreLabel。如果有效,请告诉我。

Swift 4和Xcode 9代码:

let screenSize = UIScreen.main.bounds
let screenWidth = screenSize.width
let screenHeight = screenSize.height
self.menuButton.position = CGPoint(x: screenWidth / 10, y: screenHeight / 15)