public ComputerControlledTank( ISoundManager soundManager, World world, Collection<IDoodad> doodads, Team team, Vector2 position, float rotation, Random random, DoodadFactory doodadFactory, IEnumerable<Waypoint> waypoints) : base(soundManager, world, doodads, team, position, rotation, doodadFactory) { this.world = world; this.random = random; this.states = new Dictionary<Type, ITankState>(); this.states.Add(typeof(MovingState), new MovingState(world, this.Body, this, waypoints, random)); this.states.Add(typeof(AttackingState), new AttackingState(world, this.Body, this)); this.states.Add(typeof(TurningState), new TurningState(this.Body, this)); this.currentState = this.states[typeof(MovingState)]; this.currentState.StateChanged += this.OnStateChanged; this.currentState.NavigateTo(); this.sensor = BodyFactory.CreateBody(world, this.Position); var shape = new CircleShape(6, 0); Fixture sensorFixture = this.sensor.CreateFixture(shape); sensorFixture.Friction = 1f; sensorFixture.IsSensor = true; sensorFixture.CollisionCategories = PhysicsConstants.SensorCategory; sensorFixture.CollidesWith = PhysicsConstants.PlayerCategory | PhysicsConstants.ObstacleCategory | PhysicsConstants.MissileCategory; }
protected override void OnUpdate(GameTime gameTime) { this.sensor.SetTransform(this.Position, this.Rotation); if (!(this.currentState is AttackingState) && this.closestTarget != null && this.closestTarget.Item2 is PlayerControlledTank) { this.Target = (Tank)this.closestTarget.Item2; this.closestTarget = null; this.interruptedState = this.currentState; this.ChangeState(this.states[typeof(AttackingState)]); return; } if (this.currentState is AttackingState && this.closestTarget != null && !(this.closestTarget.Item2 is PlayerControlledTank)) { this.Target = null; this.closestTarget = null; this.ChangeState(this.interruptedState); this.interruptedState = null; } this.elapsedTime += gameTime.ElapsedGameTime; bool isEnemyInRange = false; ContactEdge edge = this.sensor.ContactList; while (edge != null) { if (edge.Contact.IsTouching() && (edge.Contact.FixtureA.Body.UserData is PlayerControlledTank || edge.Contact.FixtureB.UserData is PlayerControlledTank)) { Fixture enemy = edge.Contact.FixtureA.Body.UserData is PlayerControlledTank ? edge.Contact.FixtureA : edge.Contact.FixtureB; isEnemyInRange = true; if (this.elapsedTime.TotalSeconds > 0.1) { this.elapsedTime = TimeSpan.Zero; this.closestTarget = null; this.TryToTargetEnemny(((Tank)enemy.Body.UserData)); } break; } if (edge.Contact.FixtureA.Body.UserData is Missile || edge.Contact.FixtureB.Body.UserData is Missile) { Missile missile = edge.Contact.FixtureA.Body.UserData is Missile ? edge.Contact.FixtureA.Body.UserData as Missile : edge.Contact.FixtureB.Body.UserData as Missile; this.TestForDanger(missile); } edge = edge.Next; } if (!isEnemyInRange && this.currentState is AttackingState) { this.Target = null; this.closestTarget = null; this.ChangeState(this.interruptedState); this.interruptedState = null; } this.currentState.Update(gameTime); }
private void ChangeState(ITankState nextState) { this.currentState.StateChanged -= this.OnStateChanged; this.currentState = nextState; this.currentState.StateChanged += this.OnStateChanged; this.currentState.NavigateTo(); }
public void ChangeState(ITankState newState) { State.Exit(this); State = newState; State.Enter(this); }