소스 검색

Big Refactor to support centralised SpriteBatch and GlobalTransformation Matrix to keep aspect ratio.

Dominique Louis 1 개월 전
부모
커밋
e16ab5ce60
27개의 변경된 파일851개의 추가작업 그리고 345개의 파일을 삭제
  1. 62 56
      CardsStarterKit/Core/Game/Blackjack/Game/BlackjackCardGame.cs
  2. 13 13
      CardsStarterKit/Core/Game/Blackjack/Misc/BetGameComponent.cs
  3. 9 8
      CardsStarterKit/Core/Game/Blackjack/UI/BlackJackAnimatedPlayerHandComponent.cs
  4. 6 5
      CardsStarterKit/Core/Game/Blackjack/UI/BlackJackTable.cs
  5. 4 3
      CardsStarterKit/Core/Game/Blackjack/UI/BlackjackAnimatedDealerHandComponent.cs
  6. 17 13
      CardsStarterKit/Core/Game/Blackjack/UI/Button.cs
  7. 5 8
      CardsStarterKit/Core/Game/BlackjackGame.cs
  8. 15 15
      CardsStarterKit/Core/Game/Misc/InputHelper.cs
  9. 0 81
      CardsStarterKit/Core/Game/Poker/README.md
  10. 14 5
      CardsStarterKit/Core/Game/ScreenManager/GameScreen.cs
  11. 4 4
      CardsStarterKit/Core/Game/ScreenManager/MenuScreen.cs
  12. 76 21
      CardsStarterKit/Core/Game/ScreenManager/ScreenManager.cs
  13. 4 3
      CardsStarterKit/Core/Game/Screens/BackgroundScreen.cs
  14. 6 6
      CardsStarterKit/Core/Game/Screens/GameplayScreen.cs
  15. 6 5
      CardsStarterKit/Core/Game/Screens/InstructionScreen.cs
  16. 14 9
      CardsStarterKit/Core/Game/Screens/OptionsMenu.cs
  17. 4 6
      CardsStarterKit/Framework/Game/CardsGame.cs
  18. 14 9
      CardsStarterKit/Framework/UI/AnimatedCardsGameComponent.cs
  19. 13 38
      CardsStarterKit/Framework/UI/AnimatedGameComponent.cs
  20. 18 12
      CardsStarterKit/Framework/UI/AnimatedHandGameComponent.cs
  21. 10 5
      CardsStarterKit/Framework/UI/GameTable.cs
  22. 19 15
      CardsStarterKit/Platforms/Android/AndroidManifest.xml
  23. 1 0
      CardsStarterKit/Platforms/Android/BlackJack.Android.csproj
  24. 22 5
      CardsStarterKit/Platforms/Android/MainActivity.cs
  25. BIN
      CardsStarterKit/Platforms/Android/Resources/drawable/icon.png
  26. 491 0
      CardsStarterKit/Platforms/Android/Resources/drawable/icon.svg
  27. 4 0
      CardsStarterKit/Platforms/Android/Resources/values/strings.xml

+ 62 - 56
CardsStarterKit/Core/Game/Blackjack/Game/BlackjackCardGame.cs

@@ -15,10 +15,10 @@ using Microsoft.Xna.Framework.Input;
 using Microsoft.Xna.Framework.Graphics;
 using GameStateManagement;
 using System.Reflection;
+using System.IO;
 
 namespace Blackjack
 {
-
     class BlackjackCardGame : CardsGame
     {
         Dictionary<Player, string> playerHandValueTexts =
@@ -68,7 +68,7 @@ namespace Blackjack
             Func<int, Vector2> placeOrder, ScreenManager screenManager, string theme)
             : base(6, 0, CardSuit.AllSuits, CardsFramework.CardValue.NonJokers,
             minPlayers, maxPlayers, new BlackJackTable(ringOffset, tableBounds,
-                dealerPosition, maxPlayers, placeOrder, theme, screenManager.Game),
+                dealerPosition, maxPlayers, placeOrder, theme, screenManager.Game, screenManager.SpriteBatch, screenManager.GlobalTransformation),
             theme, screenManager.Game)
         {
             dealerPlayer = new BlackjackPlayer("Dealer", this);
@@ -92,8 +92,8 @@ namespace Blackjack
         {
             base.LoadContent();
             // Initialize a new bet component
-            betGameComponent =
-                new BetGameComponent(players, screenManager.input, Theme, this);
+            // You may need to pass input state from elsewhere
+            betGameComponent = new BetGameComponent(players, screenManager.input, Theme, this, screenManager.SpriteBatch, screenManager.GlobalTransformation);
             Game.Components.Add(betGameComponent);
 
             // Initialize the game buttons
@@ -101,7 +101,7 @@ namespace Blackjack
             for (int buttonIndex = 0; buttonIndex < buttonsText.Length; buttonIndex++)
             {
                 Button button = new Button("ButtonRegular", "ButtonPressed",
-                    screenManager.input, this)
+                    screenManager.input, this, screenManager.SpriteBatch, screenManager.GlobalTransformation)
                 {
                     Text = buttonsText[buttonIndex],
                     Bounds = new Rectangle(screenManager.SafeArea.Left + 10 + buttonIndex * 110,
@@ -116,7 +116,7 @@ namespace Blackjack
             }
 
             newGame = new Button("ButtonRegular", "ButtonPressed",
-                screenManager.input, this)
+                    screenManager.input, this, screenManager.SpriteBatch, screenManager.GlobalTransformation)
             {
                 Text = "New Hand",
 
@@ -156,18 +156,21 @@ namespace Blackjack
                 case BlackjackGameState.Shuffling:
                     {
                         ShowShuffleAnimation();
-                    } break;
+                    }
+                    break;
                 case BlackjackGameState.Betting:
                     {
                         EnableButtons(false);
-                    } break;
+                    }
+                    break;
                 case BlackjackGameState.Dealing:
                     {
                         // Deal 2 cards and start playing
                         State = BlackjackGameState.Playing;
                         Deal();
                         StartPlaying();
-                    } break;
+                    }
+                    break;
                 case BlackjackGameState.Playing:
                     {
                         // Calculate players' current hand values
@@ -203,7 +206,8 @@ namespace Blackjack
                         }
                         else
                             EnableButtons(false);
-                    } break;
+                    }
+                    break;
                 case BlackjackGameState.RoundEnd:
                     {
                         if (dealerHandComponent.EstimatedTimeForAnimationsCompletion() == TimeSpan.Zero)
@@ -221,11 +225,13 @@ namespace Blackjack
                                 newGame.Visible = true;
                             }
                         }
-                    } break;
+                    }
+                    break;
                 case BlackjackGameState.GameOver:
                     {
 
-                    } break;
+                    }
+                    break;
                 default: break;
             }
         }
@@ -236,7 +242,7 @@ namespace Blackjack
         private void ShowShuffleAnimation()
         {
             // Add shuffling animation
-            AnimatedGameComponent animationComponent = new AnimatedGameComponent(this.Game)
+            AnimatedGameComponent animationComponent = new AnimatedGameComponent(this, null, screenManager.SpriteBatch, screenManager.GlobalTransformation)
             {
                 CurrentPosition = GameTable.DealerPosition,
                 Visible = false
@@ -245,13 +251,13 @@ namespace Blackjack
 
             animationComponent.AddAnimation(
                 new FramesetGameComponentAnimation(cardsAssets["shuffle_" + Theme], 32, 11, frameSize)
-            {
-                Duration = TimeSpan.FromSeconds(1.5f),
-                PerformBeforeStart = ShowComponent,
-                PerformBeforSartArgs = animationComponent,
-                PerformWhenDone = PlayShuffleAndRemoveComponent,
-                PerformWhenDoneArgs = animationComponent
-            });
+                {
+                    Duration = TimeSpan.FromSeconds(1.5f),
+                    PerformBeforeStart = ShowComponent,
+                    PerformBeforSartArgs = animationComponent,
+                    PerformWhenDone = PlayShuffleAndRemoveComponent,
+                    PerformWhenDoneArgs = animationComponent
+                });
             State = BlackjackGameState.Betting;
         }
 
@@ -281,17 +287,19 @@ namespace Blackjack
         /// this method.</param>
         public void Draw(GameTime gameTime)
         {
-            SpriteBatch.Begin();
+            screenManager.SpriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screenManager.GlobalTransformation);
 
             switch (State)
             {
                 case BlackjackGameState.Playing:
                     {
                         ShowPlayerValues();
-                    } break;
+                    }
+                    break;
                 case BlackjackGameState.GameOver:
                     {
-                    } break;
+                    }
+                    break;
                 case BlackjackGameState.RoundEnd:
                     {
                         if (dealerHandComponent.EstimatedTimeForAnimationsCompletion() == TimeSpan.Zero)
@@ -299,11 +307,12 @@ namespace Blackjack
                             ShowDealerValue();
                         }
                         ShowPlayerValues();
-                    } break;
+                    }
+                    break;
                 default: break;
             }
 
-            SpriteBatch.End();
+            screenManager.SpriteBatch.End();
         }
 
         /// <summary>
@@ -329,12 +338,11 @@ namespace Blackjack
             Vector2 measure = Font.MeasureString(dealerValue);
             Vector2 position = GameTable.DealerPosition - new Vector2(measure.X + 20, 0);
 
-            SpriteBatch.Draw(screenManager.BlankTexture,
+            screenManager.SpriteBatch.Draw(screenManager.BlankTexture,
                 new Rectangle((int)position.X - 4, (int)position.Y,
                 (int)measure.X + 8, (int)measure.Y), Color.Black);
 
-            SpriteBatch.DrawString(Font, dealerValue,
-                position, Color.White);
+            screenManager.SpriteBatch.DrawString(Font, dealerValue, position, Color.White);
         }
 
         /// <summary>
@@ -379,8 +387,7 @@ namespace Blackjack
                             }
                             else
                             {
-                                playerHandValueText += @"\" +
-                                    (player.FirstValue + 10).ToString();
+                                playerHandValueText += @"\" + (player.FirstValue + 10).ToString();
                             }
                         }
                         playerHandValueTexts[player] = playerHandValueText;
@@ -405,12 +412,10 @@ namespace Blackjack
                                 }
                                 else
                                 {
-                                    playerSecondHandValueText +=
-                                        @"\" + (player.SecondValue + 10).ToString();
+                                    playerSecondHandValueText += @"\" + (player.SecondValue + 10).ToString();
                                 }
                             }
-                            playerSecondHandValueTexts[player] =
-                                playerSecondHandValueText;
+                            playerSecondHandValueTexts[player] = playerSecondHandValueText;
                         }
                         else
                         {
@@ -478,10 +483,10 @@ namespace Blackjack
             position.X += (cardsAssets["CardBack_" + Theme].Bounds.Width - measure.X) / 2;
             position.Y -= measure.Y + 5;
 
-            SpriteBatch.Draw(screenManager.BlankTexture,
+            screenManager.SpriteBatch.Draw(screenManager.BlankTexture,
                 new Rectangle((int)position.X - 4, (int)position.Y,
                 (int)measure.X + 8, (int)measure.Y), Color.Black);
-            SpriteBatch.DrawString(Font, value, position, valueColor);
+            screenManager.SpriteBatch.DrawString(Font, value, position, valueColor);
 
         }
 
@@ -617,12 +622,12 @@ namespace Blackjack
                 new TransitionGameComponentAnimation(GameTable.DealerPosition,
                 animatedHand.CurrentPosition +
                 animatedHand.GetCardRelativePosition(cardLocationInHand))
-            {
-                StartTime = startTime,
-                PerformBeforeStart = ShowComponent,
-                PerformBeforSartArgs = cardComponent,
-                PerformWhenDone = PlayDealSound
-            });
+                {
+                    StartTime = startTime,
+                    PerformBeforeStart = ShowComponent,
+                    PerformBeforSartArgs = cardComponent,
+                    PerformWhenDone = PlayDealSound
+                });
 
             if (flipCard)
             {
@@ -698,11 +703,11 @@ namespace Blackjack
 
             // Add the animation component 
             AnimatedGameComponent animationComponent =
-                new AnimatedGameComponent(this, cardsAssets[assetName])
-            {
-                CurrentPosition = currentPosition,
-                Visible = false
-            };
+                new AnimatedGameComponent(this, cardsAssets[assetName], screenManager.SpriteBatch, screenManager.GlobalTransformation)
+                {
+                    CurrentPosition = currentPosition,
+                    Visible = false
+                };
             Game.Components.Add(animationComponent);
 
             // Calculate when to start the animation. The animation will only begin
@@ -745,7 +750,7 @@ namespace Blackjack
         private void ShowDealerHand()
         {
             dealerHandComponent =
-                new BlackjackAnimatedDealerHandComponent(-1, dealerPlayer.Hand, this);
+                new BlackjackAnimatedDealerHandComponent(-1, dealerPlayer.Hand, this, screenManager.SpriteBatch, screenManager.GlobalTransformation);
             Game.Components.Add(dealerHandComponent);
         }
 
@@ -940,10 +945,11 @@ namespace Blackjack
         /// </summary>
         private void DisplayPlayingHands()
         {
+
             for (int playerIndex = 0; playerIndex < players.Count; playerIndex++)
             {
                 AnimatedHandGameComponent animatedHandGameComponent =
-                    new BlackjackAnimatedPlayerHandComponent(playerIndex, players[playerIndex].Hand, this);
+                    new BlackjackAnimatedPlayerHandComponent(playerIndex, players[playerIndex].Hand, this, screenManager.SpriteBatch, screenManager.GlobalTransformation);
                 Game.Components.Add(animatedHandGameComponent);
                 animatedHands[playerIndex] = animatedHandGameComponent;
             }
@@ -1068,8 +1074,8 @@ namespace Blackjack
 
             // Add a component for an empty stalling animation. This actually acts
             // as a timer.
-            Texture2D texture = this.Game.Content.Load<Texture2D>(@"Images\youlose");
-            animationComponent = new AnimatedGameComponent(this, texture)
+            Texture2D texture = this.Game.Content.Load<Texture2D>(Path.Combine("Images", "youlose"));
+            animationComponent = new AnimatedGameComponent(this, texture, screenManager.SpriteBatch, screenManager.GlobalTransformation)
             {
                 CurrentPosition = new Vector2(
                     this.Game.GraphicsDevice.Viewport.Bounds.Center.X - texture.Width / 2,
@@ -1082,7 +1088,7 @@ namespace Blackjack
             Rectangle bounds = this.Game.GraphicsDevice.Viewport.Bounds;
             Vector2 center = new Vector2(bounds.Center.X, bounds.Center.Y);
             Button backButton = new Button("ButtonRegular", "ButtonPressed",
-                screenManager.input, this)
+                screenManager.input, this, screenManager.SpriteBatch, screenManager.GlobalTransformation)
             {
                 Bounds = new Rectangle((int)center.X - 100, (int)center.Y + 80, 200, 50),
                 Font = this.Font,
@@ -1115,7 +1121,7 @@ namespace Blackjack
             ((Button)arr[1]).Visible = true;
 
             // Remove all unnecessary game components
-            for (int compontneIndex = 0; compontneIndex < Game.Components.Count; )
+            for (int compontneIndex = 0; compontneIndex < Game.Components.Count;)
             {
                 if ((Game.Components[compontneIndex] != ((AnimatedGameComponent)arr[0]) &&
                     Game.Components[compontneIndex] != ((Button)arr[1])) &&
@@ -1270,7 +1276,7 @@ namespace Blackjack
             // Initialize visual representation of the second hand
             animatedSecondHands[playerIndex] =
                 new BlackjackAnimatedPlayerHandComponent(playerIndex, secondHandOffset,
-                    player.SecondHand, this);
+                    player.SecondHand, this, screenManager.SpriteBatch, screenManager.GlobalTransformation);
             Game.Components.Add(animatedSecondHands[playerIndex]);
 
             AnimatedCardsGameComponent animatedGameComponet = animatedSecondHands[playerIndex].GetCardGameComponent(0);
@@ -1397,7 +1403,7 @@ namespace Blackjack
         public void ShowPlayerPass(int indexPlayer)
         {
             // Add animation component
-            AnimatedGameComponent passComponent = new AnimatedGameComponent(this, cardsAssets["pass"])
+            AnimatedGameComponent passComponent = new AnimatedGameComponent(this, cardsAssets["pass"], screenManager.SpriteBatch, screenManager.GlobalTransformation)
             {
                 CurrentPosition = GameTable.PlaceOrder(indexPlayer),
                 Visible = false
@@ -1629,4 +1635,4 @@ namespace Blackjack
             screenManager.AddScreen(new MainMenuScreen(), null);
         }
     }
-}
+}

+ 13 - 13
CardsStarterKit/Core/Game/Blackjack/Misc/BetGameComponent.cs

@@ -15,6 +15,7 @@ using Microsoft.Xna.Framework.Input;
 using CardsFramework;
 using GameStateManagement;
 using Microsoft.Xna.Framework.Input.Touch;
+using System.IO;
 
 namespace Blackjack
 {
@@ -28,6 +29,7 @@ namespace Blackjack
         Vector2[] positions;
         CardsFramework.CardsGame cardGame;
         SpriteBatch spriteBatch;
+        Matrix globalTransformation;
 
         bool isKeyDown = false;
 
@@ -55,13 +57,15 @@ namespace Blackjack
         /// <param name="cardGame">An instance of <see cref="CardsGame"/> which
         /// is the current game.</param>
         public BetGameComponent(List<Player> players, InputState input,
-            string theme, CardsGame cardGame)
+            string theme, CardsGame cardGame, SpriteBatch spriteBatch, Matrix globalTransformation)
             : base(cardGame.Game)
         {
             this.players = players;
             this.theme = theme;
             this.cardGame = cardGame;
             this.input = input;
+            this.spriteBatch = spriteBatch;
+            this.globalTransformation = globalTransformation;
             chipsAssets = new Dictionary<int, Texture2D>();
         }
 
@@ -89,8 +93,6 @@ namespace Blackjack
             Game.IsMouseVisible = true;
             base.Initialize();
 
-            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
-
             // Calculate chips position for the chip buttons which allow placing the bet
             Rectangle size = chipsAssets[assetNames[0]].Bounds;
 
@@ -106,7 +108,7 @@ namespace Blackjack
             }
 
             // Initialize bet button
-            bet = new Button("ButtonRegular", "ButtonPressed", input, cardGame)
+            bet = new Button("ButtonRegular", "ButtonPressed", input, cardGame, spriteBatch, globalTransformation)
             {
                 Bounds = new Rectangle(bounds.Left + 10, bounds.Bottom - 60, 100, 50),
                 Font = cardGame.Font,
@@ -116,7 +118,7 @@ namespace Blackjack
             Game.Components.Add(bet);
 
             // Initialize clear button
-            clear = new Button("ButtonRegular", "ButtonPressed", input, cardGame)
+            clear = new Button("ButtonRegular", "ButtonPressed", input, cardGame, spriteBatch, globalTransformation)
             {
                 Bounds = new Rectangle(bounds.Left + 120, bounds.Bottom - 60, 100, 50),
                 Font = cardGame.Font,
@@ -133,15 +135,13 @@ namespace Blackjack
         protected override void LoadContent()
         {
             // Load blank chip texture
-            blankChip = Game.Content.Load<Texture2D>(
-                string.Format(@"Images\Chips\chip{0}", "White"));
+            blankChip = Game.Content.Load<Texture2D>(Path.Combine("Images", "Chips", "chipWhite"));
 
             // Load chip textures
             int[] assetNames = { 5, 25, 100, 500 };
             for (int chipIndex = 0; chipIndex < assetNames.Length; chipIndex++)
             {
-                chipsAssets.Add(assetNames[chipIndex], Game.Content.Load<Texture2D>(
-                    string.Format(@"Images\Chips\chip{0}", assetNames[chipIndex])));
+                chipsAssets.Add(assetNames[chipIndex], Game.Content.Load<Texture2D>(Path.Combine("Images", "Chips", $"chip{assetNames[chipIndex]}")));
             }
             positions = new Vector2[assetNames.Length];
 
@@ -302,7 +302,7 @@ namespace Blackjack
         /// this method.</param>
         public override void Draw(GameTime gameTime)
         {
-            spriteBatch.Begin();
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, globalTransformation);
 
             // Draws the chips
             for (int chipIndex = 0; chipIndex < chipsAssets.Count; chipIndex++)
@@ -347,7 +347,7 @@ namespace Blackjack
                 currentBet += chipValue;
                 // Add chip component
                 AnimatedGameComponent chipComponent = new AnimatedGameComponent(cardGame,
-                    chipsAssets[chipValue])
+                    chipsAssets[chipValue], spriteBatch, globalTransformation)
                 {
                     Visible = false
                 };
@@ -536,7 +536,7 @@ namespace Blackjack
         private void AddInsuranceChipAnimation(float amount)
         {
             // Add chip component
-            AnimatedGameComponent chipComponent = new AnimatedGameComponent(cardGame, blankChip)
+            AnimatedGameComponent chipComponent = new AnimatedGameComponent(cardGame, blankChip, spriteBatch, globalTransformation)
             {
                 TextColor = Color.Black,
                 Enabled = true,
@@ -751,4 +751,4 @@ namespace Blackjack
             currentBet = 0;
         }
     }
-}
+}

+ 9 - 8
CardsStarterKit/Core/Game/Blackjack/UI/BlackJackAnimatedPlayerHandComponent.cs

@@ -25,9 +25,10 @@ namespace Blackjack
         /// game table.</param>
         /// <param name="hand">The player's hand.</param>
         /// <param name="cardGame">The associated game.</param>
-        public BlackjackAnimatedPlayerHandComponent(int place, Hand hand, 
-            CardsGame cardGame)
-            : base(place, hand, cardGame)
+
+        public BlackjackAnimatedPlayerHandComponent(int place, Hand hand,
+            CardsGame cardGame, Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Microsoft.Xna.Framework.Matrix globalTransformation)
+            : base(place, hand, cardGame, spriteBatch, globalTransformation)
         {
             this.offset = Vector2.Zero;
         }
@@ -42,12 +43,12 @@ namespace Blackjack
         /// <param name="cardGame">The associated game.</param>
         /// <param name="offset">An offset which will be added to all card locations
         /// returned by this component.</param>
-        public BlackjackAnimatedPlayerHandComponent(int place, Vector2 offset, 
-            Hand hand, CardsGame cardGame)
-            : base(place, hand, cardGame)
+        public BlackjackAnimatedPlayerHandComponent(int place, Vector2 offset,
+            Hand hand, CardsGame cardGame, Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Microsoft.Xna.Framework.Matrix globalTransformation)
+            : base(place, hand, cardGame, spriteBatch, globalTransformation)
         {
             this.offset = offset;
-        } 
+        }
 
         /// <summary>
         /// Gets the position relative to the hand position at which a specific card
@@ -63,4 +64,4 @@ namespace Blackjack
                 offset;
         }
     }
-}
+}

+ 6 - 5
CardsStarterKit/Core/Game/Blackjack/UI/BlackJackTable.cs

@@ -7,6 +7,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Text;
 using CardsFramework;
 using Microsoft.Xna.Framework;
@@ -21,8 +22,8 @@ namespace Blackjack
 
 
         public BlackJackTable(Vector2 ringOffset, Rectangle tableBounds, Vector2 dealerPosition, int places,
-            Func<int, Vector2> placeOrder, string theme, Game game)
-            : base(tableBounds, dealerPosition, places, placeOrder, theme, game)
+            Func<int, Vector2> placeOrder, string theme, Game game, SpriteBatch spriteBatch, Matrix? globalTransformation = null)
+            : base(tableBounds, dealerPosition, places, placeOrder, theme, game, spriteBatch, globalTransformation)
         {
             RingOffset = ringOffset;
         }
@@ -32,7 +33,7 @@ namespace Blackjack
         /// </summary>
         protected override void LoadContent()
         {
-            string assetName = string.Format(@"Images\UI\ring");
+            string assetName = string.Format(Path.Combine("Images", "UI", "ring"));
             RingTexture = Game.Content.Load<Texture2D>(assetName);
 
             base.LoadContent();
@@ -46,7 +47,7 @@ namespace Blackjack
         {
             base.Draw(gameTime);
 
-            SpriteBatch.Begin();
+            SpriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, globalTransformation);
 
             for (int placeIndex = 0; placeIndex < Places; placeIndex++)
             {
@@ -56,4 +57,4 @@ namespace Blackjack
             SpriteBatch.End();
         }
     }
-}
+}

+ 4 - 3
CardsStarterKit/Core/Game/Blackjack/UI/BlackjackAnimatedDealerHandComponent.cs

@@ -23,8 +23,9 @@ namespace Blackjack
         /// game table.</param>
         /// <param name="hand">The dealer's hand.</param>
         /// <param name="cardGame">The associated game.</param>
-        public BlackjackAnimatedDealerHandComponent(int place, Hand hand, 
-            CardsGame cardGame) : base(place, hand, cardGame)
+        public BlackjackAnimatedDealerHandComponent(int place, Hand hand,
+            CardsGame cardGame, Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Microsoft.Xna.Framework.Matrix globalTransformation)
+            : base(place, hand, cardGame, spriteBatch, globalTransformation)
         {
         }
 
@@ -41,4 +42,4 @@ namespace Blackjack
             return new Vector2(30 * cardLocationInHand, 0);
         }
     }
-}
+}

+ 17 - 13
CardsStarterKit/Core/Game/Blackjack/UI/Button.cs

@@ -14,6 +14,7 @@ using Microsoft.Xna.Framework.Input;
 using GameStateManagement;
 using CardsFramework;
 using Microsoft.Xna.Framework.Input.Touch;
+using System.IO;
 
 namespace Blackjack
 {
@@ -36,6 +37,8 @@ namespace Blackjack
 
         InputHelper inputHelper;
 
+        private Matrix globalTransformation;
+
 
         /// <summary>
         /// Creates a new instance of the <see cref="Button"/> class.
@@ -46,15 +49,19 @@ namespace Blackjack
         /// <param name="input">A <see cref="GameStateManagement.InputState"/> object
         /// which can be used to retrieve user input.</param>
         /// <param name="cardGame">The associated card game.</param>
+        /// <param name="sharedSpriteBatch">The sprite batch used for drawing.</param>
+        /// <param name="globalTransformation">The global transformation matrix.</param>
         /// <remarks>Texture names are relative to the "Images" content 
         /// folder.</remarks>
         public Button(string regularTexture, string pressedTexture, InputState input,
-            CardsGame cardGame)
-            : base(cardGame, null)
+            CardsGame cardGame, SpriteBatch sharedSpriteBatch, Matrix globalTransformation)
+            : base(cardGame, null, sharedSpriteBatch, globalTransformation)
         {
             this.input = input;
             this.regularTexture = regularTexture;
             this.pressedTexture = pressedTexture;
+            this.spriteBatch = sharedSpriteBatch;
+            this.globalTransformation = globalTransformation;
         }
 
         /// <summary>
@@ -65,7 +72,7 @@ namespace Blackjack
             // Enable tab gesture
             TouchPanel.EnabledGestures = GestureType.Tap;
 
-            // Get Xbox curser
+            // Get Xbox cursor
             inputHelper = null;
             for (int componentIndex = 0; componentIndex < Game.Components.Count; componentIndex++)
             {
@@ -76,8 +83,6 @@ namespace Blackjack
                 }
             }
 
-            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
-
             base.Initialize();
         }
 
@@ -88,11 +93,11 @@ namespace Blackjack
         {
             if (regularTexture != null)
             {
-                RegularTexture = Game.Content.Load<Texture2D>(@"Images\" + regularTexture);
+                RegularTexture = Game.Content.Load<Texture2D>(Path.Combine("Images", regularTexture));
             }
             if (pressedTexture != null)
             {
-                PressedTexture = Game.Content.Load<Texture2D>(@"Images\" + pressedTexture);
+                PressedTexture = Game.Content.Load<Texture2D>(Path.Combine("Images", pressedTexture));
             }
 
             base.LoadContent();
@@ -150,7 +155,7 @@ namespace Blackjack
                     }
                     else
                     {
-                        
+
                         isPressed = false;
                     }
                 }
@@ -165,13 +170,13 @@ namespace Blackjack
                     if (IntersectWith(position))
                     {
                         isPressed = true;
-                        
+
                         if (BlackjackGame.IsMobile)
                         {
                             FireClick();
                             isPressed = false;
                         }
-                        
+
                     }
                     isKeyDown = true;
                 }
@@ -212,8 +217,7 @@ namespace Blackjack
         /// this method.</param>
         public override void Draw(GameTime gameTime)
         {
-            spriteBatch.Begin();
-
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, globalTransformation);
 
             spriteBatch.Draw(isPressed ? PressedTexture : RegularTexture, Bounds, Color.White);
             if (Font != null)
@@ -238,4 +242,4 @@ namespace Blackjack
             base.Dispose(disposing);
         }
     }
-}
+}

+ 5 - 8
CardsStarterKit/Core/Game/BlackjackGame.cs

@@ -31,9 +31,6 @@ namespace Blackjack
         public static float HeightScale = 1.0f;
         public static float WidthScale = 1.0f;
 
-        const int BUFFER_WIDTH = 800;
-        const int BUFFER_HEIGHT = 480;
-
         /// <summary>
         /// Indicates if the game is running on a mobile platform.
         /// </summary>
@@ -83,13 +80,13 @@ namespace Blackjack
         {
             base.Initialize();
 
-            graphicsDeviceManager.PreferredBackBufferWidth = BUFFER_WIDTH;
-            graphicsDeviceManager.PreferredBackBufferHeight = BUFFER_HEIGHT;
+            graphicsDeviceManager.PreferredBackBufferWidth = ScreenManager.BACK_BUFFER_WIDTH;
+            graphicsDeviceManager.PreferredBackBufferHeight = ScreenManager.BACK_BUFFER_HEIGHT;
             graphicsDeviceManager.ApplyChanges();
 
             Rectangle bounds = graphicsDeviceManager.GraphicsDevice.Viewport.TitleSafeArea;
-            HeightScale = bounds.Height / BUFFER_HEIGHT;
-            WidthScale = bounds.Width / BUFFER_WIDTH;
+            HeightScale = bounds.Height / ScreenManager.BACK_BUFFER_HEIGHT;
+            WidthScale = bounds.Width / ScreenManager.BACK_BUFFER_WIDTH;
         }
 
         /// <summary>
@@ -103,4 +100,4 @@ namespace Blackjack
             base.LoadContent();
         }
     }
-}
+}

+ 15 - 15
CardsStarterKit/Core/Game/Misc/InputHelper.cs

@@ -6,6 +6,8 @@
 //-----------------------------------------------------------------------------
 
 using System;
+using System.IO;
+using GameStateManagement;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Input;
@@ -24,25 +26,25 @@ namespace Blackjack
         public bool IsPressed;
 
         Vector2 drawPosition;
+        private ScreenManager screenManager;
         Texture2D texture;
         SpriteBatch spriteBatch;
         float maxVelocity;
 
 
-        public InputHelper(Game game)
-            : base(game)
+        public InputHelper(ScreenManager screenManager)
+            : base(screenManager.Game)
         {
-            texture = Game.Content.Load<Texture2D>(@"Images\GamePadCursor");
-            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
-            maxVelocity = (float)(Game.GraphicsDevice.Viewport.Width +
-                                  Game.GraphicsDevice.Viewport.Height) / 3000f;
-
-            drawPosition = new Vector2(Game.GraphicsDevice.Viewport.Width / 2,
-                Game.GraphicsDevice.Viewport.Height / 2);
+            this.screenManager = screenManager;
+            texture = screenManager.Game.Content.Load<Texture2D>(Path.Combine("Images", "GamePadCursor"));
+            spriteBatch = screenManager.SpriteBatch;
+            maxVelocity = (float)(screenManager.Game.GraphicsDevice.Viewport.Width +
+                                  screenManager.Game.GraphicsDevice.Viewport.Height) / 3000f;
+
+            drawPosition = new Vector2(screenManager.Game.GraphicsDevice.Viewport.Width / 2,
+                screenManager.Game.GraphicsDevice.Viewport.Height / 2);
         }
 
-
-
         //public static InputHelper Instance
         //{
         //    get
@@ -62,8 +64,6 @@ namespace Blackjack
             }
         }
 
-
-
         /// <summary>
         /// Updates itself.
         /// </summary>
@@ -90,11 +90,11 @@ namespace Blackjack
         /// </summary>
         public override void Draw(GameTime gameTime)
         {
-            spriteBatch.Begin();
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screenManager.GlobalTransformation);
             spriteBatch.Draw(texture, drawPosition, null, Color.White, 0, Vector2.Zero, 1,
                 SpriteEffects.None, 0);
             spriteBatch.End();
         }
 
     }
-}
+}

+ 0 - 81
CardsStarterKit/Core/Game/Poker/README.md

@@ -1,81 +0,0 @@
-# Poker Game Implementation Guide
-
-This guide will help you implement a Texas Hold 'Em Poker game using the Cards Framework provided in this repository. It is intended for new developers who want to extend the existing codebase with a new card game, leveraging the modular, event-driven, and component-based architecture already in place.
-
-## Directory Structure
-
-- `Game/` — Core Poker game logic (game state, table, dealing, betting rounds)
-- `Players/` — Player classes (human, AI, seat management)
-- `Rules/` — Poker-specific rules (hand evaluation, betting logic, round progression)
-- `UI/` — User interface components (screens, menus, in-game UI)
-- `Misc/` — Utilities, helpers, and shared resources
-
-## Getting Started
-
-1. **Familiarize Yourself with the Cards Framework**
-   - Review `Framework/Cards/TraditionalCard.cs`, `Framework/Cards/Hand.cs`, and `Framework/Game/CardsGame.cs`.
-   - Understand how the framework models cards, hands, decks, and game flow.
-
-2. **Set Up the Poker Game Class**
-   - Create `PokerGame.cs` in `Poker/Game/` inheriting from `CardsGame`.
-   - Implement game state management: lobby, dealing, betting, showdown, etc.
-   - Use the event-driven model for state transitions.
-
-3. **Implement Player Logic**
-   - Create `PokerPlayer.cs` in `Poker/Players/` inheriting from `Player`.
-   - Add properties for chips, current bet, folded status, etc.
-   - Support both human and AI players.
-
-4. **Define Poker Rules**
-   - Create `PokerRules.cs` in `Poker/Rules/`.
-   - Implement hand evaluation (pair, flush, straight, etc.).
-   - Handle betting rounds: pre-flop, flop, turn, river.
-   - Use the Strategy pattern for rule variations if needed.
-
-5. **Build the UI**
-   - Create screens in `Poker/UI/` (e.g., `PokerTableScreen.cs`, `PokerMenuScreen.cs`).
-   - Use the existing ScreenManager for navigation.
-   - Display player hands, community cards, bets, and pot.
-
-6. **Utilities and Helpers**
-   - Place shared logic (e.g., pot calculation, seat rotation) in `Poker/Misc/`.
-
-## Key Concepts
-
-- **Component-Based Design:** Extend or compose game components for animations, transitions, and UI.
-- **Event-Driven Flow:** Use events to trigger state changes and UI updates.
-- **Separation of Concerns:** Keep game logic, rules, UI, and utilities in their respective folders.
-
-## Example: PokerGame Class Skeleton
-
-```csharp
-using Cards.Framework.Game;
-
-namespace Poker.Game {
-    public class PokerGame : CardsGame {
-        // Game state, table, pot, etc.
-        // ...
-        public override void StartGame() {
-            // Initialize table, shuffle, seat players
-        }
-        // ...
-    }
-}
-```
-
-## Tips
-
-- Reuse as much as possible from the framework (deck, hand, player base classes).
-- Study the Blackjack implementation for patterns and best practices.
-- Use the MonoGame Content Pipeline for assets (cards, chips, UI elements).
-- Test incrementally: start with basic dealing and round flow, then add betting and hand evaluation.
-
-## Resources
-
-- [MonoGame Documentation](https://docs.monogame.net/)
-- [Texas Hold 'Em Rules](https://en.wikipedia.org/wiki/Texas_hold_%27em)
-- [Cards Framework Overview](../Framework/)
-
----
-
-Happy coding! If you have questions, check the existing Blackjack code or ask for help.

+ 14 - 5
CardsStarterKit/Core/Game/ScreenManager/GameScreen.cs

@@ -146,7 +146,6 @@ namespace GameStateManagement
 
         bool otherScreenHasFocus;
 
-
         /// <summary>
         /// Gets the manager that this screen belongs to.
         /// </summary>
@@ -200,7 +199,7 @@ namespace GameStateManagement
         }
 
         GestureType enabledGestures = GestureType.None;
-        
+
         /// <summary>
         /// Gets whether or not this screen is serializable. If this is true,
         /// the screen will be recorded into the screen manager's state and
@@ -223,8 +222,10 @@ namespace GameStateManagement
         /// <summary>
         /// Load graphics content for the screen.
         /// </summary>
-        public virtual void LoadContent() { }
-
+        public virtual void LoadContent()
+        {
+            ScreenManager.ScalePresentationArea();
+        }
 
         /// <summary>
         /// Unload content for the screen.
@@ -284,6 +285,14 @@ namespace GameStateManagement
                     screenState = ScreenState.Active;
                 }
             }
+
+            // Check if the back buffer size has changed (e.g., window resize).
+            if (ScreenManager.BackbufferHeight != ScreenManager.GraphicsDevice.PresentationParameters.BackBufferHeight
+                || ScreenManager.BackbufferWidth != ScreenManager.GraphicsDevice.PresentationParameters.BackBufferWidth)
+            {
+                // Adjust the presentation area to match the new back buffer size.
+                ScreenManager.ScalePresentationArea();
+            }
         }
 
 
@@ -377,4 +386,4 @@ namespace GameStateManagement
             return ScreenManager.Game.Content.Load<T>(assetName);
         }
     }
-}
+}

+ 4 - 4
CardsStarterKit/Core/Game/ScreenManager/MenuScreen.cs

@@ -231,7 +231,7 @@ namespace GameStateManagement
             bounds = ScreenManager.SafeArea;
 
             base.LoadContent();
-        } 
+        }
 
 
 
@@ -304,7 +304,7 @@ namespace GameStateManagement
             SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
             SpriteFont font = ScreenManager.Font;
 
-            spriteBatch.Begin();
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, ScreenManager.GlobalTransformation);
 
             // Draw each menu entry in turn.
             for (int i = 0; i < menuEntries.Count; i++)
@@ -357,11 +357,11 @@ namespace GameStateManagement
 
             for (int i = 0; i < menuEntries.Count; i++)
             {
-                menuEntries[i].Destination = 
+                menuEntries[i].Destination =
                     new Rectangle(
                         bounds.Left + (xStep - textureSize.Width) / 2 + (i + 1) * xStep,
                         bounds.Bottom - textureSize.Height * 2, maxWidth, 50);
             }
         }
     }
-}
+}

+ 76 - 21
CardsStarterKit/Core/Game/ScreenManager/ScreenManager.cs

@@ -25,7 +25,6 @@ namespace GameStateManagement
     /// </summary>
     public class ScreenManager : DrawableGameComponent
     {
-
         List<GameScreen> screens = new List<GameScreen>();
         List<GameScreen> screensToUpdate = new List<GameScreen>();
 
@@ -40,8 +39,24 @@ namespace GameStateManagement
 
         bool traceEnabled;
 
+        internal const int BACK_BUFFER_WIDTH = 800;
+        internal const int BACK_BUFFER_HEIGHT = 480;
+
+        private int backbufferWidth;
+        /// <summary>Gets or sets the current backbuffer width.</summary>
+        public int BackbufferWidth { get => backbufferWidth; set => backbufferWidth = value; }
+
+        private int backbufferHeight;
+        /// <summary>Gets or sets the current backbuffer height.</summary>
+        public int BackbufferHeight { get => backbufferHeight; set => backbufferHeight = value; }
 
+        private Vector2 baseScreenSize = new Vector2(BACK_BUFFER_WIDTH, BACK_BUFFER_HEIGHT);
+        /// <summary>Gets or sets the base screen size used for scaling calculations.</summary>
+        public Vector2 BaseScreenSize { get => baseScreenSize; set => baseScreenSize = value; }
 
+        private Matrix globalTransformation;
+        /// <summary>Gets or sets the global transformation matrix for scaling and positioning.</summary>
+        public Matrix GlobalTransformation { get => globalTransformation; set => globalTransformation = value; }
 
         /// <summary>
         /// A default SpriteBatch shared by all the screens. This saves
@@ -71,7 +86,6 @@ namespace GameStateManagement
             get { return font; }
         }
 
-
         /// <summary>
         /// If true, the manager prints out a list of all the screens
         /// each time it is updated. This can be useful for making sure
@@ -95,7 +109,6 @@ namespace GameStateManagement
         }
 
 
-
         /// <summary>
         /// Constructs a new screen manager component.
         /// </summary>
@@ -107,7 +120,6 @@ namespace GameStateManagement
             TouchPanel.EnabledGestures = GestureType.None;
         }
 
-
         /// <summary>
         /// Initializes the screen manager component.
         /// </summary>
@@ -118,7 +130,6 @@ namespace GameStateManagement
             isInitialized = true;
         }
 
-
         /// <summary>
         /// Load your graphics content.
         /// </summary>
@@ -139,7 +150,6 @@ namespace GameStateManagement
             }
         }
 
-
         /// <summary>
         /// Unload your graphics content.
         /// </summary>
@@ -152,10 +162,6 @@ namespace GameStateManagement
             }
         }
 
-
-
-
-
         /// <summary>
         /// Allows each screen to run logic.
         /// </summary>
@@ -209,7 +215,6 @@ namespace GameStateManagement
                 TraceScreens();
         }
 
-
         /// <summary>
         /// Prints a list of all the screens, for debugging.
         /// </summary>
@@ -223,7 +228,6 @@ namespace GameStateManagement
             Debug.WriteLine(string.Join(", ", screenNames.ToArray()));
         }
 
-
         /// <summary>
         /// Tells each screen to draw itself.
         /// </summary>
@@ -238,10 +242,6 @@ namespace GameStateManagement
             }
         }
 
-
-
-
-
         /// <summary>
         /// Adds a new screen to the screen manager.
         /// </summary>
@@ -263,7 +263,6 @@ namespace GameStateManagement
             TouchPanel.EnabledGestures = screen.EnabledGestures;
         }
 
-
         /// <summary>
         /// Removes a screen from the screen manager. You should normally
         /// use GameScreen.ExitScreen instead of calling this directly, so
@@ -289,7 +288,6 @@ namespace GameStateManagement
             }
         }
 
-
         /// <summary>
         /// Expose an array holding all the screens. We return a copy rather
         /// than the real master list, because screens should only ever be added
@@ -300,7 +298,6 @@ namespace GameStateManagement
             return screens.ToArray();
         }
 
-
         /// <summary>
         /// Helper draws a translucent black fullscreen sprite, used for fading
         /// screens in and out, and for darkening the background behind popups.
@@ -309,7 +306,7 @@ namespace GameStateManagement
         {
             Viewport viewport = GraphicsDevice.Viewport;
 
-            spriteBatch.Begin();
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, GlobalTransformation);
 
             spriteBatch.Draw(blankTexture,
                              new Rectangle(0, 0, viewport.Width, viewport.Height),
@@ -318,6 +315,64 @@ namespace GameStateManagement
             spriteBatch.End();
         }
 
+        /// <summary>
+        /// Scales the game presentation area to match the screen's aspect ratio.
+        /// </summary>
+        public void ScalePresentationArea()
+        {
+            // Validate parameters before calculation
+            if (GraphicsDevice == null || baseScreenSize.X <= 0 || baseScreenSize.Y <= 0)
+            {
+                throw new InvalidOperationException("Invalid graphics configuration");
+            }
+
+            // Fetch screen dimensions
+            backbufferWidth = GraphicsDevice.PresentationParameters.BackBufferWidth;
+            backbufferHeight = GraphicsDevice.PresentationParameters.BackBufferHeight;
+
+            // Prevent division by zero
+            if (backbufferHeight == 0 || baseScreenSize.Y == 0)
+            {
+                return;
+            }
+
+            // Calculate aspect ratios
+            float baseAspectRatio = baseScreenSize.X / baseScreenSize.Y;
+            float screenAspectRatio = backbufferWidth / (float)backbufferHeight;
+
+            // Determine uniform scaling factor
+            float scalingFactor;
+            float horizontalOffset = 0;
+            float verticalOffset = 0;
+
+            if (screenAspectRatio > baseAspectRatio)
+            {
+                // Wider screen: scale by height
+                scalingFactor = backbufferHeight / baseScreenSize.Y;
+
+                // Centre things horizontally.
+                horizontalOffset = (backbufferWidth - baseScreenSize.X * scalingFactor) / 2;
+            }
+            else
+            {
+                // Taller screen: scale by width
+                scalingFactor = backbufferWidth / baseScreenSize.X;
+
+                // Centre things vertically.
+                verticalOffset = (backbufferHeight - baseScreenSize.Y * scalingFactor) / 2;
+            }
+
+            // Update the transformation matrix
+            globalTransformation = Matrix.CreateScale(scalingFactor) *
+                                   Matrix.CreateTranslation(horizontalOffset, verticalOffset, 0);
+
+            // Update the inputTransformation with the Inverted globalTransformation
+            // TODO inputState.UpdateInputTransformation(Matrix.Invert(globalTransformation));
+
+            // Debug info
+            Debug.WriteLine($"Screen Size - Width[{backbufferWidth}] Height[{backbufferHeight}] ScalingFactor[{scalingFactor}]");
+        }
+
         /// <summary>
         /// Informs the screen manager to serialize its state to disk.
         /// </summary>
@@ -454,4 +509,4 @@ namespace GameStateManagement
         }
 
     }
-}
+}

+ 4 - 3
CardsStarterKit/Core/Game/Screens/BackgroundScreen.cs

@@ -11,6 +11,7 @@ using System.Text;
 using GameStateManagement;
 using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework;
+using System.IO;
 
 namespace Blackjack
 {
@@ -33,7 +34,7 @@ namespace Blackjack
         /// </summary>
         public override void LoadContent()
         {
-            background = ScreenManager.Game.Content.Load<Texture2D>(@"Images\titlescreen");
+            background = ScreenManager.Game.Content.Load<Texture2D>(Path.Combine("Images", "titlescreen"));
             safeArea = ScreenManager.Game.GraphicsDevice.Viewport.TitleSafeArea;
             base.LoadContent();
         }
@@ -58,7 +59,7 @@ namespace Blackjack
         /// <param name="gameTime"></param>
         public override void Draw(Microsoft.Xna.Framework.GameTime gameTime)
         {
-            ScreenManager.SpriteBatch.Begin();
+            ScreenManager.SpriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, ScreenManager.GlobalTransformation);
 
             ScreenManager.SpriteBatch.Draw(background, ScreenManager.GraphicsDevice.Viewport.Bounds,
                 Color.White * TransitionAlpha);
@@ -68,4 +69,4 @@ namespace Blackjack
             base.Draw(gameTime);
         }
     }
-}
+}

+ 6 - 6
CardsStarterKit/Core/Game/Screens/GameplayScreen.cs

@@ -27,11 +27,11 @@ namespace Blackjack
         List<DrawableGameComponent> pauseVisibleComponents = new List<DrawableGameComponent>();
         Rectangle safeArea;
 
-        static Vector2[] playerCardOffset = new Vector2[] 
-        { 
+        static Vector2[] playerCardOffset = new Vector2[]
+        {
             new Vector2(100f * BlackjackGame.WidthScale, 190f * BlackjackGame.HeightScale),
             new Vector2(336f * BlackjackGame.WidthScale, 210f * BlackjackGame.HeightScale),
-            new Vector2(570f * BlackjackGame.WidthScale, 190f * BlackjackGame.HeightScale) 
+            new Vector2(570f * BlackjackGame.WidthScale, 190f * BlackjackGame.HeightScale)
         };
 
         /// <summary>
@@ -43,7 +43,7 @@ namespace Blackjack
             TransitionOffTime = TimeSpan.FromSeconds(0.5);
 
             EnabledGestures = GestureType.Tap;
-            
+
             this.theme = theme;
         }
 
@@ -55,7 +55,7 @@ namespace Blackjack
             safeArea = ScreenManager.SafeArea;
 
             // Initialize virtual cursor
-            inputHelper = new InputHelper(ScreenManager.Game);
+            inputHelper = new InputHelper(ScreenManager);
             inputHelper.DrawOrder = 1000;
             ScreenManager.Game.Components.Add(inputHelper);
             // Ignore the curser when not run in Xbox
@@ -283,4 +283,4 @@ namespace Blackjack
             blackJackGame.Double();
         }
     }
-}
+}

+ 6 - 5
CardsStarterKit/Core/Game/Screens/InstructionScreen.cs

@@ -14,6 +14,7 @@ using Microsoft.Xna.Framework;
 using GameStateManagement;
 using Microsoft.Xna.Framework.Input;
 using Microsoft.Xna.Framework.Input.Touch;
+using System.IO;
 
 
 
@@ -38,7 +39,7 @@ namespace Blackjack
             this.theme = theme;
 
             EnabledGestures = GestureType.Tap;
-            
+
         }
 
         /// <summary>
@@ -46,8 +47,8 @@ namespace Blackjack
         /// </summary>
         public override void LoadContent()
         {
-            background = Load<Texture2D>(@"Images\instructions");
-            font = Load<SpriteFont>(@"Fonts\MenuFont");
+            background = Load<Texture2D>(Path.Combine("Images", "instructions"));
+            font = Load<SpriteFont>(Path.Combine("Fonts", "MenuFont"));
 
             // Create a new instance of the gameplay screen
             gameplayScreen = new GameplayScreen(theme);
@@ -117,7 +118,7 @@ namespace Blackjack
         {
             SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
 
-            spriteBatch.Begin();
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, ScreenManager.GlobalTransformation);
 
             // Draw Background
             spriteBatch.Draw(background, ScreenManager.GraphicsDevice.Viewport.Bounds,
@@ -137,4 +138,4 @@ namespace Blackjack
             base.Draw(gameTime);
         }
     }
-}
+}

+ 14 - 9
CardsStarterKit/Core/Game/Screens/OptionsMenu.cs

@@ -12,25 +12,30 @@ using GameStateManagement;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 using CardsFramework;
+using System.IO;
 
 namespace Blackjack
 {
     class OptionsMenu : MenuScreen
     {
+        private CardsGame cardGame;
         Dictionary<string, Texture2D> themes = new Dictionary<string, Texture2D>();
         AnimatedGameComponent card;
         Texture2D background;
         Rectangle safeArea;
 
-
-
         /// <summary>
         /// Initializes a new instance of the screen.
         /// </summary>
         public OptionsMenu()
             : base("")
         {
+        }
 
+        public OptionsMenu(CardsGame cardGame)
+            : base("")
+        {
+            this.cardGame = cardGame;
         }
 
         /// <summary>
@@ -52,14 +57,14 @@ namespace Blackjack
             MenuEntries.Add(returnMenuEntry);
 
             themes.Add("Red", ScreenManager.Game.Content.Load<Texture2D>(
-                @"Images\Cards\CardBack_Red"));
+                Path.Combine("Images", "Cards", "CardBack_Red")));
             themes.Add("Blue", ScreenManager.Game.Content.Load<Texture2D>(
-                @"Images\Cards\CardBack_Blue"));
+                Path.Combine("Images", "Cards", "CardBack_Blue")));
             background = ScreenManager.Game.Content.Load<Texture2D>(
-                @"Images\UI\table");
+                Path.Combine("Images", "UI", "table"));
 
-            card = new AnimatedGameComponent(ScreenManager.Game,
-                themes[MainMenuScreen.Theme])
+            card = new AnimatedGameComponent(cardGame,
+                themes[MainMenuScreen.Theme], ScreenManager.SpriteBatch, ScreenManager.GlobalTransformation)
             {
                 CurrentPosition = new Vector2(safeArea.Center.X, safeArea.Center.Y - 50)
             };
@@ -103,7 +108,7 @@ namespace Blackjack
         /// <param name="gameTime"></param>
         public override void Draw(GameTime gameTime)
         {
-            ScreenManager.SpriteBatch.Begin();
+            ScreenManager.SpriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, ScreenManager.GlobalTransformation);
 
             // Draw the card back
             ScreenManager.SpriteBatch.Draw(background, ScreenManager.GraphicsDevice.Viewport.Bounds,
@@ -113,4 +118,4 @@ namespace Blackjack
             base.Draw(gameTime);
         }
     }
-}
+}

+ 4 - 6
CardsStarterKit/Framework/Game/CardsGame.cs

@@ -7,6 +7,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Text;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
@@ -152,7 +153,6 @@ namespace CardsFramework
         /// </summary>
         public void LoadContent()
         {
-            SpriteBatch = new SpriteBatch(Game.GraphicsDevice);
             // Initialize a full deck
             CardPacket fullDeck = new CardPacket(1, 2, CardSuit.AllSuits,
                 CardsFramework.CardValue.NonJokers | CardsFramework.CardValue.Jokers);
@@ -168,7 +168,7 @@ namespace CardsFramework
             LoadUITexture("Cards", "CardBack_" + Theme);
 
             // Load the game's font
-            Font = Game.Content.Load<SpriteFont>(string.Format(@"Fonts\Regular"));
+            Font = Game.Content.Load<SpriteFont>(Path.Combine("Fonts", "Regular"));
 
             GameTable.Initialize();
         }
@@ -183,9 +183,7 @@ namespace CardsFramework
         /// <param name="assetName">The name of the asset.</param>
         public void LoadUITexture(string folder, string assetName)
         {
-            cardsAssets.Add(assetName,
-                Game.Content.Load<Texture2D>(string.Format(@"Images\{0}\{1}",
-                folder, assetName)));
+            cardsAssets.Add(assetName, Game.Content.Load<Texture2D>(Path.Combine("Images", folder, assetName)));
         }
     }
-}
+}

+ 14 - 9
CardsStarterKit/Framework/UI/AnimatedCardsGameComponent.cs

@@ -22,15 +22,20 @@ namespace CardsFramework
     {
         public TraditionalCard Card { get; private set; }
 
+        private SpriteBatch spriteBatch;
+        private Matrix globalTransformation;
+
         /// <summary>
         /// Initializes a new instance of the class.
         /// </summary>
         /// <param name="card">The card associated with the animation component.</param>
         /// <param name="cardGame">The associated game.</param>
-        public AnimatedCardsGameComponent(TraditionalCard card, CardsGame cardGame)
-            : base(cardGame, null)
+        public AnimatedCardsGameComponent(TraditionalCard card, CardsGame cardGame, SpriteBatch? sharedSpriteBatch = null, Matrix? globalTransformation = null)
+            : base(cardGame, null, sharedSpriteBatch, globalTransformation)
         {
             Card = card;
+            this.spriteBatch = sharedSpriteBatch;
+            this.globalTransformation = globalTransformation ?? Matrix.Identity;
         }
 
         /// <summary>
@@ -52,9 +57,7 @@ namespace CardsFramework
         /// <param name="gameTime">The game time.</param>
         public override void Draw(GameTime gameTime)
         {
-            base.Draw(gameTime);
-
-            CardGame.SpriteBatch.Begin();
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, globalTransformation);
 
             // Draw the current at the designated destination, or at the initial 
             // position if a destination has not been set
@@ -62,17 +65,19 @@ namespace CardsFramework
             {
                 if (CurrentDestination.HasValue)
                 {
-                    CardGame.SpriteBatch.Draw(CurrentFrame,
+                    spriteBatch.Draw(CurrentFrame,
                         CurrentDestination.Value, Color.White);
                 }
                 else
                 {
-                    CardGame.SpriteBatch.Draw(CurrentFrame,
+                    spriteBatch.Draw(CurrentFrame,
                         CurrentPosition, Color.White);
                 }
             }
 
-            CardGame.SpriteBatch.End();
+            spriteBatch.End();
+
+            base.Draw(gameTime);
         }
     }
-}
+}

+ 13 - 38
CardsStarterKit/Framework/UI/AnimatedGameComponent.cs

@@ -40,27 +40,8 @@ namespace CardsFramework
 
         public CardsGame CardGame { get; private set; }
 
-        /// <summary>
-        /// Initializes a new instance of the class, using black text color.
-        /// </summary>
-        /// <param name="game">The associated game class.</param>
-        public AnimatedGameComponent(Game game)
-            : base(game)
-        {
-            TextColor = Color.Black;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of the class, using black text color.
-        /// </summary>
-        /// <param name="game">The associated game class.</param>
-        /// <param name="currentFrame">The texture serving as the current frame
-        /// to display as the component.</param>
-        public AnimatedGameComponent(Game game, Texture2D currentFrame)
-            : this(game)
-        {
-            CurrentFrame = currentFrame;
-        }
+        private SpriteBatch spriteBatch;
+        private Matrix globalTransformation;
 
         /// <summary>
         /// Initializes a new instance of the class, using black text color.
@@ -68,11 +49,16 @@ namespace CardsFramework
         /// <param name="cardGame">The associated card game.</param>
         /// <param name="currentFrame">The texture serving as the current frame
         /// to display as the component.</param>
-        public AnimatedGameComponent(CardsGame cardGame, Texture2D currentFrame)
-            : this(cardGame.Game)
+        public AnimatedGameComponent(CardsGame cardGame, Texture2D? currentFrame, SpriteBatch sharedSpriteBatch, Matrix? globalTransformation = null)
+            : base(cardGame.Game)
         {
+            if (sharedSpriteBatch == null)
+                throw new ArgumentNullException(nameof(sharedSpriteBatch), "AnimatedGameComponent requires a valid SpriteBatch.");
             CardGame = cardGame;
             CurrentFrame = currentFrame;
+            TextColor = Color.Black;
+            this.spriteBatch = sharedSpriteBatch;
+            this.globalTransformation = globalTransformation ?? Matrix.Identity;
         }
 
         /// <summary>
@@ -106,20 +92,7 @@ namespace CardsFramework
         /// to this method.</param>
         public override void Draw(GameTime gameTime)
         {
-            base.Draw(gameTime);
-
-            SpriteBatch spriteBatch;
-
-            if (CardGame != null)
-            {
-                spriteBatch = CardGame.SpriteBatch;
-            }
-            else
-            {
-                spriteBatch = new SpriteBatch(Game.GraphicsDevice);
-            }
-
-            spriteBatch.Begin();
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, globalTransformation);
 
             // Draw at the destination if one is set
             if (CurrentDestination.HasValue)
@@ -157,6 +130,8 @@ namespace CardsFramework
             }
 
             spriteBatch.End();
+
+            base.Draw(gameTime);
         }
 
         /// <summary>
@@ -192,4 +167,4 @@ namespace CardsFramework
             return result;
         }
     }
-}
+}

+ 18 - 12
CardsStarterKit/Framework/UI/AnimatedHandGameComponent.cs

@@ -10,6 +10,7 @@ using System.Collections.Generic;
 using System.Text;
 using CardsFramework;
 using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
 
 namespace CardsFramework
 {
@@ -20,9 +21,9 @@ namespace CardsFramework
 
         List<AnimatedCardsGameComponent> heldAnimatedCards = new List<AnimatedCardsGameComponent>();
 
-        public override bool IsAnimating 
-        { 
-            get 
+        public override bool IsAnimating
+        {
+            get
             {
                 for (int animationIndex = 0; animationIndex < heldAnimatedCards.Count; animationIndex++)
                 {
@@ -32,7 +33,7 @@ namespace CardsFramework
                     }
                 }
                 return false;
-            } 
+            }
         }
 
         /// <summary>
@@ -44,7 +45,10 @@ namespace CardsFramework
             {
                 return heldAnimatedCards.AsReadOnly();
             }
-        } 
+        }
+
+        SpriteBatch spriteBatch;
+        Matrix globalTransformation;
 
         /// <summary>
         /// Initializes a new instance of the animated hand component. This means
@@ -56,13 +60,15 @@ namespace CardsFramework
         /// <param name="place">The player's place index (-1 for the dealer).</param>
         /// <param name="hand">The hand represented by this instance.</param>
         /// <param name="cardGame">The associated card game.</param>
-        public AnimatedHandGameComponent(int place, Hand hand, CardsGame cardGame)
-            : base(cardGame, null)
+        public AnimatedHandGameComponent(int place, Hand hand, CardsGame cardGame, SpriteBatch spriteBatch, Matrix globalTransformation)
+            : base(cardGame, null, spriteBatch, globalTransformation)
         {
             Place = place;
             Hand = hand;
             hand.ReceivedCard += Hand_ReceivedCard;
             hand.LostCard += Hand_LostCard;
+            this.spriteBatch = spriteBatch;
+            this.globalTransformation = globalTransformation;
 
             // Set the component's position
             if (place == -1)
@@ -89,7 +95,7 @@ namespace CardsFramework
             }
 
             Game.Components.ComponentRemoved += Components_ComponentRemoved;
-        } 
+        }
 
         /// <summary>
         /// Updates the component.
@@ -103,7 +109,7 @@ namespace CardsFramework
             {
                 if (!heldAnimatedCards[animationIndex].IsAnimating)
                 {
-                    heldAnimatedCards[animationIndex].CurrentPosition = CurrentPosition + 
+                    heldAnimatedCards[animationIndex].CurrentPosition = CurrentPosition +
                         GetCardRelativePosition(animationIndex);
                 }
             }
@@ -167,7 +173,7 @@ namespace CardsFramework
                 return null;
 
             return heldAnimatedCards[location];
-        } 
+        }
 
         /// <summary>
         /// Handles the ComponentRemoved event of the Components control.
@@ -218,7 +224,7 @@ namespace CardsFramework
         {
             // Add the card to the screen
             AnimatedCardsGameComponent animatedCardGameComponent =
-                new AnimatedCardsGameComponent(e.Card, CardGame) { Visible = false };
+                new AnimatedCardsGameComponent(e.Card, CardGame, spriteBatch, globalTransformation) { Visible = false };
 
             heldAnimatedCards.Add(animatedCardGameComponent);
             Game.Components.Add(animatedCardGameComponent);
@@ -261,4 +267,4 @@ namespace CardsFramework
             base.Dispose(disposing);
         }
     }
-}
+}

+ 10 - 5
CardsStarterKit/Framework/UI/GameTable.cs

@@ -7,6 +7,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Text;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
@@ -22,6 +23,9 @@ namespace CardsFramework
         public Texture2D TableTexture { get; private set; }
         public Vector2 DealerPosition { get; private set; }
         public SpriteBatch SpriteBatch { get; private set; }
+
+        protected Matrix globalTransformation;
+
         public Func<int, Vector2> PlaceOrder { get; private set; }
         public Rectangle TableBounds { get; private set; }
         public int Places { get; private set; }
@@ -54,7 +58,7 @@ namespace CardsFramework
         /// <param name="theme">The theme used to display UI elements.</param>
         /// <param name="game">The associated game object.</param>
         public GameTable(Rectangle tableBounds, Vector2 dealerPosition, int places,
-            Func<int, Vector2> placeOrder, string theme, Game game)
+            Func<int, Vector2> placeOrder, string theme, Game game, SpriteBatch sharedSpriteBatch, Matrix? globalTransformation = null)
             : base(game)
         {
             TableBounds = tableBounds;
@@ -63,7 +67,8 @@ namespace CardsFramework
             Places = places;
             PlaceOrder = placeOrder;
             Theme = theme;
-            SpriteBatch = new SpriteBatch(game.GraphicsDevice);
+            this.SpriteBatch = sharedSpriteBatch;
+            this.globalTransformation = globalTransformation ?? Matrix.Identity;
         }
 
         /// <summary>
@@ -71,7 +76,7 @@ namespace CardsFramework
         /// </summary>
         protected override void LoadContent()
         {
-            string assetName = string.Format(@"Images\UI\table");
+            string assetName = Path.Combine("Images", "UI", "table");
             TableTexture = Game.Content.Load<Texture2D>(assetName);
 
             base.LoadContent();
@@ -84,7 +89,7 @@ namespace CardsFramework
         /// this method.</param>
         public override void Draw(GameTime gameTime)
         {
-            SpriteBatch.Begin();
+            SpriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, globalTransformation);
 
             // Draw the table texture
             SpriteBatch.Draw(TableTexture, TableBounds, Color.White);
@@ -94,4 +99,4 @@ namespace CardsFramework
             base.Draw(gameTime);
         }
     }
-}
+}

+ 19 - 15
CardsStarterKit/Platforms/Android/AndroidManifest.xml

@@ -1,18 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cartblanche.audio3d">
-  <application android:label="Audio3D" android:icon="@mipmap/icon">
-    <activity android:name="android.app.NativeActivity"
-              android:label="Audio3D"
-              android:configChanges="orientation|keyboardHidden|screenSize"
-              android:screenOrientation="landscape"
-              android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
-      <intent-filter>
-        <action android:name="android.intent.action.MAIN" />
-        <category android:name="android.intent.category.LAUNCHER" />
-      </intent-filter>
-    </activity>
-  </application>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
+          package="com.monogame.roleplayinggame" 
+          android:versionCode="1" 
+          android:versionName="1.0">
+  
   <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="34" />
-  <uses-feature android:glEsVersion="0x00020000" />
+  
   <uses-permission android:name="android.permission.INTERNET" />
-</manifest>
+  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+  
+  <application android:allowBackup="true" 
+               android:icon="@drawable/icon" 
+               android:label="@string/app_name"
+               android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+    
+  </application>
+  
+  <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+  
+</manifest>

+ 1 - 0
CardsStarterKit/Platforms/Android/BlackJack.Android.csproj

@@ -11,6 +11,7 @@
     <Company>MonoGame Foundation</Company>
     <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
     <AndroidApplication>True</AndroidApplication>
+    <SupportedOSPlatformVersion>28.0</SupportedOSPlatformVersion>
   </PropertyGroup>
   
   <ItemGroup>

+ 22 - 5
CardsStarterKit/Platforms/Android/MainActivity.cs

@@ -1,19 +1,36 @@
 using Android.App;
 using Android.Content.PM;
 using Android.OS;
+using Android.Views;
+using Blackjack;
 using Microsoft.Xna.Framework;
 
 namespace BlackJack.Android
 {
-    [Activity(Label = "Blackjack", MainLauncher = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden | ConfigChanges.ScreenSize, ScreenOrientation = ScreenOrientation.Landscape)]
+    [Activity(
+        Label = "@string/app_name",
+        MainLauncher = true,
+        Icon = "@drawable/icon",
+        AlwaysRetainTaskState = true,
+        LaunchMode = LaunchMode.SingleInstance,
+        ScreenOrientation = ScreenOrientation.SensorLandscape,
+        ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden
+    )]
     public class MainActivity : AndroidGameActivity
     {
+        private BlackjackGame _game;
+        private View _view;
+
         protected override void OnCreate(Bundle bundle)
         {
             base.OnCreate(bundle);
-            var g = new BlackjackGame();
-            SetContentView((g.Services.GetService(typeof(View))) as View);
-            g.Run();
+
+            _game = new BlackjackGame();
+
+            _view = _game.Services.GetService(typeof(View)) as View;
+            SetContentView(_view);
+
+            _game.Run();
         }
     }
-}
+}

BIN
CardsStarterKit/Platforms/Android/Resources/drawable/icon.png


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 491 - 0
CardsStarterKit/Platforms/Android/Resources/drawable/icon.svg


+ 4 - 0
CardsStarterKit/Platforms/Android/Resources/values/strings.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <string name="app_name">Blackjack</string>
+</resources>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.