Using SpriteBatch.Begin() within other SpriteBatch.Begin()
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 开发者_JAVA百科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.
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.
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.
精彩评论