1
\$\begingroup\$

Summarised Problem:

I have an Animation class that I want to be able to treat as a Texture2D field when need be. I do not want to inherit from the class or its parents. I'd rather not create a parent class of both the animation class and a 'container' for a Texture2D, though that may be the only way to achieve what I want.

Code:

public class Animation : IComponent
{
  public Texture2D texture => frames[currentFrame];

  public Texture2D[] frames;
  public byte currentFrame { get; protected set; }
  /// <summary>
  /// Frame time in milliseconds;
  /// </summary>
  public ushort interval;
  public bool looping;
  public bool animate;

  protected ushort progress;

  /// <param name="interval">Time until frame is succeeded.</param>
  /// <param name="loop">Whether to loop frames.</param>
  /// <param name="start">Whether to start cycling through frames.</param>
  public Animation(Texture2D[] frames, ushort interval, bool loop, bool start)
  {
    this.frames = frames;
    currentFrame = 0;
    this.interval = interval;
    looping = loop;
    animate = start;
  }

  public void Update(ushort milliseconds)
  {
    if (looping)
      currentFrame = (byte)((progress += milliseconds) % interval % frames.Length);
    else
      currentFrame = (byte)((progress += milliseconds) % interval);
    progress %= interval;
  }
}

It's an extremely simple class that is subject to change. Its purpose is to stand in for a Texture2D for external handling of spreadsheets and whatnot. It is going to be used in an ECS but probably not as a component as I have it now.

So, for instance, I'd like to be able to put it as a stand in for a Texture2D in draw calls (can be done with the 'texture' property it has) and also be kept in the same field and be cast to treat it as the animation class again.

If anyone thinks there's a much superior implementation of this please let me know.

If there's a way I could do something like this that would be perfect:
spriteBatch.Draw(Anim as Texture2D, Vector2.Zero, Color.White);

\$\endgroup\$
  • \$\begingroup\$ Why not extend Texture2D? It could be cast down to one then \$\endgroup\$ – Bálint Mar 18 '19 at 13:04
  • \$\begingroup\$ Welcome to GDSE. In the future, please place any necessary code directly into your question. Questions that require linked material to be understood are prone to link-rot. \$\endgroup\$ – Pikalek Mar 21 '19 at 14:07
1
\$\begingroup\$

You can either just extend Texture2D, which would allow you to cast it down to a Texture2D if you want or (in my opinion preferably) extend the spriteBatch with a draw that accepts Animations.

To be honest, I wouldn't do either of these. The same draw method doesn't give enough information to the animation, e.g. when did it start? How long should it be?

\$\endgroup\$
0
\$\begingroup\$

After coming across many unrelated and somewhat-related stackoverflow/gamedev questions I managed to find what I was looking for.

I didn't fully understand the "Is-a" vs "Has-a." I knew I didn't want inheritance but didn't want to encapsulate a Texture2D just for the sake of another class to inherit from without any extra usefulness to come of that encapsulation (Seems messy and unnecessary to me). The solution most often would take the form of a sprite class:

public class Sprite
{
    public Texture2D texture;
    public float depth;
    public float scale; // Or a Vector2
    public Color mask;
    // etc, etc

    public Sprite(/* stuff */)
    {
        // do more stuff 
    }
}

I didn't actually go with this in the end, I went with having an abstarct "Graphic" class containing vital info to draw a texture, but not the texture itself and inheriting classes would be drawn in there own way via an extension to SpriteBatch.Draw (This was good for Sprite vs Spritesheet vs Animations and such)

One thing I just came across and inspired me to make this is the way to cast your object to another outside of of the class's inheritance tree. Done quite simply as follows:

static public implicit operator Texture2D(Sprite s)
{
    return s.texture;
}

Use as follows:

Texture2D texure = (Texture2D)spriteinstance

You can go backwards too if one had extra info or you were happy to settle for default variables (Could be easily worked around).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.