/// <summary> /// Constructor of the <c>EventData_ObjectsCollision</c> class. /// </summary> /// <param name="mObject"><c>MoveableObject</c> that collide with a node.</param> /// <param name="node">Node collisioned with the <c>MoveableObject</c>.</param> /// <param name="direction">Direction of the collision.</param> /// <param name="type">Type of surface collision.</param> /// <param name="addValue">Value to be added to the new position.</param> public EventData_ObjectsCollision(MoveableObject mObject, ref OcTreeNode node, CollisionDirection direction, CollisionSurface type, float addValue) { _eventType = EventManager.EventType_UnitCollision; _addValue = addValue; _direction = direction; _type = type; _node = node; _mObject = mObject; }
/// <summary> /// Check collision of the moveable model with the scene. /// </summary> /// <param name="gameTime">Global time of the game.</param> protected virtual void Collision(GameTime gameTime) { _model.BSphere = ((DrawableModel)_model).GetBoundingSphere(); _model.BSphere = new BoundingSphere(_model.BSphere.Center, 1.0f); //Check down collision Vector3 downPosition = _model.BSphere.Center; downPosition.Y += -_model.BSphere.Radius; OcTreeNode node = _scene.MainLayer.SearchNode(downPosition); if (node != null) { if (node.ModelList[0].Key == NodeType.Staircase1Down || node.ModelList[0].Key == NodeType.Staircase1Up || node.ModelList[0].Key == NodeType.Staircase2Down || node.ModelList[0].Key == NodeType.Staircase2Up) { _speed.Y = 0; EventManager.Trigger(new EventData_ObjectsCollision(this, ref node, EventData_ObjectsCollision.CollisionDirection.Down, EventData_ObjectsCollision.CollisionSurface.Plane)); _downCollision = true; } else if (node.ModelList[0].Key != NodeType.Ladder) { _speed.Y = 0; EventManager.Trigger(new EventData_ObjectsCollision(this, ref node, EventData_ObjectsCollision.CollisionDirection.Down, EventData_ObjectsCollision.CollisionSurface.Box)); _downCollision = true; } } else { _downCollision = false; } foreach (GameLayer2D layer in _scene.Layers2D) { if (DModel.BSphere.Intersects(layer.BoundingPlane) == PlaneIntersectionType.Intersecting) { EventManager.Trigger(new EventData_PlaneCollision(this, layer.BoundingPlane, 0)); break; } } // Check up collision Vector3 upPosition = _model.BSphere.Center; upPosition.Y += _model.BSphere.Radius; node = _scene.MainLayer.SearchNode(upPosition); if (node != null) { if (node.ModelList[0].Key != NodeType.Ladder) { _speed.Y = 0; EventManager.Trigger(new EventData_ObjectsCollision(this, ref node, EventData_ObjectsCollision.CollisionDirection.Up, EventData_ObjectsCollision.CollisionSurface.Box, -_model.BSphere.Radius * 2)); _upCollision = true; } else { _upCollision = false; } } else { _upCollision = false; } // Check left collision Vector3 leftPosition = _model.BSphere.Center; leftPosition.X += -_model.BSphere.Radius / 6.0f; node = _scene.MainLayer.SearchNode(leftPosition); if (node != null) { if (node.ModelList[0].Key == NodeType.None) { _speed.X = 0; EventManager.Trigger(new EventData_ObjectsCollision(this, ref node, EventData_ObjectsCollision.CollisionDirection.Left, EventData_ObjectsCollision.CollisionSurface.Box, _model.BSphere.Radius / 6.0f)); _leftCollision = true; } else { _leftCollision = false; } } else { _leftCollision = false; } // Check right collision Vector3 rightPosition = _model.BSphere.Center; rightPosition.X += _model.BSphere.Radius / 6.0f; node = _scene.MainLayer.SearchNode(rightPosition); if (node != null) { if (node.ModelList[0].Key == NodeType.None) { _speed.X = 0; EventManager.Trigger(new EventData_ObjectsCollision(this, ref node, EventData_ObjectsCollision.CollisionDirection.Right, EventData_ObjectsCollision.CollisionSurface.Box, -(_model.BSphere.Radius / 6.0f) - 0.1f)); _rightCollision = true; } else { _rightCollision = false; } } else { _rightCollision = false; } PreCollision(gameTime); Position = _correctPosition; PostCollision(gameTime); }
/// <summary> /// Update the state of the shots in the <c>ShotManager</c>. /// </summary> /// <param name="gameTime">Global time of the game.</param> public void Update(GameTime gameTime) { foreach (Shot shot in _shots) { shot.Update(gameTime); } // Check that shots are in the global scene List <Shot> aux = new List <Shot>(); foreach (Shot shot in _shots) { if (_scene.MainLayer.RootNode.BoundingBox.Contains(shot.ShotBBox) == ContainmentType.Contains) { aux.Add(shot); } } _shots = aux; // Check collisions with objects in the scene aux = new List <Shot>(); foreach (Shot shot in _shots) { OcTreeNode node = _scene.MainLayer.SearchNode(shot.ShotBBox); if (node == null || node.ModelList[0].Key == NodeType.Ladder) { aux.Add(shot); } } _shots = aux; // Check collisions with enemies aux = new List <Shot>(); List <Shot> aux2 = new List <Shot>(); foreach (Shot shot in _shots) { aux2.Add(shot); } foreach (Enemy enemy in _enemies) { if (enemy.Visible) { foreach (Shot shot in aux2) { if (shot.ShotBBSphere.Intersects(enemy.DModel.BSphere)) { if (!aux.Contains(shot)) { aux.Add(shot); EventManager.Trigger(new EventData_CharactersAttack(_player, enemy)); } } } } } _shots.Clear(); foreach (Shot shot in aux2) { if (!aux.Contains(shot)) { _shots.Add(shot); } } }
protected virtual void Collision(GameTime time) { _model.BSphere = ((DrawableModel)_model).GetBoundingSphere(); //Check down collision Vector3 downPosition = _model.BSphere.Center; downPosition.Y += -_model.BSphere.Radius; OcTreeNode node = _octree.SearchNode(downPosition); Console.WriteLine("SERA ESTO: " + (node == null ? "NULL" : node.ModelList[0].Key.ToString())); if (node != null) { if (node.ModelList[0].Key == NodeType.Staircase1Down || node.ModelList[0].Key == NodeType.Staircase1Up || node.ModelList[0].Key == NodeType.Staircase2Down || node.ModelList[0].Key == NodeType.Staircase2Up) { EventManager.Trigger(new EventData_UnitCollision(this, ref node, EventData_UnitCollision.CollisionDirection.Down, EventData_UnitCollision.CollisionSurface.Plane)); _downCollision = true; } else if (node.ModelList[0].Key != NodeType.Ladder) { EventManager.Trigger(new EventData_UnitCollision(this, ref node, EventData_UnitCollision.CollisionDirection.Down, EventData_UnitCollision.CollisionSurface.Box)); _downCollision = true; } } else { _downCollision = false; } // Check up collision Vector3 upPosition = _model.BSphere.Center; upPosition.Y += _model.BSphere.Radius; node = _octree.SearchNode(upPosition); if (node != null) { if (node.ModelList[0].Key != NodeType.Ladder) { _speed.Y = 0; EventManager.Trigger(new EventData_UnitCollision(this, ref node, EventData_UnitCollision.CollisionDirection.Up, EventData_UnitCollision.CollisionSurface.Box, -_model.BSphere.Radius * 2)); _upCollision = true; } else { _upCollision = false; } } else { _upCollision = false; } // Check left collision Vector3 leftPosition = _model.BSphere.Center; leftPosition.X += -_model.BSphere.Radius / 6.0f; node = _octree.SearchNode(leftPosition); if (node != null) { if (node.ModelList[0].Key == NodeType.None) { _speed.X = 0; EventManager.Trigger(new EventData_UnitCollision(this, ref node, EventData_UnitCollision.CollisionDirection.Left, EventData_UnitCollision.CollisionSurface.Box, _model.BSphere.Radius / 6.0f)); _leftCollision = true; } else { _leftCollision = false; } } else { _leftCollision = false; } // Check right collision Vector3 rightPosition = _model.BSphere.Center; rightPosition.X += _model.BSphere.Radius / 6.0f; node = _octree.SearchNode(rightPosition); if (node != null) { if (node.ModelList[0].Key == NodeType.None) { _speed.X = 0; EventManager.Trigger(new EventData_UnitCollision(this, ref node, EventData_UnitCollision.CollisionDirection.Right, EventData_UnitCollision.CollisionSurface.Box, -(_model.BSphere.Radius / 6.0f) - 0.1f)); _rightCollision = true; } else { _rightCollision = false; } } else { _rightCollision = false; } PreCollision(); Position = _correctPosition; PostCollision(); }
/// <summary> /// Change the result of the collision test before apply the changes. /// </summary> /// <param name="gameTime">Global time of the game.</param> protected override void PreCollision(GameTime gameTime) { base.PreCollision(gameTime); OcTreeNode node; Vector3 checkPosition; float time = (float)(gameTime.ElapsedGameTime.Milliseconds / 1000.0f); if (_startLadder) { if (_playerState != State.Climbing) { EventManager.Trigger(new EventData_UnitStateChanged(this, Player.State.Climbing)); } _speed.X = 0; switch (_playerYDirection) { case YDirection.None: _speed.Y = 0; break; case YDirection.Down: _speed.Y = -MaxSpeed.Y; break; case YDirection.Up: _speed.Y = MaxSpeed.Y; break; } _correctPosition = Position + new Vector3(0, Speed.Y * time, 0); checkPosition = _model.BSphere.Center; checkPosition.Y += -_model.BSphere.Radius + 0.2f; node = _scene.MainLayer.SearchNode(checkPosition); if (node != null && node.ModelList[0].Key == NodeType.None) { EventManager.Trigger(new EventData_ObjectsCollision(this, ref node, EventData_ObjectsCollision.CollisionDirection.Down, EventData_ObjectsCollision.CollisionSurface.Box)); } } else if (_finishLadder) { if (_playerState != State.Climbing) { EventManager.Trigger(new EventData_UnitStateChanged(this, Player.State.Climbing)); } _speed.X = 0; switch (_playerYDirection) { case YDirection.None: _speed.Y = 0; break; case YDirection.Down: _speed.Y = -MaxSpeed.Y; break; case YDirection.Up: _speed.Y = MaxSpeed.Y; break; } _correctPosition = Position + new Vector3(0, Speed.Y * time, 0); checkPosition = _model.BSphere.Center; checkPosition.X += _model.BSphere.Radius / 2f; node = _scene.MainLayer.SearchNode(checkPosition); Vector3 checkPosition2 = _model.BSphere.Center; checkPosition2.X += -_model.BSphere.Radius / 2f; OcTreeNode node2 = _scene.MainLayer.SearchNode(checkPosition2); if (node == null && node2 == null) { _startLadder = false; _climbLadder = false; _finishLadder = false; if (_playerXDirection == XDirection.None) { EventManager.Trigger(new EventData_UnitStateChanged(this, State.Waiting)); ((AnimatedModel)this.DModel).TimeSpeed = 1.0f; ((AnimatedModel)this.DModel).Animation.StartClip("Waiting", true); } else { EventManager.Trigger(new EventData_UnitStateChanged(this, State.Running)); ((AnimatedModel)this.DModel).TimeSpeed = 3.0f; if (_playerYDirection == Player.YDirection.Up) { ((AnimatedModel)this.DModel).Animation.StartClip("RunningD", true); } else { ((AnimatedModel)this.DModel).Animation.StartClip("RunningH", true); } } } } if (_climbLadder) { if (_playerState != State.Climbing) { EventManager.Trigger(new EventData_UnitStateChanged(this, Player.State.Climbing)); } _speed.X = 0; switch (_playerYDirection) { case YDirection.None: _speed.Y = 0; break; case YDirection.Down: _speed.Y = -MaxSpeed.Y; break; case YDirection.Up: _speed.Y = MaxSpeed.Y; break; } _correctPosition = Position + new Vector3(0, (Speed.Y * time), 0); } if (_stopLadder) { if (this.PlayerState != State.Waiting && this.PlayerState != State.Running) { if (_playerXDirection == XDirection.None) { EventManager.Trigger(new EventData_UnitStateChanged(this, State.Waiting)); ((AnimatedModel)this.DModel).TimeSpeed = 1.0f; ((AnimatedModel)this.DModel).Animation.StartClip("Waiting", true); } else { EventManager.Trigger(new EventData_UnitStateChanged(this, State.Running)); ((AnimatedModel)this.DModel).TimeSpeed = 3.0f; if (_playerYDirection == Player.YDirection.Up) { ((AnimatedModel)this.DModel).Animation.StartClip("RunningD", true); } else { ((AnimatedModel)this.DModel).Animation.StartClip("RunningH", true); } } } _stopLadder = false; } if (_doorDetected && !_doorActivated) { //foreach (KeyValuePair<string, KeyValuePair<Vector3, BoundingBox>> door in _scene.MainLayer.Doors) foreach (Door door in _scene.MainLayer.Doors) { //if (door.Value.Value.Contains(_doorBox) != ContainmentType.Disjoint) if (door.boundingBox.Contains(_doorBox) != ContainmentType.Disjoint) { if (CheckObject(door.neededObject)) { _doorActivated = true; EventManager.QueueEvent(new EventData_LevelChanged(door.nextLevel, this, door.nextPosition)); } else { if (_playerXDirection == XDirection.Left || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Left)) { _speed.X = 0; EventManager.Trigger(new EventData_ObjectsCollision(this, ref _door, EventData_ObjectsCollision.CollisionDirection.Left, EventData_ObjectsCollision.CollisionSurface.Box, _model.BSphere.Radius / 6.0f)); } else if (_playerXDirection == XDirection.Right || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Right)) { _speed.X = 0; EventManager.Trigger(new EventData_ObjectsCollision(this, ref _door, EventData_ObjectsCollision.CollisionDirection.Right, EventData_ObjectsCollision.CollisionSurface.Box, -(_model.BSphere.Radius / 6.0f) - 0.1f)); } } } } } }
/// <summary> /// Permits to detect elements in the scene to be considered in the next loop. /// </summary> /// <param name="gameTime">Global time of the game.</param> protected override void PostCollision(GameTime gameTime) { base.PostCollision(gameTime); Vector3 point1, point2, point3; OcTreeNode node1, node2, node3; if (!_startLadder) { // Detect left start ladder if (_playerXDirection == XDirection.Left || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Left)) { point1 = _model.BSphere.Center; point1.X += _model.BSphere.Radius - 0.5f; node1 = _scene.MainLayer.SearchNode(point1); point2 = _model.BSphere.Center; point2.Y += -_model.BSphere.Radius - 0.1f; node2 = _scene.MainLayer.SearchNode(point2); point3 = _model.BSphere.Center; point3.X += _model.BSphere.Radius + 0.5f; node3 = _scene.MainLayer.SearchNode(point3); if (node1 != null && node1.ModelList[0].Key == NodeType.Ladder && node2 != null && node2.ModelList[0].Key == NodeType.None && node3 == null) { _startLadder = true; _climbLadder = false; _finishLadder = false; Vector3 rotation = _model.Rotation; _model.Rotation = new Vector3(MathHelper.ToRadians(270), rotation.Y, rotation.Z); return; } else { if (node1 != null && node1.ModelList[0].Key == NodeType.Ladder && node2 == null && node3 == null) { _startLadder = true; _climbLadder = false; _finishLadder = false; Vector3 rotation = _model.Rotation; _model.Rotation = new Vector3(MathHelper.ToRadians(270), rotation.Y, rotation.Z); return; } else { _startLadder = false; } } } // Detect right start ladder if (_playerXDirection == XDirection.Right || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Right)) { point1 = _model.BSphere.Center; point1.X += -_model.BSphere.Radius + 0.5f; node1 = _scene.MainLayer.SearchNode(point1); point2 = _model.BSphere.Center; point2.Y += -_model.BSphere.Radius - 0.1f; node2 = _scene.MainLayer.SearchNode(point2); point3 = _model.BSphere.Center; point3.X += -_model.BSphere.Radius - 0.5f; node3 = _scene.MainLayer.SearchNode(point3); if (node1 != null && node1.ModelList[0].Key == NodeType.Ladder && node2 != null && node2.ModelList[0].Key == NodeType.None && node3 == null) { _startLadder = true; _climbLadder = false; _finishLadder = false; Vector3 rotation = _model.Rotation; _model.Rotation = new Vector3(MathHelper.ToRadians(90), rotation.Y, rotation.Z); return; } else { if (node1 != null && node1.ModelList[0].Key == NodeType.Ladder && node2 == null && node3 == null) { _startLadder = true; _climbLadder = false; _finishLadder = false; Vector3 rotation = _model.Rotation; _model.Rotation = new Vector3(MathHelper.ToRadians(90), rotation.Y, rotation.Z); return; } else { _startLadder = false; } } } } if (!_climbLadder) { // Detect left climb ladder if (_playerXDirection == XDirection.Left || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Left)) { point1 = _model.BSphere.Center; point1.X += _model.BSphere.Radius - 0.5f; point1.Y += -_model.BSphere.Radius; node1 = _scene.MainLayer.SearchNode(point1); point2 = _model.BSphere.Center; point2.X += _model.BSphere.Radius - 0.5f; point2.Y += _model.BSphere.Radius; node2 = _scene.MainLayer.SearchNode(point2); point3 = _model.BSphere.Center; point3.X += _model.BSphere.Radius + 0.5f; node3 = _scene.MainLayer.SearchNode(point3); if (node1 != null && node1.ModelList[0].Key == NodeType.Ladder && node2 != null && node2.ModelList[0].Key == NodeType.Ladder && node3 == null) { _startLadder = false; _climbLadder = true; _finishLadder = false; return; } else { _climbLadder = false; } } // Detect right climb ladder if (_playerXDirection == XDirection.Right || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Right)) { point1 = _model.BSphere.Center; point1.X += -_model.BSphere.Radius + 0.5f; point1.Y += -_model.BSphere.Radius; node1 = _scene.MainLayer.SearchNode(point1); point2 = _model.BSphere.Center; point2.X += -_model.BSphere.Radius + 0.5f; point2.Y += _model.BSphere.Radius; node2 = _scene.MainLayer.SearchNode(point2); point3 = _model.BSphere.Center; point3.X += -_model.BSphere.Radius - 0.5f; node3 = _scene.MainLayer.SearchNode(point3); if (node1 != null && node1.ModelList[0].Key == NodeType.Ladder && node2 != null && node2.ModelList[0].Key == NodeType.Ladder && node3 == null) { _startLadder = false; _climbLadder = true; _finishLadder = false; return; } else { _climbLadder = false; } } } if (!_finishLadder && _climbLadder) { // Detect left finish ladder if (_playerXDirection == XDirection.Left || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Left)) { point1 = _model.BSphere.Center; point1.X += _model.BSphere.Radius - 0.5f; node1 = _scene.MainLayer.SearchNode(point1); point2 = _model.BSphere.Center; point2.Y += _model.BSphere.Radius; node2 = _scene.MainLayer.SearchNode(point2); point3 = _model.BSphere.Center; point3.X += _model.BSphere.Radius + 1f; node3 = _scene.MainLayer.SearchNode(point3); if (node1 != null && node1.ModelList[0].Key == NodeType.Ladder && node2 == null && node3 == null) { _startLadder = false; _climbLadder = false; _finishLadder = true; return; } else { _finishLadder = false; } } // Detect right finish ladder if (_playerXDirection == XDirection.Right || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Right)) { point1 = _model.BSphere.Center; point1.X += -_model.BSphere.Radius + 0.5f; node1 = _scene.MainLayer.SearchNode(point1); point2 = _model.BSphere.Center; point2.Y += _model.BSphere.Radius; node2 = _scene.MainLayer.SearchNode(point2); point3 = _model.BSphere.Center; point3.X += -_model.BSphere.Radius - 1f; node3 = _scene.MainLayer.SearchNode(point3); if (node1 != null && node1.ModelList[0].Key == NodeType.Ladder && node2 == null && node3 == null) { _startLadder = false; _climbLadder = false; _finishLadder = true; return; } else { _finishLadder = false; } } } if (_startLadder || _climbLadder || _finishLadder) { // Detect left stop ladder if (_playerXDirection == XDirection.Left || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Left)) { point1 = _model.BSphere.Center; point1.X += _model.BSphere.Radius - 0.5f; node1 = _scene.MainLayer.SearchNode(point1); point2 = _model.BSphere.Center; point2.X += -_model.BSphere.Radius - 0.5f; point2.Y += _model.BSphere.Radius / 2f; node2 = _scene.MainLayer.SearchNode(point2); if (node1 == null && node2 == null) { _startLadder = false; _climbLadder = false; _finishLadder = false; _stopLadder = true; } else { _stopLadder = false; } } // Detect right stop ladder if (_playerXDirection == XDirection.Right || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Right)) { point1 = _model.BSphere.Center; point1.X += -_model.BSphere.Radius + 0.5f; node1 = _scene.MainLayer.SearchNode(point1); point2 = _model.BSphere.Center; point2.X += _model.BSphere.Radius + 0.5f; point2.Y += _model.BSphere.Radius / 2f; node2 = _scene.MainLayer.SearchNode(point2); if (node1 == null && node2 == null) { _startLadder = false; _climbLadder = false; _finishLadder = false; _stopLadder = true; } else { _stopLadder = false; } } } //if (!_doorDetected) //{ // Detect left door if (_playerXDirection == XDirection.Left || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Left)) { point1 = _model.BSphere.Center; point1.X += -_model.BSphere.Radius / 6.0f; node1 = _scene.MainLayer.SearchNode(point1); if (node1 != null && node1.ModelList[0].Key == NodeType.Door) { _doorDetected = true; _door = node1; _doorBox = node1.BoundingBox; } else { _doorDetected = false; } } // Detect right door if (_playerXDirection == XDirection.Right || (_playerXDirection == XDirection.None && _lastPlayerXDirection == XDirection.Right)) { point1 = _model.BSphere.Center; point1.X += _model.BSphere.Radius / 6.0f; node1 = _scene.MainLayer.SearchNode(point1); if (node1 != null && node1.ModelList[0].Key == NodeType.Door) { _doorDetected = true; _door = node1; _doorBox = node1.BoundingBox; } else { _doorDetected = false; } } //} }