public override bool GameUpdate()
    {
        age += Time.deltaTime;
        Vector3 p = launchPoint + launchVelocity * age;

        p.y -= 0.5f * 9.18f * age * age;//抛物线轨迹,最终落地

        if (p.y <= 0f)
        {
            // TargetPoint.FillBuffer(targetPoint, blastRadius);
            // for (int i = 0; i < TargetPoint.BufferedCount; i++)
            // {
            //  //结算伤害
            //     TargetPoint.GetBuffered(i).Enemy.ApplyDamage(damage);
            // }

            TowerGame.SpawnExplosion().Initialize(targetPoint, blastRadius, damage);
            OriginFactory.Reclaim(this);
            return(false);
        }

        transform.localPosition = p;

        //炮弹与轨道对齐
        Vector3 d = launchVelocity;

        d.y -= 9.81f * age;
        transform.localRotation = Quaternion.LookRotation(d);

        TowerGame.SpawnExplosion().Initialize(p, 0.1f);
        return(true);
    }
    //计算攻击轨迹
    public void Launch(TargetPoint target)
    {
        //起始位置
        Vector3 launchPoint = mortar.position;
        //终点
        Vector3 targetPoint = target.Position;

        targetPoint.y = 0f;
        Vector2 dir;

        dir.x = targetPoint.x - launchPoint.x;
        dir.y = targetPoint.z - launchPoint.z;

        float x = dir.magnitude;//模长
        float y = -launchPoint.y;

        dir /= x;//求单位向量

        //****************公式参考 https://catlikecoding.com/unity/tutorials/tower-defense/ballistics/  ****************
        float g  = 9.81f;
        float s  = launchSpeed;
        float s2 = s * s;

        float r = s2 * s2 - g * (g * x * x + 2f * y * s2);

        Debug.Assert(r >= 0f, "Launch velocity insufficient for range!");
        float tanTheta = (s2 + Mathf.Sqrt(r)) / (g * x);
        float cosTheta = Mathf.Cos(Mathf.Atan(tanTheta));
        float sinTheta = cosTheta * tanTheta;

        //****************************************************************************************************************

        mortar.localRotation = Quaternion.LookRotation(new Vector3(dir.x, tanTheta, dir.y));

        //实例化导弹
        TowerGame.SpawnShell().Initialize(launchPoint, targetPoint, new Vector3(s * cosTheta * dir.x, s * sinTheta, s * cosTheta * dir.y),
                                          shellBlastRadius, shellDamage);


        //==============画线可视化============
        // Vector3 prev = launchPoint, next;
        // for (int i = 1; i <= 10; i++)
        // {
        //     float t = i / 10f;
        //     //x轴上移动的距离:速度*时间
        //     float dx = s * cosTheta * t;
        //     //y轴上抛物线移动的距离:速度*时间 - 0.5 * g * t * t
        //     float dy = s * sinTheta * t - 0.5f * g * t * t;
        //     next = launchPoint + new Vector3(dir.x * dx, dy, dir.y * dx);//阶段抛物线终点
        //     Debug.DrawLine(prev, next, Color.blue, 1f);//持续的画出完整抛物线
        //     prev = next;
        // }

        // //三角形的长度等于从塔底指向目标点的二维矢量的长度
        // Debug.DrawLine(launchPoint, targetPoint, Color.yellow, 1f);
        // //计算在x和z轴上的偏移,与上面黄线构成三角形
        // Debug.DrawLine(new Vector3(launchPoint.x, 0.01f, launchPoint.z),
        //                 new Vector3(launchPoint.x + dir.x * x, 0.01f, launchPoint.z + dir.y * x), Color.white, 1f);
    }
        public void ShouldBeAbleToSolveARealGame()
        {
            //Arrange
            var game = new TowerGame(RandomTower.Peg.MaxDiscs);
            var sut  = CreateSut();

            //Act
            foreach (var move in sut.SolveFromStart(game))
            {
                game.PerformMove(move.From, move.To);
            }
            //Assert
            game.IsGameOver().Should().BeTrue("The game has not been solved");
        }
예제 #4
0
        static void Main(string[] args)
        {
            Console.Write("Enter the number of discs per peg (2 - 18): ");
            var pegSize = int.Parse(Console.ReadLine() ?? "3");

            Console.WriteLine("Choose the solver to run: ");
            var solvers      = FindAllSolvers().ToArray();
            var solverNumber = 0;

            foreach (var solverType in solvers)
            {
                solverNumber++;
                Console.WriteLine($"{solverNumber}: {solverType.FullName}");
            }

            solverNumber = int.Parse(Console.ReadLine() ?? "1");

            var game   = new TowerGame(pegSize);
            var drawer = new ConsoleDrawer();
            var solver = (ISolveTowers)Activator.CreateInstance(solvers[solverNumber - 1]);

            drawer.Draw(game);

            var moves = RunTowerThroughTheSolver(solver, game, drawer);

            if (game.IsGameOver())
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("The Tower has been SOLVED!!!");
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("The Tower has NOT been solved. :(");
            }

            Console.ForegroundColor = ConsoleColor.White;

            var numberOfInvalidMoves = moves.Count(m => !m.Valid);

            Console.WriteLine($"Number of moves: {moves.Count}. Invalid Moves: {numberOfInvalidMoves}.");
            Console.WriteLine("Print the move history? (Y/N)");
            var printAnswer = Console.ReadLine()?.ToUpper() ?? "";

            if (printAnswer == "Y")
            {
                PrintMoveLogToConsole(moves);
            }
        }
 //转CD
 public float Progress(float deltaTime)
 {
     cooldown += deltaTime;
     while (cooldown >= sequence.cooldown)
     {
         cooldown -= sequence.cooldown;
         if (count >= sequence.amount)
         {
             return(cooldown);
         }
         count += 1;
         TowerGame.SpawnEnemy(sequence.factory, sequence.type);
     }
     return(-1f);
 }
예제 #6
0
    public override bool GameUpdate()
    {
        if (Health <= 0f)
        {
            //OriginFactory.Reclaim(this);
            Recycle();
            return(false);
        }

        progress += Time.deltaTime * progressFactor;

        while (progress >= 1f)
        {
            if (tileTo == null)
            {
                TowerGame.EnemyReachedDestination();
                Recycle();
                return(false);
            }

            progress = (progress - 1f) / progressFactor;
            PrepareNextState();
            progress *= progressFactor;
        }

        if (directionChange == DirectionChange.None)
        {
            //不转向,一直往前走
            transform.localPosition = Vector3.LerpUnclamped(positionFrom, positionTo, progress);
        }
        else
        {
            //转向
            float angle = Mathf.LerpUnclamped(directionAngleFrom, directionAngleTo, progress);
            transform.localRotation = Quaternion.Euler(0f, angle, 0f);
        }
        return(true);
    }
예제 #7
0
 void OnEnable()
 {
     instance = this;
 }