1
\$\begingroup\$

I try to create Puzzle JigSaw,and I want to display the selected piece on the first layer, the pieces that are on the original positions(solved) on the last layer and the others on the middle.

I select a piece on the Update method

public void Update(GameTime gameTime)
     {



        var touchLocation = InputManager.Instance.GetTouchLocation();

        if (touchLocation != null && touchLocation.Value.State == TouchLocationState.Pressed)
        {
            // select a piece
            SelectPiece(touchLocation.Value.Position);
        }
        if (touchLocation != null && touchLocation.Value.State == TouchLocationState.Moved && _selectedPiece != null)
        {
            // move the selected piece
            TouchLocation prevTouchLocation;
            touchLocation.Value.TryGetPreviousLocation(out prevTouchLocation);
            var distance = touchLocation.Value.Position - prevTouchLocation.Position;
            _selectedPiece.Position += distance; 


        }
        if (touchLocation != null && touchLocation.Value.State == TouchLocationState.Released &&
            _selectedPiece != null)
        {
            var rec = _selectedPiece.OriginalCollisionRectangle;

            rec.Inflate(30,30);
            if (rec.Contains(_selectedPiece.CollisionRectangle))
            {
                _selectedPiece.Position = _selectedPiece.OriginalPosition;
                _selectedPiece.IsOnOriginalPosition = true;

            }
            _selectedPiece.IsSelected = false;
            _selectedPiece = null;

        }

Code used to select the piece

   public void SelectPiece(Vector2 currentSelectPosition)
    {
        foreach (var aPiece in PuzzlePieces)
        {
            if (aPiece.CollisionRectangle.Contains((int)currentSelectPosition.X, (int)currentSelectPosition.Y)&& !aPiece.IsOnOriginalPosition)
            {


                    _selectedPiece = aPiece;
                    _selectedPiece.IsSelected = true;
                    return;


            }
        }

    }

I used this code for drawing:

   public void Draw(SpriteBatch batch)
    {

        batch.Begin();


        foreach (var aPiece in PuzzlePieces.Where(apiece=>apiece.IsOnOriginalPosition&&!apiece.IsSelected))
        {
            aPiece.Draw(batch);
        }
        foreach (var aPiece in PuzzlePieces.Where(apiece => !apiece.IsOnOriginalPosition && !apiece.IsSelected))
        {
            aPiece.Draw(batch);
        }
         if (_selectedPiece != null)
        {
            _selectedPiece.Draw(batch);
        }

       batch.End();

    }

This code work fine, but i have display problem, when I selected a piece,the piece that behind this piece is selected.

Could you help me please?

Thanks

\$\endgroup\$
1
  • \$\begingroup\$ Show the code used to select the piece. \$\endgroup\$ Commented Mar 14, 2014 at 23:47

2 Answers 2

0
\$\begingroup\$

In SelectPiece(), don't return right away when you find a piece that contains the selection position. For all we know, that piece is at the bottom of a stack.

Instead, keep track of that piece as your "best candidate so far," then keep checking other pieces. If you find another piece, check whether it's in front of the best candidate you've found so far. If so, replace your best candidate with this piece, otherwise keep searching.

Mark the best candidate as selected only once you've checked all selectable pieces that could overlap the selection position.

At the end of the function you're guaranteed to have the frontmost piece whose bounds include the selection position, instead of just any piece whose bounds include the selection position.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks, but how can i check if a piece is in front of an other? \$\endgroup\$
    – yagoub
    Commented Mar 15, 2014 at 16:06
  • \$\begingroup\$ That's going to be somewhat implementation-dependent. For ordering within your layers, you could use something like sbrouwer's answer to draw your sprites in a deterministic order. \$\endgroup\$
    – DMGregory
    Commented Mar 15, 2014 at 16:43
3
\$\begingroup\$

XNA has a depth option when drawing with a SpriteBatch.

This is the command I use for drawing:

Batch.Draw(sprite.Sheet.Texture, sprite.Position, sprite.Sheet.GetSourceRect(sprite.SpriteX, sprite.SpriteY), sprite.Color, sprite.Rotation, sprite.Origin, sprite.Scale, SpriteEffects.None, sprite.Depth);

My sprite is a class which contains a couple of properties about a sprite. Depth can be 0.0 to 1.0, where 0.0 is background and 1.0 is foreground. You need to use FrontToBack or BackToFront sprite sorting in your Batch.Begin(...); call for this to work though.

You can of course change this to your needs, MonoDev and Visual Studio should show the different overloaded parameter lists, so you can tinker with those to your needs.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thank you for answering the question in a way that applies to more than just the original poster. \$\endgroup\$ Commented May 17, 2017 at 3:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .