using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; using SynthySound; using System.Linq; using EvilSatellites.Objects; using DavyKager; using EvilSatellites.Quadtree; namespace EvilSatellites.Screens { public class GameScreen : IScreen { public ScreenManager Manager { get; set; } public ScreenState State { get; set; } private InputManager Input = new InputManager(); public List Objects = new List(); public List Removable = new List(); public List Addable = new List(); private Quadtree objtree = new Quadtree(new Vector3(10000, 10000, 10000), 10, 20); private float Theta = 0; private Player _player; private Radar ObjectRadar; private SatelliteSpawner Spawner; public void Activate() { State = ScreenState.Active; Player player = new Player(this); Objects.Add(player); _player = player; // Satellite prop = new Satellite(this, new Vector3(5000, 5000, 5000)); // Objects.Add(prop); ObjectRadar = new Radar(_player, this); Spawner = new SatelliteSpawner(this); Spawner.Spawn(); return; } public void Deactivate() { State = ScreenState.Hidden; return; } public void Update(GameTime gameTime) { foreach (var obj in Removable) { Objects.Remove(obj); } if (Addable.Count > 0) { foreach (var obj in Addable) { Objects.Add(obj); } Addable.Clear(); } Removable.Clear(); objtree.Clear(); foreach (var obj in Objects) { obj.Update(gameTime); objtree.Add(obj); if (obj.Type == ObjectType.Player) { Manager.Sound.ListenerPosition = new System.Numerics.Vector3(obj.Position.X+obj.Dimensions.X/2, obj.Position.Y+obj.Dimensions.Y/2, obj.Position.Z+obj.Dimensions.Z/2); Manager.Sound.ListenerOrientationForward = System.Numerics.Vector3.Normalize(new System.Numerics.Vector3(obj.Rotation.Forward.X, obj.Rotation.Forward.Y, obj.Rotation.Forward.Z)); Manager.Sound.ListenerOrientationUpwards = System.Numerics.Vector3.Normalize(new System.Numerics.Vector3(obj.Rotation.Up.X, obj.Rotation.Up.Y, obj.Rotation.Up.Z)); Manager.Listener.Position = obj.Position; Manager.Listener.Forward = obj.Rotation.Forward; Manager.Listener.Up = obj.Rotation.Up; } if (obj.ShouldDestroy) { Removable.Add(obj); } } UpdateRadar(); CheckCollisions(); return; } private void UpdateRadar() { var candidates = objtree.Find(_player.Position, new Vector3(1000, 1000, 1000)); ObjectRadar.Update(Objects); } public void HandleInput(GameTime gameTime, KeyboardState inputs) { Input.Update(); Vector3 move = new Vector3(0, 0, 0); if (Input.IsPressed(Keys.W)) { move.Z = -_player.Acceleration.Z; } if (Input.IsPressed(Keys.S)) { move.Z = _player.Acceleration.Z; } if (Input.IsPressed(Keys.A)) { move.X = -_player.Acceleration.X; } if (Input.IsPressed(Keys.D)) { move.X = _player.Acceleration.X; } if (Input.IsJustPressed(Keys.A) || Input.IsJustPressed(Keys.S) || Input.IsJustPressed(Keys.D) || Input.IsJustPressed(Keys.W)) { _player.PlayTap(); } if (Input.IsJustPressed(Keys.Left)) { _player.StartTurning(-1, gameTime); } if (Input.IsJustPressed(Keys.Right)) { _player.StartTurning(1, gameTime); } if (Input.IsJustReleased(Keys.Left) || Input.IsJustReleased(Keys.Right)) { _player.StopTurning(); } if (Input.IsJustPressed(Keys.Up)) { _player.StartElevating(-1, gameTime); } if (Input.IsJustPressed(Keys.Down)) { _player.StartElevating(1, gameTime); } if (Input.IsJustReleased(Keys.Up) || Input.IsJustReleased(Keys.Down)) { _player.StopElevating(); } if (Input.IsJustPressed(Keys.V)) { _player.StartVacuuming(gameTime); } if (Input.IsJustReleased(Keys.V)) { _player.StopVacuuming(); } _player.Accelerate(move); if (Input.IsJustPressed(Keys.Space)) { _player.CurrentWeapon.Shoot(gameTime); _player.PlayTap(); } if (Input.IsJustReleased(Keys.Space)) { _player.CurrentWeapon.Stop(); } if (Input.IsJustPressed(Keys.R)) { _player.PlayTap(); if (ObjectRadar.Active) { ObjectRadar.Stop(); } else { ObjectRadar.Start(); } } if (Input.IsJustPressed(Keys.T)) { _player.PlayTap(); if (ObjectRadar.Filter == ObjectType.Satellite) { ObjectRadar.SetObjectType(ObjectType.Debris); Tolk.Output("Debris"); } else { ObjectRadar.SetObjectType(ObjectType.Satellite); Tolk.Output("Satellites"); } } if (Input.IsJustPressed(Keys.H)) { _player.PlayTap(); Tolk.Output(_player.Health.ToString() + " health", true); } if (Input.IsJustPressed(Keys.X)) { _player.PlayTap(); Tolk.Output(_player.CurrentWeapon.RemainingAmmo.ToString() + " rounds", true); } if (Input.IsJustPressed(Keys.O)) { DavyKager.Tolk.Output(Objects.Count.ToString()); } } private void CheckCollisions() { foreach (var obj in Objects) { if (!obj.Active) continue; var candidates = objtree.Find(obj.Position, obj.Dimensions); foreach (var target in candidates) { if (obj == target || !target.Active) continue; if (Intersects(obj, target)) { obj.OnCollision(target); target.OnCollision(obj); } } } } public bool Intersects(IGameObject obj1, IGameObject obj2) { return (obj1.Position.X <= (obj2.Position.X + obj2.Dimensions.X) && (obj1.Position.X + obj1.Dimensions.X) >= obj2.Position.X) && (obj1.Position.Y <= (obj2.Position.Y + obj2.Dimensions.Y) && (obj1.Position.Y + obj1.Dimensions.Y) >= obj2.Position.Y) && (obj1.Position.Z <= (obj2.Position.Z + obj2.Dimensions.Z) && (obj1.Position.Z + obj1.Dimensions.Z) >= obj2.Position.Z); } public void AddObject(IGameObject obj) { Addable.Add(obj); } public Player GetPlayer() { return _player; } } }