使用 Sprite Kit 和 Swift 在游戏中显示当前分数
Posted
技术标签:
【中文标题】使用 Sprite Kit 和 Swift 在游戏中显示当前分数【英文标题】:Display Current Score in Game using Sprite Kit and Swift 【发布时间】:2015-01-07 19:05:09 【问题描述】:我在 Sprite Kit 中开发 Flappy Bird 类型的游戏已经有几天了。我是编程新手,所以我一直在尝试通过各种在线视频和教程自学制作游戏。我已经到了需要创建一个评分系统的地步,该系统将在屏幕上实时显示当前分数。我已经寻找并寻找了一个很好的教程,但没有找到一个。我已经在下面的代码中设置了分数标签。我已经在我的整个场景下面包含了。我只需要知道每次鸟儿飞过管道时如何更新分数标签文本。任何意见或建议将不胜感激,谢谢。
//
// ArcheryScene.swift
// FlappyBird (swift)
//
// Created by Brandon Ballard on 1/6/15.
// Copyright (c) 2015 Brandon Ballard. All rights reserved.
//
import UIKit
import SpriteKit
class ArcheryScene: SKScene, SKPhysicsContactDelegate
var bird = SKSpriteNode()
var pipeUpTexture = SKTexture()
var pipeDownTexture = SKTexture()
var pipesMoveAndRemove = SKAction()
var impulse = 1
var count = 0
var scoreLabel = SKLabelNode()
let scoreLabelName = "scoreLabel"
let pipeGap = 150.0
enum ColliderType:UInt32
case BIRD = 1
case PIPE = 2
override func didMoveToView(view: SKView)
/* Setup your scene here */
backgroundColor = SKColor.cyanColor()
//physics
self.physicsWorld.gravity = CGVectorMake(0.0, -15.0);
self.physicsWorld.contactDelegate = self
//Bird
var birdTexture = SKTexture(imageNamed:"Bird")
birdTexture.filteringMode = SKTextureFilteringMode.Nearest
bird = SKSpriteNode(texture: birdTexture)
bird.setScale(0.6)
bird.position = CGPoint(x: self.frame.width * 0.35 + 20, y: self.frame.size.height * 0.95)
bird.physicsBody = SKPhysicsBody(circleOfRadius: bird.size.height / 2.0)
bird.physicsBody?.dynamic = true
bird.physicsBody?.allowsRotation = true
bird.physicsBody?.affectedByGravity = true
bird.physicsBody!.collisionBitMask = ColliderType.BIRD.rawValue
bird.physicsBody!.contactTestBitMask = ColliderType.PIPE.rawValue
self.addChild(bird)
//Ground
var groundTexture = SKTexture(imageNamed: "Ground")
var sprite = SKSpriteNode(texture: groundTexture)
sprite.setScale(2.0)
sprite.position = CGPointMake(self.size.width / 2, sprite.size.height / 2.0)
self.addChild(sprite)
var ground = SKNode()
ground.position = CGPointMake(0, groundTexture.size().height + 0)
ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, groundTexture.size().height * 2.0))
ground.physicsBody?.dynamic = false
self.addChild(ground)
//Score Label
scoreLabel = SKLabelNode(fontNamed: "ScoreLabel")
scoreLabel.name = scoreLabelName
scoreLabel.fontSize = 125
scoreLabel.fontColor = SKColor.whiteColor()
scoreLabel.text = "\(count)"
println(size.height)
scoreLabel.position = CGPointMake(frame.size.width / 2, frame.size.height / 14)
self.addChild(scoreLabel)
//Pipes
//Create the Pipes
pipeUpTexture = SKTexture(imageNamed: "PipeUp")
pipeDownTexture = SKTexture(imageNamed: "PipeDown")
//Movement of Pipes
let distanceToMove = CGFloat(self.frame.size.width + 2.0 * pipeUpTexture.size().width)
let movePipes = SKAction.moveByX(-distanceToMove, y: 0.0, duration: NSTimeInterval(0.01 * distanceToMove))
let removePipes = SKAction.removeFromParent()
pipesMoveAndRemove = SKAction.sequence([movePipes,removePipes])
//Spawn Pipes
let spawn = SKAction.runBlock(() in self.spawnPipes())
let delay = SKAction.waitForDuration(NSTimeInterval(2.0))
let spawnThenDelay = SKAction.sequence([spawn,delay])
let spawnThenDelayForever = SKAction.repeatActionForever(spawnThenDelay)
self.runAction(spawnThenDelayForever)
func spawnPipes()
let pipePair = SKNode()
pipePair.position = CGPointMake(self.frame.size.width + pipeUpTexture.size().width * 2, 0)
pipePair.zPosition = -10
let height = UInt32(self.frame.size.height / 4)
let y = arc4random() % height + height
var pipeDown = SKSpriteNode(texture: pipeDownTexture)
pipeDown.setScale(2.0)////////
pipeDown.position = CGPointMake(3.0, CGFloat(y) + pipeDown.size.height + CGFloat(pipeGap) )
pipeDown.physicsBody = SKPhysicsBody(rectangleOfSize: pipeDown.size)
pipeDown.physicsBody?.dynamic = false
pipeDown.physicsBody!.affectedByGravity = false
pipeDown.physicsBody!.collisionBitMask = ColliderType.PIPE.rawValue
pipePair.addChild(pipeDown)
var pipeUp = SKSpriteNode(texture: pipeUpTexture)
pipeUp.setScale(2.0)
pipeUp.position = CGPointMake(0.0, CGFloat(y))
pipeUp.physicsBody = SKPhysicsBody(rectangleOfSize: pipeUp.size )
pipeUp.physicsBody?.dynamic = false
pipeUp.physicsBody!.affectedByGravity = false
pipeUp.physicsBody!.collisionBitMask = ColliderType.PIPE.rawValue
pipePair.addChild(pipeUp)
pipePair.runAction(pipesMoveAndRemove)
self.addChild(pipePair)
func didBeginContact(contact: SKPhysicsContactDelegate)
impulse = 0
let fadeOut = SKAction.sequence([SKAction.waitForDuration(3.0)])
let welcomeReturn = SKAction.runBlock(
let Transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)
let welcomeScene = GameScene(fileNamed: "GameScene")
welcomeScene.scaleMode = .AspectFill
self.scene!.view?.presentScene(welcomeScene, transition: Transition)
)
let sequence = SKAction.sequence([fadeOut, welcomeReturn])
self.runAction(sequence)
override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
/* Called when a touch begins */
for touch: AnyObject in touches
let location = touch.locationInNode(self)
if bird.position.y > (self.frame.size.height * 0.999)
impulse = 0
if impulse == 1
bird.physicsBody?.velocity = CGVectorMake( 0, 0 )
bird.physicsBody?.applyImpulse(CGVectorMake(0,25))
override func update(currentTime: CFTimeInterval)
/* Called before each frame is rendered */
【问题讨论】:
参见“Flappy Fly”教程,它适用于 cocos2d,但同样的原理可以应用于 SK。基本上你需要在玩家可以通过但仍会产生碰撞事件的管道之间有一个物理体。 我去看看谢谢 【参考方案1】:只需在管道之间设置一个不可见的精灵。当您的小鸟经过它时,您可以检测到这一点并提高您的分数。
你可以像这样制作一个不可见的精灵
let scoreSprite = SKSpriteNode(color: SKColor.clearColor(), size: theSize)
在其中添加一个物理体,一切顺利。
【讨论】:
非常感谢这解决了我一半的问题,我现在唯一需要知道的是如何在小鸟穿过隐形精灵时更新分数。我已经有一个 didBeginContact() 函数来检测鸟与另一个精灵的接触但是当这个函数被调用时游戏结束。 你看过这里的答案了吗? ***.com/questions/20572309/… 有很多关于如何使用 spritekit 在互联网上处理冲突的示例。该 didbegincontact 方法不仅可用于查看是否有联系。它对于检测正在建立哪些联系人很有用以上是关于使用 Sprite Kit 和 Swift 在游戏中显示当前分数的主要内容,如果未能解决你的问题,请参考以下文章
使用 Swift 在 Sprite Kit 中构建棋盘游戏? [关闭]
游戏中的三角学——Sprite Kit 和 Swift 教程