public override void Update() { IsDownPrevious = IsDown; IsDown = false; foreach (var actorEntity in Scene.GetEntityListByComponent <StackableActorComponent>()) { var physics = actorEntity.GetComponent <PhysicsComponent>(); var position = actorEntity.GetComponent <PositionComponent>(); physics.Collider.Position = position.Position; physics.Collider.PreviousPosition = position.PreviousPosition; if (CollisionDetector.CheckCollision(_collider, physics.Collider)) { IsDown = true; break; } } if (Pressed) { var position = GetComponent <PositionComponent>(); SoundController.PlaySoundAt(Resources.Sounds.ButtonPress, position.Position); } if (Released) { var position = GetComponent <PositionComponent>(); SoundController.PlaySoundAt(Resources.Sounds.ButtonRelease, position.Position); } }
/// <summary> /// Handles the collision between a laser and a meteor. /// </summary> /// <param name="laser">The laser that may collide.</param> /// <param name="meteor">The meteor that may collide.</param> private void HandleLaserMeteorCollision(Laser laser, Meteor meteor) { if (CollisionDetector.CheckCollision(laser.BoundingRectangle, meteor.BoundingCircle)) { laser.Destroy(); meteor.Damage(laser.Damage); _entityManager.AddEntity(new Explosion(meteor.Position, meteor.BoundingCircle.Radius)); } }
/// <summary> /// Handles the collision between the player and a meteor. /// </summary> /// <param name="player">The player that may collide.</param> /// <param name="meteor">The meteor that may collide.</param> private void HandlePlayerMeteorCollision(Player player, Meteor meteor) { if (CollisionDetector.CheckCollision(player.BoundingCircle, meteor.BoundingCircle)) { player.Damage(1); meteor.Destroy(); _entityManager.AddEntity(new Explosion(meteor.Position, meteor.BoundingCircle.Radius)); } }
public static string CreateCollisionSet(string firstobjects, string secondobjects, double nmDistance) { Station station = Project.ActiveProject as Station; nmDistance = nmDistance / 1000; GraphicComponent a, b; station.GraphicComponents.TryGetGraphicComponent(firstobjects, out a); station.GraphicComponents.TryGetGraphicComponent(secondobjects, out b); Vector3 aPoint, bPoint; CollisionType colType = CollisionDetector.CheckCollision(a, b, nmDistance); switch (colType) { case CollisionType.Collision: Logger.AddMessage(new LogMessage("Part: " + a.Name + " and part: " + b.Name + " is colliding!")); break; case CollisionType.NearMiss: Logger.AddMessage(new LogMessage("There is a near miss between part: " + a.Name + " and part: " + b.Name + ".")); Logger.AddMessage(new LogMessage("The distance between them are: " + CollisionDetector.MinimumDistance(a, b, out aPoint, out bPoint))); Logger.AddMessage(new LogMessage("The closest points are: ")); Logger.AddMessage(new LogMessage("For part: " + a.Name + " x: " + aPoint.x + " y: " + aPoint.y + " z: " + aPoint.z)); Logger.AddMessage(new LogMessage("For part: " + b.Name + " x: " + bPoint.x + " y: " + bPoint.y + " z: " + bPoint.z)); break; case CollisionType.None: Logger.AddMessage(new LogMessage("No collisions!")); break; } CollisionDetector.Collision += new CollisionEventHandler(MyCollisionEventHandler); CollisionSet cs = new CollisionSet(); cs.Name = "CSet"; cs.NearMissDistance = nmDistance; cs.Active = true; station.CollisionSets.Add(cs); cs.FirstGroup.Add(a); cs.SecondGroup.Add(b); CollisionDetector.CheckCollisions(station); CollisionDetector.CheckCollisions(cs); return("Collisionset Created. Checking collisions."); }
public override void Update(List <Component> components) { foreach (FrogEnemyComponent frog in components) { frog.LogicStateMachine.Update(); frog.AttackDelay.Update(); var actor = frog.Owner.GetComponent <StackableActorComponent>(); // Damaging the player. if ( !actor.Crouching && actor.LogicStateMachine.CurrentState == ActorStates.InAir && actor.StackedNext == null ) { var players = SceneMgr.CurrentScene.GetEntityListByComponent <PlayerComponent>(); var physics = frog.Owner.GetComponent <PhysicsComponent>(); foreach (var playerEntity in players) { var player = playerEntity.GetComponent <PlayerComponent>(); var playerActor = playerEntity.GetComponent <StackableActorComponent>(); if (playerActor.Crouching && actor.LogicStateMachine.CurrentState != ActorStates.Stacked) { continue; } var position = frog.Owner.GetComponent <PositionComponent>(); var playerPosition = playerEntity.GetComponent <PositionComponent>(); var playerPhysics = playerEntity.GetComponent <PhysicsComponent>(); // Setting up colliders. physics.Collider.Position = position.Position; physics.Collider.PreviousPosition = position.PreviousPosition; playerPhysics.Collider.Position = playerPosition.Position; playerPhysics.Collider.PreviousPosition = playerPosition.PreviousPosition; // Seting up colliders. if (CollisionDetector.CheckCollision(physics.Collider, playerPhysics.Collider)) { StackableActorSystem.Damage(playerEntity.GetComponent <StackableActorComponent>()); } } } // Damaging the player. } }
private bool tireCollisionWithCar(Vector tirePos, PCar car, out Vector normal, double multR = 1) { CollisionCircle collisionTire = new CollisionCircle(tirePos, game.TireRadius * multR); CollisionRect collisionCar = new CollisionRect(car); CollisionInfo collision = new CollisionInfo(collisionTire, collisionCar); if (CollisionDetector.CheckCollision(collision)) { normal = collision.NormalObj1; return(true); } normal = null; return(false); }
/// <summary> /// Checks collision of a given collider with solid objects. /// </summary> public static Entity CheckCollision(Entity checker, ICollider collider) { // Note that this won't work well, if a lot of solid objects will be constantly created\deleted. // In case of problems, make an overload searching for a new solid list every call. foreach (var solid in _solidEntities) { if (solid != checker) { var otherCollider = solid.GetComponent <SolidComponent>().Collider; var position = solid.GetComponent <PositionComponent>(); otherCollider.Position = position.Position; otherCollider.PreviousPosition = position.PreviousPosition; if (CollisionDetector.CheckCollision(collider, otherCollider)) { return(solid); } } } return(null); }
void OnGround(StateMachine <ActorStates> stateMachine, Entity owner) { var actor = owner.GetComponent <StackableActorComponent>(); var physics = owner.GetComponent <PhysicsComponent>(); var position = owner.GetComponent <PositionComponent>(); // Jumping. if (actor.CanJump && actor.JumpActionPress && !actor.Crouching && !physics.InAir) { Jump(physics, actor); return; } // Jumping. // Falling off. if (physics.InAir) { if (!actor.Jumping) { actor.JumpBufferAlarm.Set(actor.JumpBufferTime); if (actor.Crouching) { // NOTE: This may pose problems if there is not enough room to uncrouch. Uncrouch(position, physics, actor); } } stateMachine.ChangeState(ActorStates.InAir); return; } // Falling off. if (!actor.Crouching && actor.CrouchAction) { Crouch(position, physics, actor); } if (actor.Crouching && !actor.CrouchAction) { // Setting up new collider. var collider = (ICollider)physics.Collider.Clone(); collider.Position = position.Position - Vector2.UnitY * (actor.Height - collider.Size.Y) / 2; collider.PreviousPosition = collider.Position; collider.Size = new Vector2(collider.Size.X, actor.Height); // Setting up new collider. // If a solid is above actor - keep crouching. if (PhysicsSystem.CheckCollision(actor.Owner, collider) == null) { Uncrouch(position, physics, actor); var stackables = SceneMgr.CurrentScene.GetEntityListByComponent <StackableActorComponent>(); physics.Collider.Position = position.Position; physics.Collider.PreviousPosition = position.PreviousPosition; foreach (var other in stackables) { if (other != owner && other.Enabled) { var otherPosition = other.GetComponent <PositionComponent>(); var otherPhysics = other.GetComponent <PhysicsComponent>(); var otherActor = other.GetComponent <StackableActorComponent>(); otherPhysics.Collider.Position = otherPosition.Position; otherPhysics.Collider.PreviousPosition = otherPosition.PreviousPosition; if ( CollisionDetector.CheckCollision(physics.Collider, otherPhysics.Collider) && otherActor.LogicStateMachine.CurrentState == ActorStates.OnGround ) { StackEntity(actor, otherActor); } } } } } if (actor.Crouching) { actor.MaxMovementSpeed = actor.CrouchMovementSpeed; actor.Acceleration = actor.CrouchAcceleration; actor.Deceleration = actor.CrouchDeceleration; } else { actor.MaxMovementSpeed = actor.WalkMovementSpeed; actor.Acceleration = actor.GroundAcceleration; actor.Deceleration = actor.GroundDeceleration; } physics.Gravity = actor.FallGravity; UpdateSpeed(actor, physics); }
public override void Update(List <Component> components) { foreach (CatEnemyComponent gato in components) { var physics = gato.Owner.GetComponent <PhysicsComponent>(); var actor = gato.Owner.GetComponent <StackableActorComponent>(); actor.LeftAction = (gato.Direction == -1); actor.RightAction = (gato.Direction == 1); if (actor.LogicStateMachine.CurrentState == ActorStates.OnGround) { var position = gato.Owner.GetComponent <PositionComponent>(); // Checking if there is a wall next to us. physics.Collider.Position = position.Position + Vector2.UnitX * gato.Direction * (physics.Collider.Size.X / 2 + 1); if (physics.CollisionH == gato.Direction) { gato.Direction *= -1; actor.Orientation = gato.Direction; } // Checking if there is a wall next to us. else { // Checking if there is a pit below us. var collider = new RectangleCollider(); collider.Size = Vector2.One; collider.Position = position.Position + (physics.Collider.Size / 2 + Vector2.One) * new Vector2(gato.Direction, 1); if (PhysicsSystem.CheckCollision(gato.Owner, collider) == null) { gato.Direction *= -1; actor.Orientation = gato.Direction; } // Checking if there is a pit below us. } } // Damaging the player. if ( ( actor.StackOwner == null || ( actor.StackOwner != null && !actor.StackOwner.HasComponent <PlayerComponent>() ) ) && actor.LogicStateMachine.CurrentState != ActorStates.Dead ) { var players = SceneMgr.CurrentScene.GetEntityListByComponent <PlayerComponent>(); foreach (var playerEntity in players) { var player = playerEntity.GetComponent <PlayerComponent>(); var playerActor = playerEntity.GetComponent <StackableActorComponent>(); if (playerActor.Crouching && actor.LogicStateMachine.CurrentState != ActorStates.Stacked) { continue; } var position = gato.Owner.GetComponent <PositionComponent>(); var playerPosition = playerEntity.GetComponent <PositionComponent>(); var playerPhysics = playerEntity.GetComponent <PhysicsComponent>(); // Setting up colliders. physics.Collider.Position = position.Position; physics.Collider.PreviousPosition = position.PreviousPosition; playerPhysics.Collider.Position = playerPosition.Position; playerPhysics.Collider.PreviousPosition = playerPosition.PreviousPosition; // Seting up colliders. if (CollisionDetector.CheckCollision(physics.Collider, playerPhysics.Collider)) { StackableActorSystem.Damage(playerEntity.GetComponent <StackableActorComponent>()); } } } // Damaging the player. } }
public override void Update() { var position = GetComponent <PositionComponent>(); if (!_dead) { position.Position += _direction * TimeKeeper.GlobalTime(_speed); _collider.Position = position.Position; _collider.PreviousPosition = position.PreviousPosition; if (!CollisionDetector.CheckCollision(_collider, _myCannon.GetComponent <SolidComponent>().Collider)) { foreach (SolidComponent solid in Scene.GetComponentList <SolidComponent>()) { var solidPosition = solid.Owner.GetComponent <PositionComponent>(); solid.Collider.Position = solidPosition.Position; solid.Collider.PreviousPosition = solidPosition.PreviousPosition; if (CollisionDetector.CheckCollision(_collider, solid.Collider)) { Die(); } } } var actors = SceneMgr.CurrentScene.GetEntityListByComponent <StackableActorComponent>(); foreach (var actorEntity in actors) { var playerActor = actorEntity.GetComponent <StackableActorComponent>(); var playerPosition = actorEntity.GetComponent <PositionComponent>(); var playerPhysics = actorEntity.GetComponent <PhysicsComponent>(); // Setting up colliders. playerPhysics.Collider.Position = playerPosition.Position; playerPhysics.Collider.PreviousPosition = playerPosition.PreviousPosition; // Seting up colliders. if (CollisionDetector.CheckCollision(_collider, playerPhysics.Collider)) { StackableActorSystem.Damage(actorEntity.GetComponent <StackableActorComponent>()); Die(); break; } } } else { _deadSpeed.Y += TimeKeeper.GlobalTime(_deadGravity); position.Position += TimeKeeper.GlobalTime(_deadSpeed); } if (_dead) { var inBounds = false; foreach (var camera in SceneMgr.CurrentScene.GetEntityList <GameCamera>()) { if (camera.InBounds(position.Position)) { inBounds = true; break; } } if (!inBounds) { DestroyEntity(); } } if (_lifetimeAlarm.Update()) { DestroyEntity(); } }
private MoveDirection FindSafestMove(IEnumerable <ShotViewData> allShots, ChickenUnitState unitState) { var safetyCircle = new CirclePrimitive(unitState.Position, _dangerousRadius); var dangerousShots = new List <ShotViewData>(unitState.View.Shots.Count); //// ReSharper disable once LoopCanBeConvertedToQuery foreach (var shot in allShots) { if (unitState.Position.GetDistance(shot.Position) > _tooCloseShot) { continue; } var shotDirection = shot.Angle.ToUnitVector(); var shotToUnitVector = unitState.Position - shot.Position; var angle = shotDirection.GetAngle(shotToUnitVector); if (angle.DegreeValue.Abs() >= MathHelper.QuarterRevolutionDegrees) { continue; } var shotLine = new LinePrimitive( shot.Position, shot.Position + shot.Angle.ToUnitVector() * _boardDiagonalSize); if (CollisionDetector.CheckCollision(shotLine, safetyCircle)) { dangerousShots.Add(shot); } } if (dangerousShots.Count <= 0) { return(null); } var safeMoves = GameHelper.BasicMoveDirections.ToDictionary(item => item, item => 0); foreach (var dangerousShot in dangerousShots) { var shotVector = dangerousShot.Angle.ToUnitVector(); var maxDistanceMove = MoveDirection.None; var maxDistanceSqr = float.MinValue; foreach (var moveDirection in GameHelper.BasicMoveDirections) { var potentialPosition = GameHelper.GetNewPosition( unitState.Position, unitState.BeakAngle, moveDirection, GameConstants.ChickenUnit.DefaultRectilinearSpeed); var shotToUnitVector = potentialPosition - dangerousShot.Position; var shotToUnitVectorLengthSquared = shotToUnitVector.GetLengthSquared(); var angleCosine = shotVector.GetAngleCosine(shotToUnitVector); var distanceSqr = shotToUnitVectorLengthSquared - shotToUnitVectorLengthSquared * angleCosine.Sqr(); if (distanceSqr > maxDistanceSqr) { maxDistanceSqr = distanceSqr; maxDistanceMove = moveDirection; } } safeMoves[maxDistanceMove]++; } var actuallySafeMovePair = safeMoves .Where(pair => pair.Value > 0) .OrderByDescending(pair => pair.Value) .FirstOrDefault(); return(actuallySafeMovePair.Value > 0 ? actuallySafeMovePair.Key : null); }
private bool ProcessChickenUnitMoves(IList <ChickenUnit> aliveChickens) { //// TODO: [vmcl] Use bisection to get conflicting units closer to each other //// TODO: [vmcl] Optimize number of collision checks! //// TODO: [vmcl] Divide move: eg. unit couldn't move but could turn beak or vice versa _moveInfoStates.Clear(); for (var unitIndex = 0; unitIndex < aliveChickens.Count; unitIndex++) { if (IsStopping()) { return(false); } var unit = aliveChickens[unitIndex]; _moveInfoStates[unit] = MoveInfoStates.Handled; var moveInfo = _moveInfos.GetValueOrDefault(unit); if (moveInfo == null) { continue; } DebugHelper.WriteLine( "{0} is processing move {{{1}}} of chicken {{{2}}}.", GetType().Name, moveInfo, unit); var movementAndNewPosition = GameHelper.GetMovementAndNewPosition( unit.Position, unit.BeakAngle, moveInfo.MoveDirection, GameConstants.ChickenUnit.DefaultRectilinearSpeed); var beakMovementAndNewAngle = GameHelper.GetBeakMovementAndNewAngle(unit.BeakAngle, moveInfo.BeakTurn); var newPositionElement = new ChickenElement( movementAndNewPosition.Position, beakMovementAndNewAngle.Position); if (HasOutOfBoardCollision(newPositionElement)) { _moveInfoStates[unit] = MoveInfoStates.RejectedBoardCollision; DebugHelper.WriteLine( "Blocked collision of chicken {{{0}}} with game board border.", unit); continue; } ChickenUnit conflictingChicken = null; // ReSharper disable once LoopCanBeConvertedToQuery // ReSharper disable once ForCanBeConvertedToForeach for (var conflictingIndex = 0; conflictingIndex < aliveChickens.Count; conflictingIndex++) { var aliveChicken = aliveChickens[conflictingIndex]; if (aliveChicken == unit) { continue; } if (CollisionDetector.CheckCollision(newPositionElement, aliveChicken.GetElement())) { conflictingChicken = aliveChicken; break; } } if (conflictingChicken != null) { _moveInfoStates[unit] = MoveInfoStates.RejectedOtherUnitCollision; DebugHelper.WriteLine( "Blocked collision of chicken {{{0}}} with {{{1}}}.", unit, conflictingChicken); continue; } unit.SetMovement(movementAndNewPosition.Movement, beakMovementAndNewAngle.Movement); DebugHelper.WriteLine("Chicken {{{0}}} has moved.", unit); } return(true); }
private void ProcessEngineStep() { var aliveChickens = this.AliveChickens .Where(item => !item.IsDead && item.LogicExecutor.Error == null) .ToList(); _moveInfos.Clear(); _previousMoves.Clear(); for (var logicIndex = 0; logicIndex < _logicExecutors.Count; logicIndex++) { var logic = _logicExecutors[logicIndex]; lock (logic.UnitsMovesLock) { foreach (var pair in logic.UnitsMoves) { _moveInfos.Add(pair.Key, pair.Value); _previousMoves.Add(pair.Key, pair.Value); } } } if (!ProcessChickenUnitMoves(aliveChickens)) { return; } // Processing new shot units var shootingMoves = _moveInfos.Where(item => !item.Key.IsDead && item.Value.FireMode != FireMode.None); ProcessNewShots(shootingMoves); #region Processing Shot Collisions foreach (var shotUnit in _shotUnitsDirect) { var movement = GameHelper.GetMovement( shotUnit.Angle, MoveDirection.MoveForward, GameConstants.ShotUnit.DefaultRectilinearSpeed); shotUnit.SetMovement(movement); DebugHelper.WriteLine("Shot {{{0}}} has moved.", shotUnit); var hasOutOfBoardCollision = HasOutOfBoardCollision(shotUnit.GetElement()); if (hasOutOfBoardCollision) { shotUnit.Exploded = true; DebugHelper.WriteLine("Shot {{{0}}} has exploded outside of game board.", shotUnit); } } var injuredChickens = new List <ChickenUnit>(aliveChickens.Count); for (var index = 0; index < _shotUnitsDirect.Count; index++) { var shotUnit = _shotUnitsDirect[index]; for (var otherIndex = index + 1; otherIndex < _shotUnitsDirect.Count; otherIndex++) { var otherShotUnit = _shotUnitsDirect[otherIndex]; var isCollision = CollisionDetector.CheckCollision( shotUnit.GetElement(), otherShotUnit.GetElement()); if (!isCollision) { continue; } shotUnit.Exploded = true; otherShotUnit.Exploded = true; DebugHelper.WriteLine( "Mutual annihilation of shots {{{0}}} and {{{1}}}.", shotUnit, otherShotUnit); } var shotElement = shotUnit.GetElement(); injuredChickens.Clear(); // ReSharper disable once LoopCanBeConvertedToQuery // ReSharper disable once ForCanBeConvertedToForeach for (var chickenIndex = 0; chickenIndex < aliveChickens.Count; chickenIndex++) { var aliveChicken = aliveChickens[chickenIndex]; if (!aliveChicken.IsDead && CollisionDetector.CheckCollision(shotElement, aliveChicken.GetElement())) { injuredChickens.Add(aliveChicken); } } foreach (var injuredChicken in injuredChickens) { shotUnit.Exploded = true; //// TODO [vmcl] Move out of loop injuredChicken.IsDead = true; injuredChicken.KilledBy = shotUnit.Owner; var suicide = shotUnit.Owner == injuredChicken; if (!suicide) { shotUnit.Owner.KillCount++; } DebugHelper.WriteLine( "Shot {{{0}}} has exploded and killed {{{1}}}{2}.", shotUnit, injuredChicken, suicide ? " [suicide]" : string.Empty); } } #endregion UpdateLastGamePresentation(); _aliveChickensDirect.RemoveAll(item => item.IsDead); _aliveChickensDirect.DoForEach(item => item.ApplyMovement()); _shotUnitsDirect.RemoveAll(item => item.Exploded); _shotUnitsDirect.DoForEach(item => item.ApplyMovement()); var aliveTeams = _aliveChickensDirect.Select(item => item.Team).Distinct().ToList(); if (aliveTeams.Count > 1) { return; } _finalizingStage = true; if (_shotUnitsDirect.Any()) { return; } var winningTeam = aliveTeams.SingleOrDefault(); ChickenUnitLogic winningLogic; switch (winningTeam) { case GameTeam.Light: winningLogic = _lightTeamLogicExecutor.Logic; break; case GameTeam.Dark: winningLogic = _darkTeamLogicExecutor.Logic; break; default: winningLogic = null; break; } RaiseGameEnded(winningTeam, winningLogic); }