/// <summary> /// Registers a pea /// </summary> /// <param name="pea"></param> public void Register(DataPea pea) { _peas.Add(pea); _snapshots.Add(pea, new PeaControllerState()); pea.OnRevive += new EventHandler(pea_OnRevive); }
/// <summary> /// Registers a pea /// </summary> /// <param name="pea"></param> public void Register(DataPea pea) { pea.OnSeparation += new OnSeparationEventHandler(pea_OnSeparation); pea.OnJumpStarted += new JumpEventHandler(pea_OnJumpStarted); pea.OnJumpFailed += new JumpEventHandler(pea_OnJumpFailed); pea.OnJumpCompleted += new JumpEventHandler(pea_OnJumpCompleted); }
/// <summary> /// /// </summary> /// <param name="spot"></param> /// <param name="pea"></param> public JumpEventArgs(DataJumpSpot spot, DataPea pea, Int32 points) : base() { this.Spot = spot; this.Pea = pea; this.Points = points; }
/// <summary> /// Finds a path to a jumping spot /// </summary> /// <param name="spot">Spot to jump</param> /// <param name="path">Path</param> /// <returns>Has found</returns> private Boolean FindPath(DataPea pea, DataJumpSpot spot, out Queue <MoveNode> path) { path = new Queue <MoveNode>(); var startNode = new Node <MoveNode>() { Value = GetSnapshot(pea).PreviousNode }; //.Action == MoveNode.Type.None ? new Node<MoveNode>() { Value = new MoveNode() { Position = pea.GridPosition, Action = MoveNode.Type.Walk} } : ; var goalNode = new Node <MoveNode>() { Value = new MoveNode() { Position = new Point(spot.Source.X, spot.Source.Y - 1), Action = MoveNode.Type.Walk } }; var domain = new List <Node <MoveNode> >(); domain.Add(startNode); // Notes: Normally you would build the domain from ALL the walkable places and // have the neighbourghing function run just once for each node. Because that // function is complex, I added it dynamically (runs on reach node). This changes // some of the behavior of A*. Don't forget that... // Debuging Solver <MoveNode> .SolverProgress += new EventHandler <SolverResultEventArgs <MoveNode> >(PeaController_SolverProgress); // Get a path var result = Solver <MoveNode> .Solve( startNode, goalNode, domain, CreateMoveNodesFrom, // This was initialially not in the solver n => Math.Abs(n.Value.Position.X - goalNode.Value.Position.X) + Math.Abs(n.Value.Position.Y - goalNode.Value.Position.Y), n => Math.Abs(n.Value.Position.X - startNode.Value.Position.X) + Math.Abs(n.Value.Position.Y - startNode.Value.Position.X), (n, m) => n.Value.Equals(m.Value), #if DEBUG true #else false #endif ); if (result == null) { path = null; return(false); } foreach (Node <MoveNode> node in result) { path.Enqueue(node.Value); } return(true); }
/// <summary> /// Creates a new sprite pea /// </summary> /// <param name="layer"></param> /// <param name="source"></param> /// <param name="pointsController"></param> public SpritePea(SceneLayer layer, DataPea source, PointsController pointsController) : base(layer) { _source = source; _pointsController = pointsController; _source.OnJumpStarted += new JumpEventHandler(_source_OnJumpStarted); _source.OnJumpCompleted += new JumpEventHandler(_source_OnJumpCompleted); _source.OnJumpFailed += new JumpEventHandler(_source_OnJumpCompleted); _source.OnRevive += new EventHandler(_source_OnRevive); }
/// <summary> /// Is reachable from spot /// </summary> /// <param name="spot"></param> /// <returns></returns> private Boolean IsReachable(DataPea pea, DataJumpSpot spot, out Queue <MoveNode> path) { // Question: Is it worth it to save paths found (need re-evaluation when grid // changes). Should test that later and work from there. if (!FindPath(pea, spot, out path)) { return(false); } return(true); }
/// <summary> /// Process collision /// </summary> /// <param name="pea"></param> /// <param name="speed"></param> /// <param name="block"></param> private void DoHappyCollision(DataPea pea, Vector2 speed, DataBlock block) { PointsControllerState state; if (block != null && !block.IsPlaced) { return; } if ((state = _active.FirstOrDefault(p => p.Pea == pea)) != null) { if (!state.IncreaseHappiness(speed, block)) { pea.Trap(); } } }
/// <summary> /// Finds a jump target for a pea /// <param name="pea"></param> /// </summary> private Boolean FindTarget(DataPea pea) { IEnumerable <Tuple <Boolean, DataJumpSpot, Queue <MoveNode> > > spots = null; //new List<DataJumpSpot>(); for (int y = 0; y < _destinations.Length; y++) { if (_destinations[y].Count > 0) { // See if spots are available to pea and are reachable var potential = _destinations[y].Where(spot => !spot.HasJumped(pea)); spots = potential.Select(spot => { var path = new Queue <MoveNode>(); Boolean r = IsReachable(pea, spot, out path); return(new Tuple <Boolean, DataJumpSpot, Queue <MoveNode> >(r, spot, path)); }).Where(a => a.Item1); //Debug.WriteLine("Found {0} spots for y = {1} reachable", spots.Count(), y); if (spots.Count() > 0) { break; } } } var snapshot = GetSnapshot(pea); // Select a target if (spots != null) { var targets = spots.Where(spot => spot.Item2.Completion == spots.Max(cspot => cspot.Item2.Completion)); var target = targets.Count() > 0 ? targets.ElementAt(DataPea.Random.Next(targets.Count())) : null; if (target != null) { snapshot.Target = target.Item2; // Get the path snapshot.StartPath(target.Item3); } return(target != null); } return(false); }
/// <summary> /// Jumping start /// </summary> /// <param name="pea"></param> /// <param name="gameTime"></param> public void Jump(DataPea pea, GameTime gameTime) { var snapshot = GetSnapshot(pea); var d = (snapshot.Target.Source.Position + Vector2.UnitX * 35 - Vector2.UnitY * 8 - pea.Position); // If not in range of the target, stop jumping if (d.Length() > 5 || !IsValid(snapshot.Target) || ((snapshot.Target.Placement == DataJumpSpot.Location.Left ? (snapshot.Target.Source == null ? snapshot.Target : snapshot.Target.Source.JumpLeft) : (snapshot.Target.Source == null ? snapshot.Target : snapshot.Target.Source.JumpRight)) ?? snapshot.Target).HasJumped(pea)) { // TODO REMOVE JUMPSPOT FROM CANDIDATES snapshot.Target = null; return; } pea.Jump(snapshot.Target); }
/// <summary> /// Is valid path /// </summary> /// <param name="path"></param> /// <returns></returns> private Boolean IsValid(DataPea pea, Queue <MoveNode> path) { // TODO: retry a path from a new position position if (path.Peek().Position != pea.GridPosition) { return(false); } var valid = new Queue <MoveNode>(); // Dummy previous node valid.Enqueue(CreateNode(pea.GridPosition, MoveNode.Type.Walk, MoveNode.Direction.None).Value); while (path.Count > 0) { var node = path.Peek(); // Check validity of a node itself if (!IsValid(node.Position)) { return(false); } // Check validity of moving from to the node if (!IsValid(valid.LastOrDefault(), node)) { return(false); } valid.Enqueue(path.Dequeue()); } // Remove dummy valid.Dequeue(); // Restore path while (valid.Count > 0) { path.Enqueue(valid.Dequeue()); } return(true); }
/// <summary> /// Finds a node to wander /// </summary> /// <param name="pea"></param> /// <returns></returns> protected void FindWanderNode(DataPea pea, Node <MoveNode> prev = null) { var snapshot = GetSnapshot(pea); var block = pea.GridPosition.Y >= 0 ? _grid.Grid[pea.GridPosition.X][pea.GridPosition.Y] : new DataBlock(new Point(pea.GridPosition.X, pea.GridPosition.Y - 1), BlockType.None, null); var node = (prev == null) ? (snapshot.WanderingNode.HasValue && snapshot.WanderingNode.Value.Action != MoveNode.Type.None && snapshot.WanderingNode.Value.Position == pea.GridPosition ? new Node <MoveNode>() { Value = snapshot.WanderingNode.Value } : CreateNode(block, MoveNode.Type.Walk, MoveNode.Direction.None) ) : prev; var possibleNodes = CreateMoveNodesFrom(node); if (possibleNodes.Count > 0) { // Find nodes that go higher (non walk nodes and non lineair jumps) var nonwalk = possibleNodes.Where(a => a.Value.Action != MoveNode.Type.Walk && !((a.Value.Action == MoveNode.Type.Jump) && (a.Value.Dir == MoveNode.Direction.None))); // Limit to these if needed if (nonwalk.Count() > 0) { possibleNodes = nonwalk.ToList(); } else if (DataPea.Random.Next(100) < 10) { snapshot.Wander(node.Value, null); pea.Jump(null); return; } snapshot.Wander(node.Value, possibleNodes[DataPea.Random.Next(possibleNodes.Count)].Value); } else { snapshot.Wander(node.Value, null); pea.Jump(null); } }
/// <summary> /// Registers a pea /// </summary> /// <param name="pea"></param> public void Register(DataPea pea) { if (!_peas.Add(pea)) { return; } pea.OnJumpStarted += new JumpEventHandler(pea_OnJumpStarted); pea.OnJumpCompleted += new JumpEventHandler(pea_OnJumpCompleted); pea.OnJumpFailed += new JumpEventHandler(pea_OnJumpCompleted); pea.OnRevive += new EventHandler(pea_OnRevive); var peabound = _activeSingle.Where(a => a.Value.Scope == Achievement.Times.SingleJump || a.Value.Scope == Achievement.Times.SinglePea || a.Value.Scope == Achievement.Times.MultiplePea); foreach (var achievement in peabound) { _activePea[achievement.Key].Add(pea, achievement.Value.GenerateNew()); } _peaDisabled.Add(pea, new List <Achievement>()); _jumpDisabled.Add(pea, new List <Achievement>()); }
/// <summary> /// Updates a pea /// </summary> /// <param name="gameTime"></param> public void Update(DataPea pea, GameTime gameTime) { if (!this.Enabled) { return; } // If dead, move up if (!pea.IsAlive) { if (!pea.IsDying) { pea.Position -= Vector2.UnitY * (Single)(gameTime.ElapsedGameTime.TotalSeconds * 100 * RunningSpeed); if (pea.Position.Y + 300 + 200 < 0) { pea.Revive(); } } return; } // Update task limiter var snapshot = GetSnapshot(pea); snapshot.UpdateTargetLimit(gameTime, RunningSpeed); // Wait for rehab to pass if (pea.IsRehabilitating) { // If there is still a target if (snapshot.Target != null || !GetSnapshot(pea).WanderingNode.HasValue) { // Update the wandering node to the arrived location if (IsValid(pea.GridPosition)) { var block = pea.GridPosition.Y >= 0 ? _grid.Grid[pea.GridPosition.X][pea.GridPosition.Y] : new DataBlock(new Point(pea.GridPosition.X, pea.GridPosition.Y - 1), BlockType.None, null); var wanderto = CreateNode(block, MoveNode.Type.Walk, MoveNode.Direction.None).Value; snapshot.Wander(wanderto, wanderto); } else { pea.Die(); } snapshot.Target = null; } //pea.Rotation = Math.Min((Single)(Math.PI * 2), pea.Rotation + (Single)gameTime.ElapsedGameTime.TotalSeconds * 5); return; } // If we still can move if (snapshot.HasRemainingPath) { if (UpdateMoveTo(pea, gameTime) && snapshot.Target == null && !snapshot.HasRemainingPath) { FindWanderNode(pea, new Node <MoveNode>() { Value = snapshot.PreviousNode }); } } // else Wander else if (UpdateMoveTo(pea, gameTime)) { // If no target and pathfinding is available. // What I do here is chain the pathfinding tasks so they don't take up so // much CPU. Pathfinding isn't that expensive but I didn't do a great job on it. // Reached wander node so lets find a new path if (snapshot.Target == null) // && (_targetTask == null || _targetTask.IsCompleted) && snapshot.TargetLimit <= 0) //_targetTask = Task.Factory.StartNew(() => FindTarget(pea)).ContinueWith((a) => snapshot.ResetTargetLimit()); { if (snapshot.TargetLimit <= 0) { if (!FindTarget(pea)) { // Also find a new wander node so we can wander while it searches. // when the findTarget function finishes, replaces the nodelist so // the next iteration the movement WILL go to the target FindWanderNode(pea); } snapshot.ResetTargetLimit(); } else { FindWanderNode(pea); } } } }
/// <summary> /// /// </summary> /// <param name="spot"></param> /// <param name="pea"></param> public JumpEventArgs(DataJumpSpot spot, DataPea pea) : base() { this.Spot = spot; this.Pea = pea; }
/// <summary> /// Initializes screen /// </summary> public override void Initialize() { // Create the scene and add it _camera = new Camera2D(this.Game); _camera.Initialize(); _fxcamera = new Camera2D(this.Game); _fxcamera.Initialize(); _scene = new Scene(this.Game, _camera); _scene.TransitionPosition = 0; _scene.TransitionOnTime = TimeSpan.FromSeconds(1); _scene.TransitionOffTime = TimeSpan.FromSeconds(1); _scene.OffTransition(); _fx = new World(Vector2.UnitY * 10); _fxStaticBody = new Body(_fx) { Restitution = 0, Mass = 0, BodyType = BodyType.Static, Friction = 0.5f /*, Position = * ConvertUnits.ToSimUnits(Vector2.UnitX * (_width - DataGrid.WidthInPixels) / 2f + Vector2.UnitY * 150)*/ }; // Create controllers _timeController = new TimeController(this.Game); _pointsController = new PointsController(this.Game); _dataGrid = DataGrid.CreateDataGrid(this.Game, _fxStaticBody, _width / 70 - 1, _height / 49 - 4); _peaController = new PeaController(this.Game); _inputController = new InputController(this.Game); _achievementController = new AchievementController(this.Game); // Initialize controllers _timeController.Initialize(); _pointsController.Initialize(); _dataGrid.Initialize(); _peaController.Initialize(); _inputController.Initialize(); _achievementController.Initialize(); // Register controllers _dataGrid.Register(_peaController); #if DEBUG && _ DataBlock testBlock = _dataGrid.Add(new Point(0, 0), BlockType.Normal); DataBlock testBlock2 = _dataGrid.Add(new Point(0, 1), BlockType.Gel); DataBlock testBlock3 = _dataGrid.Add(new Point(1, 1), BlockType.Normal); DataBlock testBlock4 = _dataGrid.Add(new Point(2, 1), BlockType.RightRamp); DataBlock testBlock5 = _dataGrid.Add(new Point(3, 2), BlockType.Normal); DataBlock testBlock6 = _dataGrid.Add(new Point(DataGrid.Width - 1, DataGrid.Height - 1), BlockType.Normal); #endif // Create the peas DataPea pea1 = new DataPea(this.Game, _fx, _peaController); _pointsController.Register(pea1); _achievementController.Register(pea1); pea1.Initialize(); this.Game.Components.Add(pea1); DataPea pea2 = new DataPea(this.Game, _fx, _peaController); DataPea pea3 = new DataPea(this.Game, _fx, _peaController); DataPea pea4 = new DataPea(this.Game, _fx, _peaController); DataPea pea5 = new DataPea(this.Game, _fx, _peaController); // This needs to be done BEFORE sprites of pea _pointsController.Register(pea2); _pointsController.Register(pea3); _pointsController.Register(pea4); _pointsController.Register(pea5); _achievementController.Register(pea2); _achievementController.Register(pea3); _achievementController.Register(pea4); _achievementController.Register(pea5); pea2.Initialize(); pea3.Initialize(); pea4.Initialize(); pea5.Initialize(); this.Game.Components.Add(pea2); this.Game.Components.Add(pea3); this.Game.Components.Add(pea4); this.Game.Components.Add(pea5); // Create layers _sceneryLayer = new SceneLayer(this.Game, _scene.Camera) { MoveSpeed = 0f, Distance = 0.9f }; _levelLayer = new SceneLayer(this.Game, _scene.Camera) { MoveSpeed = 0f, Distance = 0.6f }; _peasLayer = new SceneLayer(this.Game, _scene.Camera) { MoveSpeed = 0f, Distance = 0.3f }; _hudLayer = new SceneLayer(this.Game, _scene.Camera) { MoveSpeed = 0f, Distance = 0.1f }; // Create sprites _spriteGrid = new SpritesetGrid(_levelLayer) { Position = Vector2.UnitX * (_width - DataGrid.WidthInPixels) / 2f + Vector2.UnitY * 150 }; SpritePea.BaseOffset = _spriteGrid.Position; _peasLayer.Add(new SpritePea(_peasLayer, pea1, _pointsController)); #if !DEBUG || !TEST _peasLayer.Add(new SpritePea(_peasLayer, pea2, _pointsController)); _peasLayer.Add(new SpritePea(_peasLayer, pea3, _pointsController)); _peasLayer.Add(new SpritePea(_peasLayer, pea4, _pointsController)); _peasLayer.Add(new SpritePea(_peasLayer, pea5, _pointsController)); #endif #if DEBUG && TEST for (int i = 0; i < DataGrid.Width; i++) { if (new int[] { 3, 4, 5, 10, 12, 14 }.Contains(i) == false) { DataBlock b = _dataGrid.Add(new Point(i, DataGrid.Height - 1), BlockType.Normal); //_spriteGrid.Add(new SpriteBlock(_levelLayer, b)); if (new int[] { 0, 1, 2, 5, 8, 15 }.Contains(i)) { b = _dataGrid.Add(new Point(i, DataGrid.Height - 2), BlockType.Normal); //_spriteGrid.Add(new SpriteBlock(_levelLayer, b)); } if (new int[] { 0, 15 }.Contains(i)) { b = _dataGrid.Add(new Point(i, DataGrid.Height - 3), BlockType.Gel); //_spriteGrid.Add(new SpriteBlock(_levelLayer, b)); } if (new int[] { 0, 15 }.Contains(i)) { b = _dataGrid.Add(new Point(i, DataGrid.Height - 4), BlockType.Gel); //_spriteGrid.Add(new SpriteBlock(_levelLayer, b)); } } } DataBlock jump = _dataGrid.Add(new Point(3, 7), BlockType.Normal); //_spriteGrid.Add(new SpriteBlock(_levelLayer, jump)); DataBlock ramp = _dataGrid.Add(new Point(1, 8), BlockType.RightRamp); //_spriteGrid.Add(new SpriteBlock(_levelLayer, ramp)); //DataBlock gel = _dataGrid.Add(new Point(5, 10), BlockType.LeftRamp); //_spriteGrid.Add(new SpriteBlock(_levelLayer, gel)); #else // Some boundary blocks _dataGrid.Add(new Point(0, DataGrid.Height - 1), BlockType.Gel); _dataGrid.Add(new Point(DataGrid.Width - 1, DataGrid.Height - 1), BlockType.Gel); _dataGrid.Add(new Point(0, DataGrid.Height - 2), BlockType.Gel); _dataGrid.Add(new Point(DataGrid.Width - 1, DataGrid.Height - 2), BlockType.Gel); #endif SpriteToolbox toolbox = new SpriteToolbox(_hudLayer) { Position = new Vector2(_width - (1280 - 1220), (Single)Math.Ceiling(150 * (_height / 720f))) }; SpritesetHud hud = new SpritesetHud(_hudLayer, _pointsController, _inputController.State, _width, _height); // Register sprites at inputControllers _inputController.Register(_spriteGrid); _inputController.Register(toolbox); _inputController.Register(_camera, _width, _height); foreach (var blockRow in _dataGrid.Grid) { foreach (var block in blockRow) { block.Place(block.BlockType, BlockState.Placed); // Direct placing; _spriteGrid.Add(new SpriteBlock(_levelLayer, block)); } } // Add the layers _scene.Add(_sceneryLayer); _scene.Add(_levelLayer); _scene.Add(_peasLayer); _scene.Add(_hudLayer); // Add the content Sprite background = new Sprite(_sceneryLayer, "Graphics/Background"); background.Position = new Vector2(_width / 2f, _height / 2f); background.Origin = new Vector2(1280f / 2f, 720f / 2f); background.Scale = Math.Max(_width / 1280f, _height / 720f); Sprite splate = new Sprite(_sceneryLayer, "Graphics/Plate"); splate.Position = new Vector2(_width / 2f, _height / 2f); splate.Origin = new Vector2(1280f / 2f, 720f / 2f); splate.Scale = Math.Max(_width / 1280f, _height / 720f); _sceneryLayer.Add(background); _sceneryLayer.Add(splate); _levelLayer.Add(_spriteGrid); _hudLayer.Add(toolbox); _hudLayer.Add(hud); // Bottom plate physics var plate = FixtureFactory.AttachRectangle(ConvertUnits.ToSimUnits(_width), ConvertUnits.ToSimUnits(20), 1f, ConvertUnits.ToSimUnits(Vector2.UnitY * (49 * (DataGrid.Height - 3) + _spriteGrid.Position.Y + 5) + (_width / 2 - _spriteGrid.Position.X) * Vector2.UnitX), _fxStaticBody); plate.Restitution = 0; plate.Friction = 0.5f; // Initializes scene and so on base.Initialize(); _scene.Initialize(); _camera.Position = new Vector2(_width / 2f, _height / 2f); _fxcamera.Position = new Vector2(_width / 2f, _height / 2f) - _spriteGrid.Position; // + ConvertUnits.ToSimUnits(_spriteGrid.Position); _camera.Jump2Target(); _fxcamera.Jump2Target(); #if DEBUG && !SILVERLIGHT view = new DebugViewXNA(_fx); view.AppendFlags(FarseerPhysics.DebugViewFlags.CenterOfMass | FarseerPhysics.DebugViewFlags.DebugPanel | FarseerPhysics.DebugViewFlags.PerformanceGraph | FarseerPhysics.DebugViewFlags.PolygonPoints); #endif // Add components this.Game.Components.Add(_peaController); this.Game.Components.Add(_timeController); this.Game.Components.Add(_inputController); this.Game.Components.Add(_pointsController); this.Game.Components.Add(_achievementController); this.Game.Components.Add(_camera); this.Game.Components.Add(_fxcamera); this.Game.Components.Add(_dataGrid); this.Game.Components.Add(_scene); // Add popups _achievementController.OnCompletedAchievement += new AchievementCompletedHandler(_achievementController_OnCompletedAchievement); // Add overlay _overlay = new PauseOverlay(_camera, _width, _height); _overlay.Exiting += new EventHandler(_overlay_Exiting); // Events this.Exited += new EventHandler(PeaScreen_Exited); this.OnEnabledChanged += new BooleanDelegate(PeaScreen_OnEnabledChanged); this.OnVisibleChanged += new BooleanDelegate(PeaScreen_OnVisibleChanged); // Add end _pointsController.OnReachedGoal += new Action(_pointsController_OnReachedGoal); this.IsEnabled = false; this.IsVisible = false; }
/// <summary> /// Progresses an achievement /// </summary> /// <param name="id"></param> private Boolean Progress(Achievement.Identifier id, DataPea sender = null, Func <Object, Boolean> completion = null, Func <Object, Object> modification = null) { var achievement = _activeSingle[id]; var pea = sender as DataPea; // Get correct achievement and cancel if disabled switch (achievement.Scope) { case Achievement.Times.Single: if (_activeSingle[id].IsCompleted) { return(true); } break; case Achievement.Times.SinglePea: if (_peaDisabled[pea].Contains(achievement)) { return(true); } achievement = _activePea[id][pea]; break; case Achievement.Times.SingleJump: if (_jumpDisabled[pea].Contains(achievement)) { return(true); } achievement = _activePea[id][pea]; break; case Achievement.Times.SingleSession: if (_sessionDisabled.Contains(achievement)) { return(true); } break; case Achievement.Times.MultiplePea: achievement = _activePea[id][pea]; break; } // Process switch (achievement.Type) { case Achievement.ProgressType.Event: achievement.IsCompleted = true; break; case Achievement.ProgressType.Condition: achievement.IsCompleted = completion.Invoke(null); break; case Achievement.ProgressType.Accumulation: if (modification != null) // null if check only { achievement.Progress = modification.Invoke(achievement.Progress); } if (completion != null) // null if update only { achievement.IsCompleted = completion.Invoke(achievement.Progress); } break; } // Determine recreating if (achievement.IsCompleted) { _completed.Add(achievement); OnCompletedAchievement.Invoke(achievement); System.Diagnostics.Debug.WriteLine("Achievement {0} completed [{1} - {2}]", achievement.Id, achievement.Name, achievement.Description); switch (achievement.Scope) { case Achievement.Times.Multiple: _activeSingle[id] = achievement.GenerateNew(); break; case Achievement.Times.MultiplePea: _activePea[id][pea] = achievement.GenerateNew(); break; case Achievement.Times.SingleJump: _activePea[id][pea] = achievement.GenerateNew(); _jumpDisabled[pea].Add(_activePea[id][pea]); break; case Achievement.Times.SingleSession: _activeSingle[id] = achievement.GenerateNew(); _sessionDisabled.Add(_activeSingle[id]); break; case Achievement.Times.SinglePea: _activePea[id][pea] = achievement.GenerateNew(); _peaDisabled[pea].Add(_activePea[id][pea]); break; } } return(achievement.IsCompleted); }
/// <summary> /// /// </summary> /// <param name="id"></param> /// <param name="modification"></param> private Boolean Check(Achievement.Identifier id, Func <Object, Boolean> completion = null, DataPea sender = null) { return(Progress(id, sender, completion)); }
/// <summary> /// /// </summary> /// <param name="id"></param> /// <param name="modification"></param> private void Modify(Achievement.Identifier id, Func <Object, Object> modification, DataPea sender = null) { Progress(id, sender, null, modification); }
/// <summary> /// Used to determine the active jump info /// </summary> /// <param name="pea"></param> /// <returns></returns> public Dictionary <BlockType, Int32> ActiveTimes(DataPea pea) { return(_active.FirstOrDefault(s => s.Pea == pea).Times); }
/// <summary> /// Gets the controller state for a pea /// </summary> /// <param name="pea"></param> /// <returns></returns> protected PeaControllerState GetSnapshot(DataPea pea) { return(_snapshots[pea]); }
/// <summary> /// Update moving towards a goal /// </summary> /// <param name="pea"></param> /// <param name="gameTime"></param> public Boolean UpdateMoveTo(DataPea pea, GameTime gameTime) { if (RunningSpeed <= 0) { return(false); } var snapshot = GetSnapshot(pea); var previousNode = snapshot.PreviousNode; var nextNode = snapshot.HasRemainingPath ? snapshot.CurrentNode : snapshot.WanderingNode.Value; var reached = false; // If no longer valid move if (!IsValid(previousNode, nextNode)) { // Detroy target, node list and so on snapshot.Target = null; snapshot.EndPath(); return(true); } // Branch move action switch (nextNode.Action) { case MoveNode.Type.Round: case MoveNode.Type.Climb: case MoveNode.Type.Wander: case MoveNode.Type.Ramp: var dclimbmovement = (Single)(gameTime.ElapsedGameTime.TotalSeconds * (nextNode.Action == MoveNode.Type.Wander ? 70 : 50)) * RunningSpeed; var dclimb = (nextNode.ScreenPosition - pea.Position); if (dclimb != Vector2.Zero) { var climbdir = Vector2.Normalize(dclimb); var dclimbdt = climbdir * dclimbmovement; dclimbdt = dclimbdt.Length() < dclimb.Length() ? dclimbdt : dclimb; pea.Rotation += (Single)(gameTime.ElapsedGameTime.TotalSeconds * 4) * RunningSpeed * (climbdir).Length() * (nextNode.Dir == MoveNode.Direction.Left ? -1 : 1); pea.Position = pea.Position + dclimbdt; } reached = Math.Abs((dclimb).Length()) < 1f * RunningSpeed; break; /*case MoveNode.Type.Jump: * // TODO: path * var jlength = Math.Abs((nextNode.ScreenPosition - previousNode.ScreenPosition).X); * var djumpmovement = (Single)(gameTime.ElapsedGameTime.TotalSeconds * 2.5f); * snapshot.JumpAmount += djumpmovement / (jlength / 70); * var djumpwalk = (nextNode.ScreenPosition - pea.Position); * var jumpdir = Vector2.Normalize(djumpwalk); * * var jamount = Math.Max(0, Math.Min(1, (1 - Math.Abs(djumpwalk.X) / jlength))); * * if (djumpwalk != Vector2.Zero) * { * pea.Rotation += (Single)(gameTime.ElapsedGameTime.TotalSeconds * 7) * (jumpdir).X; * * * pea.Position = Vector2.Hermite(previousNode.ScreenPosition, -Vector2.UnitY * 50, nextNode.ScreenPosition, Vector2.UnitY * 50 , snapshot.JumpAmount); * * //if (jamount < 0.4f) { * //pea.Position = Vector2.Lerp(pea.Position, nextNode.ScreenPosition - Vector2.UnitY * 60, djumpmovement / (jlength / 70f)); //pea.Position + jumpdir * djumpmovement; * Vector2.CatmullRom(previousNode.ScreenPosition + Vector2.UnitY * 5, * previousNode.ScreenPosition, * nextNode.ScreenPosition, * nextNode.ScreenPosition + Vector2.UnitY * 5, * jamount); * //} else { * //pea.Position = Vector2.Lerp(Vector2.Lerp(nextNode.ScreenPosition, nextNode.ScreenPosition - Vector2.UnitY * 60, 0.8f), * // nextNode.ScreenPosition, jamount + djumpmovement * 0.005f); * //} * * reached = Math.Abs((djumpwalk).Length()) < 0.8f; * * } else { * reached = true; * } * * * if (reached) * snapshot.JumpAmount = 0; * * * break;*/ case MoveNode.Type.None: case MoveNode.Type.Walk: default: var dwalkmovement = (Single)(gameTime.ElapsedGameTime.TotalSeconds * 70) * RunningSpeed; var dwalk = (nextNode.ScreenPosition - pea.Position); var walkdir = Vector2.Normalize(dwalk); if (dwalk != Vector2.Zero) { var dwalkdt = walkdir * dwalkmovement; dwalkdt = dwalkdt.Length() < dwalk.Length() ? dwalkdt : dwalk; pea.Rotation += (Single)(gameTime.ElapsedGameTime.TotalSeconds * 4) * RunningSpeed * (walkdir).X;; pea.Position = pea.Position + dwalkdt; } reached = Math.Abs((dwalk).Length()) < Math.Min(30f, 1f * RunningSpeed); break; } // If reached node, dequeue if (reached) { snapshot.ProgressPath(); } // Jump if reached spot if (!snapshot.HasRemainingPath && snapshot.Target != null) { Jump(pea, gameTime); } return(reached); }