1

Hey guys, i'm trying to use the following drawing logic:

Class Game
{
    Character x;

    public Draw(...)
    {
        spriteBatch.Begin(transformation1);
        x.Draw();
        spriteBatch.End();

        spriteBatch.Begin(transformation2);
        otherThing.Draw();
        spriteBatch.End();
    }
}

Class Character
{
    Animation[] animations;
    int currentAnimation;

    public Draw(...)
    {
        this.animations[this.currentAnimation].Draw();
    }
}

Class Animation
{
    Frame[] frames;
    int currentFrame;

    public Draw(...)
    {
        this.frames[this.currentFrame].Draw();
    }
}
Class Frame
{
    Texture2D texture;
    Texture2D shadow;

    public Draw(...)
    {
        spriteBatch.Begin(sub_transformation1);
        spriteBatch.Draw(texture1, ...);
        spriteBatch.End();

        spriteBatch.Begin(sub_transformation2);
        spriteBatch.Draw(shadow, ...);
        spriteBatch.End();
    }
}

If i try this logic i get a "Begin cannot be called again until End has been successfully called." error. So i'm asking if this logic is possible / makes sense? I'm using Begin() within Begin() to make additive transformations. If i have a character on x = 100 and y = 100 and i want the texture and shadow of the frame and everything else i want (bounding boxes, etc), to be drawn using that 100,100 translation, plus the -Xscale or +Xscale to flip horizontally the character (i know i could use the SpriteEffects.FlipHorizontally in the .Draw, but i wanted something that applied automatically to the bottom levels (animation and frame)), and finally in the Frame level the texture has a transformation on top of the one from the character and the shadow has another one. Don't know if i explained myself well, but ask if you have any doubts.

Thanks a lot.

xlar8or
  • 601
  • 9
  • 18

2 Answers2

2

I kind of understand where you're coming from, but it just isn't possible. SpriteBatch can't be hierarchical like you're wanting. Your objects, however, can.

Edited slightly to address your question below:

Class Frame
{
    // World - parent transformation to build from, passed 
    // from animation, from character, on up the chain...
    // localTransform - local coordinates
    // shadowTransform - maybe not needed?
    public Draw(Matrix world, Matrix localTransform, Matrix shadowTransform)
    {
        spriteBatch.Begin();
        spriteBatch.Draw(
            texture1, 
            ..., 
            Matrix.Transform(world * localTransform),
            ...);

        spriteBatch.Draw(
            shadowTexture, 
            ..., 
            Matrix.Transform(world * localTransform * shadowTransform), 
            ...);

        spriteBatch.End();
    }
}

You don't have to pass down all the character or object information into the frame - just need a transform to be set by the frame parent. Your original code was already receiving a transform (sub_transformation1 and 2) from somewhere - here we just pass that value into the Draw function. You could make the localTransform a class variable too, set it on instantiation.

The Animation class would have a similar Draw(Matrix world...) signature. I think it achieves what you're looking for and kind of similar to how OpenGL handles things - just more manual (from the little I remember of it from years ago).

Side note, there is gamedev.stackexchange.com for game related questions too.

Community
  • 1
  • 1
Leniency
  • 4,984
  • 28
  • 36
  • That makes sense, but that would imply that Animation and Frame were passed down with the Position, Facing direction, etc from the Character. I want something more independent and generic so that i could use them with upper classes that apply transformations besides Character. I come from a OpenGL / DirectX background, so not being able to do these simple things kinda confuses me. I know that XNA has a more DirectX way of doing things using CreateOrthoMatrix and using DrawPrimitives, although that's a lot more work than using SpriteBatch, but it looks like i have to use that to do what i want. – xlar8or Mar 16 '11 at 11:20
  • Edited answer to address comment. – Leniency Mar 16 '11 at 14:24
0

If you think about SpriteBatch in terms of the traditional World/View/Project model of transformation:

You should be doing your "World" transformation in the Draw call. That is to say, if your sprite is at position you should draw it at position. If it has a shadow at position + 100, draw it there as well.

You should be doing your View (and Project if you're getting fancy) transformation - that is your "camera" transformation - in the Begin call.

(There are a few situations where you can only get the world transform you want with a matrix, but that is quite unusual.)

You cannot "stack" transformations with SpriteBatch, you'd have to implement such a thing externally.

Andrew Russell
  • 26,924
  • 7
  • 58
  • 104