ZoFo/ZoFo/GameCore/GameManagers/CollisionManager/CollisionManager.cs
2024-08-20 01:15:48 +03:00

238 lines
9.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZoFo.GameCore.GameObjects;
using ZoFo.GameCore.GameManagers.CollisionManager;
using Microsoft.Xna.Framework;
using ZoFo.GameCore.GameManagers.MapManager.MapElements;
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;
namespace ZoFo.GameCore.GameManagers.CollisionManager
{
public class CollisionManager
{
//листики
public List<CollisionComponent> ObjectsWithCollisions;
public List<CollisionComponent> EntitiesWithMovements;
public List<CollisionComponent> ObjectsWithTriggers;
//чекаем коллизии в листе
/// <summary>
/// минимальный накоп изменения перед перевдижением
/// </summary>
const float minimalValueToChange = 0;
public void CheckComponentCollision(CollisionComponent componentOfEntity)
{
//ADD CHECKSPEED TODO
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;
var newRect = currentRect; // задаём значение старого РЕК новому РЕК
if (Math.Abs((int)entity.velocity.X) > minimalValueToChange ) //TODO
{
var collidedX = false; // соприкосновение
var tryingRectX = currentRect;//переменная для попытки перемещения по X
tryingRectX.Offset((int)(entity.velocity.X), 0);//задаём значения для tryingRectX по X и по Y
foreach (var item in ObjectsWithCollisions)//фильтрация
{
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 += (int)entity.velocity.X; //update player position
//entity.position.X = (float)Math.Round(entity.position.X, 2);
newRect.X = tryingRectX.X;//значение по X для нового РЕК приравниваем к значению испытуемого РЕК
}
entity.velocity.X = 0;
}
//==ПОВТОРЯЕМ ТОЖЕ САМОЕ ДЛЯ Y==
var collidedY = false; // соприкосновение
var tryingRectY = currentRect;//переменная для попытки перемещения по X
if (Math.Abs((int)entity.velocity.Y)> minimalValueToChange) //TODO
{
tryingRectY.Offset(new Point(0, (int)entity.velocity.Y));//задаём значения для tryingRectX по X и по Y
foreach (var item in ObjectsWithCollisions)//фильтрация
{
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))
{
collidedY = true;// меняем значение соприкосновения на true
entity.OnCollision(item);//подписываем entity на ивент коллизии
break;// выход
}
}
if (collidedY)// срабатывает, если перемещение блокируется
{
entity.velocity.Y = 0;// задаём значение смещения entity на 0
}
else
{
entity.position.Y += (int)entity.velocity.Y;
//entity.position.Y = (float)Math.Round(entity.position.Y, 2);
newRect.Y = tryingRectY.Y;//значение по X для нового РЕК приравниваем к значению испытуемого РЕК
}
entity.velocity.Y = 0;
}
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
}
public void UpdateTriggerZones(Player player)
{
var entity = player as LivingEntity;
var currentRect = entity.collisionComponent.stopRectangle;//задаём РЕК
currentRect.X += (int)entity.position.X;
currentRect.Y += (int)entity.position.Y;
for (int i = 0; i < ObjectsWithTriggers.Count; i++)
{
int c = ObjectsWithTriggers.Count;
if (ObjectsWithTriggers[i].triggerRectangle.SetOrigin(ObjectsWithTriggers[i].gameObject.position).Intersects(currentRect))
{
ObjectsWithTriggers[i].PlayerInZone(player);
}
i -= c - ObjectsWithTriggers.Count;
}
}
//обновление позиции объекта
public void ResolvePhysics()
{
foreach (var item in EntitiesWithMovements)
{
CheckComponentCollision(item);
}
foreach (var item in AppManager.Instance.server.players)
{
UpdateTriggerZones(item);
}
}
public CollisionManager()
{
EntitiesWithMovements = new List<CollisionComponent>();
ObjectsWithCollisions = new List<CollisionComponent>();
ObjectsWithTriggers = new List<CollisionComponent>();
}
//регистрация компонента(его коллизии)
public void Register(CollisionComponent component)
{
if (component.hasCollision)
ObjectsWithCollisions.Add(component);
if (component.isTrigger)
ObjectsWithTriggers.Add(component);
if (component.gameObject is LivingEntity)
{
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)
{
List<Player> players = new List<Player>();
foreach (var item in AppManager.Instance.server.players)//фильтрация
{
if (item.collisionComponent.stopRectangle.SetOrigin(item.position).Intersects(rectangle))
{
players.Add(item);
}
}
return players.ToArray();
}
public Entity[] GetEntities(Rectangle rectangle, Entity entity)
{
List<Entity> entities = new List<Entity>();
foreach (var item in AppManager.Instance.server.entities)//фильтрация
{
if (item.collisionComponent.stopRectangle.SetOrigin(item.position).Intersects(rectangle))
{
entities.Add(item);
}
}
if (entities.Contains(entity))
entities.Remove(entity);
return entities.ToArray();
}
}
public static class ExtentionClass
{
public static Rectangle SetOrigin(this Rectangle rectangle, Vector2 origin)
{
rectangle.X += (int)origin.X;
rectangle.Y += (int)origin.Y;
return rectangle;
}
}
}