Reputation: 375
My Goal: To achieve a scoring system that only counts when a level unit is behind the player once and therefore if the player goes back it doesn’t count the same one twice
I currently have a scoring system that adds one to the score label every time I tap my player to go forward in my game, this has its flaws as the player can go backwards and then tap to go forward which would count onto the score again if the player went backwards then forwards.
I came up with the idea to count how many platforms(LevelUnits) are behind the player so that if they go back it won’t count the same platform(LevelUnit) twice when they decide to go forward again.
This is what I came up with:
override func update(_ currentTime: TimeInterval) {
let scoreLabel = childNode(withName: "scoreLabel") as! Score // links the scorelabel with Score class
worldNode.enumerateChildNodes(withName: "levelUnit") {
node, stop in
let nodeLocation:CGPoint = self.convert(node.position, from: self.worldNode) //converts cordinates of level units with the world node.
let player1Location:CGPoint = self.convert(self.thePlayer.position, from: self.worldNode)
if (nodeLocation.y < (player1Location.y) - self.levelUnitHeight ) { // checks to see if the node is behind the player's position
self.countLevelUnits += 1
}
if (self.countLevelUnits > scoreLabel.number) {
while self.countLevelUnits > scoreLabel.number {
scoreLabel.addOneToScore()
}
} else if (self.countLevelUnits < scoreLabel.number) {
// Do Nothing
}
}
}
The only problem is that because they’re constantly behind the player the code counts it multiple times and continues to do so unless I turn off the game. Is there a way to just count the LevelUnits behind the player once for each one that goes behind the players position?
EDIT 1: LEVEL UNIT CLASS
class LevelUnit:SKNode {
//General Level Unit and Object Variables
var imageName:String = ""
var levelUnitSprite:SKSpriteNode = SKSpriteNode()
var levelUnitWidth:CGFloat = 0
var levelUnitHeight:CGFloat = 0
var theType:LevelType = LevelType.normal
let thePlayer:Player = Player(imageNamed: "Frog")
var levelUnitPicker = 0
var levelUnitsSpawned = 0
var levelUnitScored:Bool = false
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init () {
super.init()
}
func setUpLevel(){
imageName = “Wall”
let theSize:CGSize = CGSize(width: levelUnitWidth, height: levelUnitHeight) //defines the size background sprite as defined by the height and width of level unit
let tex:SKTexture = SKTexture(imageNamed: imageName) //defines the testue that the backgroundsprite will have.
levelUnitSprite = SKSpriteNode(texture: tex, color: SKColor.black, size: theSize)
scoredLevelUnit = false
self.addChild(levelUnitSprite) //adds the level unit to the scene
self.name = "levelUnit" //names the whole backgroundsprite under the name level Unit
self.position = CGPoint(x: levelUnitSprite.size.width / 2, y: 0)
//The Level Types Physics Body
if (theType == LevelType.blank) {
levelUnitSprite.physicsBody = SKPhysicsBody(rectangleOf: levelUnitSprite.size)
levelUnitSprite.physicsBody!.categoryBitMask = BodyType.normal.rawValue
levelUnitSprite.physicsBody!.contactTestBitMask = BodyType.normal.rawValue
levelUnitSprite.physicsBody!.isDynamic = false
} else if (theType == LevelType.normal) {
levelUnitSprite.physicsBody = SKPhysicsBody(rectangleOf: levelUnitSprite.size)
levelUnitSprite.physicsBody!.categoryBitMask = BodyType.normal.rawValue
levelUnitSprite.physicsBody!.contactTestBitMask = BodyType.normal.rawValue
levelUnitSprite.physicsBody!.isDynamic = false
} else if (theType == LevelType.floating) {
levelUnitSprite.physicsBody = SKPhysicsBody(rectangleOf: levelUnitSprite.size)
levelUnitSprite.physicsBody!.categoryBitMask = BodyType.floating.rawValue
levelUnitSprite.physicsBody!.contactTestBitMask = BodyType.floating.rawValue
levelUnitSprite.physicsBody!.isDynamic = false
}
}
Upvotes: 0
Views: 65
Reputation: 114828
If you use a custom subclass for your level unit, you can easily add a Bool
property scored; when you "score" this object, set scored = true
, then next time you can check if scored == true
and not score it again
override func update(_ currentTime: TimeInterval) {
let scoreLabel = childNode(withName: "scoreLabel") as! Score // links the scorelabel with Score class
worldNode.enumerateChildNodes(withName: "levelUnit") {
node, stop in
if let levelNode = node as? LevelUnit
let nodeLocation:CGPoint = self.convert(levelNode.position, from: self.worldNode) //converts cordinates of level units with the world node.
let player1Location:CGPoint = self.convert(self.thePlayer.position, from: self.worldNode)
if (nodeLocation.y < (player1Location.y) - self.levelUnitHeight ) { // checks to see if the node is behind the player's position
if !levelNode.levelUnitScored {
scoreLabel.addOneToScore()
levelNode.levelUnitScored = true
}
}
}
}
}
Upvotes: 1