예제 #1
0
        /*
         * Populates the collision grid by bucketizing each unit on the map into a cell
         * around which collisions will be processed
         */
        public List<GameUnit>[,] ConstructCollisionGrid(List<GameUnit> units, Level level)
        {
            List<GameUnit>[,] grid = new List<GameUnit>[
                (int)level.Width / CELL_SIZE, (int)level.Height / CELL_SIZE];

            foreach (GameUnit unit in units)
            {
                int x_index = (int)MathHelper.Clamp((unit.Position.X / CELL_SIZE), 0, grid.GetLength(1)-1);
                int y_index = (int)MathHelper.Clamp((unit.Position.Y / CELL_SIZE), 0, grid.GetLength(0)-1);

                if (grid[y_index, x_index] == null)
                {
                    grid[y_index, x_index] = new List<GameUnit>();
                }
                grid[y_index, x_index].Add(unit);
            }
            return grid;
        }
예제 #2
0
        private void UpdateUnit(GameUnit unit, Level level)
        {
            if (!unit.Exists) return;

            // Infection vitality update
            if (unit.Lost)
            {
                unit.InfectionVitality -= INFECTION_RECOVER_SPEED;
                unit.InfectionVitality = MathHelper.Clamp(
                    unit.InfectionVitality, 0, unit.max_infection_vitality);
            }
            else
            {
                unit.InfectionVitality += INFECTION_RECOVER_SPEED;
                unit.InfectionVitality = MathHelper.Clamp(
                    unit.InfectionVitality, 0, unit.max_infection_vitality);
            }
            // If infection vitality is 0, convert the unit, or defeat the boss
            if (unit.InfectionVitality == 0)
            {
                if (unit.Type == UnitType.BOSS)
                {
                    level.BossesDefeated++;
                    unit.Exists = false;
                }
                else
                {
                    ConvertedUnits.Add(unit);
                }
            }

            // Attack cooldown
            unit.AttackCoolDown = (int)MathHelper.Clamp(
                --unit.AttackCoolDown, 0, ATTACK_COOLDOWN);

            // Apply ally attrition if they are outside of range
            if (unit.Faction == UnitFaction.ALLY && Player != null && !unit.inRange(Player, ALLY_FOLLOW_RANGE))
            {
                unit.Health -= ALLY_ATTRITION;
            }
            // Check health
            if (unit.Health <= 0)
            {
                DeadUnits.Add(unit);
            }
        }
예제 #3
0
        /*
         * Calculates and processes all collisions that occur,
         * using the collision cell optimization structure
         */
        public void Update(List<GameUnit> units, Level level)
        {
            cellGrid = ConstructCollisionGrid(units, level);

            for (int ii = 0; ii < cellGrid.GetLength(0); ii++)
            {
                for (int jj = 0; jj < cellGrid.GetLength(1); jj++)
                {
                    if (cellGrid[ii, jj] != null)
                    {
                        ProcessCollisions(jj, ii, level.Map);
                    }
                }
            }
        }
예제 #4
0
        /*
         * Update all units
         */
        public void Update(Level level, InputController input_controller)
        {
            ConstructCombatGrid(level);

            //Pathfinder.findPath(level.Map, Player.Front, Player.Front, PLAYER_PATHFIND_FIELD_SIZE, true);
            //playerLocationField = Pathfinder.pointLocMap;
            //lostUnits.Clear();

            // Handle player logic
            bool playerFrontBlocked = false;
            if (Player != null)
            {
                playerFrontBlocked =
                    level.Map.rayCastHasObstacle(Player.Position, Player.Front, Map.TILE_SIZE / 3);
                CheckPlayerInput(input_controller);
                moveUnit(Player);
                UpdatePlayer();
            }

            // Handle lost units
            /*
            if (lostUnits.Count != 0)
            {
                GameUnit captain = lostUnits.First();
                captain.Target = Player.Position;
                //findTarget(captain, Player.Position, level.Map, 100);
                foreach (GameUnit unit in lostUnits)
                {
                    if (unit != captain)
                    {
                        unit.Lost = true;
                        unit.Target = captain.Position;
                        unit.NextMove = unit.Target;
                    }
                }
            }*/

            // Execute moves and actions
            foreach (GameUnit unit in Units)
            {
                setNextMove(unit, level, playerFrontBlocked);   // Set next moves
                setVelocity(unit);
                moveUnit(unit);
                ProcessCombat(unit);
                UpdateUnit(unit, level);
            }

            // Convert units
            foreach (GameUnit unit in ConvertedUnits)
            {
                Convert(unit);
            }
            ConvertedUnits.Clear();

            // Dispose of dead units
            foreach (GameUnit unit in DeadUnits)
            {
                if (unit.Type == UnitType.PLAYER)
                {
                    Player.Exists = false;
                    Player = null;
                }
                else Units.Remove(unit);
            }
            DeadUnits.Clear();
        }
예제 #5
0
        /*
         * Construct the combat grid by placing units in cells where
         * they are in range of other cells
         */
        private void ConstructCombatGrid(Level level)
        {
            combatRangeGrid = new List<GameUnit>[
                level.Height / COMBAT_GRID_CELL_SIZE,
                level.Width / COMBAT_GRID_CELL_SIZE];

            foreach (GameUnit unit in Units)
            {
                int x_index = (int)MathHelper.Clamp((unit.Position.X / COMBAT_GRID_CELL_SIZE),
                    0, combatRangeGrid.GetLength(1) - 1);
                int y_index = (int)MathHelper.Clamp((unit.Position.Y / COMBAT_GRID_CELL_SIZE),
                    0, combatRangeGrid.GetLength(0) - 1);

                if (combatRangeGrid[y_index, x_index] == null)
                {
                    combatRangeGrid[y_index, x_index] = new List<GameUnit>();
                }
                combatRangeGrid[y_index, x_index].Add(unit);
            }

            if (Player != null)
            {
                int x_indexp = (int)MathHelper.Clamp((Player.Position.X / COMBAT_GRID_CELL_SIZE),
                    0, combatRangeGrid.GetLength(1) - 1);
                int y_indexp = (int)MathHelper.Clamp((Player.Position.Y / COMBAT_GRID_CELL_SIZE),
                    0, combatRangeGrid.GetLength(0) - 1);

                if (combatRangeGrid[y_indexp, x_indexp] == null)
                {
                    combatRangeGrid[y_indexp, x_indexp] = new List<GameUnit>();
                }
                combatRangeGrid[y_indexp, x_indexp].Add(Player);
            }
        }
예제 #6
0
        /*
         * Determine the next move for this unit with
         * targeting specific to each unit type AI
         */
        public void setNextMove(GameUnit unit, Level level, bool playerFrontBlocked)
        {
            if (unit.Position.X < 0 || unit.Position.Y < 0) return;

            Vector2 prev_move = unit.NextMove;

            UnitFaction faction = unit.Faction;     // Unit faction, only called once

            // If an ally unit is lost, do this
            if (faction == UnitFaction.ALLY && unit.Lost)
            {
                if (rand.NextDouble() < 0.01 && Player != null)
                {
                    unit.Target = Player.Position;
                    findTarget(unit, Player.Position, level.Map, MAX_ASTAR_DIST);
                }
                else if(rand.NextDouble() < 0.05)
                {
                    unit.Target = unit.Position + new Vector2(rand.Next(600) - 300, rand.Next(600) - 300);
                    unit.NextMove = unit.Target;
                }
                return;
            }

            // Select target
            bool random_walk = false;
            switch (unit.Type)
            {
                case UnitType.TANK:
                    // tank AI
                    if (Player != null && Player.Exists &&
                        faction == UnitFaction.ENEMY && Player.inRange(unit, ENEMY_CHASE_RANGE))
                    {
                        unit.Target = Player.Position;
                    }
                    else if (rand.NextDouble() < 0.05)
                    {
                        // Random walk
                        random_walk = true;
                        unit.Target = unit.Position + new Vector2(rand.Next(600)-300, rand.Next(600)-300);
                    }

                    if (faction == UnitFaction.ALLY && Player != null)
                    {
                        if (playerFrontBlocked)
                        {
                            unit.Target = Player.Position;
                        }
                        else
                        {
                            unit.Target = Player.Front;
                        }
                    }

                    // Chase the closest enemy in range
                    GameUnit closest = findClosestEnemyInRange(unit, ATTACK_LOCK_RANGE);
                    if (closest != null)
                    {
                        unit.Target = closest.Position;
                        unit.Attacking = closest;
                    }

                    if(faction == UnitFaction.ALLY && Player != null && !Player.inRange(unit, ALLY_FOLLOW_RANGE))
                    {
                        unit.Target = Player.Position;
                    }
                    break;
                case UnitType.RANGED:
                    // ranged AI
                    break;
                case UnitType.FLYING:
                    // flying AI
                    break;
                default:
                    // Player case, do nothing
                    break;
            }

            unit.NextMove = unit.Target;
            if (unit.HasTarget())
            {
                /*
                // If the target is the player, use the player location map
                if (unit.Target.Equals(Player.Position) &&
                    Math.Abs(unit.TilePosition.X - Player.TilePosition.X) +
                    Math.Abs(unit.TilePosition.Y - Player.TilePosition.Y) < PLAYER_PATHFIND_FIELD_SIZE)
                {
                    Vector2 moveToPlayerTile = findMoveToPlayer(unit, level.Map);
                    unit.NextMove = new Vector2(moveToPlayerTile.X * Map.TILE_SIZE,
                        moveToPlayerTile.Y * Map.TILE_SIZE);
                }*/

                // Pathfind to target if necessary

                    if (!random_walk &&
                        level.Map.rayCastHasObstacle(unit.Position, unit.Target, unit.Size / 2))
                    {
                        if (rand.NextDouble() < 0.1)
                        {
                            findTarget(unit, unit.Target, level.Map, MAX_ASTAR_DIST);
                        }
                        else
                        {
                            unit.NextMove = prev_move;
                        }
                    }

            }
        }
예제 #7
0
 /*
  * Initialize units for the specified level
  */
 public void SetLevel(Level level)
 {
     Reset();
     foreach (GameUnit boss in level.Bosses)
     {
         Units.Add(boss);
     }
     Player.Position = level.PlayerStart * Map.TILE_SIZE;
     Player.Health = Player.max_health;
     Player.InfectionPoints = MAX_PLAYER_CONVERSION_POINTS;
 }
예제 #8
0
        public Level loadLevel(int num)
        {
            //return levels[num];

                // TODO Should all be loaded from file
                List<GameUnit> goals = new List<GameUnit>();
                goals.Add(createUnit(UnitType.BOSS, UnitFaction.ENEMY, 1, new Vector2(800, 800), false));
                goals.Add(createUnit(UnitType.BOSS, UnitFaction.ENEMY, 1, new Vector2(1000, 200), false));
                Level level = new Level(2000, 2000, textures[BACKGROUND1], textures[WALL], goals);
                level.PlayerStart = new Vector2(2, 2);
                return level;
        }
예제 #9
0
        /*
         * Calculates and processes all collisions that occur,
         * using the collision cell optimization structure
         */
        public void Update(List<GameUnit> units, Player player, Level level, ItemController item_controller)
        {
            ConstructCollisionGrids(units, item_controller.Items, player, level);

            foreach (GameUnit unit in units)
            {
                ProcessCollisions(unit, level.Map);
            }

            if (player != null)
            {
                ProcessCollisions(player, level.Map);
                ProcessItems(player, item_controller);
            }
        }
예제 #10
0
        /*
         * Populates the collision grid by bucketizing each unit on the map into a cell
         * around which collisions will be processed
         */
        public void ConstructCollisionGrids(List<GameUnit> units, List<Item> items,
            Player player, Level level)
        {
            // Construct unit collision grid
            List<GameUnit>[,] grid = new List<GameUnit>[
                (int)level.Width / CELL_SIZE, (int)level.Height / CELL_SIZE];

            foreach (GameUnit unit in units)
            {
                int x_index = (int)MathHelper.Clamp((unit.Position.X / CELL_SIZE), 0, grid.GetLength(1)-1);
                int y_index = (int)MathHelper.Clamp((unit.Position.Y / CELL_SIZE), 0, grid.GetLength(0)-1);

                if (grid[y_index, x_index] == null)
                {
                    grid[y_index, x_index] = new List<GameUnit>();
                }
                grid[y_index, x_index].Add(unit);
            }

            if (player != null)
            {
                int x_indexp = (int)MathHelper.Clamp((player.Position.X / CELL_SIZE), 0, grid.GetLength(1) - 1);
                int y_indexp = (int)MathHelper.Clamp((player.Position.Y / CELL_SIZE), 0, grid.GetLength(0) - 1);
                if (grid[y_indexp, x_indexp] == null)
                {
                    grid[y_indexp, x_indexp] = new List<GameUnit>();
                }
                grid[y_indexp, x_indexp].Add(player);

                cellGrid = grid;
            }

            // Contruct item collision grid
            itemGrid = new List<Item>[(int)level.Width / CELL_SIZE, (int)level.Height / CELL_SIZE];
            foreach (Item item in items)
            {
                int x_index = (int)MathHelper.Clamp((item.Position.X / CELL_SIZE), 0, grid.GetLength(1) - 1);
                int y_index = (int)MathHelper.Clamp((item.Position.Y / CELL_SIZE), 0, grid.GetLength(0) - 1);

                if (itemGrid[y_index, x_index] == null)
                {
                    itemGrid[y_index, x_index] = new List<Item>();
                }
                itemGrid[y_index, x_index].Add(item);
            }
        }