liaison avec les evenement, interuption par une erreur SIGABRT sur un cast

gameBranch
Pierre FERREIRA 10 months ago
parent d8736beacb
commit b0ccb6ba85

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
7B236FB62C29B371008E9CA7 /* DSQ.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B6426F12C00B61500575E16 /* DSQ.xcframework */; };
7B2597B82C203AFE0095F010 /* PlayerSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2597B72C203AFE0095F010 /* PlayerSelect.swift */; };
7B2597BA2C203FCB0095F010 /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2597B92C203FCB0095F010 /* ImagePicker.swift */; };
7B3B17642BF24B32002BC817 /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3B17632BF24B32002BC817 /* Player.swift */; };
@ -20,7 +21,6 @@
7B4508EA2BF206B10027E1EF /* DouShouQiIOSUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4508E92BF206B10027E1EF /* DouShouQiIOSUITestsLaunchTests.swift */; };
7B4508F72BF2084B0027E1EF /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4508F62BF2084B0027E1EF /* PlayerView.swift */; };
7B4508FA2BF214F50027E1EF /* PlayerListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4508F92BF214F50027E1EF /* PlayerListView.swift */; };
7B6426F22C00B61500575E16 /* DSQ.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B6426F12C00B61500575E16 /* DSQ.xcframework */; };
7B6426F72C00B81400575E16 /* GameScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6426F62C00B81400575E16 /* GameScene.swift */; };
7B6426F92C00BDEA00575E16 /* SpriteKitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6426F82C00BDEA00575E16 /* SpriteKitView.swift */; };
7B6426FB2C00BFF500575E16 /* SpriteMeeple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6426FA2C00BFF500575E16 /* SpriteMeeple.swift */; };
@ -96,7 +96,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7B6426F22C00B61500575E16 /* DSQ.xcframework in Frameworks */,
7B236FB62C29B371008E9CA7 /* DSQ.xcframework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};

@ -46,7 +46,7 @@ class GameScene : SKScene{
]
]
init(size s: CGSize, andVM gameVM : GameVM){
override init(size s: CGSize){ //, andVM gameVM : GameVM
//self.gameVm = gameVM
super.init(size: s)
@ -57,13 +57,18 @@ class GameScene : SKScene{
self.anchorPoint = CGPoint(x: 0.5, y:0.5)
}
private func displayBoard(_ board : DouShouQiModel.Board){
func displayBoard(_ board : DouShouQiModel.Board){
//Nettoyage des fils
self.removeAllChildren()
self.addChild(imgBoard)
for row in 0..<board.nbRows{
for col in 0..<board.nbColumns{
if let p = board.grid[row][col].piece{
pieces[p.owner]?[p.animal]?.cellPosition = CGPoint(x: row, y: col);
pieces[p.owner]?[p.animal]?.imageNode.size = CGSize(width: 120, height: 120)
self.addChild(pieces[p.owner]![p.animal]!);
self.addChild(pieces[p.owner]![p.animal]!)
}
}
}

@ -16,14 +16,14 @@ import SwiftUI
class GameVM : ObservableObject, Identifiable {
@Published var game: Game?
@Published var game: Game
@Published var gameScene: GameScene
@Published var isGameOver: Bool = false
///Players (-game -> todelete)
///Players (-game -> todelete)
// let player1 : Player
// let player2 : Player
// var pieces : [ Owner : [Animal : SpriteMeeple]]
@ -36,33 +36,43 @@ class GameVM : ObservableObject, Identifiable {
@Published var displayMessage : String = ""
//On donne directement la scene et la game à la vm
public init(withGame _game : Game?, andScene _gameScene : GameScene) {
public init(withGame _game : Game, andScene _gameScene : GameScene) {
self.game = _game
self.gameScene = _gameScene
///Abonnement aux événements
self.game?.addGameStartedListener(onGameStart)
self.game?.addPlayerNotifiedListener(onPlayerNotified)
self.game?.addMoveChosenCallbacksListener(onMoveChosen)
self.game?.addInvalidMoveCallbacksListener(onInvalidMove)
self.game?.addBoardChangedListener(onBoardChanged)
self.game?.addGameOverListener(onGameOver)
self.game.addGameStartedListener(onGameStart)
self.game.addPlayerNotifiedListener(onPlayerNotified)
self.game.addMoveChosenCallbacksListener(onMoveChosen)
self.game.addInvalidMoveCallbacksListener(onInvalidMove)
self.game.addBoardChangedListener(onBoardChanged)
self.game.addGameOverListener(onGameOver)
//self.game?.addGameChangedListener({}) - //? cas persistance
self.subscribesToMeeple()
Task{
try! await self.game.start()
}
}
func onGameStart(board : Board){
displayMessage = " ==>> 🎉 GAME STARTS! 🎉 <<== "
self.gameScene.displayBoard(board)
print("GAME STARTS")
}
func onPlayerNotified(board : Board, player : Player) async{
print("PLAYER NOTIFIED")
if player is HumanPlayer {
displayMessage = "Player \(player.id == .player1 ? "🟡 1" : "🔴 2") - \(player.name), it's your turn!"
//try! await (player as! HumanPlayer).chooseMove(move)
}
else {
do{
_ = try await player.chooseMove(in: board, with: self.game!.rules)
_ = try await player.chooseMove(in: board, with: self.game.rules)
}
catch{
hasError = true
@ -84,12 +94,54 @@ class GameVM : ObservableObject, Identifiable {
///Mouvement invalide
func onInvalidMove(board : Board, move : Move, player : Player, result : Bool){
displayMessage = "⚠️⚠️⚠️⚠️ Invalid Move detected: \(move) by \(player.name) (\(player.id))"
if result { ///* invalidité terminante
if let piece = board.grid[move.rowDestination][move.columnDestination].piece{
// Delete le meeple
let meeples = gameScene.pieces[player.id == .player1 ? .player2 : .player1]
let meeple = meeples?.first(where: {
$0.key == piece.animal
})
meeple?.value.parent?.removeChildren(in: [meeple!.value])
}
return
}
displayMessage = "⚠️⚠️⚠️⚠️ Invalid Move detected: \(move) by \(player.name) (\(player.id))"
let piece = board.grid[move.rowOrigin][move.columnOrigin]
let meeples = gameScene.pieces[move.owner]
let meeple = meeples?.first(where: {
$0.key == piece.piece?.animal
})
meeple?.value.cellPosition = CGPoint(x: move.rowOrigin, y: move.columnOrigin);
print("INVALID")
}
func invalideMoveChosen(board: Board, move: Move, player: Player, result: Bool) {
if result {
if let piece = board.grid[move.rowDestination][move.columnDestination].piece{
// Delete le meeple
let meeples = gameScene.pieces[player.id == .player1 ? .player2 : .player1]
let meeple = meeples?.first(where: {
$0.key == piece.animal
})
meeple?.value.parent?.removeChildren(in: [meeple!.value])
}
return
}
let piece = board.grid[move.rowOrigin][move.columnOrigin]
let meeples = gameScene.pieces[move.owner]
let meeple = meeples?.first(where: {
$0.key == piece.piece?.animal
})
meeple?.value.cellPosition = CGPoint(x: move.rowOrigin, y: move.columnOrigin);
}
func onBoardChanged(board : Board){
/// Bruit d'un placement de pion ?
}
@ -100,27 +152,37 @@ class GameVM : ObservableObject, Identifiable {
}
func readInt(withMessage message: String) -> Int {
var temp: Int?
while temp == nil {
print(message)
let result = readLine()
temp = Int(result ?? "")
///Meeples
func subscribesToMeeple(){
for meeple in gameScene.pieces[.player1]!{
meeple.value.observers.append(meepleMoved)
}
for meeple in gameScene.pieces[.player2]!{
meeple.value.observers.append(meepleMoved)
}
return temp!
}
func readMove(from player: HumanPlayer) -> Move? {
var originRow, originCol, destRow, destCol : Int?
originRow = readInt(withMessage: "\(player.name) please enter the origin row in which your piece is)")
originCol = readInt(withMessage: "\(player.name) please enter the origin column in which your piece is)")
destRow = readInt(withMessage: "\(player.name) please enter the destination row in which you want to move your piece)")
destCol = readInt(withMessage: "\(player.name) please enter the destination column in which you want to move your piece)")
//self.pieces[player.id][Animal.cat]?
func meepleMoved(spriteMeeple: SpriteMeeple, startX: Int, startY: Int, endX: Int, endY: Int) async{
let owner : Owner = game.board.grid[startX][startY].piece!.owner
let otherPlayer : Owner = self.game.rules.getNextPlayer()
return Move(of: player.id, fromRow: originRow!, andFromColumn: originCol!, toRow: destRow!, andToColumn: destCol!)
let move: Move = Move(of: owner, fromRow: startX, andFromColumn: startY, toRow: endX, andToColumn: endY)
if(otherPlayer != owner){ ///Mauvais Joueur pour ce jeton
print("invalide de la part de meepleMoved")
onInvalidMove(board: game.board, move: move, player: game.players[otherPlayer]!, result: false)
return
}
if let player: HumanPlayer = game.players[owner] as? HumanPlayer{
try! await player.chooseMove(move)
}
// else { ///IMPOSSIBLE DE CAST LE JOUEUR HUMAIN
// let player: HumanPlayer = game.players[.player1] as! HumanPlayer
// try! await player.chooseMove(move)
// }
print("il a bougé")
}
}

@ -9,7 +9,7 @@ import Foundation
import SpriteKit
import SwiftUI
class SpriteMeeple : SKNode{
class SpriteMeeple : SKNode, ObservableObject{
let imageNode : SKSpriteNode
let ellipseNode : SKShapeNode
@ -24,6 +24,11 @@ class SpriteMeeple : SKNode{
static let offset = CGPoint(x:-400, y:-300)
static let direction = CGVector(dx:100, dy:100);
//@Published var observers : [ any ObservableObject ] = []
@Published var observers : [ (SpriteMeeple, Int, Int, Int, Int) async ->() ] = []
public init(imageName imgN : String,size meepleSize : CGSize,color meepleColor : Color){
imageNode = SKSpriteNode(imageNamed: imgN)
imageNode.size = meepleSize;
@ -86,7 +91,14 @@ class SpriteMeeple : SKNode{
self.position.y = (calcy.rounded(.toNearestOrAwayFromZero))*100;
}
///Envoi au observers d'une notif
///* Exectution des Observeurs
Task {
for observer in observers {
await observer(self, Int(cellPosition.x), Int(cellPosition.y), Int(position.x), Int(position.y))
}
}
}
required init?(coder aDecoder: NSCoder) {

@ -19,8 +19,6 @@ struct GameView: View {
@State private var player1Pieces = 8
@State private var player2Pieces = 8
// On donne les deux player à la vue ?
var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
let gridItems = Array(repeating: GridItem(.flexible()), count: 8)
@ -29,13 +27,18 @@ struct GameView: View {
var gameVM : GameVM
///SK
var gs : GameScene
//var gs : GameScene
init (){
self.gameVM = GameVM(andPlayer1: Player(withName: "Meruemu", andId: .player1)!, andPlayer2: Player(withName: "Kumogi", andId: .player2)!)
init (gameVM : GameVM){
//self.gameVM = GameVM(andPlayer1: Player(withName: "Meruemu", andId: .player1)!, andPlayer2: Player(withName: "Kumogi", andId: .player2)!)
self.gameVM = gameVM
// self.gs = GameScene(size: CGSizeMake(940,740), andVM: gameVM)
//self.gs = GameScene(size: CGSizeMake(940,740))
self.gs = GameScene(size: CGSizeMake(940,740), andVM: gameVM)
}
var body: some View {
@ -44,7 +47,7 @@ struct GameView: View {
VStack {
VStack {
Text(gameVM.displayMessage)
.font(.title)
.font(.title3)
.padding(.top, 20)
HStack {
@ -77,7 +80,7 @@ struct GameView: View {
.padding(20)
*/
SpriteView(scene: gs)
SpriteView(scene: gameVM.gameScene)
.frame(width: 350, height: 275)
.padding(10)
.background(Color.primaryColor)
@ -122,6 +125,6 @@ struct GameView: View {
struct GameView_Previews: PreviewProvider {
static var previews: some View {
GameView()
GameView(gameVM: GameVM(withGame: try! Game(withRules: ClassicRules(), andPlayer1: Player(withName: "toto", andId: .player1)!, andPlayer2: Player(withName: "tata", andId: .player2)!), andScene: GameScene(size: CGSize(width: 120, height: 120))))
}
}

@ -6,10 +6,18 @@
//
import SwiftUI
import DouShouQiModel
struct MainMenuView: View {
@Environment(\.colorScheme) var colorScheme
var gamevm : GameVM = GameVM(withGame: try! Game(withRules: ClassicRules(),
andPlayer1: Player(withName: "Meruemu", andId: .player1)!,
andPlayer2: Player(withName: "Kumogi", andId: .player2)!),
andScene: GameScene(size: CGSize(width: 940, height: 740)))
var body: some View {
NavigationStack {
@ -27,7 +35,8 @@ struct MainMenuView: View {
.bold()
.padding()
NavButton("Jouer Seul", destinationView: {PlayerSelect(versus: false)})
//NavButton("Jouer Seul", destinationView: {PlayerSelect(versus: false)})
NavButton("Jouer Seul", destinationView: {GameView(gameVM: gamevm)})
.padding(.top, 10)
NavButton("Jouer en Multi", destinationView: {PlayerSelect(versus: true)})

Loading…
Cancel
Save