From 58a2885f29726bc831a113b7a9a19f606042b255 Mon Sep 17 00:00:00 2001 From: CraZyB1336 Date: Sun, 20 Apr 2025 19:38:07 +0200 Subject: [PATCH 1/6] feat: make pieces flip on each client --- .../{explotionCard.png => explosionCard.png} | Bin .../new_movementCard.png} | Bin .../swapCard.png} | Bin assets/abilities/explosion-card-temp.png | Bin 1395 -> 0 bytes assets/abilities/explosion-card.png | Bin 1674 -> 0 bytes assets/abilities/shield-card.png | Bin 6779 -> 0 bytes assets/abilities/swap-card.png | Bin 6779 -> 0 bytes .../entities/AbilityItemFactory.kt | 5 +-- .../chessevolved/entities/PieceFactory.kt | 7 ++- .../singletons/EcsEntityMapper.kt | 9 +++- .../chessevolved/singletons/GameSettings.kt | 4 ++ .../github/chessevolved/singletons/Lobby.kt | 9 ++++ .../supabase/SupabaseGameHandler.kt | 1 + .../chessevolved/presenters/GamePresenter.kt | 41 +++++++++++------- 14 files changed, 55 insertions(+), 21 deletions(-) rename assets/abilities/cards/{explotionCard.png => explosionCard.png} (100%) rename assets/abilities/{mirror-card.png => cards/new_movementCard.png} (100%) rename assets/abilities/{new_movement-card.png => cards/swapCard.png} (100%) delete mode 100644 assets/abilities/explosion-card-temp.png delete mode 100644 assets/abilities/explosion-card.png delete mode 100644 assets/abilities/shield-card.png delete mode 100644 assets/abilities/swap-card.png diff --git a/assets/abilities/cards/explotionCard.png b/assets/abilities/cards/explosionCard.png similarity index 100% rename from assets/abilities/cards/explotionCard.png rename to assets/abilities/cards/explosionCard.png diff --git a/assets/abilities/mirror-card.png b/assets/abilities/cards/new_movementCard.png similarity index 100% rename from assets/abilities/mirror-card.png rename to assets/abilities/cards/new_movementCard.png diff --git a/assets/abilities/new_movement-card.png b/assets/abilities/cards/swapCard.png similarity index 100% rename from assets/abilities/new_movement-card.png rename to assets/abilities/cards/swapCard.png diff --git a/assets/abilities/explosion-card-temp.png b/assets/abilities/explosion-card-temp.png deleted file mode 100644 index b1befe02db5ab986467fd6bd0020e6f2470f7e23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1395 zcmV-(1&sQMP)Px)6G=otRCt{2TTf^lRT%$m$)P7NQVO$Pqz#d}3n{p4C`iGp$)zepSPxT>=HQNY za|;N9u;69W&Rzst=3ozs?J2ECiwH}W2&wG0bR|#}GoT{krHGgHF#ElE^X9$zx0yei z%@0D}yqP!e`+nb__svUQ3BVY0j0FJr{LWW-%aIE<8tXX4Us&DkJmtv*R(Bg4jdgat zK#h96j()!ny$QVf%2F=ErH#i=N9gzasMqVPj}f3ZuS0LT55NA}#Y}}u8$bNG55OPp z3;cy>`ENdcFJ-Z^!8@OR3Bc9w@zW8zw;(<&TK>{owKQc*9ld*d09?Ju69_&6fa7C% z0_j7Zz(Yy^F#DD#kRId-B2Gzr=LjbRfi0jr?Eb-QjhBOdzox72>mD zVPx*DoI2^RCt{2olj^SRUF5^D?NDfB2w6Tks1`;1q+4^1rfZOT>JwO*24;74(@7` zTR{+nfS0u0TokQ)um{EJCF;>4LdXyyO19EUK@?r6MZ`-HFYz$@W`6I@dpmD-XY$*f z{e3Q(c{}^&<@e|N{>)3J0^kS&8~1QGVBR^Q4&J-+31>UzlC|b)>;P2&0F6cit@b&V zMwOM`_5}by5CmGViv%&FWk93R01$eq)eg%ZfAo=KZ&ca1e&Z&BAOH~CSfM#U$&NC< z;;ARk6xh7-^4<3b(Xp$K6$xVIgsspeJDGM68Lx?0**Wz@M?3%Hhwic6TQY!|xy}F;`R&aueDTryiSpyf z1jztq!~x9AwFD`N;p~Lx+5x8F&2s4j<^XX3Gjk1=9Ud1XT>9Z>DrM>o@mNDwpZ8BpzYFlddJ&dx}$0hL$7 zLm%1s@=8xTUv9Pl=u&jBw~JE`$6E~Znk(ey0IM--0Q$!HkilZuaBBR_(ou7i*Rxf_ ziAWGLnKD3&&>Esh8{FG<%19OAcT~h%>r|0ki?6Hh8`+?u`Vcb};b~-YfR9#FCkHnkrJ_21Nc8@6kfo2_Vq1|aGWCLNlJ1TmBQ zC`jv6_d9WCJ3@lgcQlD3QLkkQWeh1&BOHor6m%REIt+CgUAu-j%-N4P97FF>{daaI zUlfrbX4ofUK8(tYYCrD4XOWq3fQyMHaZ`dw5HqE5z_{y4+|0BDnb3(4-E^gR=rMiV zsut#4!%jN!O5E$#&BQ&&p)?sVtCT7O6tqL$KEECvo68d_BV5mfO;pt9$<#YQ8PjW$ zrkJ52sYnnrQgiX4I&id?EUqlACkr!B#I}^FaX{KI()M|^*U{I8UK;)+ z&kRN_QM-0UD9pZ~h+PpPLCj1|28@H56|=Y;G1Cq(nZ>msksxMr&wxqx`Q%B|hD-KI z*|d;*2B^n}vmyc9hy*cHNGD7uPesbnsQPWIp(a`90k-<5W^1CATKZbfB+%UwuKK&T z*Q42T=T7X5G~)xwy`j&&@>+DBSAQZB#Ee%4WQk%b3xmaOv^6nnJ-$S8w;wM{(E2+k zw}3n0arc>ZbiN6*zzPlwwRyI7A`SZl!VNJf6;lIyXQ;Rbab!KqR(FaIuVFYx;nXG&pKbTj}KppzFcvb%!?s^8kjT|DQAZGj|NJVbn z9;IH-YsnvU0LZ+v*>+zV(OT5^p+6}bmYb2g@>dx3=I-bfgylQ^Ui^^9r@f|q?o0o_ z+kOtHlb>|{;vpSQ*|F8{;tr#n^ykm%tB(_rLmNjiR{IxDr(Pl%z>GM68F2tJ z;s9pE0nCU4nDH8hUfsMH9lvn?&B7W}2Ht%(edtM%3}7ZT1L$k`KB**(X05pj0BAHCXtmEpmk}a}kiTjG000hUSV?A0O#mtY000O800000 U007cclK=n!07*qoM6N<$f=a3qg8%>k diff --git a/assets/abilities/shield-card.png b/assets/abilities/shield-card.png deleted file mode 100644 index 6379f6eb5cf7bc3429d16f72902460aea7acd63e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6779 zcmeHLXEdDO)<0t~I*ArUiRc6oB1#yYgfTjQqC}MFy+oNwM2Zsrh%Q=)E<*GgMDIjz zi8}fqqRqVAyVkv*-uv->c-Q-^^{jo)K6{_@?ETxn^E~Hyi$thVk};D304O!om309i zxM&gp66l3!&E@L65KvD=4Sf<4lIcb5g^Mn!o4Sc70A!q(H>5;g_{N2j$xFr9OV8ET z%h$@o2Kf5=3O{vm^t85evk`XnuuIvNWxkko1F5O6g2&@8?EnAz{|x+}&wvuyjmnE4 z|9I&l^ZqPso5h7ORLA$ zPi$=M?4LR~Iyt+zy19FJdi(hL`9BK?3__uwzX*95`s($Yw_)KCk?;PFiH&<7pOBc8 zoRXUMAw45AEBj+k?x(!`g2JNWlG4v*U&<@KR#sKl)YjEEG&VK2d~0oM|K8Er)zjP8 zKQK5nJTf}=V|-$AYInLe;z`6)#DD?vZix=~}J3aJaz z5Sd`G#64(L;wyY|LT4bxp36g&^Im=QqgHWmy3`NKW%?Y)J*JiUdiroO&k_IN`}^KM zUS@V~@iu;bcYHrwXT|5vIYl|gyjrGf+EQ_ESjCgfA64p4tf1vw39!r=Np5TTa^A5Z zon02O!snB5tyP&z<2*i6-d!>HuR zTRuP1C88AeO1aWaQXU>)+P*cs6MSO6vU*uKYd$E{m^g!_5RnV zcgIj!*%)?yj9q87@=c~c?xz;yvQFCPzYyIZ1_A;2^7YKJCX$&9~jpAGQWkqfaarwBXgKjdULORgvds)adWK=5Np6j~PMK zVkp6yTD@!U;Vrb7)%kcVE3ju;WijPFuE3Rj^Lot_$KyasFR{zmO{zkk(YC9?Q2uJoXL zQI6_YQ|MBR@*S@?n*{KOe)Bl;dB`>HPU$eV>=Vche1(0h2q)Jz009*O(sw`c>2 zEt8rCfD1s1xrWC@u^%v^DPNHO_4EP;0oTk?Orv2CnNZ~w(6`dauw3Z9tg`cRpzJEZ zV~zbIqQG@V&B1Fjke7Jso!91jL(5>uI|JfFknvJ}KNw?&gA8&dW+*>|AlbKl{O2W{ zn4eLw$k-rozqI8~zddXU+VVB^*__$m9->B!r@Gp^-&Y8R!Ik_`EVrz+lF-$q!Kn3j z9F@2VMxgcUd?p7aYIShF;_O19#0J-G!2vb_D4fZme>- zoGvOz2y#zSprzeQW1L2OA05Li^efk@#y}pUD<%K$tXylveDi3#3lM*Ens8A4?q=iB zvLP`j0E6=GlE|c-SwB~cT)z(LX~A*L27SvCQlU!vY*RZg9RecUES+wRnE52Jzo>O}Dm8aALXa^foJy>vOG+l${#N?!B0M1`;j%T&<}q=y|Yy2Nian z2~-ntobqo|%`xk;)|b?Onr=8{MISh_LH!)n%erM`T;7CV*uX?}YIEFYI#z%COw?lW zEr5drNEP5lPJ&>?g7RM}!3)U3QXelar*c*LNub5k$AE?c@EW;i;hLQbK0{v}wO_=c z0O9i;p4h6F_-H&m8XYCPcb^!vK;V;{!l{vqHTz4iN5=so5cn?ex#zSiUsJrbO;?+#($ESx{D2nKI4*pm*LnMJ zuvidJ2n9soI*yjZSShTG`-Tie9D=?I-We%sEuwz+lMi*?6$40u=3{C5oAQfa$EBsX zpe(D^aaz1SMb8S>I%=fuls8HEjDCil@E&0p*cW}lRo5=rrRt#_w`s@g%rD$kWa
5ec!X?SgpzpNBZY{ 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
5ec!X?SgpzpNBZY{ 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 aICgHbY%*ai^{dM_r-lkbxkS TextureRegion(assetManager.get("abilities/cards/shieldCard.png", Texture::class.java)) AbilityType.EXPLOSION -> TextureRegion(assetManager.get("abilities/cards/explosionCard.png", Texture::class.java)) - // TODO: update all cards - AbilityType.SWAP -> TextureRegion(assetManager.get("abilities/swap-card.png", Texture::class.java)) + AbilityType.SWAP -> TextureRegion(assetManager.get("abilities/cards/swapCard.png", Texture::class.java)) AbilityType.MIRROR -> TextureRegion(assetManager.get("abilities/cards/mirrorCard.png", Texture::class.java)) - AbilityType.NEW_MOVEMENT -> TextureRegion(assetManager.get("abilities/new_movement-card.png", Texture::class.java)) + AbilityType.NEW_MOVEMENT -> TextureRegion(assetManager.get("abilities/cards/new_movementCard.png", Texture::class.java)) } fun createAbilityItem(abilityType: AbilityType): Entity { diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt index 3144b3e6..502eab3b 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt @@ -21,6 +21,7 @@ import io.github.chessevolved.data.Position import io.github.chessevolved.enums.MoveType import io.github.chessevolved.enums.PieceType import io.github.chessevolved.enums.PlayerColor +import io.github.chessevolved.singletons.GameSettings import io.github.chessevolved.systems.InputService import ktx.actors.onClick @@ -107,7 +108,11 @@ class PieceFactory( getPieceActor( positionProvider = { PositionComponent.mapper.get(this).position }, stage, - ) { clickedPosition -> inputService.clickPieceAtPosition(clickedPosition) }, + ) { clickedPosition -> + if (playerColor == GameSettings.clientPlayerColor) { + inputService.clickPieceAtPosition(clickedPosition) + } + }, ), ) engine.addEntity(this) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt index f92e1280..50ef18e1 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt @@ -34,8 +34,14 @@ object EcsEntityMapper { fun extractStateFromEngine(engine: Engine): Pair, List> { val pieces = engine.getEntitiesFor(pieceFamily).map { entity -> + val piecePosition = PositionComponent.mapper.get(entity) + PieceDto( - position = PositionComponent.mapper.get(entity).position, + position = + Position( + piecePosition.position.x, + GameSettings.getBoardSize() - 1 - piecePosition.position.y, + ), type = PieceTypeComponent.mapper.get(entity).type, color = PlayerColorComponent.mapper.get(entity).color, ) @@ -60,6 +66,7 @@ object EcsEntityMapper { receivedBoardSquares: List, ) { Gdx.app.log("ECSEntityMapper", "Applying received state to engine...") + try { val existingPieceEntities = engine.getEntitiesFor(pieceFamily) val existingPiecesMap = diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/GameSettings.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/GameSettings.kt index 7fa12f12..f2801cfc 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/GameSettings.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/GameSettings.kt @@ -1,10 +1,14 @@ package io.github.chessevolved.singletons import io.github.chessevolved.dtos.SettingsDto +import io.github.chessevolved.enums.PlayerColor object GameSettings { private var fogOfWar: Boolean = false private var boardSize: Int = 8 + var clientPlayerColor: PlayerColor = PlayerColor.WHITE + var opponentPlayerColor: PlayerColor = PlayerColor.BLACK + var isSecondPlayer: Boolean = false /** * The current setting of FOW diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt index 1b632a5d..a3dab9c1 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt @@ -2,6 +2,7 @@ package io.github.chessevolved.singletons import com.badlogic.gdx.Gdx import io.github.chessevolved.dtos.LobbyDto +import io.github.chessevolved.enums.PlayerColor import io.github.chessevolved.singletons.supabase.SupabaseLobbyHandler object Lobby { @@ -19,6 +20,10 @@ object Lobby { try { SupabaseLobbyHandler.joinLobby(lobbyId, ::onLobbyRowUpdate) this.lobbyId = lobbyId + GameSettings.clientPlayerColor = PlayerColor.BLACK + GameSettings.opponentPlayerColor = PlayerColor.WHITE + GameSettings.isSecondPlayer = true + println("Player Color: ${GameSettings.clientPlayerColor}") } catch (e: Exception) { throw e } @@ -54,6 +59,10 @@ object Lobby { val lobbyId = SupabaseLobbyHandler.createLobby(::onLobbyRowUpdate) this.lobbyId = lobbyId Gdx.app.log("Lobby", "Creating lobby with ID: $lobbyId...") + GameSettings.clientPlayerColor = PlayerColor.WHITE + GameSettings.opponentPlayerColor = PlayerColor.BLACK + GameSettings.isSecondPlayer = true + println("Player Color: ${GameSettings.clientPlayerColor}") } catch (e: Exception) { throw Exception("Problem when creating lobby! " + e.message) } diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt index 699550af..17ab783c 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt @@ -20,6 +20,7 @@ import kotlinx.serialization.json.Json object SupabaseGameHandler { private val supabase = getSupabaseClient() private const val SUPABASE_GAME_TABLE_NAME = "games" + var sendingGameState = false suspend fun joinGame( lobbyCode: String, diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt index 5238a303..4044eae4 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt @@ -28,7 +28,9 @@ import io.github.chessevolved.singletons.EcsEntityMapper import io.github.chessevolved.singletons.Game import io.github.chessevolved.singletons.Game.subscribeToGameUpdates import io.github.chessevolved.singletons.Game.unsubscribeFromGameUpdates +import io.github.chessevolved.singletons.GameSettings import io.github.chessevolved.singletons.Lobby +import io.github.chessevolved.singletons.supabase.SupabaseGameHandler import io.github.chessevolved.systems.AbilitySystem import io.github.chessevolved.systems.CaptureSystem import io.github.chessevolved.systems.FowRenderingSystem @@ -136,7 +138,8 @@ class GamePresenter( AbilityType.entries.forEach { ability -> val abilityName = ability.name.lowercase() - assetManager.load("abilities/$abilityName-card.png", Texture::class.java) + println("abilities/cards/${abilityName}Card.png") + assetManager.load("abilities/cards/${abilityName}Card.png", Texture::class.java) } } @@ -147,8 +150,7 @@ class GamePresenter( } } - // TODO: Pass in if the player is the white player or not. - gameUIView = GameUIView(gameUIViewport, true, ::onSelectAbilityCardButtonClicked) + gameUIView = GameUIView(gameUIViewport, GameSettings.clientPlayerColor == PlayerColor.WHITE, ::onSelectAbilityCardButtonClicked) gameUIView.init() gameBoardView = GameView(gameUIView.getStage(), gameViewport) @@ -182,7 +184,7 @@ class GamePresenter( .createPawn( true, Position(startPos, 1), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) @@ -190,7 +192,7 @@ class GamePresenter( .createPawn( false, Position(startPos, boardWorldSize - 2), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -202,13 +204,13 @@ class GamePresenter( for (j in listOf(0, 7)) { pieceFactory.createRook( Position(startXLocal + j, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createRook( Position(startXLocal + j, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -217,13 +219,13 @@ class GamePresenter( for (j in listOf(1, 6)) { pieceFactory.createKnight( Position(startXLocal + j, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createKnight( Position(startXLocal + j, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -232,13 +234,13 @@ class GamePresenter( for (j in listOf(2, 5)) { pieceFactory.createBishop( Position(startXLocal + j, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createBishop( Position(startXLocal + j, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -246,26 +248,26 @@ class GamePresenter( startXLocal + 3 -> { pieceFactory.createQueen( Position(startPos, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createQueen( Position(startPos, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } startXLocal + 4 -> { pieceFactory.createKing( Position(startPos, 0), - PlayerColor.WHITE, + GameSettings.clientPlayerColor, gameStage, ) pieceFactory.createKing( Position(startPos, boardWorldSize - 1), - PlayerColor.BLACK, + GameSettings.opponentPlayerColor, gameStage, ) } @@ -349,7 +351,7 @@ class GamePresenter( } AbilityType.entries.forEach { ability -> val abilityName = ability.name.lowercase() - val filename = "abilities/$abilityName-card.png" + val filename = "abilities/cards/${abilityName}Card.png" if (assetManager.isLoaded(filename)) { assetManager.unload(filename) } @@ -431,6 +433,11 @@ class GamePresenter( val pieces = gameDto.pieces val boardSquares = gameDto.boardSquares + if (SupabaseGameHandler.sendingGameState) { + SupabaseGameHandler.sendingGameState = false + return + } + EcsEntityMapper.applyStateToEngine(engine, pieceFactory, gameStage, pieces, boardSquares) } @@ -439,6 +446,8 @@ class GamePresenter( launch { val (pieces, boardSquares) = EcsEntityMapper.extractStateFromEngine(engine) + SupabaseGameHandler.sendingGameState = true + Game.updateGameState( Lobby.getLobbyId()!!, pieces, From b8e7ab8928e9a11487922e6ecf49b70205906355 Mon Sep 17 00:00:00 2001 From: CraZyB1336 Date: Sun, 20 Apr 2025 19:40:08 +0200 Subject: [PATCH 2/6] refactor: remove isPlayerOne boolean --- .../github/chessevolved/entities/PieceFactory.kt | 16 +++------------- .../chessevolved/presenters/GamePresenter.kt | 2 -- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt index 502eab3b..4e9b6032 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt @@ -119,24 +119,14 @@ class PieceFactory( } fun createPawn( - isPlayerOne: Boolean, position: Position, color: PlayerColor, stage: Stage, ) = createPiece(position, PieceType.PAWN, color, stage).apply { getComponent(MovementRuleComponent::class.java).apply { - val pawnDirections: List - val pawnCaptureDirections: List - val pawnStartDirections: List - if (isPlayerOne) { - pawnDirections = listOf(Vector2(0f, 1f)) - pawnCaptureDirections = listOf(Vector2(1f, 1f), Vector2(-1f, 1f)) - pawnStartDirections = listOf(Vector2(0f, 2f)) - } else { - pawnDirections = listOf(Vector2(0f, -1f)) - pawnCaptureDirections = listOf(Vector2(1f, -1f), Vector2(-1f, -1f)) - pawnStartDirections = listOf(Vector2(0f, -2f)) - } + val pawnDirections: List = listOf(Vector2(0f, 1f)) + val pawnCaptureDirections: List = listOf(Vector2(1f, 1f), Vector2(-1f, 1f)) + val pawnStartDirections: List = listOf(Vector2(0f, 2f)) addPattern( MovementPattern( diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt index 4044eae4..fb8c6920 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt @@ -182,7 +182,6 @@ class GamePresenter( for (startPos in startX until startX + 8) { pieceFactory .createPawn( - true, Position(startPos, 1), GameSettings.clientPlayerColor, gameStage, @@ -190,7 +189,6 @@ class GamePresenter( pieceFactory .createPawn( - false, Position(startPos, boardWorldSize - 2), GameSettings.opponentPlayerColor, gameStage, From 3c2bc44fbecc0dda9a8625bea9b850a01c9a7b7b Mon Sep 17 00:00:00 2001 From: chrisjk Date: Mon, 21 Apr 2025 13:22:20 +0200 Subject: [PATCH 3/6] feat: :sparkles: add wincondition and navigation to endgame --- .../chessevolved/entities/PieceFactory.kt | 6 +-- .../singletons/EcsEntityMapper.kt | 2 +- .../github/chessevolved/singletons/Lobby.kt | 1 - .../systems/SelectionEntityListener.kt | 5 +++ .../io/github/chessevolved/Navigator.kt | 2 + .../presenters/EndGamePresenter.kt | 17 ++++++-- .../chessevolved/presenters/GamePresenter.kt | 42 ++++++++++++------- 7 files changed, 51 insertions(+), 24 deletions(-) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt index 4e9b6032..d329aec2 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt @@ -108,11 +108,7 @@ class PieceFactory( getPieceActor( positionProvider = { PositionComponent.mapper.get(this).position }, stage, - ) { clickedPosition -> - if (playerColor == GameSettings.clientPlayerColor) { - inputService.clickPieceAtPosition(clickedPosition) - } - }, + ) { clickedPosition -> inputService.clickPieceAtPosition(clickedPosition) }, ), ) engine.addEntity(this) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt index 50ef18e1..b7e6b7bb 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt @@ -137,7 +137,7 @@ object EcsEntityMapper { pieceData: PieceDto, ) { when (pieceData.type) { - PieceType.PAWN -> pieceFactory.createPawn(true, pieceData.position, pieceData.color, stage) + PieceType.PAWN -> pieceFactory.createPawn(pieceData.position, pieceData.color, stage) PieceType.ROOK -> pieceFactory.createRook(pieceData.position, pieceData.color, stage) PieceType.KNIGHT -> pieceFactory.createKnight(pieceData.position, pieceData.color, stage) PieceType.BISHOP -> pieceFactory.createBishop(pieceData.position, pieceData.color, stage) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt index a3dab9c1..3a87d1bc 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt @@ -23,7 +23,6 @@ object Lobby { GameSettings.clientPlayerColor = PlayerColor.BLACK GameSettings.opponentPlayerColor = PlayerColor.WHITE GameSettings.isSecondPlayer = true - println("Player Color: ${GameSettings.clientPlayerColor}") } catch (e: Exception) { throw e } diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/SelectionEntityListener.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/SelectionEntityListener.kt index c2e06c92..284d326a 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/SelectionEntityListener.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/SelectionEntityListener.kt @@ -14,6 +14,7 @@ import io.github.chessevolved.components.PositionComponent import io.github.chessevolved.components.ValidMovesComponent import io.github.chessevolved.components.WeatherEventComponent import io.github.chessevolved.singletons.EcsEngine +import io.github.chessevolved.singletons.GameSettings class SelectionEntityListener( private val boardSize: Int, @@ -35,6 +36,10 @@ class SelectionEntityListener( piece.remove(CanBeCapturedComponent::class.java) } + if (PlayerColorComponent.mapper.get(entity).color != GameSettings.clientPlayerColor) { + return + } + val availablePositions = moveValidator.checkAvailablePositions( PlayerColorComponent.mapper.get(entity).color, diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/Navigator.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/Navigator.kt index fecc3324..83238c1e 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/Navigator.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/Navigator.kt @@ -69,11 +69,13 @@ class Navigator( } fun goBack() { + print("${PresenterManager.getCurrent()} before") if (!PresenterManager.isEmpty()) { PresenterManager.pop() } if (PresenterManager.isEmpty()) { PresenterManager.push(createMenuPresenter()) } + print("${PresenterManager.getCurrent()} after") } } diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt index 1f209383..142ccb3d 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt @@ -19,6 +19,7 @@ class EndGamePresenter( private var otherPlayerLeft = false init { + println("${Game.isInGame()} init") Game.subscribeToGameUpdates(this.toString(), ::onGameUpdate) endGameView.endGameStatus = endGameStatus endGameView.init() @@ -27,6 +28,7 @@ class EndGamePresenter( } private fun requestRematch() { + println("${Game.isInGame()} rematch") endGameView.disableRematchButton() endGameView.updateRematchText("Rematch request\nsent...") runBlocking { @@ -37,6 +39,7 @@ class EndGamePresenter( } private fun returnToMenu() { + println("${Game.isInGame()} returntomenu") runBlocking { launch { val wantsRematch = Game.getWantsRematch() @@ -66,18 +69,25 @@ class EndGamePresenter( } override fun dispose() { + println("${Game.isInGame()} dispose") // Denne e false.... Noe leavea gamen alt for tidlig endGameView.dispose() Game.unsubscribeFromGameUpdates(this.toString()) - runBlocking { + // Both isInGame and isInLobby must be checked here + // game and lobby is being left somewhere else leading to a fatal error if not checked + runBlocking { launch { val wantsRematch = Game.getWantsRematch() - Game.leaveGame() + if (Game.isInGame()) { + Game.leaveGame() + } if (wantsRematch && !otherPlayerLeft) { Lobby.leaveLobbyWithoutUpdating() } else { - Lobby.leaveLobby() + if(Lobby.isInLobby()) { + Lobby.leaveLobby() + } } } } @@ -88,6 +98,7 @@ class EndGamePresenter( } fun onGameUpdate(updatedGame: GameDto) { + println("${Game.isInGame()} gameupdate") if (updatedGame.wantRematch) { if (!Game.getWantsRematch()) { otherPlayerHasAskedForRematch = true diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt index fb8c6920..e2663086 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt @@ -15,6 +15,8 @@ import io.github.chessevolved.components.AbilityCardComponent import io.github.chessevolved.components.AbilityComponent import io.github.chessevolved.components.SelectionComponent import io.github.chessevolved.components.TextureRegionComponent +import io.github.chessevolved.components.PieceTypeComponent +import io.github.chessevolved.components.PlayerColorComponent import io.github.chessevolved.data.Position import io.github.chessevolved.entities.AbilityItemFactory import io.github.chessevolved.entities.BoardSquareFactory @@ -26,9 +28,9 @@ import io.github.chessevolved.enums.WeatherEvent import io.github.chessevolved.singletons.EcsEngine import io.github.chessevolved.singletons.EcsEntityMapper import io.github.chessevolved.singletons.Game +import io.github.chessevolved.singletons.GameSettings import io.github.chessevolved.singletons.Game.subscribeToGameUpdates import io.github.chessevolved.singletons.Game.unsubscribeFromGameUpdates -import io.github.chessevolved.singletons.GameSettings import io.github.chessevolved.singletons.Lobby import io.github.chessevolved.singletons.supabase.SupabaseGameHandler import io.github.chessevolved.systems.AbilitySystem @@ -44,6 +46,7 @@ import io.github.chessevolved.views.GameUIView import io.github.chessevolved.views.GameView import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import ktx.graphics.color class GamePresenter( private val navigator: Navigator, @@ -314,19 +317,8 @@ class GamePresenter( gameBatch.dispose() engine.removeAllEntities() unloadAssets() + println("${this.toString()}") unsubscribeFromGameUpdates(this.toString()) - if (Game.isInGame() && !navigatingToEndGame) { - runBlocking { - launch { - try { - Game.leaveGame() - Lobby.leaveLobby() - } catch (e: Exception) { - error("Non fatal error: Problem with calling leaveGame(). Error: " + e.message) - } - } - } - } } private fun unloadAssets() { @@ -433,10 +425,32 @@ class GamePresenter( if (SupabaseGameHandler.sendingGameState) { SupabaseGameHandler.sendingGameState = false + + val kings = pieces.filter { it.type == PieceType.KING } + + if (kings.size != 2) { + val winningColor = kings[0].color + Gdx.app.postRunnable { + goToGameOverScreen(winningColor == GameSettings.clientPlayerColor) + } + } + return } - EcsEntityMapper.applyStateToEngine(engine, pieceFactory, gameStage, pieces, boardSquares) + Gdx.app.postRunnable { + EcsEntityMapper.applyStateToEngine(engine, pieceFactory, gameStage, pieces, boardSquares) + + val kings = EcsEngine.getEntitiesFor(Family.all(PieceTypeComponent::class.java).get()).filter { + PieceTypeComponent.mapper.get(it).type == PieceType.KING + } + + if(kings.size != 2) { + val winningColor = kings.get(0).getComponent(PlayerColorComponent::class.java).color + + goToGameOverScreen(winningColor == GameSettings.clientPlayerColor) + } + } } private fun onTurnComplete() { From 69baf465708557fb6f1f3905e2fa38cb2891063c Mon Sep 17 00:00:00 2001 From: Sivert Underdal Date: Mon, 21 Apr 2025 14:22:52 +0200 Subject: [PATCH 4/6] fix: problem with rematch system where you couldn't start the game, and sometimes not registering that a second player has joined --- .../kotlin/io/github/chessevolved/singletons/Game.kt | 5 +++++ .../io/github/chessevolved/singletons/Lobby.kt | 2 ++ .../singletons/supabase/SupabaseGameHandler.kt | 12 ++++++++++++ .../chessevolved/presenters/EndGamePresenter.kt | 12 +++++++----- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt index 4c25fd85..4aa89785 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt @@ -36,6 +36,11 @@ object Game { } } + suspend fun deleteGame() { + leaveGame() + SupabaseGameHandler.deleteGameRow(Lobby.getLobbyId()!!) + } + suspend fun askForRematch() { if (!isInGame() && !hasAskedForRematch) { throw IllegalStateException("Can't ask for rematch if not in a game or have already asked for rematch!") diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt index 3a87d1bc..c5e880e8 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Lobby.kt @@ -36,6 +36,7 @@ object Lobby { try { SupabaseLobbyHandler.leaveLobbyNoUpdateSecondPlayer(lobbyId!!) SupabaseLobbyHandler.joinLobbyNoUpdateSecondPlayer(lobbyId!!, ::onLobbyRowUpdate) + onLobbyRowUpdate(getLobby()) } catch (e: Exception) { Gdx.app.error("Lobby", "Error when joining rematch lobby: " + e.message) } @@ -48,6 +49,7 @@ object Lobby { try { SupabaseLobbyHandler.leaveLobbyNoUpdateSecondPlayer(lobbyId!!) SupabaseLobbyHandler.joinLobby(lobbyId!!, ::onLobbyRowUpdate) + onLobbyRowUpdate(getLobby()) } catch (e: Exception) { throw e } diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt index 17ab783c..87ba08cc 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/supabase/SupabaseGameHandler.kt @@ -77,6 +77,18 @@ object SupabaseGameHandler { SupabaseChannelManager.unsubscribeFromChannel("game_$lobbyCode") } + suspend fun deleteGameRow(lobbyCode: String) { + try { + supabase.from(SUPABASE_GAME_TABLE_NAME).delete { + filter { + eq("lobby_code", lobbyCode) + } + } + } catch (e: PostgrestRestException) { + throw e + } + } + suspend fun requestRematch(lobbyCode: String) { try { val response = diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt index 142ccb3d..2758dba5 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/EndGamePresenter.kt @@ -75,18 +75,20 @@ class EndGamePresenter( // Both isInGame and isInLobby must be checked here // game and lobby is being left somewhere else leading to a fatal error if not checked - runBlocking { + runBlocking { launch { val wantsRematch = Game.getWantsRematch() if (Game.isInGame()) { Game.leaveGame() } + // TODO: This logic doesn't work as of yet. In further iterations, this would be priority. if (wantsRematch && !otherPlayerLeft) { - Lobby.leaveLobbyWithoutUpdating() + // TODO: Need to discern between a player that leaves the rematch-screen, and a player that goes from rematch-screen to a lobby. + // Lobby.leaveLobbyWithoutUpdating() } else { - if(Lobby.isInLobby()) { - Lobby.leaveLobby() + if (Lobby.isInLobby()) { + // Lobby.leaveLobby() } } } @@ -120,7 +122,7 @@ class EndGamePresenter( } else { runBlocking { launch { - Game.leaveGame() + Game.deleteGame() Lobby.joinRematchLobbyAsHost() } } From e5d24430b84cb13fd82d720f609dfd450b7c12ef Mon Sep 17 00:00:00 2001 From: chrisjk Date: Mon, 21 Apr 2025 15:06:12 +0200 Subject: [PATCH 5/6] feat: :sparkles: make players unable to move when not their turn also fixes a bug where actor was not removed on piece movement --- .../io/github/chessevolved/singletons/EcsEntityMapper.kt | 4 ++++ .../main/kotlin/io/github/chessevolved/singletons/Game.kt | 1 + .../kotlin/io/github/chessevolved/systems/InputSystem.kt | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt index b7e6b7bb..0cd65006 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/EcsEntityMapper.kt @@ -4,6 +4,7 @@ import com.badlogic.ashley.core.Engine import com.badlogic.ashley.core.Family import com.badlogic.gdx.Gdx import com.badlogic.gdx.scenes.scene2d.Stage +import io.github.chessevolved.components.ActorComponent import io.github.chessevolved.components.PieceTypeComponent import io.github.chessevolved.components.PlayerColorComponent import io.github.chessevolved.components.PositionComponent @@ -98,7 +99,10 @@ object EcsEntityMapper { val pos = PositionComponent.mapper.get(existingEntity).position if (pos !in currentPositions) { Gdx.app.debug("ECSEntityMapper", "Removing piece no longer in state at $pos") + val actorComponent = ActorComponent.mapper.get(existingEntity) + actorComponent.actor.remove() engine.removeEntity(existingEntity) + println("ActorComp: $actorComponent") } } diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt index 4aa89785..73a2bd11 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/singletons/Game.kt @@ -17,6 +17,7 @@ object Game { try { SupabaseGameHandler.joinGame(gameId, ::onGameRowUpdate) this.inGame = true + this.currentTurn = PlayerColor.WHITE } catch (e: Exception) { throw Exception("Problem with joining game: " + e.message) } diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt index 598e5b37..c90230f0 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt @@ -15,6 +15,8 @@ import io.github.chessevolved.components.SelectionComponent import io.github.chessevolved.components.WeatherEventComponent import io.github.chessevolved.data.Position import io.github.chessevolved.singletons.EcsEngine +import io.github.chessevolved.singletons.Game +import io.github.chessevolved.singletons.GameSettings class InputSystem : IteratingSystem( @@ -98,6 +100,9 @@ class InputSystem : class InputService { fun clickPieceAtPosition(position: Position) { + println("piece clicked") + if(Game.getCurrentTurn() != GameSettings.clientPlayerColor) return + val entity = EcsEngine .getEntitiesFor(Family.all(PieceTypeComponent::class.java).get()) @@ -107,6 +112,7 @@ class InputService { } fun clickBoardSquareAtPosition(position: Position) { + println("boardsquare clicked") val entity = EcsEngine .getEntitiesFor(Family.all(WeatherEventComponent::class.java).get()) From fb9847315f5d60e9da8bd7f9314a1e1339b0a12f Mon Sep 17 00:00:00 2001 From: chrisjk Date: Mon, 21 Apr 2025 15:12:53 +0200 Subject: [PATCH 6/6] refactor: :art: complete ktlintformatting --- .../chessevolved/entities/PieceFactory.kt | 1 - .../chessevolved/systems/InputSystem.kt | 2 +- .../chessevolved/presenters/GamePresenter.kt | 19 ++++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt index d329aec2..c8bf50db 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/entities/PieceFactory.kt @@ -21,7 +21,6 @@ import io.github.chessevolved.data.Position import io.github.chessevolved.enums.MoveType import io.github.chessevolved.enums.PieceType import io.github.chessevolved.enums.PlayerColor -import io.github.chessevolved.singletons.GameSettings import io.github.chessevolved.systems.InputService import ktx.actors.onClick diff --git a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt index c90230f0..865fadd1 100644 --- a/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt +++ b/chessevolved_model/src/main/kotlin/io/github/chessevolved/systems/InputSystem.kt @@ -101,7 +101,7 @@ class InputSystem : class InputService { fun clickPieceAtPosition(position: Position) { println("piece clicked") - if(Game.getCurrentTurn() != GameSettings.clientPlayerColor) return + if (Game.getCurrentTurn() != GameSettings.clientPlayerColor) return val entity = EcsEngine diff --git a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt index e2663086..ad01607b 100644 --- a/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt +++ b/chessevolved_presenter/src/main/kotlin/io/github/chessevolved/presenters/GamePresenter.kt @@ -13,10 +13,10 @@ import com.badlogic.gdx.utils.viewport.Viewport import io.github.chessevolved.Navigator import io.github.chessevolved.components.AbilityCardComponent import io.github.chessevolved.components.AbilityComponent -import io.github.chessevolved.components.SelectionComponent -import io.github.chessevolved.components.TextureRegionComponent import io.github.chessevolved.components.PieceTypeComponent import io.github.chessevolved.components.PlayerColorComponent +import io.github.chessevolved.components.SelectionComponent +import io.github.chessevolved.components.TextureRegionComponent import io.github.chessevolved.data.Position import io.github.chessevolved.entities.AbilityItemFactory import io.github.chessevolved.entities.BoardSquareFactory @@ -28,9 +28,9 @@ import io.github.chessevolved.enums.WeatherEvent import io.github.chessevolved.singletons.EcsEngine import io.github.chessevolved.singletons.EcsEntityMapper import io.github.chessevolved.singletons.Game -import io.github.chessevolved.singletons.GameSettings import io.github.chessevolved.singletons.Game.subscribeToGameUpdates import io.github.chessevolved.singletons.Game.unsubscribeFromGameUpdates +import io.github.chessevolved.singletons.GameSettings import io.github.chessevolved.singletons.Lobby import io.github.chessevolved.singletons.supabase.SupabaseGameHandler import io.github.chessevolved.systems.AbilitySystem @@ -317,7 +317,7 @@ class GamePresenter( gameBatch.dispose() engine.removeAllEntities() unloadAssets() - println("${this.toString()}") + println("$this") unsubscribeFromGameUpdates(this.toString()) } @@ -441,13 +441,14 @@ class GamePresenter( Gdx.app.postRunnable { EcsEntityMapper.applyStateToEngine(engine, pieceFactory, gameStage, pieces, boardSquares) - val kings = EcsEngine.getEntitiesFor(Family.all(PieceTypeComponent::class.java).get()).filter { - PieceTypeComponent.mapper.get(it).type == PieceType.KING - } + val kings = + EcsEngine.getEntitiesFor(Family.all(PieceTypeComponent::class.java).get()).filter { + PieceTypeComponent.mapper.get(it).type == PieceType.KING + } - if(kings.size != 2) { + if (kings.size != 2) { val winningColor = kings.get(0).getComponent(PlayerColorComponent::class.java).color - + goToGameOverScreen(winningColor == GameSettings.clientPlayerColor) } }