Content loading system functioning.

This commit is contained in:
Harrison Deng 2018-10-30 18:29:54 -05:00
parent 3a4dfb94ac
commit a9647f2146
14 changed files with 189 additions and 87 deletions

View File

@ -43,8 +43,13 @@
<PropertyGroup> <PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Zer01HD\Utilities\Persistence\IPreferences.cs" /> <Compile Include="Zer01HD\Utilities\ContentSystem\NormalContentResolver.cs" />
<Compile Include="Zer01HD\Utilities\Persistence\Preferences.cs" />
<Compile Include="Zer01HD\Utilities\Renderer\ScaledRenderer.cs" />
<Compile Include="Zer01HD\Utilities\UI\LoadingScreen.cs" /> <Compile Include="Zer01HD\Utilities\UI\LoadingScreen.cs" />
<Compile Include="Zer01HD\Game\MainScreen\MainScreen.cs" /> <Compile Include="Zer01HD\Game\MainScreen\MainScreen.cs" />
<Compile Include="Zer01HD\Utilities\UI\Modular\Module.cs" /> <Compile Include="Zer01HD\Utilities\UI\Modular\Module.cs" />
@ -60,7 +65,7 @@
<Compile Include="Zer01HD\Game\ContentResolvers\FontContentResolver.cs" /> <Compile Include="Zer01HD\Game\ContentResolvers\FontContentResolver.cs" />
<Compile Include="Zer01HD\Game\ContentResolvers\ResolutionContentResolver.cs" /> <Compile Include="Zer01HD\Game\ContentResolvers\ResolutionContentResolver.cs" />
<Compile Include="Zer01HD\Utilities\ContentSystem\ContentSystem.cs" /> <Compile Include="Zer01HD\Utilities\ContentSystem\ContentSystem.cs" />
<Compile Include="Zer01HD\Utilities\ContentSystem\IContentResolver.cs" /> <Compile Include="Zer01HD\Utilities\ContentSystem\IContentPathModifier.cs" />
<Compile Include="Zer01HD\Utilities\ParticleSystem\Particle.cs" /> <Compile Include="Zer01HD\Utilities\ParticleSystem\Particle.cs" />
<Compile Include="Zer01HD\Game\Preferences\Controls.cs" /> <Compile Include="Zer01HD\Game\Preferences\Controls.cs" />
<Compile Include="Zer01HD\Game\Preferences\General.cs" /> <Compile Include="Zer01HD\Game\Preferences\General.cs" />

View File

@ -7,8 +7,10 @@ using RhythmBullet.Zer01HD.Game.Preferences;
using RhythmBullet.Zer01HD.UI; using RhythmBullet.Zer01HD.UI;
using RhythmBullet.Zer01HD.Utilities; using RhythmBullet.Zer01HD.Utilities;
using RhythmBullet.Zer01HD.Utilities.ContentSystem; using RhythmBullet.Zer01HD.Utilities.ContentSystem;
using RhythmBullet.Zer01HD.Utilities.DataTypes;
using RhythmBullet.Zer01HD.Utilities.UI; using RhythmBullet.Zer01HD.Utilities.UI;
using System; using System;
using System.Diagnostics;
namespace RhythmBullet namespace RhythmBullet
{ {
@ -17,6 +19,10 @@ namespace RhythmBullet
/// </summary> /// </summary>
public class RhythmBulletGame : Game public class RhythmBulletGame : Game
{ {
public const int WORLD_WIDTH = 4;
public const int WORLD_HEIGHT = 3;
public static int pixels_per_WU;
public GraphicsDeviceManager Graphics; public GraphicsDeviceManager Graphics;
SpriteBatch spriteBatch; SpriteBatch spriteBatch;
public readonly ContentSystem Assets; public readonly ContentSystem Assets;
@ -34,12 +40,11 @@ namespace RhythmBullet
Assets = new ContentSystem(Content); Assets = new ContentSystem(Content);
resolutionContentResolver = new ResolutionContentResolver(); resolutionContentResolver = new ResolutionContentResolver();
FontContentResolver fcr = new FontContentResolver(resolutionContentResolver); FontContentResolver fcr = new FontContentResolver(resolutionContentResolver);
Assets.contentResolver.Add(typeof(Texture2D), resolutionContentResolver); Assets.contentPathModifier.Add(typeof(Texture2D), resolutionContentResolver);
Assets.contentResolver.Add(typeof(SpriteFont), fcr); Assets.contentPathModifier.Add(typeof(SpriteFont), fcr);
preferencesManager = new PreferencesManager(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/RhythmBullet", preferencesManager = new PreferencesManager(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/RhythmBullet",
new Controls(), new General(),
new General()); new Controls());
} }
public Screen Screen public Screen Screen
@ -67,7 +72,14 @@ namespace RhythmBullet
/// </summary> /// </summary>
protected override void Initialize() protected override void Initialize()
{ {
// TODO: Add your initialization logic here //Load preferences
preferencesManager.Load();
Resolution resolution = preferencesManager.GetPreferences<General>().Resolution;
resolutionContentResolver.Width = resolution.Width;
resolutionContentResolver.Height = resolution.Height;
QueueContent();
Debug.WriteLine("Initial setup complete.");
base.Initialize(); base.Initialize();
} }
@ -80,7 +92,6 @@ namespace RhythmBullet
// Create a new SpriteBatch, which can be used to draw textures. // Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice); spriteBatch = new SpriteBatch(GraphicsDevice);
Screen = new LoadingScreen(Content.Load<Texture2D>("recrown")); Screen = new LoadingScreen(Content.Load<Texture2D>("recrown"));
// TODO: use this.Content to load your game content here // TODO: use this.Content to load your game content here
} }
@ -95,12 +106,17 @@ namespace RhythmBullet
/// <summary> /// <summary>
/// Allows the game to run logic such as updating the world, /// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio. /// checking for collisions, gathering input, and playing audio.
/// </summary> /// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param> /// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime) protected override void Update(GameTime gameTime)
{ {
if (!Assets.Done)
{
Assets.Update();
}
Screen.Update(gameTime); Screen.Update(gameTime);
base.Update(gameTime); base.Update(gameTime);
} }
@ -114,7 +130,7 @@ namespace RhythmBullet
spriteBatch.Begin(); spriteBatch.Begin();
Screen.Draw(spriteBatch); Screen.Draw(spriteBatch);
spriteBatch.End(); spriteBatch.End();
base.Draw(gameTime); base.Draw(gameTime);
} }
@ -124,16 +140,31 @@ namespace RhythmBullet
resolutionContentResolver.Width = Graphics.PreferredBackBufferWidth; resolutionContentResolver.Width = Graphics.PreferredBackBufferWidth;
resolutionContentResolver.Height = Graphics.PreferredBackBufferHeight; resolutionContentResolver.Height = Graphics.PreferredBackBufferHeight;
QueueContent(); QueueContent();
Screen.AssetLoadStateChange(true);
} }
public void PostAssetLoad() public void PostAssetLoad()
{ {
Screen.AssetLoadStateChange(false);
} }
void QueueContent() void QueueContent()
{ {
Assets.Queue<Texture2D>("Tech-Circle1");
Assets.Queue<Texture2D>("polyjet-standard");
Assets.Queue<Texture2D>("cybercircle3B");
Assets.Queue<Texture2D>("title");
Assets.Queue<Texture2D>("cybercircle1");
Assets.Queue<Texture2D>("defaultCover");
Assets.Queue<Texture2D>("laser");
Assets.Queue<Texture2D>("pellet");
Assets.Queue<Texture2D>("shard");
Assets.Queue<Texture2D>("bar");
Assets.Queue<Texture2D>("flake");
Assets.Queue<Texture2D>("void_circle");
Assets.Queue<Texture2D>("tpSelector");
Assets.Queue<Texture2D>("backgrounds/mainBG");
Assets.Queue<Texture2D>("magic1");
} }
} }
} }

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace RhythmBullet.Zer01HD.Game.ContentResolvers namespace RhythmBullet.Zer01HD.Game.ContentResolvers
{ {
class FontContentResolver : IContentResolver class FontContentResolver : IContentPathModifier
{ {
readonly ResolutionContentResolver rcr; readonly ResolutionContentResolver rcr;
@ -16,9 +16,9 @@ namespace RhythmBullet.Zer01HD.Game.ContentResolvers
this.rcr = rcr; this.rcr = rcr;
} }
public string Load(string assetName) public string Modify(string assetName)
{ {
return rcr.Load("fonts/" + assetName); return rcr.Modify("fonts/" + assetName);
} }
} }
} }

View File

@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace RhythmBullet.Zer01HD.Game.ContentResolvers namespace RhythmBullet.Zer01HD.Game.ContentResolvers
{ {
class ResolutionContentResolver : IContentResolver class ResolutionContentResolver : IContentPathModifier
{ {
int width, height; int width, height;
bool updated; bool updated;
@ -98,7 +98,7 @@ namespace RhythmBullet.Zer01HD.Game.ContentResolvers
return best; return best;
} }
public string Load(string path) public string Modify(string path)
{ {
if (updated) if (updated)
{ {

View File

@ -1,18 +1,14 @@
using RhythmBullet.Zer01HD.Utilities.Persistence; using Microsoft.Xna.Framework.Input;
using System; using RhythmBullet.Zer01HD.Utilities.Persistence;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RhythmBullet.Zer01HD.Game.Preferences namespace RhythmBullet.Zer01HD.Game.Preferences
{ {
public class Controls : IPreferences public class Controls : Utilities.Persistence.Preferences
{ {
public int Forward; public Keys Forward = Keys.Up;
public int Backward; public Keys Backward = Keys.Down;
public int Left; public Keys Left = Keys.Left;
public int Right; public Keys Right = Keys.Right;
public int Shoot; public Keys Shoot = Keys.Space;
} }
} }

View File

@ -1,20 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Xml.Serialization;
using System.Linq; using RhythmBullet.Zer01HD.Utilities.DataTypes;
using System.Text;
using System.Threading.Tasks;
using RhythmBullet.Zer01HD.Utilities;
using RhythmBullet.Zer01HD.Utilities.Persistence; using RhythmBullet.Zer01HD.Utilities.Persistence;
namespace RhythmBullet.Zer01HD.Game.Preferences namespace RhythmBullet.Zer01HD.Game.Preferences
{ {
public class General : IPreferences public class General : Utilities.Persistence.Preferences
{ {
public Resolution Resolution; public Resolution Resolution = new Resolution(1920, 1080);
public bool Fullscreen; public bool Fullscreen = false;
public float MusicVolume; public float MusicVolume = 1f;
public float FXVolume; public float FXVolume = 1f;
public string MusicDirectory; public string MusicDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
public string GameDirectory;
} }
} }

View File

@ -2,6 +2,8 @@
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -11,57 +13,57 @@ namespace RhythmBullet.Zer01HD.Utilities.ContentSystem
{ {
public class ContentSystem public class ContentSystem
{ {
volatile bool queued;
Thread thread; Thread thread;
readonly ContentManager contentManager; readonly ContentManager contentManager;
readonly Queue<LoadableContent> queue; readonly Queue<LoadableContent> queue;
Dictionary<string, IDisposable> assets; Dictionary<string, IDisposable> assets;
public readonly Dictionary<Type, IContentResolver> contentResolver; public readonly Dictionary<Type, IContentPathModifier> contentPathModifier;
public ContentSystem(ContentManager contentManager) public ContentSystem(ContentManager contentManager)
{ {
this.contentManager = contentManager; this.contentManager = contentManager;
assets = new Dictionary<string, IDisposable>(); assets = new Dictionary<string, IDisposable>();
queue = new Queue<LoadableContent>(); queue = new Queue<LoadableContent>();
contentResolver = new Dictionary<Type, IContentResolver>(); contentPathModifier = new Dictionary<Type, IContentPathModifier>();
} }
private void Load(string assetName, Type type) private void Load(string assetName, Type type)
{ {
IContentResolver handler = contentResolver[type]; IContentPathModifier handler = contentPathModifier[type];
string path = handler.Load(assetName); string path = handler.Modify(assetName);
assets.Add(assetName, contentManager.Load<IDisposable>(path)); try
{
assets.Add(assetName, contentManager.Load<IDisposable>(path));
} catch (ContentLoadException cle)
{
Debug.WriteLine("Failed to load " + assetName + "with modified path: " + cle.Message);
Debug.WriteLine("Loading asset from root: " + assetName);
assets.Add(assetName, contentManager.Load<IDisposable>(assetName));
}
Debug.WriteLine("Loaded asset: " + assetName);
} }
private void LoadBatch()
{
while (queue.Count != 0)
{
lock (queue)
{
LoadableContent content = queue.Dequeue();
Load(content.assetName, content.type);
}
queued = false;
}
}
public T Get<T>(string assetName) public T Get<T>(string assetName)
{ {
lock(queue) lock (queue)
{ {
return (T)assets[assetName]; return (T)assets[assetName];
} }
} }
public void Queue(string assetName, Type type) public void Queue<T>(string assetName) where T : IDisposable
{ {
queued = true;
lock (queue) lock (queue)
{ {
if (!assets.ContainsKey(assetName)) if (!assets.ContainsKey(assetName))
{ {
queue.Enqueue(new LoadableContent(assetName, type)); queue.Enqueue(new LoadableContent(assetName, typeof(T)));
Debug.WriteLine("Queued asset: " + assetName);
}
else
{
Debug.WriteLine("Did not queue asset due to asset with same name being loaded: " + assetName);
} }
} }
} }
@ -77,10 +79,22 @@ namespace RhythmBullet.Zer01HD.Utilities.ContentSystem
{ {
ThreadStart threadStart = new ThreadStart(LoadBatch); ThreadStart threadStart = new ThreadStart(LoadBatch);
thread = new Thread(threadStart); thread = new Thread(threadStart);
thread.Start();
} }
} }
} }
private void LoadBatch()
{
while (queue.Count != 0)
{
lock (queue)
{
LoadableContent content = queue.Dequeue();
Load(content.assetName, content.type);
}
}
}
/// <summary> /// <summary>
/// Removes the asset from the list of assets in the system. /// Removes the asset from the list of assets in the system.
/// Cannot remove from queue. /// Cannot remove from queue.
@ -100,9 +114,9 @@ namespace RhythmBullet.Zer01HD.Utilities.ContentSystem
/// </summary> /// </summary>
public void ClearQueue() public void ClearQueue()
{ {
lock(queue) lock (queue)
{ {
queue.Clear(); queue.Clear();
} }
} }
@ -119,9 +133,12 @@ namespace RhythmBullet.Zer01HD.Utilities.ContentSystem
ClearQueue(); ClearQueue();
} }
public bool Done() public bool Done
{ {
return queued; get
{
return queue.Count == 0;
}
} }
} }
} }

View File

@ -6,13 +6,13 @@ using System.Threading.Tasks;
namespace RhythmBullet.Zer01HD.Utilities.ContentSystem namespace RhythmBullet.Zer01HD.Utilities.ContentSystem
{ {
public interface IContentResolver public interface IContentPathModifier
{ {
/// <summary> /// <summary>
/// Returns the complete path with the content folder as root. /// Returns the complete path with the content folder as root.
/// </summary> /// </summary>
/// <param name="assetName">Is the asset's name</param> /// <param name="assetName">Is the asset's name</param>
/// <returns></returns> /// <returns></returns>
string Load(string assetName); string Modify(string assetName);
} }
} }

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RhythmBullet.Zer01HD.Utilities.ContentSystem
{
class NormalContentResolver : IContentPathModifier
{
public string Modify(string assetName)
{
return assetName;
}
}
}

View File

@ -16,6 +16,10 @@ namespace RhythmBullet.Zer01HD.Utilities.DataTypes
Height = height; Height = height;
} }
public Resolution()
{
}
public int CompareTo(Resolution other) public int CompareTo(Resolution other)
{ {
return Area() - other.Area(); return Area() - other.Area();

View File

@ -3,10 +3,11 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Serialization;
namespace RhythmBullet.Zer01HD.Utilities.Persistence namespace RhythmBullet.Zer01HD.Utilities.Persistence
{ {
public interface IPreferences public class Preferences
{ {
} }
} }

View File

@ -11,43 +11,67 @@ namespace RhythmBullet.Zer01HD.Utilities
{ {
public class PreferencesManager public class PreferencesManager
{ {
private readonly Dictionary<Type, IPreferences> preferenceList; private readonly Dictionary<Type, Preferences> preferenceList;
public string SavePath; public string SavePath;
XmlSerializer xmlSerializer; XmlSerializer xmlSerializer;
public PreferencesManager(string savePath, params IPreferences[] preferences) public PreferencesManager(string savePath, params Preferences[] preferences)
{ {
this.SavePath = savePath; this.SavePath = savePath;
preferenceList = new Dictionary<Type, IPreferences>(); preferenceList = new Dictionary<Type, Preferences>();
foreach (IPreferences prefs in preferences)
Type[] preferenceTypes = new Type[preferences.Length];
for (int prefID = 0; prefID < preferences.Length; prefID++)
{ {
preferenceList.Add(prefs.GetType(), prefs); preferenceList.Add(preferences[prefID].GetType(), preferences[prefID]);
preferenceTypes[prefID] = preferences[prefID].GetType();
} }
xmlSerializer = new XmlSerializer(typeof(Preferences), preferenceTypes);
} }
public T GetPreferences<T>() where T : IPreferences public T GetPreferences<T>() where T : Preferences
{ {
return (T) preferenceList[typeof(T)]; return (T)preferenceList[typeof(T)];
} }
public void Load() public void Load()
{ {
foreach (KeyValuePair<Type, IPreferences> prefs in preferenceList) foreach (KeyValuePair<Type, Preferences> prefs in preferenceList)
{ {
Stream stream = new FileStream(SavePath + nameof(prefs.Key), FileMode.Open); if (!LoadSpecific(prefs.Key))
preferenceList[prefs.Key] = (IPreferences) xmlSerializer.Deserialize(stream); {
stream.Close(); SaveSpecific(prefs.Key);
}
} }
} }
public void Save() public void Save()
{ {
foreach (KeyValuePair<Type, IPreferences> prefs in preferenceList) foreach (KeyValuePair<Type, Preferences> prefs in preferenceList)
{ {
Stream stream = new FileStream(SavePath + nameof(prefs.Key), FileMode.Create); SaveSpecific(prefs.Key);
xmlSerializer.Serialize(stream, prefs.Value);
stream.Close();
} }
} }
private bool LoadSpecific(Type preference)
{
string path = SavePath + "/" + preference.Name;
if (File.Exists(path))
{
Stream stream = new FileStream(SavePath + "/" + preference.Name, FileMode.Open);
preferenceList[preference] = (Preferences)xmlSerializer.Deserialize(stream);
stream.Close();
return true;
}
return false;
}
private void SaveSpecific(Type preference)
{
Stream stream = new FileStream(SavePath + preference.Name, FileMode.Create);
xmlSerializer.Serialize(stream, preferenceList[preference]);
stream.Close();
}
} }
} }

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RhythmBullet.Zer01HD.Utilities.Renderer
{
class ScaledRenderer
{
}
}

View File

@ -30,7 +30,7 @@ namespace RhythmBullet.Zer01HD.Utilities.UI
} }
public virtual void Resize() public virtual void AssetLoadStateChange(bool state)
{ {
} }