Merge branch '36-runde-beenden-mit-berechnetem-angriff' into 'development'

Resolve "Runde beenden mit berechnetem Angriff"

Closes #36

See merge request marcel.schwarz/software-projekt-2!78
This commit is contained in:
Aldin Duraki 2020-05-21 13:52:11 +00:00
commit 3ab40f94cb
11 changed files with 124 additions and 69 deletions

View File

@ -25,8 +25,7 @@ class AtkBoostSkillComponent: GKComponent{
}else { }else {
base.unitType = .Attack base.unitType = .Attack
} }
} }})
})
super.init() super.init()
} }

View File

@ -23,20 +23,29 @@ class TeamComponent: GKComponent {
fire.particleColorSequence = nil fire.particleColorSequence = nil
fire.particleColorBlendFactor = 1.0 fire.particleColorBlendFactor = 1.0
switch team {
case .team1: fire.particleColor = SKColor.red
case .team2: fire.particleColor = SKColor.purple
case .team3: fire.particleColor = SKColor.green
case .team4: fire.particleColor = SKColor.gray
}
self.team = team self.team = team
self.player = player self.player = player
super.init() super.init()
fire.particleColor = getColor(by: team)
} }
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
func getColor(by team: Team) -> SKColor {
switch team {
case .team1: return SKColor.red
case .team2: return SKColor.purple
case .team3: return SKColor.green
case .team4: return SKColor.gray
}
}
func change(to team: Team, to player: GKPlayer) -> Void {
self.team = team
self.player = player
self.fire.particleColor = getColor(by: team)
}
} }

View File

@ -13,6 +13,7 @@ class TimerComponent: GKComponent {
let labelNode :SKLabelNode let labelNode :SKLabelNode
var endTime :Date! var endTime :Date!
var duration :Double var duration :Double
var isRunning = false
init(text: String, anchorPoint: CGPoint, duration: TimeInterval) { init(text: String, anchorPoint: CGPoint, duration: TimeInterval) {
self.labelNode = SKLabelNode(text: text) self.labelNode = SKLabelNode(text: text)
@ -25,18 +26,26 @@ class TimerComponent: GKComponent {
} }
func startWithDuration(duration: TimeInterval){ func startWithDuration(duration: TimeInterval){
isRunning = true
endTime = Date().addingTimeInterval(duration) endTime = Date().addingTimeInterval(duration)
RoundCalculatorService.sharedInstance.isCalculating = false RoundCalculatorService.sharedInstance.isCalculating = false
} }
func timeLeft() -> Int { func timeLeft() -> Int {
if isRunning {
let remainingSeconds = Int(endTime.timeIntervalSince(Date())) let remainingSeconds = Int(endTime.timeIntervalSince(Date()))
if(remainingSeconds < 0 ){ if(remainingSeconds == 0) {
startWithDuration(duration: duration) isRunning = false
} }
return remainingSeconds return remainingSeconds
} }
// if(remainingSeconds < 0){
// startWithDuration(duration: duration)
// }
return 0
}
func isFinished() -> Bool { func isFinished() -> Bool {
return timeLeft() == 0 return timeLeft() == 0
} }

View File

@ -31,9 +31,10 @@ class Base: GKEntity{
self.position = position self.position = position
super.init() super.init()
addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: position)) let spritePos = position
addComponent(DefaultBaseComponent(texture: SKTexture(imageNamed: "Base"), position: spritePos))
if(team != nil && player != nil){ if(team != nil && player != nil){
addComponent(TeamComponent(team: team!, player: player!, position: position)) addComponent(TeamComponent(team: team!, player: player!, position: spritePos))
self.unitCount = 500 self.unitCount = 500
} }
} }

View File

@ -43,10 +43,10 @@ class EntityManager {
scene.addChild(modal.header) scene.addChild(modal.header)
scene.addChild(modal.body) scene.addChild(modal.body)
scene.addChild(modal.footer) scene.addChild(modal.footer)
isModal = true
} }
if let skillButtonNode = entity.component(ofType: AtkBoostSkillComponent.self)?.skillButtonNode { if let skillButtonNode = entity.component(ofType: AtkBoostSkillComponent.self)?.skillButtonNode {
scene.addChild(skillButtonNode) scene.addChild(skillButtonNode)
isModal = true
} }
if let skillButtonNode = entity.component(ofType: DefBoostSkillComponent.self)?.skillButtonNode { if let skillButtonNode = entity.component(ofType: DefBoostSkillComponent.self)?.skillButtonNode {
scene.addChild(skillButtonNode) scene.addChild(skillButtonNode)
@ -60,7 +60,6 @@ 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 {
@ -76,7 +75,6 @@ class EntityManager {
} }
if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode { if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode {
scene.addChild(cancelBtnNode) scene.addChild(cancelBtnNode)
isModal = true
} }
if let node = entity.component(ofType: SpinningLogoComponent.self)?.node { if let node = entity.component(ofType: SpinningLogoComponent.self)?.node {
scene.addChild(node) scene.addChild(node)
@ -97,6 +95,7 @@ class EntityManager {
modal.header.removeFromParent() modal.header.removeFromParent()
modal.body.removeFromParent() modal.body.removeFromParent()
modal.footer.removeFromParent() modal.footer.removeFromParent()
isModal = false
} }
if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode { if let sliderNode = entity.component(ofType: SliderComponent.self)?.sliderNode {
sliderNode.sliderKnob.removeFromParent() sliderNode.sliderKnob.removeFromParent()
@ -104,11 +103,9 @@ class EntityManager {
} }
if let modalButton = entity.component(ofType: ButtonComponent.self) { if let modalButton = entity.component(ofType: ButtonComponent.self) {
modalButton.buttonNode.removeFromParent() modalButton.buttonNode.removeFromParent()
isModal = false
} }
if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode { if let cancelBtnNode = entity.component(ofType: CancelBtnComponent.self)?.cancelBtnNode {
cancelBtnNode.removeFromParent() cancelBtnNode.removeFromParent()
isModal = false
} }
entities.remove(entity) entities.remove(entity)
} }
@ -119,9 +116,9 @@ class EntityManager {
let base = (entity as! Base) let base = (entity as! Base)
if base.changeOwnership { if base.changeOwnership {
//FIX-ME: Find a way to update the Component without deleting it upfront if (entity.component(ofType: TeamComponent.self) != nil) {
//TODO: outsource component handling to a generic function entity.component(ofType: TeamComponent.self)!.change(to: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team, to: (entities[0] as! Base).component(ofType: TeamComponent.self)!.player)
//base.removeComponent(ofType: TeamComponent.self) } else {
base.addComponent(TeamComponent( base.addComponent(TeamComponent(
team: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team, team: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team,
player: (entities[0] as! Base).component(ofType: TeamComponent.self)!.player, player: (entities[0] as! Base).component(ofType: TeamComponent.self)!.player,
@ -131,6 +128,7 @@ class EntityManager {
if let fire = entity.component(ofType: TeamComponent.self)?.fire{ if let fire = entity.component(ofType: TeamComponent.self)?.fire{
scene.addChild(fire) scene.addChild(fire)
} }
}
base.changeOwnership = false base.changeOwnership = false
} }
} }
@ -146,13 +144,15 @@ class EntityManager {
if snapBase.ownership != nil { if snapBase.ownership != nil {
getOwnerBySnapBase = MatchmakingHelper.sharedInstance.getGKPlayerByUsername(displayName: snapBase.ownership!) getOwnerBySnapBase = MatchmakingHelper.sharedInstance.getGKPlayerByUsername(displayName: snapBase.ownership!)
} else {
entity.removeComponent(ofType: TeamComponent.self)
} }
if getOwnerBySnapBase != nil { if getOwnerBySnapBase != nil {
base.changeOwnership = true base.changeOwnership = true
base.ownershipPlayer = getOwnerBySnapBase base.ownershipPlayer = getOwnerBySnapBase
//FIX-ME: Find a way to update the Component without deleting it upfront if (entity.component(ofType: TeamComponent.self) != nil) {
//TODO: outsource component handling to a generic function entity.component(ofType: TeamComponent.self)!.change(to: getTeamByPlayer(playerName: snapBase.ownership!), to: getOwnerBySnapBase!)
//entity.removeComponent(ofType: TeamComponent.self) } else {
entity.addComponent(TeamComponent( entity.addComponent(TeamComponent(
team: getTeamByPlayer(playerName: snapBase.ownership!), team: getTeamByPlayer(playerName: snapBase.ownership!),
player: getOwnerBySnapBase!, player: getOwnerBySnapBase!,
@ -165,6 +165,7 @@ class EntityManager {
} }
} }
} }
}
func getSnapshotBaseById(baseId: Int, snapshotModel: SnapshotModel) -> BaseEntityModel{ func getSnapshotBaseById(baseId: Int, snapshotModel: SnapshotModel) -> BaseEntityModel{
return snapshotModel.baseEntites.filter { $0.baseId == baseId }[0] return snapshotModel.baseEntites.filter { $0.baseId == baseId }[0]
@ -257,4 +258,8 @@ class EntityManager {
return SnapshotModel(baseEntites: snapBase) return SnapshotModel(baseEntites: snapBase)
} }
func getTimer() -> TimerComponent {
return entities.filter{$0 is HUD}[0].component(ofType: TimerComponent.self)!
}
} }

View File

@ -58,6 +58,7 @@ class Modal: GKEntity{
for base in currentDraggedBase!.adjacencyList { for base in currentDraggedBase!.adjacencyList {
if base == collisionBase { if base == collisionBase {
EntityManager.sharedInstance.update((currentDraggedBase?.doPlayerMoveTypeToBase(base: base, playerMoveType: PlayerMoveType.AtkMove, units: Int(GameScene.sendUnits)))!) EntityManager.sharedInstance.update((currentDraggedBase?.doPlayerMoveTypeToBase(base: base, playerMoveType: PlayerMoveType.AtkMove, units: Int(GameScene.sendUnits)))!)
GameScene.sendUnits = 0
} }
} }
} }

View File

@ -120,6 +120,7 @@ class MatchmakingHelper: NSObject, GKMatchmakerViewControllerDelegate, GKMatchDe
if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) { if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) {
DataService.sharedInstance.snapshotModel = snapshotModel DataService.sharedInstance.snapshotModel = snapshotModel
EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: snapshotModel) EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: snapshotModel)
EntityManager.sharedInstance.getTimer().startWithDuration(duration: 31)
} }
if let mapModel = try? jsonDecoder.decode(MapGenerationModel.self, from: data) { if let mapModel = try? jsonDecoder.decode(MapGenerationModel.self, from: data) {

View File

@ -45,9 +45,9 @@ class MultiplayerNetwork{
let encoder = JSONEncoder() let encoder = JSONEncoder()
let encoded = (try? encoder.encode(playerMoves))! let encoded = (try? encoder.encode(playerMoves))!
sendDataToHost(data: encoded) sendDataToHost(data: encoded)
}
DataService.sharedInstance.localPlayerMoves.removeAll() DataService.sharedInstance.localPlayerMoves.removeAll()
} }
}
func sendHostIdentifier() { func sendHostIdentifier() {
let encoder = JSONEncoder() let encoder = JSONEncoder()

Binary file not shown.

View File

@ -84,20 +84,35 @@ class RoundCalculatorService {
for base in currentSnapshotModel!.baseEntites { for base in currentSnapshotModel!.baseEntites {
if base.baseId == playerMoveWithMaxUnits.value.toBase { if base.baseId == playerMoveWithMaxUnits.value.toBase {
if base.ownership == nil {
base.unitCount += playerMoveWithMaxUnits.value.unitCount base.unitCount += playerMoveWithMaxUnits.value.unitCount
if playerMoveWithMaxUnits.value.unitCount == 0 { if playerMoveWithMaxUnits.value.unitCount == 0 {
base.ownership = nil base.ownership = nil
} else { } else {
base.ownership = playerMoveWithMaxUnits.key base.ownership = playerMoveWithMaxUnits.key
} }
} else {
if base.unitCount < playerMoveWithMaxUnits.value.unitCount {
base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount
base.ownership = playerMoveWithMaxUnits.key
} else if (base.unitCount == playerMoveWithMaxUnits.value.unitCount) {
base.ownership = nil
} else {
base.unitCount -= playerMoveWithMaxUnits.value.unitCount
}
}
} }
} }
} }
baseSpecificMoves.removeValue(forKey: baseId) baseSpecificMoves.removeValue(forKey: baseId)
} }
allPlayerMoves.removeAll() allPlayerMoves.removeAll()
DataService.sharedInstance.localPlayerMoves.removeAll()
MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers() MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers()
DataService.sharedInstance.snapshotModel = currentSnapshotModel
EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: currentSnapshotModel!) EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: currentSnapshotModel!)
sleep(1)
EntityManager.sharedInstance.getTimer().startWithDuration(duration: 31)
os_log("Finished calculating Round", log: RoundCalculatorService.LOG, type: .info) os_log("Finished calculating Round", log: RoundCalculatorService.LOG, type: .info)
} }

View File

@ -13,7 +13,6 @@ import GameKit
class GameScene: SKScene{ class GameScene: SKScene{
var isMoveTouch = false var isMoveTouch = false
var currentDraggedBasePos = CGPoint()
var currentDraggedBase : Base? var currentDraggedBase : Base?
static var sendUnits: CGFloat = 0 static var sendUnits: CGFloat = 0
var collisionBase: Base? var collisionBase: Base?
@ -26,14 +25,15 @@ class GameScene: SKScene{
} }
func initMap() { func initMap() {
if (DataService.sharedInstance.gameHost?.playerName == GKLocalPlayer.local.displayName) { if (DataService.sharedInstance.gameHost?.playerName == GKLocalPlayer.local.displayName) {
let mapModel = MapFactory(scene: self, entityManager: EntityManager.sharedInstance).loadMap() let mapModel = MapFactory(scene: self, entityManager: EntityManager.sharedInstance).loadMap()
MultiplayerNetwork.sharedInstance.sendMapModelToPlayers(mapModel: mapModel) MultiplayerNetwork.sharedInstance.sendMapModelToPlayers(mapModel: mapModel)
}
DataService.sharedInstance.setSnapshotModel(snapshotModel: EntityManager.sharedInstance.getSnapshotModel()) DataService.sharedInstance.setSnapshotModel(snapshotModel: EntityManager.sharedInstance.getSnapshotModel())
} }
if CommandLine.arguments.contains("--no-matchmaking") {
MapFactory(scene: self, entityManager: EntityManager.sharedInstance).loadMap()
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { guard let touch = touches.first else {
@ -44,8 +44,8 @@ class GameScene: SKScene{
if isMoveTouch{ if isMoveTouch{
isMoveTouch = false isMoveTouch = false
currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = currentDraggedBasePos currentDraggedBase!.component(ofType: DefaultBaseComponent.self)?.spriteNode.position = currentDraggedBase!.position
currentDraggedBase!.component(ofType: TeamComponent.self)?.fire.position = currentDraggedBasePos currentDraggedBase!.component(ofType: TeamComponent.self)?.fire.position = currentDraggedBase!.position
addAttackDetails(touchLocation: touchLocation) addAttackDetails(touchLocation: touchLocation)
} }
@ -53,6 +53,7 @@ class GameScene: SKScene{
for entity in EntityManager.sharedInstance.entities { for entity in EntityManager.sharedInstance.entities {
let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode let spriteNode = entity.component(ofType: DefaultBaseComponent.self)?.spriteNode
//FIXME: this is confusing
addBaseDetails(touchLocation: touchLocation, spriteNode: spriteNode, touches: touches, event: event, entity: entity) addBaseDetails(touchLocation: touchLocation, spriteNode: spriteNode, touches: touches, event: event, entity: entity)
} }
} }
@ -85,7 +86,8 @@ class GameScene: SKScene{
func addBaseDetails(touchLocation: CGPoint, spriteNode: SKNode?, touches: Set<UITouch>, event: UIEvent?, entity: GKEntity){ func addBaseDetails(touchLocation: CGPoint, spriteNode: SKNode?, touches: Set<UITouch>, event: UIEvent?, entity: GKEntity){
if atPoint(touchLocation) == spriteNode && !EntityManager.sharedInstance.isModal { if atPoint(touchLocation) == spriteNode && !EntityManager.sharedInstance.isModal {
spriteNode?.touchesBegan(touches, with: event) spriteNode?.touchesBegan(touches, with: event)
if !EntityManager.sharedInstance.isModal { if let baseEntity = entity as? Base {
if baseEntity.ownershipPlayer == GKLocalPlayer.local {
for child in self.children { for child in self.children {
if(child.name != "fire"){ if(child.name != "fire"){
child.alpha = 0.3 child.alpha = 0.3
@ -94,7 +96,10 @@ class GameScene: SKScene{
EntityManager.sharedInstance.add(Modal(modaltype: .BaseDetails, EntityManager.sharedInstance.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),
gameScene: self, currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase)) gameScene: self,
currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase))
}
} }
} }
} }
@ -104,10 +109,13 @@ class GameScene: SKScene{
if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode { if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode {
collisionBase = base collisionBase = base
// TODO: change interaction based on collision instead of touchlocation // TODO: change interaction based on collision instead of touchlocation
if currentDraggedBase!.unitCount > 1 {
EntityManager.sharedInstance.add(Modal(modaltype: .BaseAttack, EntityManager.sharedInstance.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),
gameScene: self, currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase)) gameScene: self, currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase))
GameScene.sendUnits = CGFloat(currentDraggedBase!.unitCount / 2)
}
} }
} }
} }
@ -116,6 +124,13 @@ class GameScene: SKScene{
for e in EntityManager.sharedInstance.entities{ for e in EntityManager.sharedInstance.entities{
if let body = e.component(ofType: ModalContentComponent.self)?.body{ if let body = e.component(ofType: ModalContentComponent.self)?.body{
GameScene.sendUnits = ((e.component(ofType: SliderComponent.self)?.sliderNode.getValue ?? 0) * CGFloat((e as! Modal).unitCount)).rounded(.up) GameScene.sendUnits = ((e.component(ofType: SliderComponent.self)?.sliderNode.getValue ?? 0) * CGFloat((e as! Modal).unitCount)).rounded(.up)
//TODO: refactor this quick and dirty fix
if GameScene.sendUnits == 0 {
GameScene.sendUnits = 1
} else if Int(GameScene.sendUnits) == currentDraggedBase?.unitCount {
GameScene.sendUnits -= 1
}
body.text = "Schicke \(GameScene.sendUnits) Einheiten " body.text = "Schicke \(GameScene.sendUnits) Einheiten "
} }
} }
@ -123,8 +138,8 @@ class GameScene: SKScene{
func checkBases(bases: Set<Base>, touchLocation: CGPoint){ func checkBases(bases: Set<Base>, touchLocation: CGPoint){
for base in bases { for base in bases {
if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode{ if !isMoveTouch { if atPoint(touchLocation) == base.component(ofType: DefaultBaseComponent.self)?.spriteNode{
currentDraggedBasePos = base.component(ofType: DefaultBaseComponent.self)!.spriteNode.position if !isMoveTouch {
currentDraggedBase = base currentDraggedBase = base
} }
isMoveTouch = true isMoveTouch = true