/******************************************************************************/ /*! \file SwitchingEvent.cs \author Kevin Carey Logic event involving rapid disk switching Copyright © 2007 DigiPen(USA) Corporation. All rights reserved. */ /******************************************************************************/ #region Using Statements using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; #endregion namespace Shooting_Range { // SwitchingEvent class // 3 targets appear on the screen, 2 of them the same, 1 different. // All targets then change to one color and start moving. // When the targets stop, the player must shoot the one that was different class SwitchingEvent : IEvent { // Constructor public SwitchingEvent(List objectList, Dictionary modelDictionary, Text instructions, Text timerText, Sound sound, Statistics stats) { // Set the member variables m_ObjectList = objectList; m_OriginalObjectList = new List(); m_ModelDictionary = modelDictionary; m_Instructions = instructions; m_TimerText = timerText; m_Sound = sound; m_Stats = stats; // Create a new list m_ModelList = new List(); // Add models to the list m_ModelList.Add(m_ModelDictionary["BlueDisk"]); m_ModelList.Add(m_ModelDictionary["RedDisk"]); m_ModelList.Add(m_ModelDictionary["GreenDisk"]); m_ModelList.Add(m_ModelDictionary["YellowDisk"]); m_ModelList.Add(m_ModelDictionary["OneDisk"]); m_ModelList.Add(m_ModelDictionary["TwoDisk"]); m_ModelList.Add(m_ModelDictionary["ThreeDisk"]); m_ModelList.Add(m_ModelDictionary["FourDisk"]); m_ModelList.Add(m_ModelDictionary["FiveDisk"]); m_ModelList.Add(m_ModelDictionary["ADisk"]); m_ModelList.Add(m_ModelDictionary["BDisk"]); m_ModelList.Add(m_ModelDictionary["CDisk"]); m_ModelList.Add(m_ModelDictionary["DDisk"]); m_ModelList.Add(m_ModelDictionary["EDisk"]); } // IEvent Init function public void Init(int round) { // Set the member variables m_Timer = new TimeSpan(0, 0, 8); m_PreviousTimer = m_Timer; m_InstructionsTimer = m_Timer - new TimeSpan(0, 0, 3); m_ShowTimer = m_InstructionsTimer - new TimeSpan(0, 0, 2); m_ShowFlag = false; m_TimerText.IsActive = false; m_Instructions.IsActive = true; m_InstructionsFlag = true; m_End = false; m_Fail = false; m_IsActive = true; m_SwitchFlag = false; m_NewSwitchFlag = true; m_EndTime = TimeSpan.MinValue; m_Count = 3 + (round / 10); m_Speed = 1.0f + (0.3f * (float)round); // Check the maximum speed if (m_Speed > 7.0f) { m_Speed = 7.0f; } // Get two random models Random random = new Random(); m_TargetModel = m_ModelList[random.Next(m_ModelList.Count)]; Model otherModel = m_ModelList[random.Next(m_ModelList.Count)]; // While the models are the same while (otherModel == m_TargetModel) { // Get another model otherModel = m_ModelList[random.Next(m_ModelList.Count)]; } // Get the index of the goal target for consistancy between lists int targetIndex = random.Next(3); // Clear the original list (list used for storing what the models originally were, // as they will be changed in the event, and objects can only store 1 model) m_OriginalObjectList.Clear(); // For each object in the object list for (int i = 0; i < m_ObjectList.Count; ++i) { // Set the object to inactive m_ObjectList[i].IsActive = false; // Move the object m_ObjectList[i].Move(new Vector3(-50.0f + (50.0f * i), 0.0f, 0.0f) - m_ObjectList[i].Position); // If it is the goal target object if (i == targetIndex) { // Set the model to the goal model m_ObjectList[i].ModelData = m_TargetModel; } // If not else { // Set the model to the other model m_ObjectList[i].ModelData = otherModel; } // Store a clone of the object in the original list m_OriginalObjectList.Add(m_ObjectList[i].CloneObject()); } } // IEvent Update function public void Update(TimeSpan deltaTime) { // Set the previous timer m_PreviousTimer = m_Timer; // If the targets are not being switched around if(!m_SwitchFlag) { // Decrement the timer m_Timer -= deltaTime; } // If the timer text needs to be updated if (m_EndTime == TimeSpan.MinValue) { // Update it String timerString = m_Timer.Seconds.ToString() + ':' + m_Timer.Milliseconds.ToString().PadRight(3, '0'); m_TimerText.TextString = timerString; } // If the timer is actively ticking down, and 1 second has passed if (m_IsActive && m_TimerText.IsActive && (m_Timer.Seconds != m_PreviousTimer.Seconds)) { // Play the beep sound m_Sound.Play("Timer"); } // If the instructions state is over if (m_InstructionsFlag && m_Timer < m_InstructionsTimer) { // Set the flags m_Instructions.IsActive = false; m_InstructionsFlag = false; m_ShowFlag = true; // For each object in the list for (int i = 0; i < m_ObjectList.Count; ++i) { // Make the object active m_ObjectList[i].IsActive = true; } } // If the show state is over if (m_ShowFlag && m_Timer < m_ShowTimer) { // Set the flags m_ShowFlag = false; m_SwitchFlag = true; // For each object in the list for (int i = 0; i < m_ObjectList.Count; ++i) { // Set the model to the whit disk m_ObjectList[i].ModelData = m_ModelDictionary["WhiteDisk"]; } } // If the switch state is over if (m_Count == 0) { // Set the flags m_SwitchFlag = false; m_TimerText.IsActive = true; } // If in the switch state if (m_SwitchFlag) { // If a new switch needs to happen if (m_NewSwitchFlag) { // Get two random objects Random random = new Random(); m_FirstSwitchObject = m_ObjectList[random.Next(m_ObjectList.Count)]; m_SecondSwitchObject = m_ObjectList[random.Next(m_ObjectList.Count)]; // While the objects are the same while (m_FirstSwitchObject == m_SecondSwitchObject) { // Get a different random object m_SecondSwitchObject = m_ObjectList[random.Next(m_ObjectList.Count)]; } // If the objects are backwards for checking the X position if (m_FirstSwitchObject.PositionX > m_SecondSwitchObject.PositionX) { // Swap them Object temp = m_FirstSwitchObject; m_FirstSwitchObject = m_SecondSwitchObject; m_SecondSwitchObject = temp; } // Initialize the objects to be switched SwitchObjects(m_FirstSwitchObject, m_SecondSwitchObject); // Set the flag m_NewSwitchFlag = false; } // If the objects have arrives at their appropriate destination if (m_FirstSwitchObject.PositionX >= m_SecondObjectPosition.X) { // Stop the objects m_FirstSwitchObject.PhysicsData.VelocityDirection = Vector3.Zero; m_SecondSwitchObject.PhysicsData.VelocityDirection = Vector3.Zero; // Position the objects their exact original positions m_FirstSwitchObject.Move(m_SecondObjectPosition - m_FirstSwitchObject.Position); m_SecondSwitchObject.Move(m_FirstObjectPosition - m_SecondSwitchObject.Position); // Set the flag for a new switch m_NewSwitchFlag = true; // Decrement the counter m_Count--; } } // If time has run out if (m_Timer < new TimeSpan(0, 0, 0) && m_EndTime == TimeSpan.MinValue) { // Set the flags m_Fail = true; m_IsActive = false; // Set the end timer m_EndTime = m_Timer - new TimeSpan(0, 0, 2); // Reset the timer string m_TimerText.TextString = "0:000"; // For each object for (int i = 0; i < m_ObjectList.Count; ++i) { // Reveal the model m_ObjectList[i].ModelData = m_OriginalObjectList[i].ModelData; } } // If the event is to end if (m_Timer <= m_EndTime) { // Set the flag m_End = true; } } // IEvent HandleCollision function public void HandleCollision(Object bullet, Object obj) { // If not at a point where collision should be checked if (!m_TimerText.IsActive || !m_IsActive) { // return return; } // For each object in the list int i; for (i = 0; i < m_ObjectList.Count; ++i) { // if the object hit is the object in the list if (obj == m_ObjectList[i]) { // break. The index of the hit target is now stored break; } } // Reveal the target hit m_ObjectList[i].ModelData = m_OriginalObjectList[i].ModelData; // If the target hit originally had the goal model if (m_OriginalObjectList[i].ModelData == m_TargetModel) { // Set the end timer m_EndTime = m_Timer - new TimeSpan(0, 0, 2); // Udate the statistics ++m_Stats.TargetsHit; m_Stats.LeftoverTime += m_Timer; // Set the flag m_IsActive = false; // Play the event passed sound m_Sound.Play("Success"); } // If the target hit did not originally have the goal model else { // Set the fail flag m_Fail = true; // Update the statistics ++m_Stats.FailedTargetsHit; // Play the incorrect target hit sounds m_Sound.Play("Fail"); } // Set the bullet to inactive bullet.IsActive = false; } // IEvent Shutdown function public void Shutdown() { // For each object for (int i = 0; i < m_ObjectList.Count; ++i) { // Make it inactive m_ObjectList[i].IsActive = false; } // Make everyhting else inactive m_Instructions.IsActive = false; m_TimerText.IsActive = false; } // IEvent End function public bool End() { return m_End; } // IEvent Fail function public bool Fail() { return m_Fail; } // IEvent ResetFail function public void ResetFail() { m_Fail = false; } // IEvent IsActive flag public bool IsActive { get { return m_IsActive; } } // IEvent Timer public TimeSpan Timer { get { return m_Timer; } } // SwitchObjects function // Initializes two objects to switch places private void SwitchObjects(Object firstObject, Object secondObject) { // Store the original positions m_FirstObjectPosition = firstObject.Position; m_SecondObjectPosition = secondObject.Position; // Set the velocities of the objects firstObject.PhysicsData.VelocityDirection = new Vector3(m_Speed, 0.0f, 0.0f); secondObject.PhysicsData.VelocityDirection = new Vector3(-m_Speed, 0.0f, 0.0f); } // Memebers private TimeSpan m_Timer; private TimeSpan m_PreviousTimer; private TimeSpan m_EndTime; private bool m_End; private bool m_Fail; private bool m_IsActive; private bool m_NewSwitchFlag; private bool m_SwitchFlag; private List m_ObjectList; private List m_OriginalObjectList; private Dictionary m_ModelDictionary; private List m_ModelList; private Text m_Instructions; private bool m_InstructionsFlag; private TimeSpan m_InstructionsTimer; private TimeSpan m_ShowTimer; private bool m_ShowFlag; private Text m_TimerText; private int m_Count; private Sound m_Sound; private Statistics m_Stats; private float m_Speed; private Object m_FirstSwitchObject; private Object m_SecondSwitchObject; private Vector3 m_FirstObjectPosition; private Vector3 m_SecondObjectPosition; private Model m_TargetModel; } }