From 94dc84490554bbe62fbe698986f0c4c837e94c0e Mon Sep 17 00:00:00 2001 From: Mathieu GROUSSEAU Date: Wed, 25 Jun 2025 06:41:43 +0200 Subject: [PATCH] UI polish --- App/App/Localizable.xcstrings | 64 +++++++++++++++++++++++++++++++ App/App/SpriteKit/GameScene.swift | 7 ---- App/App/View/IngameView.swift | 31 +++++++++++---- App/App/ViewModel/InGameVM.swift | 29 ++++---------- 4 files changed, 95 insertions(+), 36 deletions(-) diff --git a/App/App/Localizable.xcstrings b/App/App/Localizable.xcstrings index 55932e6..c839414 100644 --- a/App/App/Localizable.xcstrings +++ b/App/App/Localizable.xcstrings @@ -335,6 +335,70 @@ } } }, + "inGame.status.new" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Loading..." + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Préparation..." + } + } + } + }, + "inGame.status.result.even" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Even" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ex aequo" + } + } + } + }, + "inGame.status.result.winner %@" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Winner is %@" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@ remporte la partie" + } + } + } + }, + "inGame.status.turn %@" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@'s turn" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "À %@ de jouer" + } + } + } + }, "mainMenu.button.newGame" : { "extractionState" : "manual", "localizations" : { diff --git a/App/App/SpriteKit/GameScene.swift b/App/App/SpriteKit/GameScene.swift index 0893c5a..fcb2026 100644 --- a/App/App/SpriteKit/GameScene.swift +++ b/App/App/SpriteKit/GameScene.swift @@ -39,13 +39,6 @@ public class GameScene: SKScene { self.draggablePiece.piece = .init(withOwner: $0) }) self.cancellables.append(vm.$currentBoard.sink(receiveValue: self.updateBoard)) - self.cancellables.append(vm.$paused.sink { paused in - self.draggablePiece.onDragHandler = if paused { - nil - } else { - self.onPieceDragEnd - } - }) vm.game.addGameStartedListener { _ in DispatchQueue.main.async { diff --git a/App/App/View/IngameView.swift b/App/App/View/IngameView.swift index 12bdcf8..fd6bc77 100644 --- a/App/App/View/IngameView.swift +++ b/App/App/View/IngameView.swift @@ -1,10 +1,3 @@ -// -// IngameView.swift -// App -// -// Created by etudiant2 on 21/05/2025. -// - import SwiftUI import SpriteKit import Connect4Core @@ -29,6 +22,24 @@ struct IngameView: View { ) } + let statusText: LocalizedStringKey = switch (self.vm.result) { + case .even: "inGame.status.result.even" + case .winner(let winner, _): + switch (winner) { + case .player1: "inGame.status.result.winner \(self.vm.player1.name)" + case .player2: "inGame.status.result.winner \(self.vm.player2.name)" + default: fatalError("Unreachable") + } + default: + switch (self.vm.currentPlayer) { + case .player1: "inGame.status.turn \(self.vm.player1.name)" + case .player2: "inGame.status.turn \(self.vm.player2.name)" + default: "inGame.status.new" + } + } + + Text(statusText).tint(.accentColor) + Spacer() VStack(alignment: .center) { @@ -99,7 +110,11 @@ private struct PlayerView: View { VStack(alignment: textAlignment) { Text(who.name) - Text(LocalizedStringKey(who.type.baseTranslationKey)) + let type = String(localized: String.LocalizationValue(who.type.baseTranslationKey)) + + if type != who.name { + Text(type) + } } if !self.dockLeft { diff --git a/App/App/ViewModel/InGameVM.swift b/App/App/ViewModel/InGameVM.swift index 2b499dc..120080e 100644 --- a/App/App/ViewModel/InGameVM.swift +++ b/App/App/ViewModel/InGameVM.swift @@ -37,17 +37,7 @@ class IngameVM: ObservableObject { var currentBoard: Board @Published - var paused: Bool = false { - didSet { - Task.detached(priority: .userInitiated) { - if (self.paused) { - // TODO - } else { - // TODO - } - } - } - } + var result: Connect4Core.Result = .notFinished private var running: Bool = false @@ -80,11 +70,10 @@ class IngameVM: ObservableObject { self.scene = GameScene(viewModel: self) game.addGameOverListener { board, result, player in - print("game over") DispatchQueue.main.async { self.currentPlayer = .noOne + self.result = result } - // TODO } game.addGameChangedListener { game, result in if game.players.contains(where: { $0.value is ReplayPlayer }) { @@ -117,10 +106,6 @@ class IngameVM: ObservableObject { withFolderName: Persistance.saveDirectory ) } - game.addGameStartedListener { board in - print("game started") - // TODO - } game.addBoardChangedListener { board, lastCell in DispatchQueue.main.async { self.currentBoard = board @@ -152,15 +137,17 @@ class IngameVM: ObservableObject { } private static func playerOf(settings: PlayerSettingsVM, id: Owner) -> Player? { + let name = settings.name.nilIfEmpty ?? String(localized: String.LocalizationValue(settings.type.baseTranslationKey)) + return switch (settings.type) { case .Human: - HumanPlayer(withName: settings.name, andId: id) + HumanPlayer(withName: name, andId: id) case .AIRandom: - RandomPlayer(withName: settings.name, andId: id) + RandomPlayer(withName: name, andId: id) case .AIFinnishHim: - FinnishHimPlayer(withName: settings.name, andId: id) + FinnishHimPlayer(withName: name, andId: id) case .AISimpleNegaMax: - SimpleNegaMaxPlayer(withName: settings.name, andId: id) + SimpleNegaMaxPlayer(withName: name, andId: id) } } }