Merge branch 'development' into '33-basisownership-anhand-des-gkplayers'

# Conflicts:
#   GoldWars/GoldWars/Components/BackgroundComponent.swift
#   GoldWars/GoldWars/Components/TeamComponent.swift
#   GoldWars/GoldWars/Entities/Base.swift
#   GoldWars/GoldWars/Entities/EntityManager.swift
#   GoldWars/GoldWars/Entities/Modal.swift
#   GoldWars/GoldWars/Map/TwoPlayerDefaultTestMap.swift
#   GoldWars/GoldWars/Scenes/GameScene.swift
#   GoldWars/GoldWars/Scenes/MenuScene.swift
This commit is contained in:
Aldin Duraki 2020-05-15 09:08:26 +00:00
commit 4a48ed9b17
15 changed files with 489 additions and 115 deletions

View File

@ -46,6 +46,12 @@
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759F245DEC0500671525 /* MapFactory.swift */; }; AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB1D759F245DEC0500671525 /* MapFactory.swift */; };
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; }; ABA03DA0244BD54F00A66916 /* Base.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA03D9F244BD54F00A66916 /* Base.swift */; };
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE151588245F18EF001D363E /* MatchmakingHelper.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 */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -103,6 +109,12 @@
AB1D759F245DEC0500671525 /* MapFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapFactory.swift; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -146,6 +158,7 @@
110360D1244B101A008610AF /* GoldWars */ = { 110360D1244B101A008610AF /* GoldWars */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C04783ED2468583F004961FB /* intro-music.mp3 */,
9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */, 9ECD3699245C91F7008DEEBD /* GoldWars.entitlements */,
9E11FF74245CD79100EED3BE /* Partikels */, 9E11FF74245CD79100EED3BE /* Partikels */,
116060F5245C5709004E5A36 /* Entities */, 116060F5245C5709004E5A36 /* Entities */,
@ -155,11 +168,16 @@
9EC86BA4245C8A1E00796EF3 /* Scenes */, 9EC86BA4245C8A1E00796EF3 /* Scenes */,
9EC86BA3245C89F400796EF3 /* Storyboards */, 9EC86BA3245C89F400796EF3 /* Storyboards */,
110360D2244B101A008610AF /* AppDelegate.swift */, 110360D2244B101A008610AF /* AppDelegate.swift */,
C05FAED52468559D0006AF2E /* SoundManager.swift */,
110360DA244B101A008610AF /* GameViewController.swift */, 110360DA244B101A008610AF /* GameViewController.swift */,
110360DF244B101B008610AF /* Assets.xcassets */, 110360DF244B101B008610AF /* Assets.xcassets */,
110360E4244B101B008610AF /* Info.plist */, 110360E4244B101B008610AF /* Info.plist */,
AE151588245F18EF001D363E /* MatchmakingHelper.swift */, AE151588245F18EF001D363E /* MatchmakingHelper.swift */,
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */, 3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */,
C04783EF24685995004961FB /* SettingsScene.swift */,
C064E9A7246C0EA50022B228 /* LabelNode.swift */,
C064E9A9246C114C0022B228 /* LabelComponent.swift */,
C064E9AB246C151F0022B228 /* Label.swift */,
); );
path = GoldWars; path = GoldWars;
sourceTree = "<group>"; sourceTree = "<group>";
@ -347,6 +365,7 @@
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */, 9E11FF79245CD81100EED3BE /* Fire.sks in Resources */,
110360E0244B101B008610AF /* Assets.xcassets in Resources */, 110360E0244B101B008610AF /* Assets.xcassets in Resources */,
110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */, 110360E3244B101B008610AF /* LaunchScreen.storyboard in Resources */,
C04783EE2468583F004961FB /* intro-music.mp3 in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -372,7 +391,9 @@
9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */, 9EA3ABEB245C6DFA006BC61D /* BaseNode.swift in Sources */,
9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */, 9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */,
110360D9244B101A008610AF /* GameScene.swift in Sources */, 110360D9244B101A008610AF /* GameScene.swift in Sources */,
C04783F024685995004961FB /* SettingsScene.swift in Sources */,
116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */, 116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */,
C064E9AA246C114C0022B228 /* LabelComponent.swift in Sources */,
3EBD242E245D9332003CECE7 /* Team.swift in Sources */, 3EBD242E245D9332003CECE7 /* Team.swift in Sources */,
9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */, 9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */,
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */, 9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */,
@ -383,12 +404,14 @@
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */, 9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */,
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */, 9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */, 9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */,
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */, 3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */,
AB1D759C245DD18100671525 /* MapProtocol.swift in Sources */, AB1D759C245DD18100671525 /* MapProtocol.swift in Sources */,
AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */, AB1D75A0245DEC0500671525 /* MapFactory.swift in Sources */,
AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */, AB1D759D245DD18100671525 /* TwoPlayerDefaultTestMap.swift in Sources */,
9EBFD7552462CF5A00E1E219 /* SliderComponent.swift in Sources */, 9EBFD7552462CF5A00E1E219 /* SliderComponent.swift in Sources */,
ABA03DA0244BD54F00A66916 /* Base.swift in Sources */, ABA03DA0244BD54F00A66916 /* Base.swift in Sources */,
C064E9AC246C151F0022B228 /* Label.swift in Sources */,
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */, 9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */,
9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */, 9EC7E48B2461FBF700396BCD /* SliderNode.swift in Sources */,
9E174C84245DD8CE00209FF0 /* Button.swift in Sources */, 9E174C84245DD8CE00209FF0 /* Button.swift in Sources */,
@ -397,6 +420,7 @@
110360D3244B101A008610AF /* AppDelegate.swift in Sources */, 110360D3244B101A008610AF /* AppDelegate.swift in Sources */,
9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */, 9EC86B9F245C88A300796EF3 /* Modal.swift in Sources */,
9E78ACC2245CC9EE00526FF7 /* DefBoostSkillComponent.swift in Sources */, 9E78ACC2245CC9EE00526FF7 /* DefBoostSkillComponent.swift in Sources */,
C05FAED62468559D0006AF2E /* SoundManager.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

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

View File

@ -12,17 +12,16 @@ import GameKit
class TeamComponent: GKComponent { class TeamComponent: GKComponent {
let team: Team let team: Team
let fire: SKEmitterNode let fire: SKEmitterNode
let player: GKPlayer
init(team: Team, position: CGPoint) {
init(team: Team, position: CGPoint, player: GKPlayer) { fire = SKEmitterNode(fileNamed: "Fire")!
fire = SKEmitterNode(fileNamed: "Fire")! fire.zPosition = -1
fire.zPosition = -1 fire.position = position
fire.position = position fire.name = "fire"
fire.name = "fire" fire.particleColorSequence = nil
fire.particleColorSequence = nil fire.particleColorBlendFactor = 1.0
fire.particleColorBlendFactor = 1.0
switch team { switch team {
case .team1: fire.particleColor = SKColor.red case .team1: fire.particleColor = SKColor.red
case .team2: fire.particleColor = SKColor.purple case .team2: fire.particleColor = SKColor.purple

View File

@ -8,20 +8,17 @@
import SpriteKit import SpriteKit
import GameplayKit import GameplayKit
import GameKit
class Base: GKEntity { class Base: GKEntity {
var unitCount: Int var unitCount: Int
var adjacencyList: Array<Base> var adjacencyList: Array<Base>
var changeOwnership: Bool var changeOwnerShip: Bool
var ownershipPlayer: GKPlayer?
init(position: CGPoint, player: GKPlayer! = nil, team: Team! = nil) { init(position: CGPoint, team: Team! = nil) {
self.unitCount = 0 self.unitCount = 0
self.adjacencyList = [Base]() self.adjacencyList = [Base]()
self.changeOwnership = false self.changeOwnerShip = false
self.ownershipPlayer = player
super.init() super.init()
addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: position)) addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: position))
@ -31,13 +28,12 @@ class Base: GKEntity {
} }
} }
func attackBase(base: Base, units:Int) -> [GKEntity]{ func attackBase(base: Base, units:Int) -> [GKEntity]{
base.changeOwnership = true base.changeOwnerShip = true
base.ownershipPlayer = self.ownershipPlayer self.unitCount -= units
self.unitCount -= units base.unitCount += units
base.unitCount += units return [self, base]
return [self, base] }
}
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")

View File

@ -31,7 +31,6 @@ class EntityManager {
} }
if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode { if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode {
scene.addChild(spriteNode) scene.addChild(spriteNode)
isModal = true
} }
if let modal = entity.component(ofType: ModalContentComponent.self) { if let modal = entity.component(ofType: ModalContentComponent.self) {
scene.addChild(modal.header) scene.addChild(modal.header)
@ -55,6 +54,7 @@ class EntityManager {
} }
if let buttonNode = entity.component(ofType: ButtonComponent.self)?.buttonNode { if let buttonNode = entity.component(ofType: ButtonComponent.self)?.buttonNode {
scene.addChild(buttonNode) scene.addChild(buttonNode)
isModal = true
} }
if let nodes = entity.component(ofType: BackgroundComponent.self)?.nodes { if let nodes = entity.component(ofType: BackgroundComponent.self)?.nodes {
for node in nodes { for node in nodes {
@ -65,6 +65,9 @@ class EntityManager {
scene.addChild(sliderNode.sliderKnob) scene.addChild(sliderNode.sliderKnob)
scene.addChild(sliderNode.sliderLine) scene.addChild(sliderNode.sliderLine)
} }
if let labelNode = entity.component(ofType: LabelComponent.self)?.labelNode {
scene.addChild(labelNode)
}
} }
func remove(_ entity: GKEntity) { func remove(_ entity: GKEntity) {
@ -73,7 +76,6 @@ class EntityManager {
} }
if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode { if let spriteNode = entity.component(ofType: ModalBackgroundComponent.self)?.spriteNode {
spriteNode.removeFromParent() spriteNode.removeFromParent()
isModal = false
} }
if let modal = entity.component(ofType: ModalContentComponent.self) { if let modal = entity.component(ofType: ModalContentComponent.self) {
modal.header.removeFromParent() modal.header.removeFromParent()
@ -84,35 +86,30 @@ class EntityManager {
sliderNode.sliderKnob.removeFromParent() sliderNode.sliderKnob.removeFromParent()
sliderNode.sliderLine.removeFromParent() sliderNode.sliderLine.removeFromParent()
} }
if let modalButton = entity.component(ofType: ButtonComponent.self) {
modalButton.buttonNode.removeFromParent()
isModal = false
}
entities.remove(entity) entities.remove(entity)
} }
func update(_ entities: [GKEntity]){ func update(_ entities: [GKEntity]){
for entity in entities { for entity in entities {
self.entities.update(with: entity) self.entities.update(with: entity)
let base = (entity as! Base) let base = (entity as! Base)
if base.changeOwnership { if base.changeOwnerShip {
base.addComponent( base.addComponent(TeamComponent(team: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team, position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!))
TeamComponent( base.changeOwnerShip = false
team: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team, scene.addChild(base.component(ofType: TeamComponent.self)!.fire)
position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!, }
player: (entities[0] as! Base).component(ofType: TeamComponent.self)!.player)) }
base.changeOwnership = false
scene.addChild(base.component(ofType: TeamComponent.self)!.fire) }
} func getBaseByTeam(for team: Team) -> GKEntity? {
} for entity in entities {
if let teamComponent = entity.component(ofType: TeamComponent.self),
} let _ = entity.component(ofType: DefaultBaseComponent.self) {
func getBaseByPlayer(for player: GKPlayer) -> Set<Base> {
return entities.filter{$0 is Base && ($0 as! Base).component(ofType: TeamComponent.self)?.player == player } as! Set<Base>
}
func getBaseByTeam(for team: Team) -> GKEntity? {
for entity in entities {
if let teamComponent = entity.component(ofType: TeamComponent.self),
let _ = entity.component(ofType: DefaultBaseComponent.self) {
if teamComponent.team == team { if teamComponent.team == team {
return entity return entity
} }

View File

@ -12,28 +12,43 @@ class Modal: GKEntity{
var unitCount:Int var unitCount:Int
init(modaltype: ModalType, base: Base, anchorPoint: CGPoint) { var unitCount:Int
unitCount = base.unitCount
super.init() init(modaltype: ModalType, base: Base, anchorPoint: CGPoint, entityManager: EntityManager, gameScene: SKScene) {
switch modaltype{ unitCount = base.unitCount
case .BaseDetails: super.init()
addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint)) switch modaltype{
addComponent(ModalContentComponent(header: "Basis Information", case .BaseDetails:
body: "Diese Basis enthält \(base.unitCount) Einheiten", addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint))
footer: "", addComponent(ModalContentComponent(header: "Basis Information", body: "Diese Basis enthält \(base.unitCount) Einheiten", footer: "", anchorPoint: anchorPoint))
anchorPoint: anchorPoint)) addComponent(ButtonComponent(iconName: "", text: "Zurück", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 120), isEnabled: true, onButtonPress: {
case .BaseAttack: self.removeModalEntities(entityManager: entityManager, gameScene: gameScene)
addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint)) }))
addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 80))) case .BaseAttack:
addComponent(ModalContentComponent(header: "Angriff", addComponent(ModalBackgroundComponent(anchorPoint: anchorPoint))
body: "Schicke \(unitCount / 2) Einheiten", addComponent(SliderComponent(width: 300, position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 50)))
footer: "", addComponent(ModalContentComponent(header: "Angriff", body: "Schicke \(unitCount / 2) Einheiten",
anchorPoint: anchorPoint)) footer: "", anchorPoint: anchorPoint))
} addComponent(ButtonComponent(iconName: "", text: "Senden", position: CGPoint(x: anchorPoint.x , y: anchorPoint.y - 120), isEnabled: true, onButtonPress: {
} self.removeModalEntities(entityManager: entityManager, gameScene: gameScene)
}))
required init?(coder: NSCoder) { }
fatalError("init(coder:) has not been implemented") }
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func removeModalEntities(entityManager: EntityManager, gameScene: SKScene){
for entity in entityManager.entities {
if entityManager.isModal && entity.isMember(of: Modal.self) {
entityManager.remove(entity)
}
for child in gameScene.children {
if(child.name != "fire"){
child.alpha = 1
}
}
}
}
} }

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

@ -8,7 +8,6 @@
import Foundation import Foundation
import SpriteKit import SpriteKit
import GameKit
class TwoPlayerDefaultTestMap: MapProtocol { class TwoPlayerDefaultTestMap: MapProtocol {
@ -26,7 +25,6 @@ class TwoPlayerDefaultTestMap: MapProtocol {
// Create Bases // Create Bases
let basePlayerOne = Base( let basePlayerOne = Base(
position: CGPoint(x: self.size.width * 0.1, y: self.size.height / 2), position: CGPoint(x: self.size.width * 0.1, y: self.size.height / 2),
player: (MatchmakingHelper.sharedInstance.isServer) ? GKLocalPlayer.local : MatchmakingHelper.sharedInstance.mpMatch?.players[0],
team: .team1 team: .team1
) )

View File

@ -39,38 +39,29 @@ class GameScene: SKScene{
isMoveTouch = false isMoveTouch = false
currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = currentDraggedBasePos currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = currentDraggedBasePos
currentDraggedBase!.component(ofType: TeamComponent.self)?.fire.position = currentDraggedBasePos currentDraggedBase!.component(ofType: TeamComponent.self)?.fire.position = currentDraggedBasePos
for base in currentDraggedBase!.adjacencyList { for base in currentDraggedBase!.adjacencyList {
if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode { if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode {
// TODO: change interaction based on collision instead of touchlocation // TODO: change interaction based on collision instead of touchlocation
if !(entityManager.getTeamByBase(base: currentDraggedBase!) == entityManager.getTeamByBase(base: base)){ if !(entityManager.getTeamByBase(base: currentDraggedBase!) == entityManager.getTeamByBase(base: base)){
entityManager.add(Modal(modaltype: .BaseAttack, entityManager.add(Modal(modaltype: .BaseAttack,
base: currentDraggedBase!, base: currentDraggedBase!,
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2))) anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2), entityManager: entityManager, gameScene: self))
entityManager.update((currentDraggedBase?.attackBase(base: base, units: 100))!) entityManager.update((currentDraggedBase?.attackBase(base: base, units: 100))!)
}else { }else {
entityManager.add(Modal(modaltype: .BaseAttack, entityManager.add(Modal(modaltype: .BaseAttack,
base: currentDraggedBase!, base: currentDraggedBase!,
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2))) anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2), entityManager: entityManager, gameScene: self))
} }
} }
} }
} }
else { else {
for entity in entityManager.entities { for entity in entityManager.entities {
let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode
if entityManager.isModal && entity.isMember(of: Modal.self) {
entityManager.remove(entity)
for child in self.children {
if(child.name != "fire"){
child.alpha = 1
}
}
}
if atPoint(touchLocation) == spriteNode && !entityManager.isModal { if atPoint(touchLocation) == spriteNode && !entityManager.isModal {
spriteNode?.touchesBegan(touches, with: event) spriteNode?.touchesBegan(touches, with: event)
if !entityManager.isModal { if !entityManager.isModal {
@ -81,7 +72,7 @@ class GameScene: SKScene{
} }
entityManager.add(Modal(modaltype: .BaseDetails, entityManager.add(Modal(modaltype: .BaseDetails,
base: entity as! Base, base: entity as! Base,
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2))) anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2), entityManager: entityManager, gameScene: self))
} }
} }
} }

View File

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