当前位置: 动力学知识库 > 问答 > 编程问答 >

ios - Score label in top left Corner for all devices

问题描述:

I’m new to programming and I recently did a tutorial that I found online to make a endless frogger game. The tutorial person didn’t show me how to do the score label and I have tried endlessly to find a video tutorial that will show me how to position a score label in the top left corner. I have tried using this code:

label.horizontalAlignmentMode = .Left

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

but I have had no luck, It does not show up in the top left corner. So i tried another way to get it positioned in the corner and I played around with the values and ended up with this

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

which positions it perfectly in the corner of the screen on the simulator, but not for all the devices. I have a seperate swift file for my score label with is here:

import Foundation

import SpriteKit

import 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)"

}

}

I have a world node that has a player inside it and the camera position is focused on the player. I have provided my game Scene class for you to have a look at. All I want is to be able to position a score label in the top left or top right corner of the screen for all devices.

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)

}

}

网友答案:

If other solutions don't work, you could try something like this:

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

This will get the dimensions of the screen and store them in the screenHeight and screenWidth variables. Then when you call scoreLabel.position you could say

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

Or something like that but experiment with the math until it is in the correct position.

If this doesn't work you may also need to declare the size or scoreLabel. Let me know if it works.

网友答案:

I think you are on the right track with:

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

But I think you also need to add

scoreLabel.verticalAlignmentMode = .Top

as the default is.Baseline which would cause it draw most off the screen.

分享给朋友:
您可能感兴趣的文章:
随机阅读: