using System; using System.Collections.Generic; using System.IO; using SFML.Graphics; using SFML.Window; namespace Blashyrkh.Game { public enum Orientation { Horizontal, Vertical } public enum TextureType { None, Icon, Map, Scenery, Sprite, Tile } public abstract class GameObject : Drawable { private static Dictionary Textures; protected string Name; public Vector2u Position; public Vector2u Size; protected List Inventory; protected bool IsContainer; protected string ID; protected TextureType TextureType; protected Text LabelText; static GameObject() { GameObject.Textures = new Dictionary(); } public GameObject() { // DO NOTHING. } public GameObject(string name, TextureType type, Vector2u position) { this.Name = name; this.Position = position; this.Inventory = new List(); this.IsContainer = true; this.TextureType = type; } public GameObject(string name, TextureType type, Vector2u position, Vector2u size) { this.Name = name; this.Position = position; this.Size = size; this.Inventory = new List(); this.IsContainer = true; this.TextureType = type; } public virtual bool AddToInventory(GameObject item) { if (!(this.IsContainer)) { Console.Error.WriteLine("{0} cannot contain other objects.", this.ToString()); return false; } this.Inventory.Add(item); return true; } public virtual bool Contains(GameObject item) { if (!(this.IsContainer)) { Console.Error.WriteLine("{0} cannot contain other objects.", this.ToString()); return false; } return this.Inventory.Contains(item); } public void AttachLabel(string text) { this.LabelText = new Text(text, Font.DefaultFont, 10); this.LabelText.Color = new Color(0, 0, 0); this.LabelText.Position = new Vector2f(this.Position.X, this.Position.Y); } public void DetachLabel() { this.LabelText = null; } protected static Texture LoadTexture(TextureType type, string name) { if (GameObject.Textures.ContainsKey(name)) return GameObject.Textures[name]; // Find the texture, string path = Path.Combine(Game.BasePath, "Data", "Images", type.ToString() + "s", name + ".png"); new LogMessage(LogLevel.Debug, "Loading texture: {0}", path); // Load, add and return the texture. Texture texture = new Texture(path); GameObject.Textures.Add(name, texture); return texture; } public static Texture GetTexture(TextureType type, string name) { try { Texture texture = GameObject.Textures[name]; return texture; } catch(KeyNotFoundException) { // If the texture wasn't found, try to load it. return GameObject.LoadTexture(type, name); } } public virtual void Draw(RenderTarget target, RenderStates states) { Texture texture = GameObject.GetTexture(this.TextureType, this.Name); Sprite sprite = new Sprite(texture); sprite.Position = new Vector2f((float)this.Position.X, (float)this.Position.Y); target.Draw(sprite, states); if (this.LabelText != null) target.Draw(this.LabelText, states); } public override string ToString() { return String.Format("<{0}:{1}>", this.ID, this.Name); } public bool IsCollidingWith(GameObject entity) { // The top/left co-ords are moved down/right by 10% // and the bottom/right co-ords are moved up/left by 10% // to make the overall bounding box 20% smaller than the // size of the objects, to give tighter detection. uint top1 = (uint)((float)this.Position.Y * 1.1f), top2 = (uint)((float)entity.Position.Y * 1.1f), left1 = (uint)((float)this.Position.X * 1.1f), left2 = (uint)((float)entity.Position.Y * 1.1f), right1 = (uint)((float)(this.Position.X + this.Size.X) * 0.9f), right2 = (uint)((float)(entity.Position.X + entity.Size.X) * 0.9f), bottom1 = (uint)((float)(this.Position.Y + this.Size.Y) * 0.9f), bottom2 = (uint)((float)(entity.Position.Y + entity.Size.Y) * 0.9f); if (top1 > bottom2) return false; if (left1 > right2) return false; if (right1 < left2) return false; if (bottom1 < top2) return false; return true; } } }