add LabelEntity, LabelNode and Labelcomponent - ability to customize and add a Label with animation
This commit is contained in:
parent
2a42379610
commit
1ca5399a2e
@ -49,6 +49,9 @@
|
||||
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C04783ED2468583F004961FB /* intro-music.mp3 */; };
|
||||
C04783F024685995004961FB /* SettingsScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04783EF24685995004961FB /* SettingsScene.swift */; };
|
||||
C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C05FAED52468559D0006AF2E /* SoundManager.swift */; };
|
||||
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A7246C0EA50022B228 /* LabelNode.swift */; };
|
||||
C064E9AA246C114C0022B228 /* LabelComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9A9246C114C0022B228 /* LabelComponent.swift */; };
|
||||
C064E9AC246C151F0022B228 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = C064E9AB246C151F0022B228 /* Label.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -109,6 +112,9 @@
|
||||
C04783ED2468583F004961FB /* intro-music.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "intro-music.mp3"; sourceTree = "<group>"; };
|
||||
C04783EF24685995004961FB /* SettingsScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScene.swift; sourceTree = "<group>"; };
|
||||
C05FAED52468559D0006AF2E /* SoundManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundManager.swift; sourceTree = "<group>"; };
|
||||
C064E9A7246C0EA50022B228 /* LabelNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelNode.swift; sourceTree = "<group>"; };
|
||||
C064E9A9246C114C0022B228 /* LabelComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelComponent.swift; sourceTree = "<group>"; };
|
||||
C064E9AB246C151F0022B228 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -169,6 +175,9 @@
|
||||
AE151588245F18EF001D363E /* MatchmakingHelper.swift */,
|
||||
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */,
|
||||
C04783EF24685995004961FB /* SettingsScene.swift */,
|
||||
C064E9A7246C0EA50022B228 /* LabelNode.swift */,
|
||||
C064E9A9246C114C0022B228 /* LabelComponent.swift */,
|
||||
C064E9AB246C151F0022B228 /* Label.swift */,
|
||||
);
|
||||
path = GoldWars;
|
||||
sourceTree = "<group>";
|
||||
@ -384,6 +393,7 @@
|
||||
110360D9244B101A008610AF /* GameScene.swift in Sources */,
|
||||
C04783F024685995004961FB /* SettingsScene.swift in Sources */,
|
||||
116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */,
|
||||
C064E9AA246C114C0022B228 /* LabelComponent.swift in Sources */,
|
||||
3EBD242E245D9332003CECE7 /* Team.swift in Sources */,
|
||||
9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */,
|
||||
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */,
|
||||
@ -394,12 +404,14 @@
|
||||
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */,
|
||||
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
|
||||
9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */,
|
||||
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
|
||||
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */,
|
||||
AB1D759C245DD18100671525 /* MapProtocol.swift in Sources */,
|
||||
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */,
|
||||
AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */,
|
||||
9EBFD7552462CF5A00E1E219 /* SliderComponent.swift in Sources */,
|
||||
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */,
|
||||
C064E9AC246C151F0022B228 /* Label.swift in Sources */,
|
||||
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */,
|
||||
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */,
|
||||
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */,
|
||||
|
21
GoldWars/GoldWars/Label.swift
Normal file
21
GoldWars/GoldWars/Label.swift
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// Label.swift
|
||||
// GoldWars
|
||||
//
|
||||
// Created by Tim Herbst on 13.05.20.
|
||||
// Copyright © 2020 SP2. All rights reserved.
|
||||
//
|
||||
|
||||
import GameplayKit
|
||||
|
||||
class Label: GKEntity {
|
||||
|
||||
init(fontnamed: String, name: String, text: String, fontSize: CGFloat, fontColor: UIColor, position: CGPoint, horizontalAlignmentMode: SKLabelHorizontalAlignmentMode, vertikalAligmentMode: SKLabelVerticalAlignmentMode, isAnimationEnabled: Bool, isAnimationInfinite: Bool) {
|
||||
super.init()
|
||||
self.addComponent(LabelComponent(fontnamed: fontnamed, name: name, text: text, fontSize: fontSize, fontColor: fontColor, position: position, horizontalAlignmentMode: horizontalAlignmentMode, vertikalAligmentMode: vertikalAligmentMode, isAnimationEnabled: isAnimationEnabled, isAnimationInfinite: isAnimationInfinite))
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
32
GoldWars/GoldWars/LabelComponent.swift
Normal file
32
GoldWars/GoldWars/LabelComponent.swift
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// LabelComponent.swift
|
||||
// GoldWars
|
||||
//
|
||||
// Created by Tim Herbst on 13.05.20.
|
||||
// Copyright © 2020 SP2. All rights reserved.
|
||||
//
|
||||
|
||||
import GameplayKit
|
||||
|
||||
class LabelComponent: GKComponent {
|
||||
var labelNode: LabelNode
|
||||
|
||||
init(fontnamed: String?, name: String, text: String, fontSize: CGFloat, fontColor: UIColor, position: CGPoint, horizontalAlignmentMode: SKLabelHorizontalAlignmentMode, vertikalAligmentMode: SKLabelVerticalAlignmentMode, isAnimationEnabled: Bool, isAnimationInfinite: Bool) {
|
||||
labelNode = LabelNode(fontNamed: fontnamed)
|
||||
labelNode.name = name
|
||||
labelNode.text = text
|
||||
labelNode.fontSize = fontSize
|
||||
labelNode.fontColor = fontColor
|
||||
labelNode.horizontalAlignmentMode = horizontalAlignmentMode
|
||||
labelNode.verticalAlignmentMode = vertikalAligmentMode
|
||||
labelNode.position = position
|
||||
if isAnimationEnabled {
|
||||
labelNode.sequentiallyBouncingZoom(delay: 0.3, infinite: isAnimationInfinite)
|
||||
}
|
||||
super.init()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
152
GoldWars/GoldWars/LabelNode.swift
Normal file
152
GoldWars/GoldWars/LabelNode.swift
Normal file
@ -0,0 +1,152 @@
|
||||
//
|
||||
// LabelNode.swift
|
||||
// GoldWars
|
||||
//
|
||||
// Created by Tim Herbst on 13.05.20.
|
||||
// Copyright © 2020 SP2. All rights reserved.
|
||||
//
|
||||
|
||||
import SpriteKit
|
||||
|
||||
class LabelNode: SKNode {
|
||||
let colt = SKLabelNode()
|
||||
var labels = [SKLabelNode]()
|
||||
var text = "" {
|
||||
didSet {
|
||||
refreshLabels()
|
||||
}
|
||||
}
|
||||
var fontName = "HelveticaNeue-UltraLight" {
|
||||
didSet {
|
||||
_ = labels.compactMap({ $0.fontName = fontName })
|
||||
refreshLabels()
|
||||
}
|
||||
}
|
||||
var fontSize = CGFloat(30.0) {
|
||||
didSet {
|
||||
_ = labels.compactMap({ $0.fontSize = fontSize })
|
||||
refreshLabels()
|
||||
}
|
||||
}
|
||||
var fontColor = UIColor.init(white: 1.0, alpha: 1.0) {
|
||||
didSet {
|
||||
_ = labels.compactMap({ $0.fontColor = fontColor })
|
||||
refreshLabels()
|
||||
}
|
||||
}
|
||||
var horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.init(rawValue: 0) { // left
|
||||
didSet {
|
||||
_ = labels.compactMap({ $0.horizontalAlignmentMode = horizontalAlignmentMode! })
|
||||
refreshLabels()
|
||||
}
|
||||
}
|
||||
var verticalAlignmentMode = SKLabelVerticalAlignmentMode.init(rawValue: 0) { // center
|
||||
didSet {
|
||||
_ = labels.compactMap({ $0.verticalAlignmentMode = verticalAlignmentMode! })
|
||||
refreshLabels()
|
||||
}
|
||||
}
|
||||
var lineSpacingFactor: CGFloat = -1.3 {
|
||||
didSet {
|
||||
refreshLabels()
|
||||
}
|
||||
}
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
convenience init(text: String) {
|
||||
self.init()
|
||||
self.text = text
|
||||
}
|
||||
convenience init(fontNamed fontName: String?) {
|
||||
self.init(text: "")
|
||||
if let f = fontName {
|
||||
self.fontName = f
|
||||
}
|
||||
}
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func refreshLabels() {
|
||||
_ = labels.compactMap({ $0.removeFromParent() })
|
||||
labels.removeAll()
|
||||
if text.count > 0 {
|
||||
var newX: CGFloat = 0.0
|
||||
var gapX: CGFloat = 0.0
|
||||
let ghostSpace = SKLabelNode(text: ".")
|
||||
ghostSpace.fontName = fontName
|
||||
ghostSpace.fontSize = fontSize
|
||||
let ghostSpaceWidth = ghostSpace.frame.size.width
|
||||
var fullNodeWidth:CGFloat = 0.0
|
||||
for char in text {
|
||||
if String(char) != " " {
|
||||
let charLabelNode = SKLabelNode(text: String(char))
|
||||
charLabelNode.fontName = fontName
|
||||
charLabelNode.fontSize = fontSize
|
||||
fullNodeWidth += charLabelNode.frame.size.width + lineSpacingFactor
|
||||
} else {
|
||||
fullNodeWidth += ghostSpaceWidth + lineSpacingFactor
|
||||
}
|
||||
}
|
||||
switch horizontalAlignmentMode {
|
||||
case .left? : gapX = 0.0
|
||||
case .center? : gapX = fullNodeWidth/2
|
||||
case .right? : gapX = fullNodeWidth
|
||||
default: break
|
||||
}
|
||||
var index: Int = 0
|
||||
for char in text {
|
||||
if String(char) != " " {
|
||||
let charLabelNode = SKLabelNode(text: String(char))
|
||||
charLabelNode.fontName = fontName
|
||||
charLabelNode.fontSize = fontSize
|
||||
charLabelNode.fontColor = fontColor
|
||||
charLabelNode.horizontalAlignmentMode = .left
|
||||
charLabelNode.verticalAlignmentMode = verticalAlignmentMode!
|
||||
charLabelNode.position.x = newX - gapX
|
||||
charLabelNode.alpha = 1
|
||||
self.addChild(charLabelNode)
|
||||
labels.append(charLabelNode)
|
||||
newX += charLabelNode.frame.size.width + lineSpacingFactor
|
||||
} else {
|
||||
ghostSpace.horizontalAlignmentMode = .left
|
||||
ghostSpace.verticalAlignmentMode = verticalAlignmentMode!
|
||||
ghostSpace.position.x = newX - gapX
|
||||
labels.append(ghostSpace)
|
||||
newX += ghostSpaceWidth + lineSpacingFactor
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sequentiallyBouncingZoom(delay:TimeInterval, infinite:Bool = false) {
|
||||
if labels.count > 0 && self.action(forKey: "sequentiallyBouncingZoom") == nil {
|
||||
let main = SKAction.run { [weak self] in
|
||||
guard let strongSelf = self else { return }
|
||||
for i in 0..<strongSelf.labels.count {
|
||||
let zoomIn = SKAction.scale(to: 2.0, duration: delay)
|
||||
let zoomOut = SKAction.scale(to: 1.0, duration: delay)
|
||||
let currentDuration = delay * TimeInterval(i)
|
||||
let wait = SKAction.wait(forDuration: currentDuration)
|
||||
let seq = SKAction.sequence([wait,zoomIn,zoomOut])
|
||||
let currentLab = strongSelf.labels[i]
|
||||
currentLab.run(seq, withKey: "seq\(i)")
|
||||
}
|
||||
}
|
||||
let waitAfter = SKAction.wait(forDuration: delay * TimeInterval(self.labels.count+1))
|
||||
let seq = SKAction.sequence([main,waitAfter])
|
||||
let finalAction = infinite ? SKAction.repeatForever(seq) : main
|
||||
self.run(finalAction, withKey: "sequentiallyBouncingZoom")
|
||||
}
|
||||
}
|
||||
}
|
||||
extension SKAction {
|
||||
class func afterDelay(_ delay: TimeInterval, performAction action: SKAction) -> SKAction {
|
||||
return SKAction.sequence([SKAction.wait(forDuration: delay), action])
|
||||
}
|
||||
class func afterDelay(_ delay: TimeInterval, runBlock block: @escaping () -> Void) -> SKAction {
|
||||
return SKAction.afterDelay(delay, performAction: SKAction.run(block))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user