PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/SimpleCardGame/SimpleCardGame/SimpleCardGame/Menus/MainGame.cs

https://bitbucket.org/optimus290/xna-wp7-cardgame
C# | 645 lines | 499 code | 110 blank | 36 comment | 99 complexity | be9feef88a3dfbc7be2f1183cc52bc4c MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Content;
  7. using Microsoft.Xna.Framework.Graphics;
  8. using Microsoft.Xna.Framework.Input;
  9. using Microsoft.Xna.Framework.Input.Touch;
  10. using Microsoft.Xna.Framework.GamerServices;
  11. using SimpleCardGame.Animation;
  12. using SimpleCardGame.Entities;
  13. namespace SimpleCardGame.Menus
  14. {
  15. class MainGame : Screen
  16. {
  17. int turn = 0;
  18. static bool turnPlayed = false;
  19. static Card attackerCard = null;
  20. static bool attackerCardSelected = false;
  21. static bool targetCardSelected = false;
  22. static bool movePerformed = false;
  23. TouchCollection touches;
  24. Point point;
  25. List<Card> playerOneCards;
  26. List<Card> playerTwoCards;
  27. List<Card> deadCards;
  28. ///Score related data
  29. bool isHighScoreAchieved = false;
  30. int currentHighScore;
  31. string winnerName;
  32. string scoreType;
  33. PauseMenu pauseMenu; ///Pause Menu object
  34. GestureSample gesture; ///Input mechanism for power card
  35. Text statusText; ///Displays current status in the middle of the screen
  36. SpriteFont statusFont;
  37. #region
  38. ///Animation related data
  39. float timer = 0;
  40. float interval = 100;
  41. bool playAnimation = false; //Determines whether animation should be played
  42. public Vector2 animationPosition;
  43. public AnimationType animationType;
  44. static CardAnimations cardAnimations; //Wrapper class for all the animations
  45. #endregion
  46. public MainGame(Game game, SpriteBatch spriteBatch, ChangeScreen changeScreen)
  47. : base(game, spriteBatch, changeScreen)
  48. {}
  49. public override void Activate()
  50. {
  51. ///Reset both cards list and draw three cards
  52. ///from each of the decks,
  53. playerOneCards = new List<Card>();
  54. playerTwoCards = new List<Card>();
  55. foreach (Card card in playerOneDeck.cards)
  56. card.Selected = false;
  57. foreach (Card card in playerTwoDeck.cards)
  58. card.Selected = false;
  59. for (int i = 0; i < 3; i++)
  60. {
  61. playerOneCards.Add(playerOneDeck.DrawCard());
  62. playerTwoCards.Add(playerTwoDeck.DrawCard());
  63. }
  64. ///Load current highest score
  65. isHighScoreAchieved = false;
  66. switch (gameType)
  67. {
  68. case GameType.PvC:
  69. currentHighScore = highScores.CurrentHighScore("PvC");
  70. break;
  71. case GameType.PvP:
  72. currentHighScore = highScores.CurrentHighScore("PvP");
  73. break;
  74. }
  75. ///Set the initial game state
  76. gameState = GameState.Running;
  77. }
  78. protected override void LoadScreenContent(ContentManager content)
  79. {
  80. statusFont = content.Load<SpriteFont>("fonts/gameFont");
  81. statusText = new Text(statusFont,
  82. "PLAYER ONE'S TURN, CARDS LEFT : " + playerOneDeck.cards.Count.ToString(),
  83. new Vector2(0, 0), Color.White, Color.Black,
  84. Text.Alignment.Both, new Rectangle(0, 0, 800, 480));
  85. }
  86. #region ///Actual Gameplay Function
  87. public void SimulateGame(GameTime gameTime, DisplayOrientation screenOrientation)
  88. {
  89. //Placed before player turn logic, so that animation occurs before dead card is replaced
  90. #region
  91. ///If playAnimation is true, then
  92. ///set animation parameters and play until
  93. ///animation completes
  94. if (playAnimation == true)
  95. {
  96. timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
  97. if (cardAnimations == null)
  98. cardAnimations = new CardAnimations(animationPosition, animationType, game.Content);
  99. if ((timer > interval) && !cardAnimations.animations[animationType].AnimationComplete)
  100. {
  101. timer = 0;
  102. cardAnimations.Update(gameTime);
  103. }
  104. else if (cardAnimations.animations[animationType].AnimationComplete == true)
  105. {
  106. playAnimation = false;
  107. cardAnimations = null;
  108. }
  109. }
  110. #endregion
  111. //Check for inputs
  112. if (turn == 0)
  113. {
  114. replaceDeadCards(ref playerOneCards, ref playerOneDeck);
  115. if (!turnPlayed)
  116. {
  117. ///Not checking the game type here
  118. ///since in this case first player will always be
  119. ///a human, hence calling manual attack function
  120. turnPlayed = attack(ref playerOneCards, ref playerTwoCards);
  121. }
  122. else if (turnPlayed)
  123. {
  124. turn = 1;
  125. turnPlayed = false;
  126. }
  127. }
  128. else if (turn == 1)
  129. {
  130. replaceDeadCards(ref playerTwoCards, ref playerTwoDeck);
  131. if (!turnPlayed)
  132. {
  133. ///Call attack function depending on the game type
  134. if (gameType == GameType.PvC)
  135. turnPlayed = computerAttack(ref playerTwoCards, ref playerOneCards);
  136. else if (gameType == GameType.PvP)
  137. turnPlayed = attack(ref playerTwoCards, ref playerOneCards);
  138. }
  139. else if (turnPlayed)
  140. {
  141. turn = 0;
  142. turnPlayed = false;
  143. }
  144. }
  145. GameOver = GameEnds();
  146. if (GameOver)
  147. {
  148. if (!isHighScoreAchieved && TotalPoints > currentHighScore)
  149. {
  150. switch (gameType)
  151. {
  152. ///Here we set the name of player
  153. ///depending upon the game's type
  154. case GameType.PvC:
  155. scoreType = "PvC";
  156. if (winningPlayer == WinningPlayer.PlayerOne)
  157. getWinnerName();
  158. else if (winningPlayer == WinningPlayer.PlayerTwo)
  159. winnerName = "Com";
  160. break;
  161. case GameType.PvP:
  162. scoreType = "PvP";
  163. getWinnerName();
  164. break;
  165. }
  166. ///Add score after getting winner's name
  167. highScores.AddScore(scoreType, winnerName, TotalPoints);
  168. }
  169. ChangeScreenDelegate(ScreenState.GameOver);
  170. }
  171. }
  172. #endregion
  173. protected override void UpdateScreen(GameTime gameTime, DisplayOrientation screenOrientation)
  174. {
  175. if (gameState == GameState.Running)
  176. {
  177. SimulateGame(gameTime, screenOrientation);
  178. if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  179. gameState = GameState.Paused;
  180. }
  181. else if (gameState == GameState.Paused)
  182. {
  183. pauseMenu = new PauseMenu(game.Content);
  184. foreach (TouchLocation touch in TouchPanel.GetState())
  185. pauseMenu.Update(touch);
  186. ///Exit Game if Back button pressed while paused
  187. if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  188. this.game.Exit();
  189. if (pauseMenu.btnResume.Pressed)
  190. gameState = GameState.Running;
  191. if (pauseMenu.btnRestart.Pressed)
  192. ChangeScreenDelegate(ScreenState.MainGameScreen);
  193. if (pauseMenu.btnQuitMainMenu.Pressed)
  194. ChangeScreenDelegate(ScreenState.MainMenu);
  195. }
  196. }//End of UpdateScreen()
  197. #region/// SIP functionality for player to input name
  198. private void getWinnerName()
  199. {
  200. Guide.BeginShowKeyboardInput(PlayerIndex.One,
  201. "You Win",
  202. "Insert your name",
  203. "",
  204. new AsyncCallback(OnEndShowKeyboardInput),
  205. null);
  206. }
  207. private void OnEndShowKeyboardInput(IAsyncResult result)
  208. {
  209. winnerName = Guide.EndShowKeyboardInput(result);
  210. }
  211. #endregion
  212. protected override void DrawScreen(SpriteBatch spriteBatch, DisplayOrientation screenOrientation)
  213. {
  214. setVisibleCardsPosition();
  215. foreach(Card card in playerOneCards)
  216. card.Draw(spriteBatch);
  217. foreach (Card card in playerTwoCards)
  218. card.Draw(spriteBatch);
  219. spriteBatch.DrawString(spriteFont, ""+playerOneDeck.cards.Count, new Vector2(0, 0), Color.Red);
  220. spriteBatch.DrawString(spriteFont, "" + playerTwoDeck.cards.Count, new Vector2(0, 400), Color.Red);
  221. statusText.Draw(spriteBatch);
  222. ///Draw animation if available
  223. if (playAnimation && cardAnimations != null)
  224. cardAnimations.Draw(spriteBatch);
  225. ///Display the pause menu if game is paused
  226. if(gameState == GameState.Paused && pauseMenu != null)
  227. pauseMenu.Draw(spriteBatch);
  228. }
  229. private void setVisibleCardsPosition()
  230. {
  231. ///Used before drawing the cards
  232. ///since position of all cards when
  233. ///created is 0,0
  234. int cWidth = 173;
  235. for (int i = 0; i < playerOneCards.Count; i++)
  236. {
  237. playerOneCards[i].Position = new Vector2( i * cWidth + (100 * i) + 10, 10 );
  238. }
  239. for (int j = 0; j < playerTwoCards.Count; j++)
  240. {
  241. playerTwoCards[j].Position = new Vector2(j * cWidth + (100 * j) + 10, 290);
  242. }
  243. }
  244. private bool attack(ref List<Card> ownList, ref List<Card> enemyList)
  245. {
  246. if (!attackerCardSelected)
  247. {
  248. statusText.ChangeText( ((turn == 0) ? "PLAYER ONE'S TURN" : "PLAYER TWO'S TURN") + " SELECT ATTACKER CARD");
  249. touches = TouchPanel.GetState();
  250. foreach(TouchLocation touch in touches)
  251. {
  252. if (touch.State == TouchLocationState.Pressed)
  253. {
  254. point = new Point((int)touch.Position.X, (int)touch.Position.Y);
  255. foreach (Card card in ownList)
  256. {
  257. if (card.Rectangle.Contains(point))
  258. {
  259. card.Selected = true;
  260. attackerCard = card;
  261. attackerCardSelected = true;
  262. break;
  263. }
  264. else
  265. {
  266. card.Selected = false;
  267. attackerCardSelected = false;
  268. }
  269. }
  270. }
  271. }
  272. }
  273. if (attackerCardSelected == true && !targetCardSelected)
  274. {
  275. switch (attackerCard.cType)
  276. {
  277. case cardType.Melee:
  278. if (ownList.IndexOf(attackerCard) < enemyList.Count)
  279. {
  280. ///melee cards can attack only immediate cards
  281. targetCardSelected = true;
  282. enemyList[ownList.IndexOf(attackerCard)].Hitpoints -= attackerCard.Damage;
  283. }
  284. ///placing move performed outside, so as to skip if
  285. ///no card exists in front of selected attackerCard
  286. movePerformed = true;
  287. break;
  288. case cardType.Range:
  289. statusText.ChangeText(((turn == 0) ? "PLAYER ONE'S TURN" : "PLAYER TWO'S TURN") + " SELECT CARD TO ATTACK");
  290. touches = TouchPanel.GetState();
  291. foreach(TouchLocation touch in touches)
  292. {
  293. if (touch.State == TouchLocationState.Pressed)
  294. {
  295. point = new Point((int)touch.Position.X, (int)touch.Position.Y);
  296. foreach (Card card in enemyList)
  297. {
  298. if (card.Rectangle.Contains(point))
  299. {
  300. targetCardSelected = true;
  301. card.Selected = true;
  302. card.Hitpoints -= attackerCard.Damage;
  303. movePerformed = true;
  304. }
  305. }
  306. }
  307. }
  308. break;
  309. case cardType.Healing:
  310. statusText.ChangeText( ((turn == 0) ? "PLAYER ONE'S TURN" : "PLAYER TWO'S TURN") + " SELECT CARD TO HEAL");
  311. touches = TouchPanel.GetState();
  312. foreach (TouchLocation touch in touches)
  313. {
  314. if (touch.State == TouchLocationState.Pressed)
  315. {
  316. point = new Point((int)touch.Position.X, (int)touch.Position.Y);
  317. foreach (Card card in ownList)
  318. {
  319. if (card.Rectangle.Contains(point))
  320. {
  321. {
  322. targetCardSelected = true;
  323. card.Selected = true;
  324. card.Hitpoints += attackerCard.Damage;
  325. movePerformed = true;
  326. }
  327. }
  328. }
  329. }
  330. }
  331. break;
  332. case cardType.Bomb:
  333. targetCardSelected = true;
  334. foreach (Card card in enemyList)
  335. {
  336. card.Hitpoints -= attackerCard.Damage;
  337. }
  338. ownList[ownList.IndexOf(attackerCard)].Dead = true;
  339. //ownList.Remove(attackerCard);
  340. movePerformed = true;
  341. break;
  342. case cardType.Power:
  343. statusText.ChangeText("FLICK TO BUFF SELF, DOUBLE TAP TO DEBUFF ENEMIES");
  344. bool powerCardUsed = false;
  345. if (TouchPanel.IsGestureAvailable)
  346. {
  347. gesture = TouchPanel.ReadGesture();
  348. if (gesture.GestureType == GestureType.DoubleTap)
  349. {
  350. foreach (Card card in enemyList)
  351. card.Damage -= attackerCard.Damage;
  352. powerCardUsed = true;
  353. }
  354. else if (gesture.GestureType == GestureType.Flick)
  355. {
  356. foreach (Card card in ownList)
  357. card.Damage += attackerCard.Damage;
  358. powerCardUsed = true;
  359. }
  360. if (powerCardUsed)
  361. {
  362. targetCardSelected = true;
  363. movePerformed = true;
  364. ownList[ownList.IndexOf(attackerCard)].Dead = true;
  365. }
  366. }
  367. break;
  368. case cardType.Mysterious:
  369. Random random = new Random();
  370. int mysteriousCardType = random.Next(0, 5);
  371. switch (mysteriousCardType)
  372. {
  373. case 0: //Card increases own hp
  374. statusText.ChangeText("OWN HP INCREASED MYSTERIOUSLY");
  375. foreach (Card card in ownList)
  376. card.Hitpoints += attackerCard.Damage;
  377. break;
  378. case 1: //Card increases own damage
  379. statusText.ChangeText("OWN DAMAGE INCREASED MYSTERIOUSLY");
  380. foreach (Card card in ownList)
  381. card.Damage += attackerCard.Damage;
  382. break;
  383. case 2: //Card decreases enemy hp
  384. statusText.ChangeText("ENEMY HP DECREASED MYSTERIOUSLY");
  385. foreach (Card card in enemyList)
  386. card.Hitpoints -= attackerCard.Damage;
  387. break;
  388. case 4: //Card decreases enemy damage
  389. statusText.ChangeText("ENEMY DAMAGE DECREASED MYSTERIOUSLY");
  390. foreach (Card card in enemyList)
  391. card.Damage -= attackerCard.Damage;
  392. break;
  393. case 5: //Card acts as trap, own turn skipped
  394. statusText.ChangeText("IT WAS A TRAP! TURN SKIPPED!");
  395. break;
  396. }
  397. ownList[ownList.IndexOf(attackerCard)].Dead = true;
  398. targetCardSelected = true;
  399. movePerformed = true;
  400. break;
  401. }
  402. }
  403. if (movePerformed)
  404. {
  405. deselectCards(ref ownList, ref enemyList);
  406. attackerCardSelected = false;
  407. targetCardSelected = false;
  408. attackerCard = null;
  409. movePerformed = false;
  410. return true;
  411. }
  412. else
  413. return false;
  414. }//end of attack function
  415. public bool computerAttack(ref List<Card> ownList, ref List<Card> enemyList)
  416. {
  417. Random random = new Random();
  418. int comAttackCardIndex;
  419. Card comCard = null;
  420. bool attackComplete = false;
  421. ///select an attacker card
  422. if (ownList.Count > 0)
  423. comAttackCardIndex = random.Next(0, ownList.Count);
  424. else
  425. {
  426. ///bug encountered incase one card left and
  427. ///it dies, hence return TURNPLAYED = TRUE
  428. return true;
  429. }
  430. ownList[comAttackCardIndex].Selected = true;
  431. comCard = ownList[comAttackCardIndex];
  432. switch (comCard.cType)
  433. {
  434. case cardType.Melee:
  435. if (comAttackCardIndex < enemyList.Count)
  436. {
  437. enemyList[comAttackCardIndex].Hitpoints -= comCard.Damage;
  438. attackComplete = true;
  439. }
  440. break;
  441. case cardType.Range:
  442. int victimIndex = random.Next(0, enemyList.Count);
  443. if (victimIndex <= enemyList.Count)
  444. {
  445. enemyList[victimIndex].Hitpoints -= comCard.Damage;
  446. attackComplete = true;
  447. }
  448. break;
  449. case cardType.Healing:
  450. int targetIndex = random.Next(0, ownList.Count);
  451. if (targetIndex <= ownList.Count)
  452. {
  453. ownList[targetIndex].Hitpoints += comCard.Damage;
  454. attackComplete = true;
  455. }
  456. break;
  457. case cardType.Power:
  458. attackComplete = true;
  459. break;
  460. case cardType.Bomb:
  461. foreach (Card card in enemyList)
  462. {
  463. card.Hitpoints -= comCard.Damage;
  464. }
  465. ownList.Remove(comCard);
  466. attackComplete = true;
  467. break;
  468. }
  469. deselectCards(ref ownList, ref enemyList);
  470. return attackComplete;
  471. }
  472. public void replaceDeadCards(ref List<Card> cardList, ref Deck parentDeck)
  473. {
  474. deadCards = new List<Card>();
  475. ///Adding dead cards to seperate list
  476. ///otherwise if removed from list while
  477. ///iterating in foreach loop, the enumerator becomes invalid
  478. foreach (Card card in cardList)
  479. if (card.isDead())
  480. {
  481. deadCards.Add(card);
  482. playAnimation = true;
  483. animationPosition = card.Position;
  484. animationType = AnimationType.DeadAnimation;
  485. }
  486. foreach (Card card in deadCards)
  487. cardList.Remove(card);
  488. while (cardList.Count != 3)
  489. {
  490. if (parentDeck.hasCards())
  491. {
  492. cardList.Add(parentDeck.DrawCard());
  493. turnPlayed = true;
  494. }
  495. else
  496. {
  497. break;
  498. }
  499. }
  500. }
  501. public bool GameEnds()
  502. {
  503. ///if player 2 wins
  504. if (!playerOneDeck.hasCards() && playerOneCards.Count <= 0)
  505. {
  506. winningPlayer = WinningPlayer.PlayerTwo;
  507. if (playerTwoDeck.hasCards())
  508. foreach (Card card in playerTwoDeck.cards)
  509. TotalPoints += card.cost;
  510. foreach (Card card in playerTwoCards)
  511. TotalPoints += card.cost;
  512. return true;
  513. }
  514. ///if player 1 wins
  515. if (!playerTwoDeck.hasCards() && playerTwoCards.Count <= 0)
  516. {
  517. winningPlayer = WinningPlayer.PlayerOne;
  518. if (playerOneDeck.hasCards())
  519. foreach (Card card in playerOneDeck.cards)
  520. TotalPoints += card.cost;
  521. foreach (Card card in playerOneCards)
  522. TotalPoints += card.cost;
  523. return true;
  524. }
  525. return false;
  526. }
  527. private void deselectCards(ref List<Card> ownList, ref List<Card> enemyList)
  528. {
  529. foreach (Card card in ownList)
  530. card.Selected = false;
  531. foreach (Card card in enemyList)
  532. card.Selected = false;
  533. }
  534. }
  535. }