From 588e1c18306910e9ea09f4289aa5f92573583d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Regnault?= Date: Fri, 21 Jun 2024 12:14:50 +0200 Subject: [PATCH] :construction: --- .../DouShouQi_App.xcodeproj/project.pbxproj | 24 ++++++++++++-- .../Player/SelectPlayerButtonView.swift | 1 - .../Components/Scene/GameScene.swift | 25 +++++++++++---- .../Components/Scene/SpriteMeeple.swift | 15 ++++++--- .../ViewModel/Game/PlayingGameVM.swift | 32 +++++++++++++++++++ .../DouShouQi_App/Views/Game/GameView.swift | 1 + 6 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 DouShouQi_App/DouShouQi_App/ViewModel/Game/PlayingGameVM.swift diff --git a/DouShouQi_App/DouShouQi_App.xcodeproj/project.pbxproj b/DouShouQi_App/DouShouQi_App.xcodeproj/project.pbxproj index 79ff41e..ae2026d 100644 --- a/DouShouQi_App/DouShouQi_App.xcodeproj/project.pbxproj +++ b/DouShouQi_App/DouShouQi_App.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 6437FF132C25846F009D0EAF /* PlayingGameVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6437FF122C25846F009D0EAF /* PlayingGameVM.swift */; }; + 6437FF142C25870C009D0EAF /* DSQ.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EC62C5322C1C188F0048CD0B /* DSQ.xcframework */; }; + 6437FF152C25870C009D0EAF /* DSQ.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EC62C5322C1C188F0048CD0B /* DSQ.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 6458345C2BF5F92300E18321 /* DouShouQi_AppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6458345B2BF5F92300E18321 /* DouShouQi_AppApp.swift */; }; 6458345E2BF5F92300E18321 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6458345D2BF5F92300E18321 /* ContentView.swift */; }; 645834602BF5F92500E18321 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6458345F2BF5F92500E18321 /* Assets.xcassets */; }; @@ -56,7 +59,6 @@ EC62C5252C0F68830048CD0B /* PlayerVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC62C5242C0F68830048CD0B /* PlayerVM.swift */; }; EC62C5292C1974000048CD0B /* PlayersVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC62C5282C1974000048CD0B /* PlayersVM.swift */; }; EC62C52D2C197ED10048CD0B /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC62C52C2C197ED10048CD0B /* Player.swift */; }; - EC62C5332C1C188F0048CD0B /* DSQ.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EC62C5322C1C188F0048CD0B /* DSQ.xcframework */; }; EC62C5382C1C64EE0048CD0B /* CoreManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC62C5372C1C64EE0048CD0B /* CoreManager.swift */; }; EC62C53D2C1C69200048CD0B /* DouShouQi_App.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = EC62C53B2C1C69200048CD0B /* DouShouQi_App.xcdatamodeld */; }; EC62C53F2C1C6D1A0048CD0B /* CDPlayerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC62C53E2C1C6D1A0048CD0B /* CDPlayerExtension.swift */; }; @@ -84,7 +86,22 @@ }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + 6437FF162C25870C009D0EAF /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 6437FF152C25870C009D0EAF /* DSQ.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ + 6437FF122C25846F009D0EAF /* PlayingGameVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayingGameVM.swift; sourceTree = ""; }; 645834582BF5F92300E18321 /* DouShouQi_App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DouShouQi_App.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6458345B2BF5F92300E18321 /* DouShouQi_AppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DouShouQi_AppApp.swift; sourceTree = ""; }; 6458345D2BF5F92300E18321 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -154,7 +171,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - EC62C5332C1C188F0048CD0B /* DSQ.xcframework in Frameworks */, + 6437FF142C25870C009D0EAF /* DSQ.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -300,6 +317,7 @@ children = ( 646FA83D2C072340001466BA /* GameVM.swift */, 646FA8422C0730D6001466BA /* HistoricVM.swift */, + 6437FF122C25846F009D0EAF /* PlayingGameVM.swift */, ); path = Game; sourceTree = ""; @@ -479,6 +497,7 @@ 645834542BF5F92300E18321 /* Sources */, 645834552BF5F92300E18321 /* Frameworks */, 645834562BF5F92300E18321 /* Resources */, + 6437FF162C25870C009D0EAF /* Embed Frameworks */, ); buildRules = ( ); @@ -652,6 +671,7 @@ 646F04BE2C0F54C0003C8600 /* SettingsVM.swift in Sources */, EC62C52D2C197ED10048CD0B /* Player.swift in Sources */, EC62C5292C1974000048CD0B /* PlayersVM.swift in Sources */, + 6437FF132C25846F009D0EAF /* PlayingGameVM.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/DouShouQi_App/DouShouQi_App/Components/Player/SelectPlayerButtonView.swift b/DouShouQi_App/DouShouQi_App/Components/Player/SelectPlayerButtonView.swift index ce3ebb0..f70d42e 100644 --- a/DouShouQi_App/DouShouQi_App/Components/Player/SelectPlayerButtonView.swift +++ b/DouShouQi_App/DouShouQi_App/Components/Player/SelectPlayerButtonView.swift @@ -116,7 +116,6 @@ struct SelectPlayerButtonView: View { struct SelectPlayerButtonView_Previews: PreviewProvider { static var previews: some View { - @StateObject var playersVM = PlayersVM() SelectPlayerButtonView(playersVM: PlayersVM()) } } diff --git a/DouShouQi_App/DouShouQi_App/Components/Scene/GameScene.swift b/DouShouQi_App/DouShouQi_App/Components/Scene/GameScene.swift index 6f955a2..0ad1191 100644 --- a/DouShouQi_App/DouShouQi_App/Components/Scene/GameScene.swift +++ b/DouShouQi_App/DouShouQi_App/Components/Scene/GameScene.swift @@ -53,11 +53,24 @@ class GameScene : SKScene { for piece in pieces.flatMap({owner, pieces in pieces.values}) { self.addChild(piece) - //piece.setOnMove(onMove: onMeepleMove) + piece.setOnMove(onMove: onMeepleMove) } initializeBoard(game.board) + game.addInvalidMoveCallbacksListener { _, move, player, result in + if result { + return + } + print("**************************************") + print("⚠️⚠️⚠️⚠️ Invalid Move detected: \(move) by \(player.name) (\(player.id))") + print("**************************************") + + } + + Task { + try await game.start() + } } func initializeBoard(_ board: Board) { @@ -77,18 +90,18 @@ class GameScene : SKScene { super.init(coder: aDecoder); } - func onMeepleMove(_ start: CGPoint, _ end: CGPoint) async { + func onMeepleMove(_ start: CGPoint, _ end: CGPoint) { let owner = game.rules.getNextPlayer() let player = game.players[owner] let move = Move(of: owner, fromRow: Int(start.x), andFromColumn: Int(start.y), toRow: Int(end.x), andToColumn: Int(end.y)) - print("Meeple moved") - - try! await (player as! HumanPlayer).chooseMove(move) - + print("Meeple moved = ", start, " -> ", end) + Task { + try! await (player as! HumanPlayer).chooseMove(move) + } } public func start() async throws { diff --git a/DouShouQi_App/DouShouQi_App/Components/Scene/SpriteMeeple.swift b/DouShouQi_App/DouShouQi_App/Components/Scene/SpriteMeeple.swift index 0a74775..7a34e9a 100644 --- a/DouShouQi_App/DouShouQi_App/Components/Scene/SpriteMeeple.swift +++ b/DouShouQi_App/DouShouQi_App/Components/Scene/SpriteMeeple.swift @@ -19,7 +19,7 @@ class SpriteMeeple : SKNode { var originalSize: CGSize var originalEllipseSize: CGSize - var onMove: ((CGPoint, CGPoint) async -> ())? + var onMove: ((CGPoint, CGPoint) -> ())? var cellPosition: CGPoint{ didSet(cellPosition){ @@ -28,6 +28,12 @@ class SpriteMeeple : SKNode { } } + private var oldCellPosition: CGPoint? + + func getCellPosition() -> CGPoint { + return CGPoint(x: Int((self.position.x - SpriteMeeple.offset.x)/SpriteMeeple.direction.dx), y: Int((self.position.y - SpriteMeeple.offset.y)/SpriteMeeple.direction.dy)) + } + init(imageNamed imageName: String, size: CGSize, backgroundColor: UIColor, imageRotation : Double = 0){ imageNode = SKSpriteNode(imageNamed: imageName) originalSize = CGSize(width: 80, height: 65) @@ -67,6 +73,8 @@ class SpriteMeeple : SKNode { } override func touchesBegan(_ touches: Set, with event: UIEvent?){ + self.oldCellPosition = getCellPosition() + imageNode.size = CGSize(width: imageNode.size.width * 1.1, height: imageNode.size.height * 1.1) ellipseNode.path = SKShapeNode(ellipseOf: CGSize(width: originalEllipseSize.width*1.1, height: originalEllipseSize.height*1.1)).path self.zPosition = 1 @@ -88,13 +96,12 @@ class SpriteMeeple : SKNode { imageNode.size = originalSize ellipseNode.path = SKShapeNode(ellipseOf: originalEllipseSize).path - if let onMove: (CGPoint, CGPoint) async -> () = onMove { - //onMove(CGPoint(x: 100, y: 100), CGPoint(x: 200, y: 100)) + if let onMove: (CGPoint, CGPoint) -> () = onMove { + onMove(self.oldCellPosition!, self.getCellPosition()) } self.zPosition = 0 } - override func touchesMoved(_ touches: Set, with event: UIEvent?){ self.position = touches.first?.location(in: parent!) ?? CGPoint(x: 0, y: 0) diff --git a/DouShouQi_App/DouShouQi_App/ViewModel/Game/PlayingGameVM.swift b/DouShouQi_App/DouShouQi_App/ViewModel/Game/PlayingGameVM.swift new file mode 100644 index 0000000..07db904 --- /dev/null +++ b/DouShouQi_App/DouShouQi_App/ViewModel/Game/PlayingGameVM.swift @@ -0,0 +1,32 @@ +// +// PlayingGameVM.swift +// DouShouQi_App +// +// Created by Rémi REGNAULT on 21/06/2024. +// + +import Foundation +import DouShouQiModel + +class PlayingGameVM: ObservableObject { + + // Properties + @Published var game: Game + + // Computed properties + public var currentPlayerName: String { game.players[game.rules.getNextPlayer()]?.name ?? (game.rules.getNextPlayer() == .player1 : "p1" ?? "p2") } + + // Inits + init(withGame game: Game) { + self.game = game + } + + init?(withRules rules: Rules, andPlayer1 p1: DouShouQiModel.Player, andPlayer2 p2: DouShouQiModel.Player) { + do { + self.game = try Game(withRules: rules, andPlayer1: p1, andPlayer2: p2) + } catch { + print("Error") + } + } + +} diff --git a/DouShouQi_App/DouShouQi_App/Views/Game/GameView.swift b/DouShouQi_App/DouShouQi_App/Views/Game/GameView.swift index 45ad8f4..c322d33 100644 --- a/DouShouQi_App/DouShouQi_App/Views/Game/GameView.swift +++ b/DouShouQi_App/DouShouQi_App/Views/Game/GameView.swift @@ -10,6 +10,7 @@ import SpriteKit struct GameView: View { var gameScene : GameScene = GameScene(size: CGSize(width: 700, height: 900)) + var body: some View { VStack { TopGameBoard().frame(maxHeight: 200)