#region File Description
//-----------------------------------------------------------------------------
// ShipUpgradeScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.Diagnostics;
using Microsoft.Xna.Framework.Audio;
#endregion
namespace Spacewar
{
///
/// ShipUpgradeScreen handles the screen that allows either user to select weapon upgrades
///
public class ShipUpgradeScreen : Screen
{
private static string upgradeTexture = @"textures\weapon_select_FINAL";
private Vector4 white = new Vector4(1f, 1f, 1f, 1f);
private Vector4 upgradeFontColor = new Vector4(.882f, .596f, .286f, 1f);
private const int countSpeed = 3;
private bool player1Ready = false;
private bool player2Ready = false;
private bool playingTallySound = false;
private Cue tallySound;
private Cue menuMusic;
private static string[] scoreLookup = new string[] { "000", "001", "011", "111" };
private int[] playerCashCount = new int[] { 0, 0 };
private float[] flashPercent = new float[2]; //Amount of flash on a selected weapon
private TimeSpan[] flashEndTime = new TimeSpan[2]; //How long left to flash
private TimeSpan flashTime = new TimeSpan(0, 0, 3);
private SceneItem[] weapons = new SceneItem[2];
private ProjectileType[] purchasedWeapon = new ProjectileType[] { ProjectileType.Peashooter, ProjectileType.Peashooter };
private Vector2[,] weaponPositions = new Vector2[,]
{
{
new Vector2(248, 133),
new Vector2(75, 314),
new Vector2(444, 314),
new Vector2(248, 501),
},
{
new Vector2(864, 133),
new Vector2(686, 314),
new Vector2(1055, 314),
new Vector2(864, 501),
}
};
///
/// Creates the ShipUpgradeScreen
///
public ShipUpgradeScreen(Game game)
: base(game)
{
//Play the menu music
menuMusic = Sound.Play(Sounds.MenuMusic);
weapons[0] = new SceneItem(game, new EvolvedShape(game, EvolvedShapes.Weapon, PlayerIndex.One, (int)ProjectileType.Peashooter, LightingType.Menu), new Vector3(-170, -30, 0));
weapons[0].Scale = new Vector3(.06f, .06f, .06f);
scene.Add(weapons[0]);
weapons[1] = new SceneItem(game, new EvolvedShape(game, EvolvedShapes.Weapon, PlayerIndex.Two, (int)ProjectileType.Peashooter, LightingType.Menu), new Vector3(170, -30, 0));
weapons[1].Scale = new Vector3(.06f, .06f, .06f);
scene.Add(weapons[1]);
}
///
/// ShipUpgrade update will change the gamestate and start the next level when either
/// 1. The upgrade timer expires
/// 2. Both users have pressed A for ready
///
/// Total game time since it was started
/// Elapsed game time since the last call to update
///
public override GameState Update(TimeSpan time, TimeSpan elapsedTime)
{
if ((XInputHelper.GamePads[PlayerIndex.One].APressed) || (!XInputHelper.GamePads[PlayerIndex.One].State.IsConnected && SpacewarGame.CurrentPlatform != PlatformID.Win32NT))
player1Ready = true;
if ((XInputHelper.GamePads[PlayerIndex.Two].APressed) || (!XInputHelper.GamePads[PlayerIndex.Two].State.IsConnected && SpacewarGame.CurrentPlatform != PlatformID.Win32NT))
player2Ready = true;
if (XInputHelper.GamePads[PlayerIndex.One].BPressed)
player1Ready = false;
if (XInputHelper.GamePads[PlayerIndex.Two].BPressed)
player2Ready = false;
//DPAD purchases weapons you can afford
for (int player = 0; player < 2; player++)
{
//Can only buy weapons if you are not ready
if ((!player1Ready && player == 0) || (!player2Ready && player == 1))
{
for (int weapon = 1; weapon < 5; weapon++)
{
//Associate weapon selection with dpad direction
bool dpadPressed = false;
switch (weapon)
{
case 1:
dpadPressed = XInputHelper.GamePads[(PlayerIndex)player].UpPressed;
break;
case 2:
dpadPressed = XInputHelper.GamePads[(PlayerIndex)player].LeftPressed;
break;
case 3:
dpadPressed = XInputHelper.GamePads[(PlayerIndex)player].RightPressed;
break;
case 4:
dpadPressed = XInputHelper.GamePads[(PlayerIndex)player].DownPressed;
break;
}
//If a dpad is selected and you have enough money then purchase that weapon
if (dpadPressed && SpacewarGame.Players[player].Cash >= SpacewarGame.Settings.Weapons[weapon].Cost)
{
Sound.PlayCue(Sounds.MenuAdvance);
purchasedWeapon[player] = (ProjectileType)weapon;
SpacewarGame.Players[player].Cash -= SpacewarGame.Settings.Weapons[weapon].Cost;
SpacewarGame.Players[player].ProjectileType = (ProjectileType)weapon;
weapons[player].ShapeItem = new EvolvedShape(GameInstance, EvolvedShapes.Weapon, (PlayerIndex)player, weapon, LightingType.Menu);
flashEndTime[player] = time + flashTime;
}
}
}
}
//Make the totals 'count'
bool AnyPlayersCounting = false;
for (int player = 0; player < 2; player++)
{
//If the count doesn't match the total
if (playerCashCount[player] != SpacewarGame.Players[player].Cash)
{
AnyPlayersCounting = true;
if (!playingTallySound)
{
tallySound = Sound.Play(Sounds.PointsTally);
playingTallySound = true;
}
//Then move the count towards it
int countDirection = Math.Sign(SpacewarGame.Players[player].Cash - playerCashCount[player]);
playerCashCount[player] += (int)(elapsedTime.TotalMilliseconds * (double)countSpeed * (double)countDirection);
//Ensure we don't go past the actual count
if (countDirection == 1)
{
playerCashCount[player] = Math.Min(playerCashCount[player], SpacewarGame.Players[player].Cash);
}
else
{
playerCashCount[player] = Math.Max(playerCashCount[player], SpacewarGame.Players[player].Cash);
}
}
}
if (!AnyPlayersCounting && playingTallySound)
{
Sound.Stop(tallySound);
playingTallySound = false;
}
//Spin the weapon
for (int i = 0; i < 2; i++)
{
//(i * 2 -1) makes player 2 spin the other way
weapons[i].Rotation = new Vector3(-.3f, (float)time.TotalSeconds * (i * 2 - 1), 0);
}
//Flash the select icon
for (int player = 0; player < 2; player++)
{
if (flashEndTime[player] > time)
{
flashPercent[player] = (float)(Math.Sin((time - flashEndTime[player]).TotalSeconds * 40) * .5 + 1);
}
else
{
//Fully on
flashPercent[player] = 1.0f;
}
}
//Don't forget to call the base class
base.Update(time, elapsedTime);
//Play the next level when both players are ready
if (player1Ready && player2Ready)
{
//Copy over the purchased weapons
for (int i = 0; i < 2; i++)
{
SpacewarGame.Players[i].ProjectileType = purchasedWeapon[i];
}
Shutdown();
return GameState.PlayEvolved;
}
else
{
return GameState.None;
}
}
///
/// Tidy up anything that needs to be tidied
///
public override void Shutdown()
{
//Silence any looped sounds
if (playingTallySound)
Sound.Stop(tallySound);
Sound.Stop(menuMusic);
base.Shutdown();
}
///
/// Renders this The ship upgrade screen. Current money and settings come from the static SpacewarGame object
///
public override void Render()
{
IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService));
GraphicsDevice device = graphicsService.GraphicsDevice;
Texture2D mainTexture = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + upgradeTexture);
SpriteBatch.Begin(SpriteSortMode.Texture, BlendState.Opaque);
//Sprites will always be at the back.
device.DepthStencilState = DepthStencilState.DepthRead;
//Main background
SpriteBatch.Draw(mainTexture, Vector2.Zero, new Rectangle(0, 0, 1280, 720), Color.White);
SpriteBatch.End();
//New sprite to ensure they are drawn on top
SpriteBatch.Begin(SpriteSortMode.Texture, BlendState.AlphaBlend);
for (int player = 0; player < 2; player++)
{
for (int weapon = 1; weapon < 5; weapon++)
{
//Grey out weapons when you are ready
if ((player1Ready && player == 0) || (player2Ready && player == 1))
{
SpriteBatch.Draw(mainTexture, weaponPositions[player, weapon - 1], readySprite(player, weapon), Color.White);
}
//Show purchased weapon
else if ((int)purchasedWeapon[player] == weapon)
{
SpriteBatch.Draw(mainTexture, weaponPositions[player, weapon - 1], selectedSprite(player, weapon), new Color(new Vector4(1f, 1f, 1f, flashPercent[player])));
}
//Disable weapons you can't afford
else if (SpacewarGame.Players[player].Cash < SpacewarGame.Settings.Weapons[weapon].Cost)
{
SpriteBatch.Draw(mainTexture, weaponPositions[player, weapon - 1], disabledSprite(player, weapon), Color.White);
}
}
}
//Ready buttons
if (player1Ready)
SpriteBatch.Draw(mainTexture, new Vector2(55, 620), new Rectangle(10, 1205, 190, 70), Color.White);
if (player2Ready)
SpriteBatch.Draw(mainTexture, new Vector2(1040, 620), new Rectangle(330, 1205, 190, 70), Color.White);
SpriteBatch.End();
Font.Begin(); //Could reuse the sprite above but things may be drawn in the wrong order
//Current cash and weapon costs
//Ensure we use US number formatting
for (int i = 0; i < 621; i += 620)
{
if ((!player1Ready && i == 0) || (!player2Ready && i == 620))
{
Font.Draw(FontStyle.WeaponSmall, 296 + i, 255, String.Format("{0:$##,##0}", SpacewarGame.Settings.Weapons[1].Cost), upgradeFontColor);
Font.Draw(FontStyle.WeaponSmall, 110 + i, 438, String.Format("{0:$##,##0}", SpacewarGame.Settings.Weapons[2].Cost), upgradeFontColor);
Font.Draw(FontStyle.WeaponSmall, 480 + i, 438, String.Format("{0:$##,##0}", SpacewarGame.Settings.Weapons[3].Cost), upgradeFontColor);
Font.Draw(FontStyle.WeaponSmall, 296 + i, 621, String.Format("{0:$##,##0}", SpacewarGame.Settings.Weapons[4].Cost), upgradeFontColor);
}
}
Font.Draw(FontStyle.WeaponLarge, 322, 40, "$", upgradeFontColor);
Font.Draw(FontStyle.WeaponLarge, 346, 40, String.Format("{0:##,##0}", playerCashCount[0]), upgradeFontColor);
Font.Draw(FontStyle.WeaponLarge, 840, 40, "$", upgradeFontColor);
Font.Draw(FontStyle.WeaponLarge, 866, 40, String.Format("{0:##,##0}", playerCashCount[1]), upgradeFontColor);
//Score buttons
Font.Draw(FontStyle.ScoreButtons, 60 + 349, 70 + 24, scoreLookup[SpacewarGame.Players[0].Score]);
Font.Draw(FontStyle.ScoreButtons, 1140 - 351, 70 + 24, scoreLookup[SpacewarGame.Players[1].Score]);
Font.End();
base.Render();
}
private Rectangle selectedSprite(int player, int weapon)
{
return new Rectangle(10 + 320 * (weapon - 1), 730 + player * 160, 150, 150);
}
private Rectangle disabledSprite(int player, int weapon)
{
return new Rectangle(170 + 320 * (weapon - 1), 730 + player * 160, 150, 150);
}
private Rectangle readySprite(int player, int weapon)
{
return new Rectangle(10 + 160 * (weapon - 1) + 640 * player, 1050, 150, 150);
}
public override void OnCreateDevice()
{
base.OnCreateDevice();
weapons[0].ShapeItem.OnCreateDevice();
weapons[1].ShapeItem.OnCreateDevice();
}
}
}