Хорошо, наша игра идет хорошо, и вот фото, подтверждающее это.
Если вы только что наткнулись на эту статью, вам нужно сначала прочитать эти, чтобы попасть сюда.
Naked Networking с SwiftUI
Больше Naked Networking, больше SwiftUI
Naked Networking и SwiftUI, план игры
Naked Networking и SwiftUI, геймификация
Naked Networking и SwiftUI, геймификация II
Теперь нам нужно следить за счетом. Мы могли бы сделать две простые метки, с названиями выигранных игр и проигранных игр, но не лучше ли иметь более наглядный индикатор. Давайте поставим в строке o или x, чтобы указать, сколько игр вы сыграли, сколько выиграли и сколько проиграли. Мы будем играть по 7 игр за раунд.
Как только раунд закончится, нам понадобится средство для сброса настроек, чтобы мы могли начать все сначала. Но ладно, забегаю вперед.
SwiftUI
Основные изменения в ContentView.swift. Нам нужен горизонтальный StackView и список индикаторов, чтобы сказать, выиграли ли мы [o] или проиграли [an x].
@State var game = 1 @State var game1 = "" @State var game2 = "" @State var game3 = "" @State var game4 = "" @State var game5 = "" @State var game6 = "" @State var game7 = "" HStack { Text(game1) Text(game2) Text(game3) Text(game4) Text(game5) Text(game6) Text(game7) }
Здесь нам нужно использовать переменные @State, потому что мы будем изменять значения в ContentView.swift во время игры.
Я попытался создать их массив, как в UIKit, но, похоже, на данный момент он не поддерживается в SwiftUI, поэтому я пошел на компромисс и создал функцию для установки каждой из игр в правильное состояние во время игры.
func winWin(game: Int, leader: String) { switch self.game { case 1: self.game1 = leader case 2: self.game2 = leader case 3: self.game3 = leader case 4: self.game4 = leader case 5: self.game5 = leader case 6: self.game6 = leader case 7: self.game7 = leader default: break } self.game = self.game + 1 }
Каждый раз, когда вы его вызываете, он устанавливает следующую игру в серии. Очевидно, вам нужно вызвать эту функцию на обоих клиентах. Поэтому мы добавляем его в раздел «Вы проиграли» и «Вы выиграли». Я собираюсь вставить весь блок кода, чтобы вы могли перепроверить, что у вас есть все, что мы сделали до сих пор.
... .onReceive(pingPublisher) { ( data ) in print("data ",data) self.hit = false self.disable = false self.volley = "" var countDown = Float(data) if countDown! > 4 { countDown = 4 } self.youLose = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { timer in countDown = countDown! - 0.1 self.timeToDie = String(countDown!) if countDown! < 0.0 && !self.disable { self.disable = true self.youLose?.invalidate() self.volley = "You Lose" self.globalVariable.score = "lose" self.winWin(game: self.game,leader: "x") if self.model.state { makeConnect(port: "1984", message: "win") } else { makeConnect(port: "4891", message: "win") } } }) } ...
И для победителя.
... .onReceive(winPublisher, perform: { self.hit = false self.volley = "You Win" self.disable = false self.winWin(game: self.game,leader: "o") self.globalVariable.score = "" }) ...
Добавьте разделы, скомпилируйте и вперед. Это должно работать с единственным возвратом, ничего не происходит, когда вы подходите к концу раунда, и вы не можете сбросить его. Нам нужно больше. Чувствую, как эти маленькие проекты становятся все больше и больше.
Объявить, кто выиграет, а кто проиграет, мы можем сделать в функции winWin. Добавьте этот код в конец. Новый код выделен полужирным курсивом.
@State var remoteWin = 0 @State var localWin = 0 @State var localLose = 0 @State var remoteLose = 0 @State var newGame = false .... self.game = self.game + 1 if leader == "o" && !self.model.state { remoteWin = remoteWin + 1 } if leader == "o" && self.model.state { localWin = localWin + 1 } if leader == "x" && !self.model.state { remoteLose = remoteLose + 1 } if leader == "x" && self.model.state { localLose = localLose + 1 } if game == 7 { newGame = true if self.model.state { self.volley = "game over yang wins " + " " + String(localWin) + " ying wins " + String(localLose) } else { self.volley = "game over ying wins " + " " + String(remoteWin) + " yang wins " + String(remoteLose) } }
Но подождите, нам нужен сброс. Нам нужен другой протокол. Давайте ненадолго вернемся к сети и добавим ее.
Сеть
let gamePublisher = PassthroughSubject<Void, Never>()
Нам также нужно изменить нашу функцию приема, теперь у нее есть три разных случая, с которыми нужно иметь дело.
DispatchQueue.main.async { globalVariable.score = backToString if backToString == "ping" || backToString == "pong" { pingPublisher.send(string2Send) } if backToString == "win" { winPublisher.send() } if backToString == "game" { gamePublisher.send() } }
Я мог бы использовать оператор case здесь, если я в конечном итоге добавлю что-то еще, я это сделаю. Вернемся к SwiftUI.
SwiftUI
Итак, нам нужна еще одна кнопка. Добавьте его под HStack, который вы только что установили.
@State var newGame = false ... Button(action: { self.reset() self.disable = false self.remoteWin = 0 self.localWin = 0 self.volley = "" self.newGame = false self.game = 1 self.timeToDie = "" self.globalVariable.score = "" if self.model.state { makeConnect(port: "1984", message: "game") } else { makeConnect(port: "4891", message: "game") } }) { Text("new game").disabled(newGame ? false: true) }.onReceive(gamePublisher) { (_) in self.reset() self.disable = false self.remoteWin = 0 self.localWin = 0 self.volley = "" self.newGame = false self.game = 1 self.timeToDie = "" self.globalVariable.score = "" }
Признаюсь, это немного монструозного кода. Примечательный момент в нем, тот факт, что мы отключаем или активируем кнопку на значении переменной newGame. Я украл этот кусок кода в предыдущем разделе, пока вы не смотрели. Вы же не хотите сбрасывать сериал посреди этого, не так ли?
Хорошо, если у вас все на месте, и я ничего не упустил, вы сможете сыграть одну или две игры даже в несколько раундов.
Давайте остановимся на минутку, подведем итоги и посмотрим, что, как мы сказали, мы могли бы сделать помимо этого. Мы говорили о большем количестве кнопок, мы говорили об анимации. Но когда я перешел к седьмой статье в этой серии, я только что понял, что мы оставили там этот противный жестко закодированный IP-адрес. Нам нужно это исправить. Это должно быть предметом статьи семь.