Пример #1
0
        /// <summary>
        /// Get the card layout for a <see cref="TableauPile"/>.
        /// </summary>
        /// <returns>
        /// An array of integers where the i-th integer denotes the vertical shift, in pixels, of the i-th card; the 0-th elements
        /// represents the shift for the TOP-MOST card.
        /// </returns>
        private float[] GetTableauPileCardLayout(Card[] cards)
        {
            // Choose an arbitrary card and get its texture.
            float cardHeight      = Card.GetTexture(CardSuit.Clubs, CardRank.Ace).Height;
            float pixelVisibility = cardHeight * PercentPixelVisibility;

            // The number of cards (including the first one) that can be fitted into the area without shrinking
            // the pixel visibility for a group of cards.
            int minimumCards = (int)Math.Ceiling((fullAreaHeight - cardHeight) / pixelVisibility);
            // The minimum pixel visibility when trying to fit all the cards in the tableau pile.
            float minimumPixelVisibility = (fullAreaHeight - cardHeight) / (MaximumSize - 1);

            int   excess            = cards.Length - minimumCards;
            float compressionFactor = cardHeight * PercentCardCompressionFactor;

            // Check if one of the cards in this tableau pile IN the compressed group is selected
            GameplayScreen gameplayScreen       = MainGame.Context.GameScreenManager.Get <GameplayScreen>();
            bool           isCompressedSelected = false;

            if (gameplayScreen.CurrentSelection != null)
            {
                for (int i = 0; i < cards.Length; i++)
                {
                    if (gameplayScreen.CurrentSelection.Card != cards[i])
                    {
                        continue;
                    }

                    isCompressedSelected = i < CardCompressionGroupSize - 1;
                    break;
                }
            }

            float compressionVisibility = isCompressedSelected ? pixelVisibility : Math.Max(pixelVisibility - excess * compressionFactor, minimumPixelVisibility);

            // Distribute the leftover space among the non-compressed cards.
            float leftoverVisibility = (fullAreaHeight - cardHeight - compressionVisibility * CardCompressionGroupSize) / (Count - CardCompressionGroupSize - 1);

            float[] allocations = new float[cards.Length];
            for (int i = 0; i < cards.Length; i++)
            {
                // The bottom card has no shift since there is no card after it.
                if (i == cards.Length - 1)
                {
                    continue;
                }
                if (cards.Length <= minimumCards)
                {
                    allocations[i] = pixelVisibility;
                }
                else
                {
                    allocations[i] = cards.Length - i <= CardCompressionGroupSize ? compressionVisibility : leftoverVisibility;
                }
            }

            return(allocations);
        }
Пример #2
0
        /// <summary>
        /// Initialize the <see cref="TableauPile"/>s.
        /// </summary>
        private void InitializeTableauPiles()
        {
            tableauPiles = new TableauPile[TableauPileCount];

            float tableauPilePositionY = GetTableauPileStartPositionY();
            float cardTextureWidth     = Card.GetTexture(CardSuit.Clubs, CardRank.Ace).Width;

            // The width of all the tableau piles (including spacing).
            float fullWidth = cardTextureWidth * tableauPiles.Length + TableauPileHorizontalSpacing * (tableauPiles.Length - 1);
            // The amount of pixels to offset each tableau pile such that they are horizontally centered.
            float centreOffsetX = 0.5f * (MainGame.GameScreenWidth - fullWidth);

            for (int i = 0; i < tableauPiles.Length; i++)
            {
                float positionX = centreOffsetX + i * (cardTextureWidth + TableauPileHorizontalSpacing);

                // The height of the tableau card area, in pixels.
                float height = MainGame.GameScreenHeight - tableauPilePositionY - TableauPileBottomPadding;
                tableauPiles[i] = new TableauPile(new RectangleF(positionX, tableauPilePositionY, cardTextureWidth, height), height);
            }
        }
Пример #3
0
        /// <summary>
        /// Update the positioning information of this <see cref="TableauPile"/>.
        /// </summary>
        public void UpdateRectangles()
        {
            Card[]       cards         = this.ToArray();
            RectangleF[] newRectangles = CalculateCardRectangles(cards);
            for (int i = 0; i < Count; i++)
            {
                this[i].Rectangle = newRectangles[i];
            }

            float height = fullAreaHeight;

            if (Count > 0)
            {
                RectangleF?lastCardRectangle = this[Count - 1].Rectangle;
                if (lastCardRectangle.HasValue)
                {
                    // Recalculate the tableau height
                    height = lastCardRectangle.Value.Bottom - Rectangle.Y;
                }
                else
                {
                    // If the rectangle of the final card is null, something went terribly wrong!
                    // (especially since we set the rectangles of the cards in the loop above).
                    // Use the full area height for the calculation instead and log this occurence.

                    Logger.LogFunctionEntry(string.Empty, "Rectangle of last card is null!", LoggerVerbosity.Warning);
                }
            }
            else
            {
                // Choose an arbitrary card and get its height.
                height = Card.GetTexture(CardSuit.Clubs, CardRank.Ace).Height;
            }

            Rectangle = new RectangleF(Rectangle.Position, new Vector2(Rectangle.Width, height));
        }