0

I would like to flip character when it walks left\right, I created a character from different body parts so flipping each of them caused this: enter image description here

the reason of course was because it flipped the body parts in their own position, but not all the player together.

after that I had an idea and it was to draw the player to render target and flip the rendertarget when drawing, it worked (kind of), but when I walked when flipped it walked backwards and it also flipped the player position on the screen. here is the code:

  if(mLeavusSprite.isflipped==0)
        spriteBatch.Draw(character, rec,rec, Color.White,0,Vector2.Zero,SpriteEffects.None,0);
        else
            spriteBatch.Draw(character, rec, rec, Color.White, 0, Vector2.Zero, SpriteEffects.FlipHorizontally, 0);

character=render target that the player was drawn to.

is there anything I can do? flipping manually going to be a serious pain, I will need to move manually over 10 animations with 4+ frames each twice!

edit: here is the code for drawing:

           if (Frame == 0)
            {
                HeadPosition.X = Position.X;
                HeadPosition.Y = Position.Y;
                BodyPosition.X = HeadPosition.X + 8;
                BodyPosition.Y = HeadPosition.Y + 32;
                TopHandPosition.X = HeadPosition.X + 2;
                TopHandPosition.Y = HeadPosition.Y + 36;
                BackHandPosition.X = HeadPosition.X + 20;
                BackHandPosition.Y = HeadPosition.Y + 36;
                HeadSource = new Rectangle(0, 0, this.Head.Width, this.Head.Height);
                BodySource = new Rectangle(0, 0, 24, 54);
                TopHandSource = new Rectangle(0, 0, 10, 27);
                BackHandSource = new Rectangle(0, 0, 15, 27);
                theSpriteBatch.Draw(BackHand, BackHandPosition, BackHandSource,
   Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
                theSpriteBatch.Draw(Body, BodyPosition, BodySource,
             Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
                theSpriteBatch.Draw(Head, HeadPosition, HeadSource,
                Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
                theSpriteBatch.Draw(TopHand, TopHandPosition, TopHandSource,
         Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0); 

            }

Edit 2:

  if (Frame == 0)
            {
                HeadPosition.X = Position.X;
                HeadPosition.Y = Position.Y;
                BodyPosition.X = HeadPosition.X + 8 ;
                BodyPosition.Y = HeadPosition.Y + 32;
                TopHandPosition.X = HeadPosition.X + 2 ;
                TopHandPosition.Y = HeadPosition.Y + 36;
                BackHandPosition.X = HeadPosition.X + 20 ;
                BackHandPosition.Y = HeadPosition.Y + 36;
                HeadSource = new Rectangle(0, 0, this.Head.Width, this.Head.Height);
                BodySource = new Rectangle(0, 0, 24, 54);
                TopHandSource = new Rectangle(0, 0, 10, 27);
                BackHandSource = new Rectangle(0, 0, 15, 27);
                int bigx=0;
                int smallx=0;
                float[] numbers = new[] { HeadPosition.X, BodyPosition.X , TopHandPosition.X, BackHandPosition.X};
                float min = numbers.Min();
                numbers = new[] { HeadPosition.X+HeadSource.Width, BodyPosition.X + BodySource.Width, TopHandPosition.X + TopHandSource.Width, BackHandPosition.X + BackHandSource.Width };
                float max = numbers.Max();
                float center = (max - min) / 2;
                if (flip==1)
                {
                    HeadPosition.X = Position.X;

                    BodyPosition.X = HeadPosition.X +center+ 8*flipOffset;

                    TopHandPosition.X = HeadPosition.X +center+ 2*flipOffset;

                    BackHandPosition.X = HeadPosition.X +center+ 20*flipOffset;

                }
                Debug.WriteLine("fff: " + center);
                theSpriteBatch.Draw(BackHand, BackHandPosition, BackHandSource, Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
                theSpriteBatch.Draw(Body, BodyPosition, BodySource, Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
                theSpriteBatch.Draw(Head, HeadPosition, HeadSource, Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
                theSpriteBatch.Draw(TopHand, TopHandPosition, TopHandSource, Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
            }

enter image description here

SpoocyCrep
  • 604
  • 7
  • 23

1 Answers1

2

hmm.. that is a tricky one.

There's probably a few different ways to do this and I think drawing they player to a render target is a reasonable approach if you can get it to work.

However, if you want a quick and dirty approach you might be able to simply flip the offsets of each part like this:

var flipOffset = FlipIs == SpriteEffects.FlipHorizontally ? -1 : 1;

if (Frame == 0)
{
    HeadPosition.X = Position.X;
    HeadPosition.Y = Position.Y;
    BodyPosition.X = HeadPosition.X + 8 * flipOffset;
    BodyPosition.Y = HeadPosition.Y + 32 * flipOffset;
    TopHandPosition.X = HeadPosition.X + 2 * flipOffset;
    TopHandPosition.Y = HeadPosition.Y + 36 * flipOffset;
    BackHandPosition.X = HeadPosition.X + 20 * flipOffset;
    BackHandPosition.Y = HeadPosition.Y + 36 * flipOffset;
    HeadSource = new Rectangle(0, 0, this.Head.Width, this.Head.Height);
    BodySource = new Rectangle(0, 0, 24, 54);
    TopHandSource = new Rectangle(0, 0, 10, 27);
    BackHandSource = new Rectangle(0, 0, 15, 27);
    theSpriteBatch.Draw(BackHand, BackHandPosition, BackHandSource, Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
    theSpriteBatch.Draw(Body, BodyPosition, BodySource, Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
    theSpriteBatch.Draw(Head, HeadPosition, HeadSource, Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0);
    theSpriteBatch.Draw(TopHand, TopHandPosition, TopHandSource,Color.White, 0.0f, Vector2.Zero, Scale, FlipIs, 0); 
}

This is assuming that Position is right in the center of the sprite, if not you might need to do some tweaking.

Look, I'll be honest with you. There are better ways to approach this problem, but they'd require a significant redesign of the code and it's difficult to explain in one answer.

The first thing I would do to refactor the design is create a class to represent a single Sprite part to hold the common data points (offset, source rectangle, texture, color, etc) and setup data in one place. The animation code needs to be decoupled from the drawing code, etc.

craftworkgames
  • 9,437
  • 4
  • 41
  • 52
  • thank you for helping out, but the solution didnt work for me, unsure why. The position is not the center, but I tried to find the center and add it, I edited in the result and new code – SpoocyCrep Sep 15 '15 at 14:40