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; public void Activate() { State = ScreenState.Active; Player player = new Player(this); Objects.Add(player); _player = player; Satellite prop = new Satellite(this, new Vector3(15, 0, 15)); Objects.Add(prop); if (_player == null) Environment.Exit(1); ObjectRadar = new Radar(_player, this); 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.Position.Y, obj.Position.Z); 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(candidates); } 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.IsPressed(Keys.Left)) { _player.RotateY(0.05f); } if (Input.IsPressed(Keys.Right)) { _player.RotateY(-0.05f); } if (Input.IsPressed(Keys.Up)) { _player.RotateX(0.05f); } if (Input.IsPressed(Keys.Down)) { _player.RotateX(-0.05f); } _player.Accelerate(move); if (Input.IsJustPressed(Keys.Space)) { _player.CurrentWeapon.Shoot(gameTime); } if (Input.IsJustReleased(Keys.Space)) { _player.CurrentWeapon.Stop(); } if (Input.IsJustPressed(Keys.V)) { Tolk.Speak(_player.Movement.Length().ToString(), true); } if (Input.IsJustPressed(Keys.C)) { Tolk.Speak(_player.Position.ToString()); } if (Input.IsJustPressed(Keys.R)) { if (ObjectRadar.Active) { ObjectRadar.Stop(); } else { ObjectRadar.Start(); } } if (Input.IsJustPressed(Keys.O)) { Tolk.Speak(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); } } }