Merge branch 'development' of https://gitlab.com/marcel.schwarz/software-projekt-2 into 35-datenubertragung-zwischen-spielern

* 'development' of https://gitlab.com/marcel.schwarz/software-projekt-2:
  add Label to EntityManager and implement Labels to SettingsScene
  add LabelEntity, LabelNode and Labelcomponent - ability to customize and add a Label with animation
  add sharedInstance, small cleanup Code
  add button to SettingsScene for Background Movement
  forgot return type in func getVolume
  add button on-off to settingsScene
  fix multiple calls from startMenuMusic with static Bool, stop music when enter Game
  add SettingsScene with background and music also boolean query for multiple audioplayer start
  add backgroundMusic for MenuScene with SoundManager for futher Sound-Management - music with commercial use
This commit is contained in:
127-Z3R0 2020-05-13 16:19:14 +02:00
commit 1b8fb6b126
10 changed files with 387 additions and 6 deletions

View File

@ -47,6 +47,12 @@
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759F245DEC0500671525 /* MapFactory.swift */; };
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; };
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE151588245F18EF001D363E /* MatchmakingHelper.swift */; };
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 */
@ -105,6 +111,12 @@
AB1D759F245DEC0500671525 /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = "<group>"; };
ABA03D9F244BD54F00A66916 /* Base.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base.swift; sourceTree = "<group>"; };
AE151588245F18EF001D363E /* MatchmakingHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchmakingHelper.swift; sourceTree = "<group>"; };
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 */
@ -148,6 +160,7 @@
110360D1244B101A008610AF /* GoldWars */ = {
isa = PBXGroup;
children = (
C04783ED2468583F004961FB /* intro-music.mp3 */,
9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */,
9E11FF74245CD79100EED3BE /* Partikels */,
116060F5245C5709004E5A36 /* Entities */,
@ -157,12 +170,17 @@
9EC86BA4245C8A1E00796EF3 /* Scenes */,
9EC86BA3245C89F400796EF3 /* Storyboards */,
110360D2244B101A008610AF /* AppDelegate.swift */,
C05FAED52468559D0006AF2E /* SoundManager.swift */,
110360DA244B101A008610AF /* GameViewController.swift */,
110360DF244B101B008610AF /* Assets.xcassets */,
9EC239E0246878A900952F74 /* MessageProtocol.swift */,
110360E4244B101B008610AF /* Info.plist */,
AE151588245F18EF001D363E /* MatchmakingHelper.swift */,
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */,
C04783EF24685995004961FB /* SettingsScene.swift */,
C064E9A7246C0EA50022B228 /* LabelNode.swift */,
C064E9A9246C114C0022B228 /* LabelComponent.swift */,
C064E9AB246C151F0022B228 /* Label.swift */,
);
path = GoldWars;
sourceTree = "<group>";
@ -350,6 +368,7 @@
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */,
110360E0244B101B008610AF /* Assets.xcassets in Resources */,
110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */,
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -376,7 +395,9 @@
9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */,
9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */,
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 */,
@ -387,12 +408,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 */,
@ -401,6 +424,7 @@
110360D3244B101A008610AF /* AppDelegate.swift in Sources */,
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */,
9E78ACC2245CC9EE00526FF7 /* DefBoostSkillComponent.swift in Sources */,
C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -12,6 +12,7 @@ class BackgroundComponent: GKComponent{
var nodes = [SKSpriteNode]()
let size: CGSize
static var isMovingBackgroundEnabled = true
init(size: CGSize) {
self.size = size
@ -27,10 +28,12 @@ class BackgroundComponent: GKComponent{
}
func update(){
for node in nodes{
node.position.x -= 2
if node.position.x < -(size.width) {
node.position.x += (size.width) * 3
if BackgroundComponent.isMovingBackgroundEnabled {
for node in nodes{
node.position.x -= 2
if node.position.x < -(size.width) {
node.position.x += (size.width) * 3
}
}
}
}

View File

@ -64,6 +64,9 @@ class EntityManager {
scene.addChild(sliderNode.sliderKnob)
scene.addChild(sliderNode.sliderLine)
}
if let labelNode = entity.component(ofType: LabelComponent.self)?.labelNode {
scene.addChild(labelNode)
}
}
func remove(_ entity: GKEntity) {

View 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")
}
}

View 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")
}
}

View 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))
}
}

View File

@ -23,6 +23,7 @@ class MenuScene: SKScene {
onButtonPress: {
if CommandLine.arguments.contains("--no-matchmaking") {
self.loadScene(scene: GameScene(size: self.size))
SoundManager.sharedInstance.stopMenuMusic()
} else {
MatchmakingHelper.sharedInstance.presentMatchmaker(scene: self)
}
@ -32,9 +33,13 @@ class MenuScene: SKScene {
text: "Settings",
position: CGPoint(x: midX, y: midY - 80 ),
onButtonPress: {
//TODO: create Settings Scene
}))
self.loadScene(scene: SettingsScene(size: self.size))
}))
entityManager.add(Background(size: self.size))
if SoundManager.sharedInstance.isMusicPlaying == false && SoundManager.sharedInstance.isMusicEnabled == true {
SoundManager.sharedInstance.startMenuMusic()
}
}
func loadScene(scene: SKScene) {

View File

@ -0,0 +1,94 @@
//
// SettingsScene.swift
// GoldWars
//
// Created by Tim Herbst on 10.05.20.
// Copyright © 2020 SP2. All rights reserved.
//
import SpriteKit
class SettingsScene: SKScene {
var entityManager: EntityManager!
override func sceneDidLoad() {
entityManager = EntityManager(scene: self)
let positionX = self.size.width * 0.1
let positionY = self.size.height * 0.05
entityManager.add(Button(name: "backToMenuScene",
iconName: "",
text: "Back",
position: CGPoint(x: positionX, y: positionY),
onButtonPress: {
self.loadScene(scene: MenuScene(size: self.size))
}))
entityManager.add(Button(name: "StopMenuMusic",
iconName: "",
text: "ON/OFF",
position: CGPoint(x: self.size.width * 0.6, y: self.size.height / 2),
onButtonPress: {
if SoundManager.sharedInstance.isMusicPlaying {
SoundManager.sharedInstance.stopMenuMusic()
SoundManager.sharedInstance.isMusicEnabled = false
} else {
SoundManager.sharedInstance.isMusicEnabled = true
SoundManager.sharedInstance.startMenuMusic()
}
}))
entityManager.add(Button(name: "StopMovingBackground",
iconName: "",
text: "MOVE/STOP",
position: CGPoint(x: self.size.width * 0.6, y: self.size.height / 2 - 100),
onButtonPress: {
if BackgroundComponent.isMovingBackgroundEnabled {
BackgroundComponent.isMovingBackgroundEnabled = false
} else {
BackgroundComponent.isMovingBackgroundEnabled = true
}
}))
entityManager.add(Label(fontnamed: "Courier-Bold",
name: "SettingsLabel",
text: "Settings",
fontSize: 200.0,
fontColor: .black,
position: CGPoint(x: self.size.width * 0.5, y: self.size.height * 0.7),
horizontalAlignmentMode: .center,
vertikalAligmentMode: .baseline,
isAnimationEnabled: true,
isAnimationInfinite: true)
)
entityManager.add(Label(fontnamed: "Courier-Bold",
name: "LabelMusic",
text: "Music", fontSize: 50.0,
fontColor: .black,
position: CGPoint(x: self.size.width * 0.5, y: self.size.height / 2 - 15),
horizontalAlignmentMode: .right,
vertikalAligmentMode: .baseline,
isAnimationEnabled: true,
isAnimationInfinite: false)
)
entityManager.add(Label(fontnamed: "Courier-Bold",
name: "LabelBackground",
text: "Background",
fontSize: 50.0,
fontColor: .black,
position: CGPoint(x: self.size.width * 0.5, y: self.size.height / 2 - 115),
horizontalAlignmentMode: .right,
vertikalAligmentMode: .baseline,
isAnimationEnabled: true,
isAnimationInfinite: false)
)
entityManager.add(Background(size: self.size))
}
func loadScene(scene: SKScene) {
let transition = SKTransition.flipVertical(withDuration: 0.5)
self.view?.presentScene(scene, transition: transition)
}
override func update(_ currentTime: TimeInterval) {
entityManager.getBackground()!.update(deltaTime: currentTime)
}
}

View File

@ -0,0 +1,47 @@
//
// SoundManager.swift
// GoldWars
//
// Created by Tim Herbst on 10.05.20.
// Copyright © 2020 SP2. All rights reserved.
//
import SpriteKit
import AVFoundation
class SoundManager {
public static var sharedInstance = SoundManager()
var audioPlayer = AVAudioPlayer()
var backgroundMainMenuAudio: URL?
var isMusicPlaying = false
var isMusicEnabled = true
func startMenuMusic() {
self.isMusicPlaying = true
backgroundMainMenuAudio = Bundle.main.url(forResource: "intro-music", withExtension: "mp3")
do {
audioPlayer = try AVAudioPlayer(contentsOf: backgroundMainMenuAudio!)
} catch {
print("Datei nicht gefunden!")
}
audioPlayer.numberOfLoops = -1
audioPlayer.prepareToPlay()
if self.isMusicEnabled == true {
audioPlayer.play()
}
}
func stopMenuMusic() {
audioPlayer.pause()
self.isMusicPlaying = false
}
func setVolume(_ volume: Float) {
audioPlayer.volume = volume
}
func getVolume() -> Float {
return audioPlayer.volume
}
}

Binary file not shown.