diff --git a/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj b/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj index ae8cdcb..b70f1e4 100644 --- a/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj +++ b/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj @@ -10,6 +10,8 @@ 82740EBE2C19762C009711A5 /* ArKitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82740EBD2C19762C009711A5 /* ArKitView.swift */; }; 82740EC02C197A48009711A5 /* ArKitViewRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82740EBF2C197A48009711A5 /* ArKitViewRepresentable.swift */; }; 82740EC22C197C1A009711A5 /* UIViewArKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82740EC12C197C1A009711A5 /* UIViewArKit.swift */; }; + 82CCA5442C1C2B6400AFF485 /* board.usdz in Resources */ = {isa = PBXBuildFile; fileRef = 82CCA5432C1C2B6400AFF485 /* board.usdz */; }; + 82CCA5462C1C2B8E00AFF485 /* CatPiece.usdz in Resources */ = {isa = PBXBuildFile; fileRef = 82CCA5452C1C2B8E00AFF485 /* CatPiece.usdz */; }; 82CE59E92C045D1100ADEE24 /* GameScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CE59E82C045D1100ADEE24 /* GameScene.swift */; }; 82CE59EB2C045E3800ADEE24 /* GameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CE59EA2C045E3800ADEE24 /* GameView.swift */; }; 82CE59EF2C0460E500ADEE24 /* SpriteMoople.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CE59EE2C0460E500ADEE24 /* SpriteMoople.swift */; }; @@ -64,6 +66,9 @@ 82740EBD2C19762C009711A5 /* ArKitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArKitView.swift; sourceTree = ""; }; 82740EBF2C197A48009711A5 /* ArKitViewRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArKitViewRepresentable.swift; sourceTree = ""; }; 82740EC12C197C1A009711A5 /* UIViewArKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewArKit.swift; sourceTree = ""; }; + 82CCA53C2C1C255E00AFF485 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 82CCA5432C1C2B6400AFF485 /* board.usdz */ = {isa = PBXFileReference; lastKnownFileType = file.usdz; path = board.usdz; sourceTree = ""; }; + 82CCA5452C1C2B8E00AFF485 /* CatPiece.usdz */ = {isa = PBXFileReference; lastKnownFileType = file.usdz; name = CatPiece.usdz; path = Object/CatPiece.usdz; sourceTree = SOURCE_ROOT; }; 82CE59E82C045D1100ADEE24 /* GameScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScene.swift; sourceTree = ""; }; 82CE59EA2C045E3800ADEE24 /* GameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameView.swift; sourceTree = ""; }; 82CE59EE2C0460E500ADEE24 /* SpriteMoople.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpriteMoople.swift; sourceTree = ""; }; @@ -186,6 +191,7 @@ C205A2B52BF373360097BD93 /* ArkitDoushiQi */ = { isa = PBXGroup; children = ( + 82CCA53C2C1C255E00AFF485 /* Info.plist */, 82740EBA2C19739A009711A5 /* ArKit */, C2F015352C09D592000F7221 /* Resources */, C2F015072C09D366000F7221 /* Utils */, @@ -193,6 +199,8 @@ C205A2B62BF373360097BD93 /* ArkitDoushiQiApp.swift */, C205A2B82BF373360097BD93 /* ContentView.swift */, C205A2BA2BF373380097BD93 /* Assets.xcassets */, + 82CCA5452C1C2B8E00AFF485 /* CatPiece.usdz */, + 82CCA5432C1C2B6400AFF485 /* board.usdz */, C205A2BC2BF373380097BD93 /* Views */, ); path = ArkitDoushiQi; @@ -450,8 +458,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 82CCA5442C1C2B6400AFF485 /* board.usdz in Resources */, C205A2BE2BF373380097BD93 /* Preview Assets.xcassets in Resources */, C2F0153D2C09D5C0000F7221 /* Localizable.strings in Resources */, + 82CCA5462C1C2B8E00AFF485 /* CatPiece.usdz in Resources */, C2F015392C09D5A5000F7221 /* Localizable.strings in Resources */, C205A2BB2BF373380097BD93 /* Assets.xcassets in Resources */, ); @@ -683,6 +693,7 @@ DEVELOPMENT_ASSET_PATHS = "\"ArkitDoushiQi/Views\""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ArkitDoushiQi/Info.plist; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; @@ -711,6 +722,7 @@ DEVELOPMENT_ASSET_PATHS = "\"ArkitDoushiQi/Views\""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ArkitDoushiQi/Info.plist; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; diff --git a/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitView.swift b/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitView.swift index 126951a..4a28b7f 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitView.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitView.swift @@ -16,12 +16,13 @@ class ArKitView : ARView { static let offset = CGPoint(x: -400, y: -300 ) static let direction = CGVector(dx: 100, dy: 100) - var game:Game = try! Game(withRules: ClassicRules(), andPlayer1: HumanPlayer(withName: "Bot1", andId: .player1)!, andPlayer2: RandomPlayer(withName: "Bot2", andId: .player2)!) + var game:Game var pieces: [Owner : [ Animal : Entity?]] required init(frame frameRect: CGRect) { pieces = [.noOne:[.cat:nil]] + game = try! Game(withRules: ClassicRules(), andPlayer1: HumanPlayer(withName: "Bot1", andId: .player1)!, andPlayer2: RandomPlayer(withName: "Bot2", andId: .player2)!) super.init(frame: frameRect) } @@ -29,12 +30,47 @@ class ArKitView : ARView { fatalError("init(coder:) not implemented") } - convenience init() { + convenience init(_ game:Game) { self.init(frame: UIScreen.main.bounds) + self.game = game let anchor = defineAnchors() addBoard(anchor: anchor) generatePieces(anchor:anchor) + + self.game.addBoardChangedListener { board in self.boardChange() } + self.game.addPieceRemovedListener { _,_,piece in self.removePiece(piece: piece) } + self.game.addInvalidMoveCallbacksListener { board,move,player,bool in self.invalidMove(board: board, move: move, player:player, bool:bool)} + } + + + // ------ Listener -------- // + func boardChange() { + print("Board change !") + displayBoard(board: game.board) + } + func removePiece(piece:Piece){ + print("Remove piece") + + if let entity = pieces[piece.owner]![piece.animal] { + if let x = entity { + x.removeFromParent() + } + } + } + func invalidMove(board:Board,move:Move,player:Player,bool:Bool) { + + if (bool){ // Valid + print("Move valid de \(player.id)") + print("Move : \(move.description)") + } + else { // Invalid + print("Move invalid de \(player.id)") + print("Move : \(move.description)") + displayBoard(board: game.board) + } + print("------------") } + // ------------------------ // func applyConfiguration() { let configuration = ARWorldTrackingConfiguration() @@ -42,14 +78,13 @@ class ArKitView : ARView { } func defineAnchors() -> AnchorEntity { - //let anchor = AnchorEntity(world: .zero) let anchor = AnchorEntity(.plane(.horizontal, classification: .any, minimumBounds: SIMD2(0.2, 0.2))) scene.addAnchor(anchor) return anchor } func addBoard(anchor:AnchorEntity){ - let board = try? Entity.load(named: "test") + let board = try? Entity.load(named: "board") if let board { anchor.addChild(board) } @@ -63,21 +98,21 @@ class ArKitView : ARView { var entity:Entity? switch c.self.key { case .cat : - entity = try? Entity.load(named: "ArKitCat") + entity = try? Entity.load(named: "CatPiece") case .elephant : - entity = try? Entity.load(named: "ArKitElephant") + entity = try? Entity.load(named: "CatPiece") case .dog : - entity = try? Entity.load(named: "ArKitDog") + entity = try? Entity.load(named: "CatPiece") case .leopard : - entity = try? Entity.load(named: "ArKitLeopard") + entity = try? Entity.load(named: "CatPiece") case .lion : - entity = try? Entity.load(named: "ArKitLion") + entity = try? Entity.load(named: "CatPiece") case .rat : - entity = try? Entity.load(named: "ArKitRat") + entity = try? Entity.load(named: "CatPiece") case .tiger : - entity = try? Entity.load(named: "ArKitTiger") + entity = try? Entity.load(named: "CatPiece") case .wolf : - entity = try? Entity.load(named: "ArKitWolf") + entity = try? Entity.load(named: "CatPiece") default: fatalError("Animal non compris") @@ -86,6 +121,12 @@ class ArKitView : ARView { if let entityNotNull = entity { anchor.addChild(entityNotNull) entityNotNull.position = SIMD3(0,0,10) + entityNotNull.generateCollisionShapes(recursive:true) + + /* + self.installGestures([.all], for: entityNotNull as! Entity & HasCollision).forEach { gestureRecognizer in + gestureRecognizer.addTarget(self, action: #selector(handleGesture(_:)))}*/ + print("Piece \(c.self.key) a été crée !") } else { print("La pièce \(c.self.key) n'a pas été crée !") @@ -132,8 +173,6 @@ class ArKitView : ARView { break } } - //self.installGestures([.all], for: robot as Entity & HasCollision).forEach { gestureRecognizer in - // gestureRecognizer.addTarget(self, action: #selector(handleGesture(_:))) - // -- // + //-------------------------// } diff --git a/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitViewRepresentable.swift b/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitViewRepresentable.swift index c02af36..ac84ec6 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitViewRepresentable.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitViewRepresentable.swift @@ -7,11 +7,18 @@ import Foundation import SwiftUI +import DouShouQiModel struct ArKitViewRepresentable : UIViewRepresentable { + private let game:Game + + init(_ game: Game){ + self.game = game + } + func makeUIView(context: Context) -> ArKitView { - return ArKitView() + return ArKitView(self.game) } func updateUIView(_ uiView: UIViewType, context: Context) { } diff --git a/ArkitDoushiQi/ArkitDoushiQi/ArKit/UIViewArKit.swift b/ArkitDoushiQi/ArkitDoushiQi/ArKit/UIViewArKit.swift index b375e2a..212bd38 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/ArKit/UIViewArKit.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/ArKit/UIViewArKit.swift @@ -6,20 +6,66 @@ // import SwiftUI +import DouShouQiModel struct UIViewArKit: View { + + var game:Game = try! Game(withRules: ClassicRules(), andPlayer1: HumanPlayer(withName: "Bot1", andId: .player1)!, andPlayer2: RandomPlayer(withName: "Bot2", andId: .player2)!) + + + @State var msg:String = "Msg" + var body: some View { - ZStack { - ArKitViewRepresentable() + VStack { + Text(msg) + ArKitViewRepresentable(game) .ignoresSafeArea() .navigationBarBackButtonHidden(true) + .task { + game.addGameStartedListener { board in startGame()} + game.addGameOverListener { board, result, player in gameOver() } + game.addGameChangedListener { game in gameChange() } + + game.addMoveChosenCallbacksListener { board, move, player in moveChose(board: board, move: move, player: player) } + + game.addPieceRemovedListener { _,_,piece in removePiece(piece: piece) } + + game.addPlayerNotifiedListener { board, player in + print("Player notif : \(player.id) à toi de jouer ") + msg = "Player notif : \(player.id) à toi de jouer !" + + if (player is IAPlayer ){ + try! await player.chooseMove(in: board, with: game.rules) + } + } + + //try! await game.start() + } } } + + // ------ Listener -------- // + + func startGame() { print("Start game !") + msg = "Start !!" + } + func gameOver() { print("Game over !") + msg = "Game over !!" + } + func gameChange() { print("Game change !") } + + func moveChose(board:Board,move:Move,player:Player) { + } + + func removePiece(piece:Piece){ + msg = "Piece manger !!" + } + + + // ------------------------- // } - - struct UIViewArKit_Previews: PreviewProvider { static var previews: some View { UIViewArKit() diff --git a/ArkitDoushiQi/ArkitDoushiQi/ArkitDoushiQiApp.swift b/ArkitDoushiQi/ArkitDoushiQi/ArkitDoushiQiApp.swift index 2ccbca9..42e9e62 100644 --- a/ArkitDoushiQi/ArkitDoushiQi/ArkitDoushiQiApp.swift +++ b/ArkitDoushiQi/ArkitDoushiQi/ArkitDoushiQiApp.swift @@ -21,13 +21,15 @@ struct ArkitDoushiQiApp: App { @StateObject private var languageSettings = LanguageSettings(selectedLanguage: .English) var body: some Scene { WindowGroup { + /* MainMenu( playButtonText: "Play", registeredGamesButtonText: "Registered Games", parametersButtonText: "Parameters" ) .environmentObject(languageSettings) - .preferredColorScheme(isDarkMode ? .dark : .light) + .preferredColorScheme(isDarkMode ? .dark : .light)*/ + UIViewArKit() } } } diff --git a/ArkitDoushiQi/ArkitDoushiQi/Info.plist b/ArkitDoushiQi/ArkitDoushiQi/Info.plist new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/ArkitDoushiQi/ArkitDoushiQi/Info.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/ArkitDoushiQi/ArkitDoushiQi/board.usdz b/ArkitDoushiQi/ArkitDoushiQi/board.usdz new file mode 100644 index 0000000..ddba6fe Binary files /dev/null and b/ArkitDoushiQi/ArkitDoushiQi/board.usdz differ diff --git a/ArkitDoushiQi/Object/CatPiece.usdz b/ArkitDoushiQi/Object/CatPiece.usdz new file mode 100644 index 0000000..021f023 Binary files /dev/null and b/ArkitDoushiQi/Object/CatPiece.usdz differ diff --git a/ArkitDoushiQi/Object/board.usdz b/ArkitDoushiQi/Object/board.usdz new file mode 100644 index 0000000..ddba6fe Binary files /dev/null and b/ArkitDoushiQi/Object/board.usdz differ