From c9c281a4be18e738d9fa246489e96f0f545a06d6 Mon Sep 17 00:00:00 2001 From: SergoDobro Date: Sun, 18 Aug 2024 22:51:47 +0300 Subject: [PATCH] Object delete allowed + minor collision fix --- ZoFo/GameCore/Client.cs | 24 ++- .../CollisionManager/CollisionManager.cs | 146 +++++++++++------- .../Entities/LivingEntities/Enemies/Zombie.cs | 2 +- .../Entities/LivingEntities/LivingEntity.cs | 17 +- .../Entities/LivingEntities/Player/Player.cs | 13 +- ZoFo/GameCore/Server.cs | 12 +- 6 files changed, 141 insertions(+), 73 deletions(-) diff --git a/ZoFo/GameCore/Client.cs b/ZoFo/GameCore/Client.cs index 47fdc88..25ae68c 100644 --- a/ZoFo/GameCore/Client.cs +++ b/ZoFo/GameCore/Client.cs @@ -167,14 +167,22 @@ namespace ZoFo.GameCore { var ent = FindEntityById(update.IdEntity); - ent.position = (update as UpdatePosition).NewPosition; + ent.position = (update as UpdatePosition).NewPosition; } else if (update is UpdateAnimation) + { + var ent = FindEntityById(update.IdEntity); + if (ent != null) + ((ent as Entity).graphicsComponent as AnimatedGraphicsComponent).StartAnimation((update as UpdateAnimation).animationId); + //DebugHUD.Instance.Log("new Animation " + ent.position); + } + else if (update is UpdateGameObjectDeleted) { var ent = FindEntityById(update.IdEntity); - ((ent as Entity).graphicsComponent as AnimatedGraphicsComponent).StartAnimation((update as UpdateAnimation).animationId); - DebugHUD.Instance.Log("new Animation " + ent.position); + if (ent != null) + DeleteObject(ent); + } } @@ -193,6 +201,16 @@ namespace ZoFo.GameCore } return null; } + public void DeleteObject(Entity entity) + { + + if (gameObjects.Contains(entity)) + gameObjects.Remove(entity); + //if (entities.Contains(entity)) + // entities.Remove(entity); + if (players.Contains(entity)) + players.Remove(entity as Player); + } } } \ No newline at end of file diff --git a/ZoFo/GameCore/GameManagers/CollisionManager/CollisionManager.cs b/ZoFo/GameCore/GameManagers/CollisionManager/CollisionManager.cs index f1acc92..fc9ee75 100644 --- a/ZoFo/GameCore/GameManagers/CollisionManager/CollisionManager.cs +++ b/ZoFo/GameCore/GameManagers/CollisionManager/CollisionManager.cs @@ -12,7 +12,7 @@ using ZoFo.GameCore.GameObjects.Entities; using ZoFo.GameCore.GameObjects.Entities.LivingEntities; using ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient; using ZoFo.GameCore.Graphics; -using ZoFo.GameCore.GameObjects.Entities.LivingEntities.Player; +using ZoFo.GameCore.GameObjects.Entities.LivingEntities.Player; namespace ZoFo.GameCore.GameManagers.CollisionManager { @@ -26,107 +26,123 @@ namespace ZoFo.GameCore.GameManagers.CollisionManager //чекаем коллизии в листе + + /// + /// минимальный накоп изменения перед перевдижением + /// + const float minimalValueToChange = 4; public void CheckComponentCollision(CollisionComponent componentOfEntity) { var entity = componentOfEntity.gameObject as LivingEntity; //for (int i = 0; i < ObjectsWithCollisions.Count; i++) //{ var currentRect = entity.collisionComponent.stopRectangle;//задаём РЕК - currentRect.X+=(int)entity.position.X; - currentRect.Y+=(int)entity.position.Y; + currentRect.X += (int)entity.position.X; + currentRect.Y += (int)entity.position.Y; var newRect = currentRect; // задаём значение старого РЕК новому РЕК - var collidedX = false; // соприкосновение - var tryingRectX = currentRect;//переменная для попытки перемещения по X - - tryingRectX.Offset((int)(entity.velocity.X), 0);//задаём значения для tryingRectX по X и по Y - - foreach (var item in ObjectsWithCollisions)//фильтрация + if (Math.Abs((int)entity.velocity.X) > minimalValueToChange ) //TODO { - if (item == componentOfEntity) continue; - - Rectangle rectChecking = item.stopRectangle.SetOrigin(item.gameObject.position); - if (Math.Abs(item.gameObject.position.X - componentOfEntity.gameObject.position.X) < 550 - && Math.Abs(item.gameObject.position.Y - componentOfEntity.gameObject.position.Y) < 550 - && tryingRectX.Intersects(rectChecking)) + var collidedX = false; // соприкосновение + var tryingRectX = currentRect;//переменная для попытки перемещения по X + tryingRectX.Offset((int)(entity.velocity.X), 0);//задаём значения для tryingRectX по X и по Y + + foreach (var item in ObjectsWithCollisions)//фильтрация { - collidedX = true;// меняем значение соприкосновения на true - //entity.OnCollision(item);//подписываем entity на ивент коллизии - item.OnCollisionWithObject(entity); - entity.collisionComponent.OnCollisionWithObject(item.gameObject); - break;// выход + if (item == componentOfEntity) continue; + + Rectangle rectChecking = item.stopRectangle.SetOrigin(item.gameObject.position); + if (Math.Abs(item.gameObject.position.X - componentOfEntity.gameObject.position.X) < 550 + && Math.Abs(item.gameObject.position.Y - componentOfEntity.gameObject.position.Y) < 550 + && tryingRectX.Intersects(rectChecking)) + + { + collidedX = true;// меняем значение соприкосновения на true + //entity.OnCollision(item);//подписываем entity на ивент коллизии + item.OnCollisionWithObject(entity); + entity.collisionComponent.OnCollisionWithObject(item.gameObject); + break;// выход + } } - } - if (collidedX)// срабатывает, если перемещение блокируется - { - entity.velocity.X = 0;// задаём значение смещения entity на 0 - } - else - { - entity.position.X += entity.velocity.X; //update player position - newRect.X = tryingRectX.X;//значение по X для нового РЕК приравниваем к значению испытуемого РЕК - } + if (collidedX)// срабатывает, если перемещение блокируется + { + entity.velocity.X = 0;// задаём значение смещения entity на 0 + } + else + { + entity.position.X += entity.velocity.X; //update player position + newRect.X = tryingRectX.X;//значение по X для нового РЕК приравниваем к значению испытуемого РЕК + } + entity.velocity.X = 0; + } //==ПОВТОРЯЕМ ТОЖЕ САМОЕ ДЛЯ Y== var collidedY = false; // соприкосновение var tryingRectY = currentRect;//переменная для попытки перемещения по X - tryingRectY.Offset(new Point(0, (int)entity.velocity.Y));//задаём значения для tryingRectX по X и по Y - - foreach (var item in ObjectsWithCollisions)//фильтрация + if (Math.Abs((int)entity.velocity.Y)> minimalValueToChange) //TODO { - if (item == componentOfEntity) continue; - Rectangle rectChecking = item.stopRectangle.SetOrigin(item.gameObject.position); - if (Math.Abs(item.gameObject.position.X - componentOfEntity.gameObject.position.X) < 550 - && Math.Abs(item.gameObject.position.Y - componentOfEntity.gameObject.position.Y) < 550 - && tryingRectY.Intersects(rectChecking)) + tryingRectY.Offset(new Point(0, (int)entity.velocity.Y));//задаём значения для tryingRectX по X и по Y + + foreach (var item in ObjectsWithCollisions)//фильтрация { - collidedY = true;// меняем значение соприкосновения на true - entity.OnCollision(item);//подписываем entity на ивент коллизии + if (item == componentOfEntity) continue; + Rectangle rectChecking = item.stopRectangle.SetOrigin(item.gameObject.position); + if (Math.Abs(item.gameObject.position.X - componentOfEntity.gameObject.position.X) < 550 + && Math.Abs(item.gameObject.position.Y - componentOfEntity.gameObject.position.Y) < 550 + && tryingRectY.Intersects(rectChecking)) - break;// выход + { + collidedY = true;// меняем значение соприкосновения на true + entity.OnCollision(item);//подписываем entity на ивент коллизии + + break;// выход + } } + + if (collidedY)// срабатывает, если перемещение блокируется + { + entity.velocity.Y = 0;// задаём значение смещения entity на 0 + } + else + { + entity.position.Y += entity.velocity.Y; + newRect.Y = tryingRectY.Y;//значение по X для нового РЕК приравниваем к значению испытуемого РЕК + } + entity.velocity.Y = 0; } - if (collidedY)// срабатывает, если перемещение блокируется - { - entity.velocity.Y = 0;// задаём значение смещения entity на 0 - } - else - { - entity.position.Y += entity.velocity.Y; - newRect.Y = tryingRectY.Y;//значение по X для нового РЕК приравниваем к значению испытуемого РЕК - } - + entity.graphicsComponent.ObjectDrawRectangle.X = (int)entity.position.X; entity.graphicsComponent.ObjectDrawRectangle.Y = (int)entity.position.Y; AppManager.Instance.server.AddData(new UpdatePosition() { NewPosition = entity.position, IdEntity = entity.Id }); AppManager.Instance.debugHud.Set("testPos", entity.position.ToString()); //TODO remove - entity.velocity = Vector2.Zero; } public void UpdateTriggerZones(Player player) { - var entity = player as LivingEntity; + var entity = player as LivingEntity; var currentRect = entity.collisionComponent.stopRectangle;//задаём РЕК currentRect.X += (int)entity.position.X; currentRect.Y += (int)entity.position.Y; - - - foreach (var item in ObjectsWithTriggers)//фильтрация + + for (int i = 0; i < ObjectsWithTriggers.Count; i++) { - if (item.triggerRectangle.SetOrigin(item.gameObject.position).Intersects(currentRect)) + int c = ObjectsWithTriggers.Count; + + if (ObjectsWithTriggers[i].triggerRectangle.SetOrigin(ObjectsWithTriggers[i].gameObject.position).Intersects(currentRect)) { - item.PlayerInZone(player); + ObjectsWithTriggers[i].PlayerInZone(player); } + i -= c - ObjectsWithTriggers.Count; } } @@ -146,7 +162,7 @@ namespace ZoFo.GameCore.GameManagers.CollisionManager public CollisionManager() - { + { EntitiesWithMovements = new List(); ObjectsWithCollisions = new List(); ObjectsWithTriggers = new List(); @@ -163,6 +179,18 @@ namespace ZoFo.GameCore.GameManagers.CollisionManager EntitiesWithMovements.Add(component); } } + public void Deregister(CollisionComponent component) + { + if (ObjectsWithCollisions.Contains(component)) + ObjectsWithCollisions.Remove(component); + if (ObjectsWithTriggers.Contains(component)) + ObjectsWithTriggers.Remove(component); + if (component.gameObject is LivingEntity) + { + if (EntitiesWithMovements.Contains(component)) + EntitiesWithMovements.Remove(component); + } + } public Player[] GetPlayersInZone(Rectangle rectangle) { diff --git a/ZoFo/GameCore/GameObjects/Entities/LivingEntities/Enemies/Zombie.cs b/ZoFo/GameCore/GameObjects/Entities/LivingEntities/Enemies/Zombie.cs index 4e2ce66..7741cee 100644 --- a/ZoFo/GameCore/GameObjects/Entities/LivingEntities/Enemies/Zombie.cs +++ b/ZoFo/GameCore/GameObjects/Entities/LivingEntities/Enemies/Zombie.cs @@ -25,7 +25,7 @@ namespace ZoFo.GameCore.GameObjects.Entities.LivingEntities.Enemies Vector2 duration = Vector2.Normalize( AppManager.Instance.server.players[0].position - position ); - velocity=new Vector2(duration.X * speed, duration.Y*speed); + velocity+=new Vector2(duration.X * speed, duration.Y*speed); if (Random.Shared.NextDouble() > 0.9) { diff --git a/ZoFo/GameCore/GameObjects/Entities/LivingEntities/LivingEntity.cs b/ZoFo/GameCore/GameObjects/Entities/LivingEntities/LivingEntity.cs index cc6cb9c..c1f95ac 100644 --- a/ZoFo/GameCore/GameObjects/Entities/LivingEntities/LivingEntity.cs +++ b/ZoFo/GameCore/GameObjects/Entities/LivingEntities/LivingEntity.cs @@ -19,6 +19,7 @@ public class LivingEntity : Entity public LivingEntity(Vector2 position) : base(position) { inputManager = new InputManager(); + collisionComponent.hasCollision = true; } public override GraphicsComponent graphicsComponent { get; } = null; @@ -34,7 +35,21 @@ public class LivingEntity : Entity { } - + + public override void UpdateAnimations() + { + base.UpdateAnimations(); + } + Vector2 prevPosition_forClient; + public override void Draw(SpriteBatch spriteBatch) + { + if ((position - prevPosition_forClient).X< 0) + graphicsComponent.Flip = SpriteEffects.FlipHorizontally; + else if((position - prevPosition_forClient).X > 0) + graphicsComponent.Flip = SpriteEffects.None; + base.Draw(spriteBatch); + prevPosition_forClient = position; + } } diff --git a/ZoFo/GameCore/GameObjects/Entities/LivingEntities/Player/Player.cs b/ZoFo/GameCore/GameObjects/Entities/LivingEntities/Player/Player.cs index 84d3e74..0041c90 100644 --- a/ZoFo/GameCore/GameObjects/Entities/LivingEntities/Player/Player.cs +++ b/ZoFo/GameCore/GameObjects/Entities/LivingEntities/Player/Player.cs @@ -29,6 +29,8 @@ public class Player : LivingEntity //InputPlayerRotation = new Vector2(0, 0); graphicsComponent.ObjectDrawRectangle = new Rectangle(0, 0, 100, 100); collisionComponent.stopRectangle = new Rectangle(0, 0, 100, 100); + + StartAnimation("player_look_down"); } @@ -40,17 +42,16 @@ public class Player : LivingEntity float t; public void MovementLogic() { - IsTryingToShoot = true; - StartAnimation("player_look_down");//gslkjfsnblkjsdfnnlkjbn;zkcjnb;kkjnzx;cjkb;kzjxb;kSErgo + IsTryingToShoot = true; //gslkjfsnblkjsdfnnlkjbn;zkcjnb;kkjnzx;cjkb;kzjxb;kSErgo //velocity.X = 3+(float)Math.Sin(t); t++; if (InputPlayerRotation.X > 0.9) { } - if (Keyboard.GetState().IsKeyDown(Keys.D)) velocity.X = 5; - if (Keyboard.GetState().IsKeyDown(Keys.A)) velocity.X = -5; - if (Keyboard.GetState().IsKeyDown(Keys.S)) velocity.Y = 5; - if (Keyboard.GetState().IsKeyDown(Keys.W)) velocity.Y = -5; + if (Keyboard.GetState().IsKeyDown(Keys.D)) velocity.X += 5; + if (Keyboard.GetState().IsKeyDown(Keys.A)) velocity.X += -5; + if (Keyboard.GetState().IsKeyDown(Keys.S)) velocity.Y += 5; + if (Keyboard.GetState().IsKeyDown(Keys.W)) velocity.Y += -5; } public void HandleNewInput(UpdateInput updateInput) { diff --git a/ZoFo/GameCore/Server.cs b/ZoFo/GameCore/Server.cs index 3658bb9..944b098 100644 --- a/ZoFo/GameCore/Server.cs +++ b/ZoFo/GameCore/Server.cs @@ -212,12 +212,18 @@ namespace ZoFo.GameCore /// Удаляет игровой объект /// /// - public void DeleteObject(GameObject gameObject) + public void DeleteObject(Entity entity) { - gameObjects.Remove(gameObject); + if (gameObjects.Contains(entity)) + gameObjects.Remove(entity); + if (entities.Contains(entity)) + entities.Remove(entity); + if (players.Contains(entity)) + players.Remove(entity as Player); AddData(new UpdateGameObjectDeleted() - { GameObjectType = gameObject.GetType().Name} + { GameObjectType = entity.GetType().Name, IdEntity = entity .Id} ); + collisionManager.Deregister(entity.collisionComponent); } }