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

@ -14,7 +14,7 @@ class TeamComponent: GKComponent {
var team: Team var team: Team
var player: GKPlayer var player: GKPlayer
let fire: SKEmitterNode let fire: SKEmitterNode
init(team: Team, player: GKPlayer, position: CGPoint) { init(team: Team, player: GKPlayer, position: CGPoint) {
fire = SKEmitterNode(fileNamed: "Fire")! fire = SKEmitterNode(fileNamed: "Fire")!
fire.zPosition = -1 fire.zPosition = -1
@ -22,21 +22,30 @@ class TeamComponent: GKComponent {
fire.name = "fire" fire.name = "fire"
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,16 +26,24 @@ 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 {
let remainingSeconds = Int(endTime.timeIntervalSince(Date())) if isRunning {
if(remainingSeconds < 0 ){ let remainingSeconds = Int(endTime.timeIntervalSince(Date()))
startWithDuration(duration: duration) if(remainingSeconds == 0) {
isRunning = false
}
return remainingSeconds
} }
return remainingSeconds
// if(remainingSeconds < 0){
// startWithDuration(duration: duration)
// }
return 0
} }
func isFinished() -> Bool { func isFinished() -> Bool {

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,17 +116,18 @@ 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,
position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)! position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!
)
) )
) 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,21 +144,24 @@ 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!,
position: (entity.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)! position: (entity.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!
)
) )
) if let fire = entity.component(ofType: TeamComponent.self)?.fire{
if let fire = entity.component(ofType: TeamComponent.self)?.fire{ scene.addChild(fire)
scene.addChild(fire) }
} }
} }
} }
@ -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,8 +45,8 @@ 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() {

Binary file not shown.

View File

@ -54,7 +54,7 @@ class RoundCalculatorService {
} }
playerMovesByBase.removeValue(forKey: playerName) playerMovesByBase.removeValue(forKey: playerName)
} }
for (_, playerMoves) in playerMovesByBase { for (_, playerMoves) in playerMovesByBase {
for playerMove in playerMoves { for playerMove in playerMoves {
for base in currentSnapshotModel!.baseEntites { for base in currentSnapshotModel!.baseEntites {
@ -84,11 +84,22 @@ class RoundCalculatorService {
for base in currentSnapshotModel!.baseEntites { for base in currentSnapshotModel!.baseEntites {
if base.baseId == playerMoveWithMaxUnits.value.toBase { if base.baseId == playerMoveWithMaxUnits.value.toBase {
base.unitCount += playerMoveWithMaxUnits.value.unitCount if base.ownership == nil {
if playerMoveWithMaxUnits.value.unitCount == 0 { base.unitCount += playerMoveWithMaxUnits.value.unitCount
base.ownership = nil if playerMoveWithMaxUnits.value.unitCount == 0 {
base.ownership = nil
} else {
base.ownership = playerMoveWithMaxUnits.key
}
} else { } else {
base.ownership = playerMoveWithMaxUnits.key 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
}
} }
} }
} }
@ -96,8 +107,12 @@ class RoundCalculatorService {
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,13 +25,14 @@ 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())
}
if CommandLine.arguments.contains("--no-matchmaking") {
MapFactory(scene: self, entityManager: EntityManager.sharedInstance).loadMap()
} }
DataService.sharedInstance.setSnapshotModel(snapshotModel: EntityManager.sharedInstance.getSnapshotModel())
} }
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
@ -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,16 +86,20 @@ 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 {
for child in self.children { if baseEntity.ownershipPlayer == GKLocalPlayer.local {
if(child.name != "fire"){ for child in self.children {
child.alpha = 0.3 if(child.name != "fire"){
child.alpha = 0.3
}
} }
EntityManager.sharedInstance.add(Modal(modaltype: .BaseDetails,
base: entity as! Base,
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
gameScene: self,
currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase))
} }
EntityManager.sharedInstance.add(Modal(modaltype: .BaseDetails,
base: entity as! Base,
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
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
EntityManager.sharedInstance.add(Modal(modaltype: .BaseAttack, if currentDraggedBase!.unitCount > 1 {
base: currentDraggedBase!, EntityManager.sharedInstance.add(Modal(modaltype: .BaseAttack,
anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2), base: currentDraggedBase!,
gameScene: self, currentDraggedBase: currentDraggedBase, touchLocation: touchLocation, collisionBase: collisionBase)) anchorPoint: CGPoint(x: self.size.width / 2 , y: self.size.height / 2),
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,9 +138,9 @@ 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
moveFireAndBase(base: base, touchLocation: touchLocation) moveFireAndBase(base: base, touchLocation: touchLocation)