From cefc96e8542302f3ef011e0079ca95c91badc1f6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 12 Jun 2024 09:53:50 +0200 Subject: [PATCH] ArkIt --- .../ArkitDoushiQi.xcodeproj/project.pbxproj | 20 +++ .../ArkitDoushiQi/ArKit/ArKitView.swift | 139 ++++++++++++++++++ .../ArKit/ArKitViewRepresentable.swift | 18 +++ .../ArkitDoushiQi/ArKit/UIViewArKit.swift | 27 ++++ 4 files changed, 204 insertions(+) create mode 100644 ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitView.swift create mode 100644 ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitViewRepresentable.swift create mode 100644 ArkitDoushiQi/ArkitDoushiQi/ArKit/UIViewArKit.swift diff --git a/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj b/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj index d8444a1..ae8cdcb 100644 --- a/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj +++ b/ArkitDoushiQi/ArkitDoushiQi.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 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 */; }; 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 */; }; @@ -58,6 +61,9 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 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 = ""; }; 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 = ""; }; @@ -128,6 +134,16 @@ name = Frameworks; sourceTree = ""; }; + 82740EBA2C19739A009711A5 /* ArKit */ = { + isa = PBXGroup; + children = ( + 82740EBD2C19762C009711A5 /* ArKitView.swift */, + 82740EBF2C197A48009711A5 /* ArKitViewRepresentable.swift */, + 82740EC12C197C1A009711A5 /* UIViewArKit.swift */, + ); + path = ArKit; + sourceTree = ""; + }; 82CE59E52C045C7500ADEE24 /* Game */ = { isa = PBXGroup; children = ( @@ -170,6 +186,7 @@ C205A2B52BF373360097BD93 /* ArkitDoushiQi */ = { isa = PBXGroup; children = ( + 82740EBA2C19739A009711A5 /* ArKit */, C2F015352C09D592000F7221 /* Resources */, C2F015072C09D366000F7221 /* Utils */, 82CE59E52C045C7500ADEE24 /* Game */, @@ -461,6 +478,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 82740EC22C197C1A009711A5 /* UIViewArKit.swift in Sources */, C2F015112C09D3C3000F7221 /* AI.swift in Sources */, C2F0152A2C09D420000F7221 /* Stub.swift in Sources */, C2F015252C09D3E7000F7221 /* ItemCollectionParty.swift in Sources */, @@ -475,8 +493,10 @@ C20310D82BFCC2410031657D /* GeneralParametersMenuView.swift in Sources */, C2F0151F2C09D3E7000F7221 /* ToggleComponent.swift in Sources */, C2F015202C09D3E7000F7221 /* ButtonComponent.swift in Sources */, + 82740EC02C197A48009711A5 /* ArKitViewRepresentable.swift in Sources */, C2F015262C09D3E7000F7221 /* ProfileEdit.swift in Sources */, C205A2B72BF373360097BD93 /* ArkitDoushiQiApp.swift in Sources */, + 82740EBE2C19762C009711A5 /* ArKitView.swift in Sources */, C2F015232C09D3E7000F7221 /* EditTextComponent.swift in Sources */, C2F015222C09D3E7000F7221 /* PhotoButtonComponent.swift in Sources */, C2F015092C09D366000F7221 /* LanguageSettings.swift in Sources */, diff --git a/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitView.swift b/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitView.swift new file mode 100644 index 0000000..126951a --- /dev/null +++ b/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitView.swift @@ -0,0 +1,139 @@ +// +// ArKitView.swift +// ArkitDoushiQi +// +// Created by Enzo JOLYS on 12/06/2024. +// + +import DouShouQiModel +import Foundation +import ARKit +import RealityKit +import UIKit + +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 pieces: [Owner : [ Animal : Entity?]] + + required init(frame frameRect: CGRect) { + pieces = [.noOne:[.cat:nil]] + super.init(frame: frameRect) + } + + required init?(coder decoder: NSCoder) { + fatalError("init(coder:) not implemented") + } + + convenience init() { + self.init(frame: UIScreen.main.bounds) + let anchor = defineAnchors() + addBoard(anchor: anchor) + generatePieces(anchor:anchor) + } + + func applyConfiguration() { + let configuration = ARWorldTrackingConfiguration() + session.run(configuration) + } + + 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") + if let board { + anchor.addChild(board) + } + } + + // -- Crée les pieces + func generatePieces(anchor:AnchorEntity) { + // Position - X,Y,Z + for c in pieces.flatMap({ animal,values in return values }) + { + var entity:Entity? + switch c.self.key { + case .cat : + entity = try? Entity.load(named: "ArKitCat") + case .elephant : + entity = try? Entity.load(named: "ArKitElephant") + case .dog : + entity = try? Entity.load(named: "ArKitDog") + case .leopard : + entity = try? Entity.load(named: "ArKitLeopard") + case .lion : + entity = try? Entity.load(named: "ArKitLion") + case .rat : + entity = try? Entity.load(named: "ArKitRat") + case .tiger : + entity = try? Entity.load(named: "ArKitTiger") + case .wolf : + entity = try? Entity.load(named: "ArKitWolf") + + default: + fatalError("Animal non compris") + } + + if let entityNotNull = entity { + anchor.addChild(entityNotNull) + entityNotNull.position = SIMD3(0,0,10) + } + else { + print("La pièce \(c.self.key) n'a pas été crée !") + } + } + + } + + // -- Affiche les pieces à la bonne positions + func displayBoard(board:Board) { + for ligne in 0.. SIMD3 { + return SIMD3(Float(ArKitView.offset.x + ArKitView.direction.dx * pos.x),Float(ArKitView.offset.y + ArKitView.direction.dy * pos.y),10) + } + func converWorldPosIntoPosModele(pos:SIMD3) -> CGPoint { + let posX = Int(round((pos.x - (-400)) / 100)) + let posY = Int(round((pos.y - (-300)) / 100)) + return CGPoint(x: posX, y: posY) + } + + + // -- Pour les mouvement -- // + var initialTransform: Transform = Transform() + + @objc private func handleGesture(_ recognizer: UIGestureRecognizer) { + guard let translationGesture = recognizer as? EntityTranslationGestureRecognizer, let entity = translationGesture.entity else { return } + + switch translationGesture.state { + case .began: + self.initialTransform = entity.transform + case .ended: + entity.move(to: initialTransform, relativeTo: entity.parent, duration: 1) + default: + 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 new file mode 100644 index 0000000..c02af36 --- /dev/null +++ b/ArkitDoushiQi/ArkitDoushiQi/ArKit/ArKitViewRepresentable.swift @@ -0,0 +1,18 @@ +// +// ArKitViewRepresentable.swift +// ArkitDoushiQi +// +// Created by Enzo JOLYS on 12/06/2024. +// + +import Foundation +import SwiftUI + +struct ArKitViewRepresentable : UIViewRepresentable { + + func makeUIView(context: Context) -> ArKitView { + return ArKitView() + } + + func updateUIView(_ uiView: UIViewType, context: Context) { } +} diff --git a/ArkitDoushiQi/ArkitDoushiQi/ArKit/UIViewArKit.swift b/ArkitDoushiQi/ArkitDoushiQi/ArKit/UIViewArKit.swift new file mode 100644 index 0000000..b375e2a --- /dev/null +++ b/ArkitDoushiQi/ArkitDoushiQi/ArKit/UIViewArKit.swift @@ -0,0 +1,27 @@ +// +// UIViewArKit.swift +// ArkitDoushiQi +// +// Created by Enzo JOLYS on 12/06/2024. +// + +import SwiftUI + +struct UIViewArKit: View { + var body: some View { + ZStack { + ArKitViewRepresentable() + .ignoresSafeArea() + .navigationBarBackButtonHidden(true) + } + } +} + + + + +struct UIViewArKit_Previews: PreviewProvider { + static var previews: some View { + UIViewArKit() + } +}