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 <string, Texture> Textures;
protected string Name;
public Vector2u Position;
public Vector2u Size;
protected List <GameObject> Inventory;
protected bool IsContainer;
protected string ID;
protected TextureType TextureType;
protected Text LabelText;
static GameObject()
{
GameObject.Textures = new Dictionary<string, Texture>();
}
public GameObject()
{
// DO NOTHING.
}
public GameObject(string name, TextureType type, Vector2u position)
{
this.Name = name;
this.Position = position;
this.Inventory = new List<GameObject>();
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<GameObject>();
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;
}
}
}