/// <summary> /// Перевод анимации прыгающей сущности в систему координат состояния назначения. /// </summary> /// <param name="animation">Анимация прыгающей сущности</param> /// <param name="destinationState">Состояние назначения</param> /// <returns>Анимация прыгающей сущности в системе координат состояния назначения</returns> private static EntityAnimation ConvertWarpedEntityAnimation( EntityAnimation animation, GameState destinationState) { var oldEntity = animation.Entity; //Перевод координат позиции в начале акта прыгающей сущности в систему координат состояния назначения //Полученная позиция будет находится за верхней границей карты состояния назначения //Она будет являться позицией в начале акта состояния назначения прыгающей сущости var newLocation = ConvertCoordinatesToAnotherState(animation.TargetLocation, destinationState.MapWidth); IEntity newEntity; //Отображение переносимой сущности из сущности родного состояния в эквивалентную сущность в состоянии назначения switch (oldEntity) { case FriendlyLaserShot friendlyLaserShot: newEntity = new EnemyLaserShot(friendlyLaserShot); break; default: throw new ArgumentException( $"Unknown transferring entity {oldEntity.GetType().Name} at location {animation.BeginActLocation}"); } //Получение действия переносимой сущности в состоянии назначения эквивалентного действию в родном состоянии var newAction = newEntity.Act(destinationState, newLocation); return(new EntityAnimation(newEntity, newAction, newLocation)); }
/// <summary> /// Проверка двух сущностей на конфликт между ними. /// </summary> /// <param name="first">Анимация первой сущности</param> /// <param name="second">Анимация второй сущности</param> /// <returns>Конфликтуют ли между собой первая и вторая сущность</returns> private static bool InConflict(EntityAnimation first, EntityAnimation second) { return(Confronted() || Crossed()); //Попали в одинаковую позицию bool Confronted() => first.TargetLocation.Equals(second.TargetLocation) && first.Entity != second.Entity; //Поменялись местами (пересеклись в движении) bool Crossed() => first.TargetLocation.Equals(second.BeginActLocation) && second.TargetLocation.Equals(first.BeginActLocation) && first.Action.DeltaX + second.Action.DeltaX == 0 && first.Action.DeltaY + second.Action.DeltaY == 0; }
/// <summary> /// Обработка конфликта сущности со списком возможных участников конфликта. /// </summary> /// <param name="animation">Анимация рассматриваемой сущности затянутой в конфликт</param> /// <param name="conflictParticipants">Список анимаций возможных участников конфликта</param> /// <returns>Выжила ли рассматриваемая сущность в конфликте со списком возможных участников</returns> private static bool SurvivedInConflictWithParticipants(EntityAnimation animation, List <EntityAnimation> conflictParticipants) { var animationIsAlive = true; //Список анимаций удостоверенных участников конфликта не включающий рассматриваемую сущность var conflictedEntitiesAnimations = conflictParticipants.FindAll(a => InConflict(animation, a)); foreach (var conflictedEntityAnimation in conflictedEntitiesAnimations) { if (animation.Entity.DeadInConflictWith(conflictedEntityAnimation.Entity)) { animationIsAlive = false; } } return(animationIsAlive); }
public GameState(int mapHeight = 10, int mapWidth = 11) { if (mapHeight < 2 || mapWidth < 3) { throw new ArgumentException("Map is too small"); } MapHeight = mapHeight; MapWidth = mapWidth; Map = new IEntity[mapHeight, mapWidth]; var playerPosition = new Location(mapHeight - 1, mapWidth / 2); PlayerEntity = new Player(); PlayerAnimation = new EntityAnimation(PlayerEntity, new EntityAction(), playerPosition); Map[playerPosition.Y, playerPosition.X] = PlayerEntity; Animations = new List <EntityAnimation>(); Animations.Add(PlayerAnimation); CommandsFromClient = GameActCommands.IdleCommands; GameOver = false; }