01748bc5f8
Adding dispose methods to AxiosFile objects Adding extended log to AxiosLog Fixing issue in CommandConsole where the first line would not be displayed Adding commands to commandconsole
585 lines
21 KiB
C#
585 lines
21 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Xml.Linq;
|
|
using Axios.Engine.Extensions;
|
|
using Axios.Engine.File;
|
|
using Axios.Engine.Gleed2D;
|
|
using Axios.Engine.Interfaces;
|
|
using Axios.Engine.Log;
|
|
using Axios.Engine.Structures;
|
|
using Axios.Engine.UI;
|
|
using FarseerPhysics.Dynamics;
|
|
using FarseerPhysics.Factories;
|
|
using FarseerPhysics.SamplesFramework;
|
|
using GameStateManagement;
|
|
using Gleed2D.Core;
|
|
using Gleed2D.InGame;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Content;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using Microsoft.Xna.Framework.Input;
|
|
|
|
namespace Axios.Engine
|
|
{
|
|
|
|
public abstract class AxiosGameScreen : PhysicsGameScreen
|
|
{
|
|
private List<AxiosGameObject> _gameObjects;
|
|
private List<AxiosGameObject> _objectstoremove = new List<AxiosGameObject>();
|
|
private AxiosGameObject prevobj;
|
|
private AxiosGameObject prevfocusobj;
|
|
|
|
#region DebugTextVariables
|
|
#if DEBUG
|
|
public SpriteFont DebugSpriteFont;
|
|
public String DebugTextFont = "Fonts/helptext";
|
|
public Color DebugTextColor = Color.Red;
|
|
#endif
|
|
#endregion
|
|
|
|
private List<AxiosTimer> _timers;
|
|
private List<AxiosUIObject> _uiobjects;
|
|
|
|
protected Dictionary<string, PathItem> PathItems = new Dictionary<string, PathItem>();
|
|
protected Dictionary<string, TextureItem> TextureItems = new Dictionary<string, TextureItem>();
|
|
//protected List<TextureItem> TextureItems = new List<TextureItem>();
|
|
|
|
protected Dictionary<string, Texture2D> cache = new Dictionary<string, Texture2D>();
|
|
|
|
private AxiosUIObject prevuiobj;
|
|
private AxiosUIObject prevuifocusobj;
|
|
|
|
protected Level Level;
|
|
|
|
private Camera camera;
|
|
#if WINDOWS
|
|
AxiosCommandConsole _console = null;
|
|
#endif
|
|
protected bool AllowKeyboardWhileConsoleIsActive = false;
|
|
|
|
#if WINDOWS
|
|
public AxiosCommandConsole Console
|
|
{
|
|
get { return _console; }
|
|
set { _console = value; }
|
|
}
|
|
#endif
|
|
|
|
protected bool screenHidden = false;
|
|
|
|
public AxiosGameScreen()
|
|
: base()
|
|
{
|
|
this._gameObjects = new List<AxiosGameObject>();
|
|
_timers = new List<AxiosTimer>();
|
|
prevobj = null;
|
|
prevfocusobj = null;
|
|
this._uiobjects = new List<AxiosUIObject>();
|
|
prevuiobj = null;
|
|
prevuifocusobj = null;
|
|
|
|
}
|
|
|
|
public void LoadLevelFromStream(Stream s)
|
|
{
|
|
XElement xml = XElement.Load(s);
|
|
Level level = LevelLoader.Load(xml);
|
|
this.Level = level;
|
|
|
|
foreach (Layer layer in level.Layers)
|
|
{
|
|
foreach (LayerItem item in layer.Items)
|
|
{
|
|
//Debug.WriteLine(item.PropertyType);
|
|
switch (item.PropertyType)
|
|
{
|
|
case "Gleed2D.InGame.PathItemProperties":
|
|
this.LoadPathItem((PathItemProperties)item.Properties, layer);
|
|
break;
|
|
case "Gleed2D.InGame.TextureItemProperties":
|
|
this.LoadTextureItem((TextureItemProperties)item.Properties, layer);
|
|
break;
|
|
case "Gleed2D.InGame.RectangleItemProperties":
|
|
this.LoadRectangleItem((RectangleItemProperties)item.Properties, layer);
|
|
break;
|
|
case "Gleed2D.InGame.CircleItemProperties":
|
|
this.LoadCircleItem((CircleItemProperties)item.Properties, layer);
|
|
break;
|
|
default:
|
|
this.LoadOtherItem(item.Properties, item.PropertyType, layer);
|
|
break;
|
|
}
|
|
/*Debug.WriteLine(item.Properties.Id);
|
|
Debug.WriteLine(item.Properties.Name);
|
|
Debug.WriteLine(item.PropertyType);*/
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public void LoadLevelFromFile(string s)
|
|
{
|
|
AxiosTitleFile file = new AxiosTitleFile(s);
|
|
this.LoadLevelFromStream(file.GetStream(FileMode.Open));
|
|
}
|
|
|
|
public void LoadLevelFromGZFile(string s)
|
|
{
|
|
AxiosTitleFile file = new AxiosTitleFile(s);
|
|
GZipStream zipstream = new GZipStream(file.GetStream(FileMode.Open), CompressionMode.Decompress);
|
|
this.LoadLevelFromStream(zipstream);
|
|
}
|
|
|
|
public Vector2 MouseAimVector(MouseState ms, Vector2 relativeposition)
|
|
{
|
|
Vector2 ret;
|
|
ret = this.Camera.ConvertScreenToWorld(ms.Position()) - relativeposition;
|
|
ret.Normalize();
|
|
return ret;
|
|
}
|
|
|
|
/*public void AddGameObject<T>(T gameobject)
|
|
{
|
|
if (gameobject is AxiosGameObject || gameobject is AxiosUIObject)
|
|
gameobject.LoadContent(this);
|
|
|
|
if (gameobject is AxiosGameObject || gameobject is AxiosUIObject)
|
|
gameobject.RemoveObject += new AxiosGameObject.RemoveAxiosGameObjectHandler(RemoveGameObject);
|
|
|
|
if (gameobject is AxiosGameObject)
|
|
{
|
|
this._gameObjects.Add(gameobject);
|
|
}
|
|
else if (gameobject is AxiosUIObject)
|
|
{
|
|
this._uiobjects.Add(gameobject);
|
|
}
|
|
}*/
|
|
|
|
/*public void AddGameObject(AxiosGameObject gameobject)
|
|
{
|
|
gameobject.LoadContent(this);
|
|
gameobject.RemoveObject += new AxiosGameObject.AxiosGameObjectHandler(RemoveGameObject);
|
|
this._gameObjects.Add(gameobject);
|
|
}
|
|
|
|
public void AddGameObject(AxiosTimer timer)
|
|
{
|
|
timer.LoadContent(this);
|
|
_timers.Add(timer);
|
|
}
|
|
|
|
public void AddGameObject(AxiosUIObject uiobject)
|
|
{
|
|
uiobject.LoadContent(this);
|
|
uiobject.RemoveObject += new AxiosEvents.AxiosGameObjectHandler(RemoveGameObject);
|
|
_uiobjects.Add(uiobject);
|
|
}*/
|
|
|
|
public void AddGameObject(object obj)
|
|
{
|
|
|
|
#if WINDOWS
|
|
if (obj is AxiosCommandConsole)
|
|
{
|
|
if (_console != null)
|
|
{
|
|
//remove the current one first
|
|
|
|
ScreenManager.Game.Components.Remove(_console);
|
|
_console.Dispose();
|
|
_console = null;
|
|
}
|
|
_console = (AxiosCommandConsole)obj;
|
|
ScreenManager.Game.Components.Add(_console);
|
|
_console.LoadContent(ScreenManager.Game.Content);
|
|
}
|
|
#endif
|
|
if (obj is AxiosGameObject || obj is AxiosUIObject || obj is AxiosTimer)
|
|
{
|
|
AxiosGameObject tmp = obj as AxiosGameObject;
|
|
if (obj is AxiosGameObject || obj is AxiosUIObject)
|
|
tmp.RemoveObject += new AxiosEvents.AxiosGameObjectHandler(RemoveGameObject);
|
|
|
|
tmp.LoadContent(this);
|
|
|
|
if (obj is AxiosGameObject && !(obj is AxiosUIObject))
|
|
{
|
|
_gameObjects.Add(tmp);
|
|
}
|
|
else if (obj is AxiosUIObject)
|
|
{
|
|
_uiobjects.Add(obj as AxiosUIObject);
|
|
}
|
|
else if (obj is AxiosTimer)
|
|
{
|
|
_timers.Add(obj as AxiosTimer);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public void RemoveGameObject(AxiosTimer timer)
|
|
{
|
|
_timers.Remove(timer);
|
|
}
|
|
|
|
public void RemoveGameObject(AxiosUIObject uiobject)
|
|
{
|
|
uiobject.RemoveObject -= new AxiosGameObject.AxiosGameObjectHandler(RemoveGameObject);
|
|
uiobject.UnloadContent(this);
|
|
_uiobjects.Remove(uiobject);
|
|
}
|
|
|
|
public void RemoveGameObject(AxiosGameObject gameobject)
|
|
{
|
|
if (this._gameObjects.Contains(gameobject))
|
|
{
|
|
try
|
|
{
|
|
gameobject.UnloadContent(this);
|
|
this._gameObjects.Remove(gameobject);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AxiosLog.Instance.AddLine("[Axios Engine] - Adding objects too fast...remove " + gameobject.Name + " later", LoggingFlag.DEBUG);
|
|
this._objectstoremove.Add(gameobject);
|
|
}
|
|
|
|
}
|
|
|
|
public void RemoveAll()
|
|
{
|
|
AxiosLog.Instance.AddLine("[Axios Engine] - Memory usage before cleanup: " + GC.GetTotalMemory(true).ToString(), LoggingFlag.DEBUG);
|
|
foreach (AxiosGameObject g in _gameObjects)
|
|
g.UnloadContent(this);
|
|
foreach (AxiosUIObject ui in _uiobjects)
|
|
ui.UnloadContent(this);
|
|
this.World.Clear();
|
|
this._gameObjects.Clear();
|
|
_timers.Clear();
|
|
_uiobjects.Clear();
|
|
AxiosLog.Instance.AddLine("[Axios Engine] - Memory usage after cleanup: ", LoggingFlag.DEBUG);
|
|
}
|
|
|
|
public override void Activate(bool instancePreserved)
|
|
{
|
|
base.Activate(instancePreserved);
|
|
|
|
|
|
#if DEBUG
|
|
if (!Axios.Settings.ScreenSaver)
|
|
{
|
|
ContentManager man = new ContentManager(ScreenManager.Game.Services, "Content");
|
|
this.DebugSpriteFont = man.Load<SpriteFont>(this.DebugTextFont);
|
|
}
|
|
#endif
|
|
camera = new Camera(ScreenManager.GraphicsDevice.Viewport.Width, ScreenManager.GraphicsDevice.Viewport.Height);
|
|
|
|
#if DEBUG
|
|
EnableCameraControl = true;
|
|
#else
|
|
EnableCameraControl = false;
|
|
#endif
|
|
}
|
|
|
|
public override void Draw(GameTime gameTime)
|
|
{
|
|
|
|
//System.Diagnostics.Debugger.Break();
|
|
if (Level != null)
|
|
{
|
|
foreach (Layer layer in Level.Layers)
|
|
{
|
|
Vector2 oldcameraposition = camera.Position;
|
|
//camera.Position *= layer.ScrollSpeed;
|
|
|
|
ScreenManager.SpriteBatch.Begin(0, null, null, null, null, null, Camera.View);
|
|
foreach (TextureItem i in TextureItems.Values)
|
|
{
|
|
if (i.LayerItem.Visible == true)
|
|
{
|
|
i.draw(ScreenManager.SpriteBatch);
|
|
}
|
|
}
|
|
ScreenManager.SpriteBatch.End();
|
|
|
|
camera.Position = oldcameraposition;
|
|
}
|
|
}
|
|
|
|
foreach (AxiosGameObject g in (from x in (from i in _gameObjects where i is IDrawableAxiosGameObject select (IDrawableAxiosGameObject)i) orderby x.DrawOrder select x))
|
|
((IDrawableAxiosGameObject)g).Draw(this, gameTime);
|
|
|
|
foreach(AxiosUIObject g in (from x in _uiobjects orderby x.DrawOrder select x))
|
|
((IDrawableAxiosGameObject)g).Draw(this, gameTime);
|
|
|
|
|
|
|
|
base.Draw(gameTime); //This is placed at the end so that Farseer debug information is visible
|
|
|
|
}
|
|
|
|
public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
|
|
{
|
|
if (otherScreenHasFocus)
|
|
{
|
|
screenHidden = true;
|
|
}
|
|
|
|
if (screenHidden && !otherScreenHasFocus)
|
|
{
|
|
this.ReActivate();
|
|
screenHidden = false;
|
|
}
|
|
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
|
|
|
|
if (this._objectstoremove.Count > 0)
|
|
{
|
|
List<AxiosGameObject> list = this._objectstoremove.ToList<AxiosGameObject>();
|
|
foreach (AxiosGameObject obj in list)
|
|
{
|
|
this.RemoveGameObject(obj);
|
|
this._objectstoremove.Remove(obj);
|
|
}
|
|
}
|
|
|
|
|
|
foreach (AxiosGameObject g in _gameObjects.ToList())
|
|
g.Update(this, gameTime, otherScreenHasFocus, coveredByOtherScreen);
|
|
|
|
foreach (AxiosTimer t in _timers.ToList())
|
|
t.Update(this, gameTime, otherScreenHasFocus, coveredByOtherScreen);
|
|
|
|
foreach(AxiosUIObject g in _uiobjects.ToList())
|
|
g.Update(this, gameTime, otherScreenHasFocus, coveredByOtherScreen);
|
|
|
|
}
|
|
|
|
public override void HandleCursor(InputState input)
|
|
{
|
|
base.HandleCursor(input);
|
|
HandleMouseEvents(input);
|
|
|
|
foreach (AxiosGameObject g in _gameObjects.ToList())
|
|
g.HandleCursor(this, input);
|
|
}
|
|
|
|
private void HandleMouseEvents(InputState input)
|
|
{
|
|
Vector2 position = this.Camera.ConvertScreenToWorld(input.Cursor);
|
|
Fixture fix = this.World.TestPoint(position);
|
|
AxiosGameObject gobj;
|
|
if (fix != null && fix.UserData != null && fix.UserData is AxiosGameObject)
|
|
{
|
|
gobj = (AxiosGameObject)fix.UserData;
|
|
|
|
if (gobj != null && gobj != prevobj)
|
|
{
|
|
gobj.OnMouseHover(this, input);
|
|
|
|
|
|
if (prevobj != gobj && prevobj != null)
|
|
prevobj.OnMouseLeave(this, input);
|
|
}
|
|
else if (gobj != null)
|
|
{
|
|
if (input.IsNewMouseButtonRelease(MouseButtons.LeftButton))
|
|
{
|
|
if (prevobj != null)
|
|
prevobj.OnFocusLeave(this, input);
|
|
gobj.OnFocusEnter(this, input);
|
|
gobj.OnMouseUp(this, input);
|
|
prevfocusobj = gobj;
|
|
//prevobj = gobj;
|
|
}
|
|
|
|
if (input.IsNewMouseButtonPress(MouseButtons.LeftButton))
|
|
gobj.OnMouseDown(this, input);
|
|
}
|
|
|
|
if (gobj != null)
|
|
prevobj = gobj;
|
|
}
|
|
else
|
|
{
|
|
if (prevobj != null)
|
|
prevobj.OnMouseLeave(this, input);
|
|
if (input.IsNewMouseButtonPress(MouseButtons.LeftButton) && prevfocusobj != null)
|
|
{
|
|
prevfocusobj.OnFocusLeave(this, input);
|
|
prevfocusobj = null;
|
|
}
|
|
prevobj = null;
|
|
}
|
|
|
|
Vector2 uiobjpos;
|
|
//Rectangle uirect;
|
|
AxiosRectangle uirect;
|
|
bool foundobject = false;
|
|
Vector2 mousepos = this.Camera.ConvertScreenToWorld(input.Cursor);
|
|
//Vector2 objpos;
|
|
//System.Diagnostics.Debugger.Break();
|
|
AxiosRectangle mousrect = new AxiosRectangle(mousepos.X, mousepos.Y, ConvertUnits.ToSimUnits(25), ConvertUnits.ToSimUnits(25));
|
|
foreach(AxiosUIObject uiobject in _uiobjects)
|
|
{
|
|
uiobjpos = uiobject.Position;
|
|
//objpos = this.Camera.ConvertScreenToWorld(uiobjpos);
|
|
|
|
uirect = new AxiosRectangle(ConvertUnits.ToSimUnits(uiobjpos.X), ConvertUnits.ToSimUnits(uiobjpos.Y), ConvertUnits.ToSimUnits(uiobject.Width), ConvertUnits.ToSimUnits(uiobject.Height));
|
|
|
|
if (uirect.Intersect(mousrect))
|
|
{
|
|
|
|
if (input.IsNewMouseButtonPress(MouseButtons.LeftButton))
|
|
{
|
|
uiobject.OnMouseDown(this, input);
|
|
}
|
|
|
|
if (input.IsNewMouseButtonRelease(MouseButtons.LeftButton))
|
|
{
|
|
//System.Diagnostics.Debugger.Break();
|
|
if (prevuifocusobj != uiobject)
|
|
{
|
|
uiobject.OnFocusEnter(this, input);
|
|
if (prevuifocusobj != null)
|
|
prevuifocusobj.OnFocusLeave(this, input);
|
|
prevuifocusobj = uiobject;
|
|
}
|
|
uiobject.OnMouseUp(this, input);
|
|
}
|
|
|
|
if (prevuiobj != uiobject)
|
|
{
|
|
//System.Diagnostics.Debugger.Break();
|
|
uiobject.OnMouseHover(this, input);
|
|
if (prevuiobj != null)
|
|
prevuiobj.OnMouseLeave(this, input);
|
|
prevuiobj = uiobject;
|
|
}
|
|
foundobject = true;
|
|
break;
|
|
|
|
}
|
|
}
|
|
if (!foundobject && prevuiobj != null)
|
|
{
|
|
//mouse moved away from object
|
|
prevuiobj.OnMouseLeave(this, input);
|
|
prevuiobj = null;
|
|
}
|
|
|
|
if (input.IsNewMouseButtonRelease(MouseButtons.LeftButton))
|
|
{
|
|
if (!foundobject && prevuifocusobj != null)
|
|
{
|
|
|
|
prevuifocusobj.OnFocusLeave(this, input);
|
|
prevuifocusobj = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void HandleInput(GameTime gameTime, InputState input)
|
|
{
|
|
#if WINDOWS
|
|
if (_console == null || !AxiosCommandConsole.Active || (AllowKeyboardWhileConsoleIsActive && AxiosCommandConsole.Active))
|
|
#endif
|
|
{
|
|
base.HandleInput(gameTime, input);
|
|
|
|
foreach (AxiosGameObject g in _gameObjects.ToList())
|
|
g.HandleInput(this, input, gameTime);
|
|
|
|
foreach (AxiosUIObject g in _uiobjects.ToList())
|
|
g.HandleInput(this, input, gameTime);
|
|
}
|
|
}
|
|
|
|
public override void Unload()
|
|
{
|
|
//this.IsExiting = true;
|
|
//System.Diagnostics.Debugger.Break();
|
|
base.Deactivate();
|
|
ScreenState = GameStateManagement.ScreenState.TransitionOff;
|
|
AxiosLog.Instance.AddLine("Memory usage before cleanup: " + GC.GetTotalMemory(true).ToString(), LoggingFlag.DEBUG);
|
|
foreach (AxiosGameObject g in _gameObjects)
|
|
g.UnloadContent(this);
|
|
|
|
foreach (AxiosUIObject g in _uiobjects)
|
|
g.UnloadContent(this);
|
|
|
|
this._gameObjects.Clear();
|
|
this._uiobjects.Clear();
|
|
this.World.Clear();
|
|
_timers.Clear();
|
|
_uiobjects.Clear();
|
|
AxiosLog.Instance.AddLine("Memory usage after cleanup: " + GC.GetTotalMemory(true).ToString(), LoggingFlag.DEBUG);
|
|
//AxiosRegularFile f = new AxiosRegularFile("log.log");
|
|
//f.WriteData(AxiosLog.Instance.GetLog(), FileMode.Append);
|
|
//AxiosIsolatedFile f = new AxiosIsolatedFile("log.log");
|
|
//f.WriteData(AxiosLog.Instance.GetLog(), FileMode.Append);
|
|
//CleanUp();
|
|
#if WINDOWS
|
|
if (_console != null && !_console.KeepRunning)
|
|
{
|
|
//System.Diagnostics.Debugger.Break();
|
|
ScreenManager.Game.Components.Remove(_console);
|
|
_console.Dispose();
|
|
_console = null;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// This allows you to customize functionality for loading a circle item.
|
|
/// </summary>
|
|
/// <param name="circleitem"></param>
|
|
/// <returns></returns>
|
|
public virtual void LoadCircleItem(CircleItemProperties circleitem, Layer l)
|
|
{
|
|
|
|
}
|
|
|
|
public virtual void LoadPathItem(PathItemProperties pathitem, Layer l)
|
|
{
|
|
PathItem p = new PathItem((PathItemProperties)pathitem);
|
|
p.load(this);
|
|
PathItems[pathitem.Name] = p;
|
|
}
|
|
|
|
public virtual void LoadRectangleItem(RectangleItemProperties rectangleitem, Layer l)
|
|
{
|
|
if (l.Properties.CustomProperties.Keys.Contains("Collision") && (bool)l.Properties.CustomProperties["Collision"].Value)
|
|
{
|
|
Body b = BodyFactory.CreateRectangle(this.World, ConvertUnits.ToSimUnits(rectangleitem.Width), ConvertUnits.ToSimUnits(rectangleitem.Height), 1f);
|
|
b.Position = rectangleitem.getSimPosition();
|
|
//b.Position.X +=
|
|
b.IsStatic = true;
|
|
b.BodyType = BodyType.Static;
|
|
b.UserData = this;
|
|
}
|
|
}
|
|
|
|
public virtual void LoadTextureItem(TextureItemProperties textureitem, Layer l)
|
|
{
|
|
TextureItem i = new TextureItem((TextureItemProperties)textureitem);
|
|
i.load(this);
|
|
TextureItems[textureitem.Name] = i;
|
|
}
|
|
|
|
public virtual void LoadOtherItem(ItemProperties prop, string type, Layer l) { }
|
|
|
|
}
|
|
}
|