/// <summary>
        /// Обнаружение столкновения между шарами
        /// </summary>
        /// <param name="parBall1">Шар первый</param>
        /// <param name="parBall2">Шар второй</param>
        /// <returns>True если есть столкновение</returns>
        private bool DetectCollision(BallModelData parBall1, BallModelData parBall2)
        {
            SpVector3 ballsDistanceVector = parBall2.Center - parBall1.Center;
            double    centersDistance     = ballsDistanceVector.Length();

            return(centersDistance <= parBall1.Radius + parBall2.Radius);
        }
        /// <summary>
        /// Обнаружение столкновения с коллайдером лузы
        /// </summary>
        /// <param name="parBall">Шар</param>
        /// <param name="parPocket">Луза</param>
        /// <returns>True если есть столкновение</returns>
        private bool IsPocketCollision(BallModelData parBall, Pocket parPocket)
        {
            SpVector3 ballDistanceVector = parPocket.Center - parBall.Center;
            double    centersDistance    = ballDistanceVector.Length();

            return(centersDistance <= parBall.Radius + parPocket.Radius);
        }
        /// <summary>
        /// Обработка столкновения двух шаров
        /// </summary>
        /// <param name="parBall1">Шар 1</param>
        /// <param name="parBall2">Шар 2</param>
        /// <returns>True, если столкновение имело место быть</returns>
        private bool CheckCollisionsWithBalls(BallModelData parBall1, BallModelData parBall2)
        {
            if (DetectCollision(parBall1, parBall2))
            {
                SpVector3 tmpVelocity = ChangeVelocities(parBall1, parBall2);
                parBall2.Velocity = ChangeVelocities(parBall2, parBall1);
                parBall1.Velocity = tmpVelocity;

                double tmpBallSpeed = Math.Max(parBall2.Speed * 0.8, parBall1.Speed * 0.8);

                double intersectionRadius = -(parBall2.Center - parBall1.Center).Length() + parBall2.Radius + parBall1.Radius;

                if (intersectionRadius <= 0)
                {
                    intersectionRadius = 1;
                }

                double posModifier = intersectionRadius / 2;
                parBall1.Center = parBall1.Center + (parBall1.Center - parBall2.Center).Normalize() * (posModifier + 1);
                parBall2.Center = parBall2.Center + (parBall2.Center - parBall1.Center).Normalize() * (posModifier + 1);


                parBall1.Speed = tmpBallSpeed;
                parBall2.Speed = tmpBallSpeed;

                return(true);
            }

            return(false);
        }
示例#4
0
        /// <summary>
        /// Проверка столкновения по модели прямоугольников AABB
        /// </summary>
        /// <param name="parBallData">Шар</param>
        /// <param name="parStart">Стартовая точка линии</param>
        /// <param name="parEnd">Конечная точка линии</param>
        /// <returns>True, если столкновение возможно</returns>
        static bool IsRectCollided(BallModelData parBallData, SpVector3 parStart, SpVector3 parEnd)
        {
            if (parBallData.Center.Y - parBallData.Radius > parEnd.Y)
            {
                return(false);
            }

            if (parBallData.Center.Y + parBallData.Radius < parStart.Y)
            {
                return(false);
            }

            // }
            double maxX = Math.Max(parStart.X, parEnd.X);
            double minX = Math.Min(parStart.X, parEnd.X);

            if (parBallData.Center.X - parBallData.Radius > maxX)
            {
                return(false);
            }

            if (parBallData.Center.X + parBallData.Radius < minX)
            {
                return(false);
            }

            return(true);
        }
示例#5
0
        /// <summary>
        /// Генерирует и возвращает функцию для проверки столкновения для заданной линии
        /// </summary>
        /// <param name="parStart">Начало линии</param>
        /// <param name="parEnd">Конец линии</param>
        /// <param name="parShouldCheckBottom">Точная проверка столкновения будет являтся пройденной,
        ///                                    если точка соприкосновения окажется снизу от линии?</param>
        /// <param name="parNormal">Нормаль</param>
        /// <returns></returns>
        static Func <BallModelData, bool> GenFunctionForPocketBorder(SpVector3 parStart, SpVector3 parEnd,
                                                                     bool parShouldCheckBottom,
                                                                     SpVector3 parNormal)
        {
            GetEquationKandB(parStart, parEnd,
                             out double k, out double b);

            Func <BallModelData, bool> retFunc = parData =>
            {
                if (IsRectCollided(parData, parStart, parEnd))
                {
                    SpVector3 pointToCheck = parData.Center + (-parNormal) * parData.Radius;

                    //необходима более точная проверка
                    if (parShouldCheckBottom)
                    {
                        return(pointToCheck.Y < k * pointToCheck.X + b);
                    }
                    else
                    {
                        return(pointToCheck.Y > k * pointToCheck.X + b);
                    }
                }
                else
                {
                    return(false);
                }
            };

            return(retFunc);
        }
示例#6
0
        /// <summary>
        /// Повернуть точки вокруг опоры
        /// </summary>
        /// <param name="parRotationDegreesAngle">Величина поворота в градусах</param>
        /// <param name="refPoints">Точки для поворота</param>
        /// <param name="parOrigin">Точка опоры</param>
        public static void RotateAroundPivot(double parRotationDegreesAngle, ref SpVector3[] refPoints, SpVector3 parOrigin)
        {
            double rotationRadians = DegreesToRadians(parRotationDegreesAngle);

            double s = System.Math.Sin(rotationRadians);
            double c = System.Math.Cos(rotationRadians);

            for (var index = 0; index < refPoints.Length; index++)
            {
                var refPoint = refPoints[index];

                //переместим
                double x = refPoint.X - parOrigin.X;
                double y = refPoint.Y - parOrigin.Y;

                //повернем
                double xRot = x * c - y * s;
                double yRot = x * s + y * c;

                //переместим обратно
                double xRes = xRot + parOrigin.X;
                double yRes = yRot + parOrigin.Y;

                refPoints[index] = new SpVector3(xRes, yRes);
            }
        }
示例#7
0
        /// <summary>
        /// Получает коэффициенты уравнения прямой y = kx + b
        /// </summary>
        /// <param name="parStart">Первая точка</param>
        /// <param name="parEnd">Вторая точка</param>
        /// <param name="parEquationK">Коэффициент уравнения k</param>
        /// <param name="parEquationB">Коэффициент уравнения b</param>
        static void GetEquationKandB(SpVector3 parStart, SpVector3 parEnd, out double parEquationK, out double parEquationB)
        {
            double dY = parEnd.Y - parStart.Y;
            double dX = parEnd.X - parStart.X;

            parEquationK = dY / dX;
            parEquationB = parStart.Y - (parEquationK * parStart.X);
        }
示例#8
0
        /// <summary>
        /// Дополнительный конструктор, генерирующий нормаль и функцию проверки коллизии самостоятельно
        /// </summary>
        /// <param name="parStart">Стартовая точка линии</param>
        /// <param name="parEnd">Конечная точка линии</param>
        /// <param name="parIsClockwiseNormal">Поиск нормали должен производится по часовой стрелке?</param>
        /// <param name="parIsCollisionCheckPreciseBottom">Точная проверка столкновения будет являтся пройденной,
        ///                                                если точка соприкосновения окажется снизу от линии?</param>
        public CollisionLine(SpVector3 parStart, SpVector3 parEnd, bool parIsClockwiseNormal,
                             bool parIsCollisionCheckPreciseBottom)
        {
            Normal = SpVector3.GetNormal2DOnly(parEnd,
                                               parStart, parIsClockwiseNormal);

            CheckCollisionFunc = GenFunctionForPocketBorder(parStart, parEnd, parIsCollisionCheckPreciseBottom, Normal);
        }
        /// <summary>
        /// Вспомогательный метод для изменения векторов скоростей столкнувшихся шаров
        /// </summary>
        /// <param name="parBall1">Шар 1</param>
        /// <param name="parBall2">Шар 2</param>
        /// <returns>Новый вектор скорости для Шара 1</returns>
        private SpVector3 ChangeVelocities(BallModelData parBall1, BallModelData parBall2)
        {
            SpVector3 centersVector        = parBall2.Center - parBall1.Center;
            SpVector3 ballOnePerpendicular = centersVector.PerpendicularComponent(parBall1.Velocity);
            SpVector3 ballTwoPerpendicular = centersVector.PerpendicularComponent(parBall2.Velocity);
            SpVector3 ballTwoParallel      = centersVector.ParralelComponent(parBall2.Velocity);

            SpVector3 newBall1Velocity = ballTwoParallel + ballOnePerpendicular;

            return(newBall1Velocity);
        }
示例#10
0
 /// <summary>
 /// Равен ли вектор другому
 /// </summary>
 /// <param name="parV2">Другой вектор</param>
 /// <returns></returns>
 public bool Equal(SpVector3 parV2)
 {
     if (_x == parV2.X && _y == parV2.Y && _z == parV2.Z
         ) //true if all components in one vector is equal to components in another.
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
示例#11
0
        /// <summary>
        /// Получить нормаль к линии в двухмерном пространстве
        /// </summary>
        /// <param name="parStart">Точка начала линии</param>
        /// <param name="parEnd">Точка конца линии</param>
        /// <param name="parIsClockwise">Нормаль нужна по часовой стрелке?</param>
        /// <returns></returns>
        public static SpVector3 GetNormal2DOnly(SpVector3 parStart, SpVector3 parEnd, bool parIsClockwise)
        {
            SpVector3 resultVector = parEnd - parStart;

            if (parIsClockwise)
            {
                return(new SpVector3(resultVector.Y, -resultVector.X, resultVector.Z).Normalize());
            }
            else
            {
                return(new SpVector3(-resultVector.Y, resultVector.X, resultVector.Z).Normalize());
            }
        }
示例#12
0
        /// <summary>
        /// Компонент переноса
        /// </summary>
        /// <param name="parV2">Второй вектор</param>
        /// <returns></returns>
        public SpVector3 ParralelComponent(SpVector3 parV2)
        {
            double lengthSquared, dotProduct, scale;

            lengthSquared = Length() * Length();
            dotProduct    = DotProduct(parV2);
            if (lengthSquared != 0)
            {
                scale = dotProduct / lengthSquared;
            }
            else
            {
                return(new SpVector3(0, 0));
            }
            return(new SpVector3(this.Scale(scale)));
        }
        /// <summary>
        /// Проверка столкновения с бортом
        /// </summary>
        /// <param name="parBall">Шар</param>
        /// <returns></returns>
        private bool CheckCollisionsWithBorders(BallModelData parBall)
        {
            foreach (var fieldCollisionLine in Field.CollisionLines)
            {
                if (fieldCollisionLine.CheckCollisionFunc(parBall))
                {
                    //столкновение произошло
                    SpVector3 ballVelocity = parBall.Velocity;

                    parBall.Velocity = 2 * ballVelocity +
                                       2 * fieldCollisionLine.Normal * (-ballVelocity.DotProduct(fieldCollisionLine.Normal)) -
                                       ballVelocity;

                    do
                    {
                        parBall.Center = parBall.Center + (fieldCollisionLine.Normal);
                    } while (fieldCollisionLine.CheckCollisionFunc(parBall));

                    return(true);
                }
            }

            return(false);
        }
示例#14
0
 /// <summary>
 /// Перекрестное произведение векторов
 /// </summary>
 /// <param name="parV2">Второй вектор</param>
 /// <returns></returns>
 public SpVector3 CrossProduct(SpVector3 parV2)
 {
     return(new SpVector3(_y * parV2.Z - _z * parV2.Y, _z * parV2.X - _x * parV2.Z, _x * parV2.Y - _y * parV2.X));
 }
示例#15
0
 /// <summary>
 /// Скалярное произведение векторов
 /// </summary>
 /// <param name="parV2">Второй вектор</param>
 /// <returns></returns>
 public double DotProduct(SpVector3 parV2)
 {
     return(_x * parV2.X + _y * parV2.Y + _z * parV2.Z);
 }
示例#16
0
 /// <summary>
 /// Стандартный конструктор
 /// </summary>
 /// <param name="parNormal">Нормаль</param>
 /// <param name="parCheckCollisionFunc">Функция для проверки коллизии с линией</param>
 public CollisionLine(SpVector3 parNormal, Func <BallModelData, bool> parCheckCollisionFunc)
 {
     CheckCollisionFunc = parCheckCollisionFunc;
     Normal             = parNormal;
 }
示例#17
0
 /// <summary>
 /// Стандартный конструктор
 /// </summary>
 /// <param name="parCenter">Центр лузы</param>
 public Pocket(SpVector3 parCenter)
 {
     Center = parCenter;
 }
示例#18
0
        /// <summary>
        /// Обновить данные для рендеринга
        /// </summary>
        public override void UpdateRenderingData()
        {
            if (_modelProviderComponent != null)
            {
                if (_modelProviderComponent.GameReady)
                {
                    //всегда есть задний фон, шары, очки и счетчик жизней
                    if (_currentRenderingBg == null)
                    {
                        _currentRenderingBg =
                            new RenderingData.RenderingData(
                                new RenderingSprite(ActualSubassetsDataLibrary.GetSprite(NORMAL_GAMEFIELD_BG_SPRITE), 0,
                                                    0,
                                                    0,
                                                    Color.White, 5));
                    }

                    if (_ballsRenderingData == null)
                    {
                        _ballsRenderingData = new LinkedList <RenderingData.RenderingData?>();
                    }

                    _ballsRenderingData.Clear();

                    foreach (var modelBall in _modelProviderComponent.BallsInGame)
                    {
                        BallGraphicsBind graphicsBind = GameFieldViewConsts.BallGraphicsBinds[modelBall.BallType];
                        _ballsRenderingData.AddLast(new RenderingData.RenderingData(new RenderingSprite(
                                                                                        ActualSubassetsDataLibrary.GetSprite(graphicsBind.StillSpriteKey),
                                                                                        GameFieldViewConsts.FIELD_MODEL_RENDER_LEFT_TOP_OFFSET_X + modelBall.Center.X,
                                                                                        GameFieldViewConsts.FIELD_MODEL_RENDER_LEFT_TOP_OFFSET_Y +
                                                                                        (GameFieldViewConsts.FIELD_HEIGHT - modelBall.Center.Y),
                                                                                        0, graphicsBind.BlendColor, 1, 1, 1, EHorizontalAlign.Middle, EVerticalAlign.Middle)));
                    }

                    if (_playerScoreAndLifeCounter == null)
                    {
                        _playerScoreAndLifeCounter = new LinkedList <RenderingData.RenderingData?>();
                    }

                    _playerScoreAndLifeCounter.Clear();

                    //очки
                    _playerScoreAndLifeCounter.AddLast(new RenderingData.RenderingData(new RenderingString(1,
                                                                                                           SCORE_RIGHT_X_OFFSET,
                                                                                                           SCORE_TOP_Y_OFFSET, _modelProviderComponent.ActualPlayer.Score.ToString(),
                                                                                                           ActualSubassetsDataLibrary.GetFont(ViewBehaviourConsts.RED_SHADOW_APP_FONT), Color.White, 1, 1,
                                                                                                           EHorizontalAlign.Right, EVerticalAlign.Top)));

                    //счетчик жизней
                    int line1Lifes = 0;
                    int line2Lifes = 0;

                    int actualPlayerLifesNumber = _modelProviderComponent.ActualPlayer.LifeCount / 2 +
                                                  _modelProviderComponent.ActualPlayer.LifeCount % 2;
                    bool isLastLifeHalfed = _modelProviderComponent.ActualPlayer.LifeCount % 2 == 1;

                    if (actualPlayerLifesNumber > 2 * LIFES_ON_ONE_LINE)
                    {
                        line1Lifes = LIFES_ON_ONE_LINE;
                        line2Lifes = LIFES_ON_ONE_LINE;
                    }
                    else
                    {
                        if (actualPlayerLifesNumber >= LIFES_ON_ONE_LINE)
                        {
                            line1Lifes = LIFES_ON_ONE_LINE;
                            line2Lifes = actualPlayerLifesNumber - LIFES_ON_ONE_LINE;
                        }
                        else
                        {
                            line1Lifes = actualPlayerLifesNumber;
                            line2Lifes = 0;
                        }
                    }

                    int currentY = LIFECOUNTER_LINE1_START_MIDDLE_Y;
                    int currentX = LIFECOUNTER_LINE1_START_MIDDLE_X;
                    for (int i = 0; i < line1Lifes; i++)
                    {
                        string chosenSpriteKey = LIFE_INDICATOR;

                        if (i == line1Lifes - 1)
                        {
                            if (line2Lifes == 0)
                            {
                                if (isLastLifeHalfed)
                                {
                                    chosenSpriteKey = LIFE_INDICATOR_HALF;
                                }
                            }
                        }


                        _playerScoreAndLifeCounter.AddLast(new RenderingData.RenderingData(new RenderingSprite(
                                                                                               ActualSubassetsDataLibrary.GetSprite(chosenSpriteKey), currentX, currentY, 0, Color.White,
                                                                                               0,
                                                                                               1, 1,
                                                                                               EHorizontalAlign.Middle, EVerticalAlign.Middle)));
                        currentX += LIFECOUNTER_X_ELEM_OFFSET;
                    }


                    currentY += LIFECOUNTER_Y_ELEM_OFFSET;
                    currentX  = LIFECOUNTER_LINE1_START_MIDDLE_X;
                    for (int i = 0; i < line2Lifes; i++)
                    {
                        string chosenSpriteKey = LIFE_INDICATOR;

                        if (i == line2Lifes - 1)
                        {
                            if (isLastLifeHalfed)
                            {
                                chosenSpriteKey = LIFE_INDICATOR_HALF;
                            }
                        }

                        _playerScoreAndLifeCounter.AddLast(new RenderingData.RenderingData(new RenderingSprite(
                                                                                               ActualSubassetsDataLibrary.GetSprite(chosenSpriteKey), currentX, currentY, 0, Color.White,
                                                                                               0,
                                                                                               1, 1,
                                                                                               EHorizontalAlign.Middle, EVerticalAlign.Middle)));
                        currentX += LIFECOUNTER_X_ELEM_OFFSET;
                    }

                    //дальнейший рендеринг зависит от текущего состояния игры
                    if (_playerCueRenderingData == null)
                    {
                        _playerCueRenderingData = new LinkedList <RenderingData.RenderingData?>();
                    }

                    _playerCueRenderingData.Clear();

                    if (_modelProviderComponent.CurrentGameState == EPocketGameState.Aiming)
                    {
                        _upperShotChoosePanelOverlay = null;

                        //прицел
                        SpVector3 whiteBallPosOrigin = _modelProviderComponent.PlayerWhiteBall.Center;
                        whiteBallPosOrigin.X += GameFieldViewConsts.FIELD_MODEL_RENDER_LEFT_TOP_OFFSET_X;
                        whiteBallPosOrigin.Y  = GameFieldViewConsts.FIELD_MODEL_RENDER_LEFT_TOP_OFFSET_Y +
                                                (GameFieldViewConsts.FIELD_HEIGHT - whiteBallPosOrigin.Y);


                        double additionalRotOffset = 0;
                        if (_modelProviderComponent.PlayerCurrentAimingAngle > 10 &&
                            _modelProviderComponent.PlayerCurrentAimingAngle < 80)
                        {
                            additionalRotOffset = ANGLE_ADJUST_TOLERANCE;
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle <= 10 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle > 0)
                        {
                            additionalRotOffset =
                                CustomLerp.GetInterpolatedValue(_modelProviderComponent.PlayerCurrentAimingAngle, 0, 10, 0,
                                                                ANGLE_ADJUST_TOLERANCE);
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle >= 80 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle < 90)
                        {
                            additionalRotOffset =
                                CustomLerp.GetInterpolatedValue(_modelProviderComponent.PlayerCurrentAimingAngle, 80, 90,
                                                                ANGLE_ADJUST_TOLERANCE,
                                                                0);
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle > 100 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle < 170)
                        {
                            additionalRotOffset = -ANGLE_ADJUST_TOLERANCE;
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle > 90 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle <= 100)
                        {
                            additionalRotOffset = -
                                                  CustomLerp.GetInterpolatedValue(_modelProviderComponent.PlayerCurrentAimingAngle, 90, 100, 0,
                                                                                  ANGLE_ADJUST_TOLERANCE);
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle >= 170 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle < 180)
                        {
                            additionalRotOffset = -
                                                  CustomLerp.GetInterpolatedValue(_modelProviderComponent.PlayerCurrentAimingAngle, 170, 180,
                                                                                  ANGLE_ADJUST_TOLERANCE,
                                                                                  0);
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle > 190 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle < 260)
                        {
                            additionalRotOffset = ANGLE_ADJUST_TOLERANCE;
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle > 180 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle <= 190)
                        {
                            additionalRotOffset =
                                CustomLerp.GetInterpolatedValue(_modelProviderComponent.PlayerCurrentAimingAngle, 180, 190, 0,
                                                                ANGLE_ADJUST_TOLERANCE);
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle >= 260 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle < 270)
                        {
                            additionalRotOffset =
                                CustomLerp.GetInterpolatedValue(_modelProviderComponent.PlayerCurrentAimingAngle, 260, 270,
                                                                ANGLE_ADJUST_TOLERANCE,
                                                                0);
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle > 280 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle < 350)
                        {
                            additionalRotOffset = -ANGLE_ADJUST_TOLERANCE;
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle > 270 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle <= 280)
                        {
                            additionalRotOffset = -
                                                  CustomLerp.GetInterpolatedValue(_modelProviderComponent.PlayerCurrentAimingAngle, 270, 280, 0,
                                                                                  ANGLE_ADJUST_TOLERANCE);
                        }
                        else if (_modelProviderComponent.PlayerCurrentAimingAngle >= 350 &&
                                 _modelProviderComponent.PlayerCurrentAimingAngle < 360)
                        {
                            additionalRotOffset = -
                                                  CustomLerp.GetInterpolatedValue(_modelProviderComponent.PlayerCurrentAimingAngle, 350, 360,
                                                                                  ANGLE_ADJUST_TOLERANCE,
                                                                                  0);
                        }


                        _playerCueRenderingData.AddLast(new RenderingData.RenderingData(whiteBallPosOrigin.X + 8,
                                                                                        whiteBallPosOrigin.Y, 100, 1, Color.Bisque, -1,
                                                                                        _modelProviderComponent.GetAngleApproximated() + additionalRotOffset, whiteBallPosOrigin.X,
                                                                                        whiteBallPosOrigin.Y));
                    }
                    else if (_modelProviderComponent.CurrentGameState == EPocketGameState.ChooseShotPower)
                    {
                        _choosingShotAnimationInfobar.CurrentFrame =
                            _modelProviderComponent.GetShotForcePercent() * ANIM_INFOBAR_MAX_FRAME;

                        _choosingShotPlayerCueAnimation.CurrentFrame =
                            _modelProviderComponent.GetShotForcePercent() * ANIM_HANDSHOT_CUE_MAX_FRAME;

                        //панель с информацией о силе удара

                        _upperShotChoosePanelOverlay = new RenderingData.RenderingData(new RenderingSprite(
                                                                                           _choosingShotAnimationInfobar.GetCurrentAnimSpriteFrame(), 145, 1, 0, Color.White, -5, 1,
                                                                                           1));

                        //анимация кия

                        SpVector3 whiteBallPosOrigin = _modelProviderComponent.PlayerWhiteBall.Center;
                        whiteBallPosOrigin.X += GameFieldViewConsts.FIELD_MODEL_RENDER_LEFT_TOP_OFFSET_X;
                        whiteBallPosOrigin.Y  = GameFieldViewConsts.FIELD_MODEL_RENDER_LEFT_TOP_OFFSET_Y +
                                                (GameFieldViewConsts.FIELD_HEIGHT - whiteBallPosOrigin.Y);

                        _playerCueRenderingData.AddLast(new RenderingData.RenderingData(new RenderingSprite(
                                                                                            _choosingShotPlayerCueAnimation.GetCurrentAnimSpriteFrame(), whiteBallPosOrigin.X + 8,
                                                                                            whiteBallPosOrigin.Y + 4, _modelProviderComponent.PlayerCurrentAimingAngle - 180,
                                                                                            Color.White,
                                                                                            -6, 1, 1, EHorizontalAlign.Left, EVerticalAlign.Middle, whiteBallPosOrigin.X,
                                                                                            whiteBallPosOrigin.Y)));
                    }
                }
            }
        }
 /// <summary>
 /// Стандартный конструктор
 /// </summary>
 /// <param name="parBallType">Определенный тип шара</param>
 /// <param name="parStartCenterPosition">Стартовая позиция на столе</param>
 public BallStartConfig(EBallType parBallType, SpVector3 parStartCenterPosition)
 {
     BallType            = parBallType;
     StartCenterPosition = parStartCenterPosition;
 }
示例#20
0
 /// <summary>
 /// Компонент перпендикуляра
 /// </summary>
 /// <param name="parV2"></param>
 /// <returns></returns>
 public SpVector3 PerpendicularComponent(SpVector3 parV2)
 {
     return(new SpVector3(parV2 - this.ParralelComponent(parV2)));
 }
示例#21
0
 /// <summary>
 /// Останавливает шар
 /// </summary>
 public void ResetMovement()
 {
     Velocity = new SpVector3(0, 0);
     Speed    = 0;
 }
示例#22
0
 /// <summary>
 /// Конструктор, принимающий другой вектор
 /// </summary>
 /// <param name="parV">Другой вектор</param>
 public SpVector3(SpVector3 parV)
 {
     _x = parV._x;
     _y = parV._y;
     _z = parV._z;
 }
示例#23
0
        /// <summary>
        /// Статический конструктор
        /// </summary>
        static GameConsts()
        {
            LinkedList <CollisionLine> collisionLines = new LinkedList <CollisionLine>();

            //низ, левая сторона
            SpVector3 lineNormalBottomLeftSide = new SpVector3(0, 1, 0).Normalize();
            Func <BallModelData, bool> lineCheckFuncBottomLeftSide = parData =>
            {
                if (parData.Center.X + parData.Radius < 32 && parData.Center.X - parData.Radius > 122)
                {
                    return(false);
                }

                if (parData.Center.Y - parData.Radius > 20)
                {
                    return(false);
                }

                return(true);
            };

            collisionLines.AddLast(new CollisionLine(lineNormalBottomLeftSide, lineCheckFuncBottomLeftSide));

            SpVector3 lineNormalBottomRightSide = new SpVector3(0, 1, 0).Normalize();
            Func <BallModelData, bool> lineCheckFuncBottomRightSide = parData =>
            {
                if (parData.Center.X + parData.Radius < 145 && parData.Center.X - parData.Radius > 235)
                {
                    return(false);
                }

                if (parData.Center.Y - parData.Radius > 20)
                {
                    return(false);
                }

                return(true);
            };

            collisionLines.AddLast(new CollisionLine(lineNormalBottomRightSide, lineCheckFuncBottomRightSide));

            SpVector3 lineNormalTopLeftSide = new SpVector3(0, -1, 0).Normalize();
            Func <BallModelData, bool> lineCheckFuncTopLeftSide = parData =>
            {
                if (parData.Center.X + parData.Radius < 32 && parData.Center.X - parData.Radius > 122)
                {
                    return(false);
                }

                if (parData.Center.Y + parData.Radius < FieldHeight - 20)
                {
                    return(false);
                }

                return(true);
            };

            collisionLines.AddLast(new CollisionLine(lineNormalTopLeftSide, lineCheckFuncTopLeftSide));

            SpVector3 lineNormalTopRightSide = new SpVector3(0, -1, 0).Normalize();
            Func <BallModelData, bool> lineCheckFuncTopRightSide = parData =>
            {
                if (parData.Center.X + parData.Radius < 145 && parData.Center.X - parData.Radius > 235)
                {
                    return(false);
                }

                if (parData.Center.Y + parData.Radius < FieldHeight - 20)
                {
                    return(false);
                }

                return(true);
            };

            collisionLines.AddLast(new CollisionLine(lineNormalTopRightSide, lineCheckFuncTopRightSide));

            SpVector3 lineNormalLeftSide = new SpVector3(1, 0, 0).Normalize();
            Func <BallModelData, bool> lineCheckFuncLeftSide = parData =>
            {
                if (parData.Center.X - parData.Radius > 21)
                {
                    return(false);
                }

                if (parData.Center.Y + parData.Radius < 32 && parData.Center.Y - parData.Radius > 128)
                {
                    return(false);
                }

                return(true);
            };

            collisionLines.AddLast(new CollisionLine(lineNormalLeftSide, lineCheckFuncLeftSide));

            SpVector3 lineNormalRightSide = new SpVector3(-1, 0, 0).Normalize();
            Func <BallModelData, bool> lineCheckFuncRightSide = parData =>
            {
                if (parData.Center.X + parData.Radius < FieldWidth - 21)
                {
                    return(false);
                }

                if (parData.Center.Y + parData.Radius < 32 && parData.Center.Y - parData.Radius > 128)
                {
                    return(false);
                }

                return(true);
            };

            collisionLines.AddLast(new CollisionLine(lineNormalRightSide, lineCheckFuncRightSide));


            //низ

            SpVector3 bottomLeftPocketBottomBorderStart = new SpVector3(27, FieldHeight - 143, 0);
            SpVector3 bottomLeftPocketBottomBorderEnd   = new SpVector3(32, FieldHeight - 138, 0);

            collisionLines.AddLast(new CollisionLine(bottomLeftPocketBottomBorderStart,
                                                     bottomLeftPocketBottomBorderEnd, false, true));

            SpVector3 bottomLeftPocketTopBorderStart = new SpVector3(16, FieldHeight - 132, 0);
            SpVector3 bottomLeftPocketTopBorderEnd   = new SpVector3(21, FieldHeight - 127, 0);

            collisionLines.AddLast(new CollisionLine(bottomLeftPocketTopBorderStart,
                                                     bottomLeftPocketTopBorderEnd, true, false));

            SpVector3 bottomMiddlePocketRightBorderStart = new SpVector3(142, FieldHeight - 143, 0);
            SpVector3 bottomMiddlePocketRightBorderEnd   = new SpVector3(145, FieldHeight - 138, 0);

            collisionLines.AddLast(new CollisionLine(bottomMiddlePocketRightBorderStart,
                                                     bottomMiddlePocketRightBorderEnd, false, true));

            SpVector3 bottomMiddlePocketLeftBorderStart = new SpVector3(125, FieldHeight - 143, 0);
            SpVector3 bottomMiddlePocketLeftBorderEnd   = new SpVector3(122, FieldHeight - 138, 0);

            collisionLines.AddLast(new CollisionLine(bottomMiddlePocketLeftBorderStart,
                                                     bottomMiddlePocketLeftBorderEnd, true, true));

            SpVector3 bottomRightPocketBottomBorderStart = new SpVector3(240, FieldHeight - 143, 0);
            SpVector3 bottomRightPocketBottomBorderEnd   = new SpVector3(235, FieldHeight - 138, 0);

            collisionLines.AddLast(new CollisionLine(bottomRightPocketBottomBorderStart,
                                                     bottomRightPocketBottomBorderEnd, true, true));

            SpVector3 bottomRightPocketTopBorderStart = new SpVector3(251, FieldHeight - 132, 0);
            SpVector3 bottomRightPocketTopBorderEnd   = new SpVector3(246, FieldHeight - 127, 0);

            collisionLines.AddLast(new CollisionLine(bottomRightPocketTopBorderStart,
                                                     bottomRightPocketTopBorderEnd, false, false));


            //верх

            SpVector3 topLeftPocketBottomBorderStart = new SpVector3(21, FieldHeight - 32, 0);
            SpVector3 topLeftPocketBottomBorderEnd   = new SpVector3(15, FieldHeight - 26, 0);

            collisionLines.AddLast(new CollisionLine(topLeftPocketBottomBorderStart,
                                                     topLeftPocketBottomBorderEnd, true, true));

            SpVector3 topLeftPocketTopBorderStart = new SpVector3(32, FieldHeight - 21, 0);
            SpVector3 topLeftPocketTopBorderEnd   = new SpVector3(26, FieldHeight - 15, 0);

            collisionLines.AddLast(new CollisionLine(topLeftPocketTopBorderStart,
                                                     topLeftPocketTopBorderEnd, false, false));

            SpVector3 topMiddlePocketRightBorderStart = new SpVector3(145, FieldHeight - 21, 0);
            SpVector3 topMiddlePocketRightBorderEnd   = new SpVector3(142, FieldHeight - 15, 0);

            collisionLines.AddLast(new CollisionLine(topMiddlePocketRightBorderStart,
                                                     topMiddlePocketRightBorderEnd, false, false));

            SpVector3 topMiddlePocketLeftBorderStart = new SpVector3(122, FieldHeight - 21, 0);
            SpVector3 topMiddlePocketLeftBorderEnd   = new SpVector3(125, FieldHeight - 15, 0);

            collisionLines.AddLast(new CollisionLine(topMiddlePocketLeftBorderStart,
                                                     topMiddlePocketLeftBorderEnd, true, false));

            SpVector3 topRightPocketBottomBorderStart = new SpVector3(246, FieldHeight - 32, 0);
            SpVector3 topRightPocketBottomBorderEnd   = new SpVector3(252, FieldHeight - 26, 0);

            collisionLines.AddLast(new CollisionLine(topRightPocketBottomBorderStart,
                                                     topRightPocketBottomBorderEnd, false, true));

            SpVector3 topRightPocketTopBorderStart = new SpVector3(235, FieldHeight - 21, 0);
            SpVector3 topRightPocketTopBorderEnd   = new SpVector3(241, FieldHeight - 15, 0);

            collisionLines.AddLast(new CollisionLine(topRightPocketTopBorderStart,
                                                     topRightPocketTopBorderEnd, true, false));


            StandardGameField = new GameField(268, 160, new Pocket[]
            {
                new Pocket(new SpVector3(16, 16, 0)), new Pocket(new SpVector3(134, 11, 0)),
                new Pocket(new SpVector3(252, 16, 0)),
                new Pocket(new SpVector3(16, 144, 0)), new Pocket(new SpVector3(134, 148, 0)),
                new Pocket(new SpVector3(252, 144, 0))
            }, collisionLines.ToArray());


            //добавляем игровые уровни

            AvailableGameLevels = new List <GameLevel>()
            {
                new GameLevel("Los Angeles", new LevelStartConfig(StandardGameField, new BallStartConfig[]
                {
                    new BallStartConfig(EBallType.Yellow, new SpVector3(90, FieldHeight - 80)),
                    new BallStartConfig(EBallType.Blue,
                                        new SpVector3(90 - BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Red,
                                        new SpVector3(90 - BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Purple,
                                        new SpVector3(90 - BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE * 1))),
                    new BallStartConfig(EBallType.Orange,
                                        new SpVector3(90 - BALLS_SETUP_BASE_DISTANCE * 2, FieldHeight - (80))),
                    new BallStartConfig(EBallType.Green,
                                        new SpVector3(90 - BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE * 1)))
                },
                                                                  new BallStartConfig(EBallType.WhitePlayerBall, StartWhiteBallPlayerPos),
                                                                  EAppMusicAssets.SPLevel1
                                                                  )),
                new GameLevel("Las Vegas", new LevelStartConfig(StandardGameField, new BallStartConfig[]
                {
                    new BallStartConfig(EBallType.Yellow, new SpVector3(100, FieldHeight - 80)),
                    new BallStartConfig(EBallType.Blue,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Red,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Purple,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE * 1))),
                    new BallStartConfig(EBallType.Orange,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 2, FieldHeight - (80))),
                    new BallStartConfig(EBallType.Green,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE * 1))),
                    new BallStartConfig(EBallType.Brown,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 3,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Black,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 3,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Yellow9Ball,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 4,
                                                      FieldHeight - 80))
                },
                                                                new BallStartConfig(EBallType.WhitePlayerBall, StartWhiteBallPlayerPos),
                                                                EAppMusicAssets.SPLevel2)),
                new GameLevel("San Francisco", new LevelStartConfig(StandardGameField, new BallStartConfig[]
                {
                    new BallStartConfig(EBallType.Yellow, new SpVector3(110, FieldHeight - 80)),
                    new BallStartConfig(EBallType.Blue,
                                        new SpVector3(110 - BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Red,
                                        new SpVector3(110 - BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Purple,
                                        new SpVector3(110 - BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE * 1))),
                    new BallStartConfig(EBallType.Orange,
                                        new SpVector3(110 - BALLS_SETUP_BASE_DISTANCE * 2, FieldHeight - (80))),
                    new BallStartConfig(EBallType.Green,
                                        new SpVector3(110 - BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE * 1)))
                },
                                                                    new BallStartConfig(EBallType.WhitePlayerBall, StartWhiteBallPlayerPos), EAppMusicAssets.SPLevel3)),
                new GameLevel("New York", new LevelStartConfig(StandardGameField, new BallStartConfig[]
                {
                    new BallStartConfig(EBallType.Yellow, new SpVector3(80, FieldHeight - 80)),
                    new BallStartConfig(EBallType.Blue,
                                        new SpVector3(80 - DOUBLED_BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 + DOUBLED_BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Red,
                                        new SpVector3(80 - DOUBLED_BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 - DOUBLED_BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Purple,
                                        new SpVector3(80 - DOUBLED_BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 + DOUBLED_BALLS_SETUP_BASE_DISTANCE * 1))),
                    new BallStartConfig(EBallType.Orange,
                                        new SpVector3(80 - DOUBLED_BALLS_SETUP_BASE_DISTANCE * 2, FieldHeight - (80))),
                    new BallStartConfig(EBallType.Green,
                                        new SpVector3(80 - DOUBLED_BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 - DOUBLED_BALLS_SETUP_BASE_DISTANCE * 1)))
                },
                                                               new BallStartConfig(EBallType.WhitePlayerBall, StartWhiteBallPlayerPos), EAppMusicAssets.SPLevel4)),

                new GameLevel("Atlantic City", new LevelStartConfig(StandardGameField, new BallStartConfig[]
                {
                    new BallStartConfig(EBallType.Yellow, new SpVector3(100, FieldHeight - 80)),
                    new BallStartConfig(EBallType.Blue,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Red,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 1,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE / 2 * 1))),
                    new BallStartConfig(EBallType.Purple,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE * 1))),
                    new BallStartConfig(EBallType.Orange,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 2, FieldHeight - (80))),
                    new BallStartConfig(EBallType.Green,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 2,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE * 1))),

                    new BallStartConfig(EBallType.Brown,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 3,
                                                      FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE * 2))),
                    new BallStartConfig(EBallType.Black,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 3, FieldHeight - (80 + BALLS_SETUP_BASE_DISTANCE * 1))),
                    new BallStartConfig(EBallType.Yellow9Ball,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 3,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE * 1))),
                    new BallStartConfig(EBallType.Blue10Ball,
                                        new SpVector3(100 - BALLS_SETUP_BASE_DISTANCE * 3,
                                                      FieldHeight - (80 - BALLS_SETUP_BASE_DISTANCE * 2))),
                },
                                                                    new BallStartConfig(EBallType.WhitePlayerBall, StartWhiteBallPlayerPos),
                                                                    EAppMusicAssets.SPLevel5)),
                new GameLevel("Test Area", new LevelStartConfig(StandardGameField, new BallStartConfig[]
                {
                    new BallStartConfig(EBallType.Yellow, new SpVector3(16, 16, 0)),
                }, new BallStartConfig(EBallType.WhitePlayerBall, StartWhiteBallPlayerPos), EAppMusicAssets.SPLevel1))
            };
        }