рдИрд╕реАрдПрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЧреЗрдо рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ: рд╢реВрдЯрд░ рдХреЛ рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдЬреЛрдбрд╝реЗрдВ



рдЪрд▓реЛ рдХрд╛рд▓реАрди рд╕реЗ рдЧрдВрднреАрд░ рдЪреАрдЬреЛрдВ рдХреА рдУрд░ рдмрдврд╝рддреЗ рд╣реИрдВред рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдИрд╕реАрдПрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреА, рдПрдХрддрд╛ рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реЗ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдХреНрдпреЛрдВ рд▓рд┐рдЦрд╛ рд╣реИ (рдЖрдк рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реВрдЪреА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ)ред рдЕрдм рд╣рдо рдЕрдкрдиреЗ рдирдП рдореЛрдмрд╛рдЗрд▓ PvP рд╢реВрдЯрд░ рдореЗрдВ ECS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╣рдо рдЦреЗрд▓ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рд╣рдо рд╕рд░реНрд╡рд░ рдкрд░ рджреБрдирд┐рдпрд╛ рдФрд░ рдЧреНрд░рд╛рд╣рдХ рдкрд░ рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдкреНрд░рдгрд╛рд▓реА рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд┐рдЬрд╝реБрдЕрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдФрд░ рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХреЛ рдПрдорд╡реАрдкреА рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рд▓реЗрдХрд┐рди рдЖрдЬ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВред

рдИрд╕реАрдПрд╕ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдбреЗрдЯрд╛-рдУрд░рд┐рдПрдВрдЯреЗрдб рд╣реИ, рдЧреЗрдо рд╡рд░реНрд▓реНрдб рдХреЗ рд╕рднреА рдбреЗрдЯрд╛ рддрдерд╛рдХрдерд┐рдд рдЧреЗрдорд╕реНрдЯреЗрдЯ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкрд░ рдХреБрдЫ рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрд╕реНрдерд╛рдУрдВ (рд╕рдВрд╕реНрдерд╛рдУрдВ) рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИред рдШрдЯрдХреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдФрд░ рдШрдЯрдХ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рддрд░реНрдХ рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдореЗрдВ рдХреЗрдВрджреНрд░рд┐рдд рд╣реИред

рд╣рдорд╛рд░реЗ рдИрд╕реАрдПрд╕ рдореЗрдВ рдЧреЗрдорд╕реНрдЯреЗрдЯ рдореЗрдВ рджреЛ рднрд╛рдЧ рд╣реЛрддреЗ рд╣реИрдВ: рдирд┐рдпрдордмреБрдХ рдФрд░ рд╡рд░реНрд▓реНрдбрд╕реНрдЯреЗрдЯред рд░реВрд▓рдмреБрдХ рдШрдЯрдХреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ рдЬреЛ рдПрдХ рдореИрдЪ рдХреЗ рджреМрд░рд╛рди рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред рд╕рднреА рд╕реНрдереИрддрд┐рдХ рдбреЗрдЯрд╛ рдХреЛ рд╡рд╣рд╛рдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рд╣рдерд┐рдпрд╛рд░реЛрдВ / рдкрд╛рддреНрд░реЛрдВ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ, рдЯреАрдореЛрдВ рдХреА рд╕рдВрд░рдЪрдирд╛) рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдЧреЗрдо рд╕рд░реНрд╡рд░ рдкрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рджреМрд░рд╛рдиред

рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ: рдПрдХ рдЪрд░рд┐рддреНрд░ рдХреЛ рд╕реНрдкреЙрди рдХрд░реЗрдВ рдФрд░ рджреЛ рдЬреЙрдпрд╕реНрдЯрд┐рдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ 2 рдбреА рд╕реНрдкреЗрд╕ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдШрдЯрдХреЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВред

рдпрд╣ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЪрд░рд┐рддреНрд░ рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ:

[Component] public class Player { } 

рдЕрдЧрд▓рд╛ рдШрдЯрдХ рдПрдХ рдирдпрд╛ рдЪрд░рд┐рддреНрд░ рдмрдирд╛рдиреЗ рдХрд╛ рдЕрдиреБрд░реЛрдз рд╣реИред рдЗрд╕рдореЗрдВ рджреЛ рдлрд╝реАрд▓реНрдб рд╣реЛрддреЗ рд╣реИрдВ: рд╡рд░реНрдг рд╕реНрдкреЙрди рдЯрд╛рдЗрдо (рдЯрд┐рдХ рдореЗрдВ) рдФрд░ рдЗрд╕рдХреА рдЖрдИрдбреА:

 [Component] public class PlayerSpawnRequest { public int SpawnTime; public unit PlayerId; } 

рдЕрдВрддрд░рд┐рдХреНрд╖ рдореЗрдВ рд╡рд╕реНрддреБ рдХреЗ рдЙрдиреНрдореБрдЦреАрдХрд░рдг рдХрд╛ рдШрдЯрдХ:

 [Component] public class Transform { public Vector2 Position; public float Rotation; } 

рдШрдЯрдХ рдЬреЛ рд╡рд╕реНрддреБ рдХреА рд╡рд░реНрддрдорд╛рди рдЧрддрд┐ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ:

 [Component] public class Movement { public Vector2 Velocity; public float RotateToAngle; } 

рдШрдЯрдХ рдЬреЛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рдЗрдирдкреБрдЯ (рдЧрддрд┐ рдЬреЙрдпрд╕реНрдЯрд┐рдХ рд╡реЗрдХреНрдЯрд░ рдФрд░ рдЪрд░рд┐рддреНрд░ рд░реЛрдЯреЗрд╢рди рдЬреЙрдпрд╕реНрдЯрд┐рдХ рд╡реЗрдХреНрдЯрд░) рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ:

 [Component] public class Input { public Vector2 MoveVector; public Vector2 RotateVector; } 

рдЪрд░рд┐рддреНрд░ рдХреА рд╕реНрдерд┐рд░ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдШрдЯрдХ (рдпрд╣ рдирд┐рдпрдордмреБрдХ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рдмреБрдирд┐рдпрд╛рджреА рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ рдФрд░ рдЧреЗрдо рдкреЗрдЬ рдХреЗ рджреМрд░рд╛рди рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ):

 [Component] public class PlayerStats { public float MoveSpeed; } 

рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдПрдХ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рд╡рд┐рдШрдЯрд┐рдд рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдЕрдХреНрд╕рд░ рдПрдХрд▓ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ: рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдПрдХ рдФрд░ рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреВрд░рд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдореЗрдВ рдХрдИ рд╕рд┐рд╕реНрдЯрдо рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЪрд░рд┐рддреНрд░ рд╕реНрдкреЙрди рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рд╕рд┐рд╕реНрдЯрдо рдПрдХ рдЧреЗрдорд╕реНрдЯреИрдЯ рдореЗрдВ рдПрдХ рдЪрд░рд┐рддреНрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ рдФрд░ рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рд╡рд┐рд╢реНрд╡ рд╕рдордп рдЖрд╡рд╢реНрдпрдХ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдПрдХ рдирдИ рдЗрдХрд╛рдИ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЙрди рдШрдЯрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдЬреЛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ: рдкреНрд▓реЗрдпрд░ , рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдо , рдореВрд╡рдореЗрдВрдЯ ред

 public class SpawnPlayerSystem : ExecutableSystem { public override void Execute(GameState gs) { var deleter = gs.Pools.Deferred.GetDeleter(gs.WorldState.SpawnAvatarRequest); foreach (var avatarRequest in gs.WorldState.SpawnAvatarRequest) { if (avatarRequest.Value.SpawnTime == gs.Time) { // create new entity with player ID var playerEntity = gs.WorldState.CreateEntity(avatarRequest.Value.PlayerId); // add components to determinate player behaviour playerEntity.AddPlayer(); playerEntity.AddTransform(Vector2.zero, 0); playerEntity.AddMovement(Vector2.zero, 0); // delete player spawn request deleter.Delete(avatarRequest.Key); } } } } 

рдЕрдм рдЬреЙрдпрд╕реНрдЯрд┐рдХ рдкрд░ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рдЖрдВрджреЛрд▓рди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рд╣рдореЗрдВ рдПрдХ рдРрд╕реА рдкреНрд░рдгрд╛рд▓реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдЗрдирдкреБрдЯ рдХреЛ рд╣реИрдВрдбрд▓ рдХрд░реЗрдЧреАред рдпрд╣ рдЗрдирдкреБрдЯ рдХреЗ рд╕рднреА рдШрдЯрдХреЛрдВ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ, рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рдЧрддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ (рд╡рд╣ рдЦрдбрд╝рд╛ рд╣реИ рдпрд╛ рдЪрд▓рддрд╛ рд╣реИ) рдФрд░ рд░реЛрдЯреЗрд╢рди рдХреЗ рдЬреЙрдпрд╕реНрдЯрд┐рдХ рдХреЗ рд╡реЗрдХреНрдЯрд░ рдХреЛ рд░реЛрдЯреЗрд╢рди рдХреЗ рдХреЛрдг рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ:

 MovementControlSystem public class MovementControlSystem : ExecutableSystem { public override void Execute(GameState gs) { var playerStats = gs.RuleBook.PlayerStats[1]; foreach (var pair in gs.Input) { var movement = gs.WorldState.Movement[pair.Key]; movement.Velocity = pair.Value.MoveVector.normalized * playerStats.MoveSpeed; movement.RotateToAngle = Math.Atan2(pair.Value.RotateVector.y, pair.Value.RotateVector.x); } } } 

рдЕрдЧрд▓рд╛ рдЖрдВрджреЛрд▓рди рдкреНрд░рдгрд╛рд▓реА рд╣реИ:

 public class MovementSystem : ExecutableSystem { public override void Execute(GameState gs) { foreach (var pair in gs.WorldState.Movement) { var transform = gs.WorldState.Transform[pair.Key]; transform.Position += pair.Value.Velocity * GameState.TickDurationSec; } } } 

рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд░реЛрдЯреЗрд╢рди рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдкреНрд░рдгрд╛рд▓реА:

 public class RotationSystem : ExecutableSystem { public override void Execute(GameState gs) { foreach (var pair in gs.WorldState.Movement) { var transform = gs.WorldState.Transform[pair.Key]; transform.Angle = pair.Value.RotateToAngle; } } } 

MoveSSystem рдФрд░ RotationSystem рдХреЗрд╡рд▓ рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдо рдФрд░ рдореВрд╡рдореЗрдВрдЯ рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рд╡реЗ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рд╕рд╛рд░ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рд╣реИрдВред рдпрджрд┐ рд╣рдорд╛рд░реЗ рдЦреЗрд▓ рдореЗрдВ рдореВрд╡рдореЗрдВрдЯ рдФрд░ рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдо рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде рдЕрдиреНрдп рдЗрдХрд╛рдЗрдпрд╛рдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИрдВ, рддреЛ рдЖрдВрджреЛрд▓рди рддрд░реНрдХ рднреА рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧрд╛ред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдЬреЛрдбрд╝реЗрдВ рдЬреЛ рд╕реНрдкреЙрди рдХреЗ рд╕рд╛рде рдПрдХ рд╕реАрдзреА рд░реЗрдЦрд╛ рдореЗрдВ рдЪрд▓реЗрдЧреА рдФрд░ рдЪрдпрди рдХрд░рддреЗ рд╕рдордп, рдЪрд░рд┐рддреНрд░ рдХреЗ рд╕реНрд╡рд╛рд╕реНрдереНрдп рдХреЛ рдлрд┐рд░ рд╕реЗ рднрд░ рджреЗрдЧреАред рдШрдЯрдХ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ:

 [Component] public class Health { public uint CurrentHealth; public uint MaxHealth; } [Component] public class HealthPowerUp { public uint NextChangeDirection; } [Component] public class HealthPowerUpSpawnRequest { public uint SpawnRequest; } [Component] public class HealthPowerUpStats { public float HealthRestorePercent; public float MoveSpeed; public float SecondsToChangeDirection; public float PickupRadius; public float TimeToSpawn; } 

рд╣рдо рд╡рд╣рд╛рдВ рдЬреАрд╡рди рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рдЬреЛрдбрд╝рдХрд░ рдЪрд░рд┐рддреНрд░ рдХреЗ рдЖрдБрдХрдбрд╝реЛрдВ рдХреЗ рдШрдЯрдХ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

 [Component] public class PlayerStats { public float MoveSpeed; public uint MaxHealth; } 

рдЕрдм рд╣рдо рд╡рд░реНрдг рд╕реНрдкреЙрди рдкреНрд░рдгрд╛рд▓реА рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЪрд░рд┐рддреНрд░ рдЕрдзрд┐рдХрддрдо рд╕реНрд╡рд╛рд╕реНрдереНрдп рдХреЗ рд╕рд╛рде рджрд┐рдЦрд╛рдИ рджреЗ:

 public class SpawnPlayerSystem : ExecutableSystem { public override void Execute(GameState gs) { var deleter = gs.Pools.Deferred.GetDeleter(gs.WorldState.SpawnAvatarRequest); var playerStats = gs.RuleBook.PlayerStats[1]; foreach (var avatarRequest in gs.WorldState.SpawnAvatarRequest) { if (avatarRequest.Value.SpawnTime <= gs.Time) { // create new entity with player ID var playerEntity = gs.WorldState.CreateEntity(avatarRequest.Value.PlayerId); // add components to determinate player behaviour playerEntity.AddPlayer(); playerEntity.AddTransform(Vector2.zero, 0); playerEntity.AddMovement(Vector2.zero, 0); playerEntity.AddHealth(playerStats.MaxHealth, playerStats.MaxHealth); // delete player spawn request deleter.Delete(avatarRequest.Key); } } } } 

рддрдм рд╣рдо рдЕрдкрдиреА рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдХреА рд╕реНрдкреЙрди рдкреНрд░рдгрд╛рд▓реА рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ:

 public class SpawnHealthPowerUpSystem : ExecutableSystem { public override void Execute(GameState gs) { var deleter = gs.Pools.Deferred.GetDeleter(gs.WorldState.HealthPowerUpSpawnRequest); var healthPowerUpStats = gs.RoolBook.healthPowerUpStats[1]; foreach (var spawnRequest in gs.WorldState.HealthPowerUpSpawnRequest) { // create new entity var powerUpEntity = gs.WorldState.CreateEntity(); // add components to determine healthPowerUp behaviour powerUpEntity.AddHealthPowerUp((uint)(healthPowerUpStats.SecondsToChangeDirection * GameState.Hz)); playerEntity.AddTransform(Vector2.zero, 0); playerEntity.AddMovement(healthPowerUpStats.MoveSpeed, 0); // delete player spawn request deleter.Delete(spawnRequest.Key); } } } 

рдФрд░ рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдХреА рдЧрддрд┐ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рдгрд╛рд▓реАред рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рд╣рд░ рдХреБрдЫ рд╕реЗрдХрдВрдб рдореЗрдВ рджрд┐рд╢рд╛ рдмрджрд▓ рджреЗрдЧреА:

 public class HealthPowerUpMovementSystem : ExecutableSystem { public override void Execute(GameState gs) { var healthPowerUpStats = gs.RoolBook.healthPowerUpStats[1]; foreach (var pair in gs.WorldState.HealthPowerUp) { var movement = gs.WorldState.Movement[pair.Key]; if(pair.Value.NextChangeDirection <= gs.Time) { pair.Value.NextChangeDirection = (uint) (healthPowerUpStats.SecondsToChangeDirection * GameState.Hz); movement.Velocity *= -1; } } } } 

рдЪреВрдВрдХрд┐ рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдЦреЗрд▓ рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдореВрд╡рдореЗрдВрдЯ рд╕рд┐рд╕реНрдЯрдо рдХреА рдШреЛрд╖рдгрд╛ рдХреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдХреЗрд╡рд▓ рд╕реНрдкреАрдб рд╡реЗрдХреНрдЯрд░, рд╣рд░ рдПрди рд╕реЗрдХрдВрдб рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЗрд▓реНрдердкреЙрд╡рд░ рдпреВрдкреАрдУрд╡рдореЗрдВрдЯрдореЗрдВрдЯ рд╕рд┐рд╕реНрдЯрдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЕрдм рд╣рдо рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдХрд╛ рдЪрдпрди рдФрд░ рдЪрд░рд┐рддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдЪрдкреА рдХреА рдЕрднрд┐рд╡реГрджреНрдзрд┐ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдЪрд░рд┐рддреНрд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЬреАрд╡рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рд╕рд╣рд╛рдпрдХ рдШрдЯрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

 [Component] public class HealthToAdd { public int Health; public Entity Target; } 

рдФрд░ рд╣рдорд╛рд░реА рд╢рдХреНрддрд┐ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдШрдЯрдХ:

 [Component] public class DeleteHealthPowerUpRequest { } 

рд╣рдо рдПрдХ рдРрд╕реА рдкреНрд░рдгрд╛рд▓реА рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдХреЗ рдЪрдпрди рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рддреА рд╣реИ:

 public class HealthPowerUpPickUpSystem : ExecutableSystem { public override void Execute(GameState gs) { var healthPowerUpStats = gs.RoolBook.healthPowerUpStats[1]; foreach(var powerUpPair in gs.WorldState.HealthPowerUp) { var powerUpTransform = gs.WorldState.Transform[powerUpPair.Key]; foreach(var playerPair in gs.WorldState.Player) { var playerTransform = gs.WorldState.Transform[playerPair.Key]; var distance = Vector2.Distance(powerUpTransform.Position, playerTransform.Position) if(distance < healthPowerUpStats.PickupRadius) { var healthToAdd = gs.WorldState.Health[playerPair.Key].MaxHealth * healthPowerUpStats.HealthRestorePercent; var entity = gs.WorldState.CreateEntity(); entity.AddHealthToAdd(healthToAdd, gs.WorldState.Player[playerPair.Key]); var powerUpEnity = gs.WorldState[powerUpPair.Key]; powerUpEnity.AddDeleteHealthPowerUpRequest(); break; } } } } } 

рд╕рд┐рд╕реНрдЯрдо рд╕рднреА рд╕рдХреНрд░рд┐рдп рдкрд╛рд╡рд░-рдЕрдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рд▓рд┐рдП рджреВрд░реА рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ рдЦрд┐рд▓рд╛рдбрд╝реА рдЪрдпрди рддреНрд░рд┐рдЬреНрдпрд╛ рдХреЗ рднреАрддрд░ рд╣реИ, рддреЛ рд╕рд┐рд╕реНрдЯрдо рджреЛ рдЕрдиреБрд░реЛрдз рдШрдЯрдХ рдмрдирд╛рддрд╛ рд╣реИ:

HealthToAdd - рдПрдХ рдЪрд░рд┐рддреНрд░ рдореЗрдВ рдЬреАрд╡рди рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП "рдЕрдиреБрд░реЛрдз";
DeleteHealthPowerUpRequest - рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП "рдЕрдиреБрд░реЛрдз" рдХрд░реЗрдВред

рдПрдХ рд╣реА рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ рдЬреАрд╡рди рдХреА рд╕рд╣реА рд╕рдВрдЦреНрдпрд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдЬреЛрдбрд╝рддреЗ? рд╣рдо рдЗрд╕ рддрдереНрдп рд╕реЗ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ рдХрд┐ рдЦрд┐рд▓рд╛рдбрд╝реА рди рдХреЗрд╡рд▓ рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рд╕реЗ, рдмрд▓реНрдХрд┐ рдЕрдиреНрдп рд╕реНрд░реЛрддреЛрдВ рд╕реЗ рднреА рдПрдЪрдкреА рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдЪрдпрди рдкреНрд░рдгрд╛рд▓реА рдФрд░ рдЪрд░рд┐рддреНрд░ рдХреА рдЬреАрд╡рди рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдЕрд▓рдЧ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕рдореАрдЪреАрди рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдПрдХрд▓ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рд╕реБрд╕рдВрдЧрдд рд╣реИред

рд╣рдо рдЪрд░рд┐рддреНрд░ рдореЗрдВ рдЬрд╛рди рдбрд╛рд▓рдиреЗ рдХреА рдкреНрд░рдгрд╛рд▓реА рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:

 public class HealingSystem : ExecutableSystem { public override void Execute(GameState gs) { var deleter = gs.Pools.Deferred.GetDeleter(gs.WorldState.HealthToAdd); foreach(var healtToAddPair in gs.WorldState.HealthToAdd) { var healthToAdd = healtToAddPair.Value.Health; var health = healtToAddPair.Value.Target.Health; health.CurrentHealth += healthToAdd; health.CurrentHealth = Mathf.Clamp(health.CurrentHealth, 0, health.MaxHealth); deleter.Delete(healtToAddPair.Key); } } } 

рд╕рд┐рд╕реНрдЯрдо HealthToAdd рдХреЗ рд╕рднреА рдШрдЯрдХреЛрдВ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ , рд▓рдХреНрд╖реНрдп рд▓рдХреНрд╖реНрдп рдЗрдХрд╛рдИ рдХреЗ рд╕реНрд╡рд╛рд╕реНрдереНрдп рдШрдЯрдХ рдореЗрдВ рдЬреАрд╡рди рдХреА рдЖрд╡рд╢реНрдпрдХ рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЗрдХрд╛рдИ рд╕реНрд░реЛрдд рдФрд░ рд▓рдХреНрд╖реНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдирд╣реАрдВ рдЬрд╛рдирддреА рд╣реИ рдФрд░ рдХрд╛рдлреА рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╣реИред рдЗрд╕ рдкреНрд░рдгрд╛рд▓реА рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХреЗрд╡рд▓ рдЪрд░рд┐рддреНрд░ рдХреЗ рдЬреАрд╡рди рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдХрд┐рд╕реА рднреА рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП рдЬреЛ рдЬреАрд╡рди рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдФрд░ рдЙрдирдХреЗ рдЙрддреНрдерд╛рди рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рддрд╛ рд╣реИред

рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдХреЗ рд╕рд╛рде рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЕрдВрддрд┐рдо рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ: рдЗрд╕рдХреЗ рдЪрдпрди рдХреЗ рдмрд╛рдж рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рд╣рдЯрд╛рдиреЗ рдХреА рдкреНрд░рдгрд╛рд▓реАред

 public class DeleteHealthPowerUpSystem : ExecutableSystem { public override void Execute(GameState gs) { var deleter = gs.Pools.Deferred.GetDeleter(gs.WorldState.DeleteHealthPowerUpReques); foreach(var healthRequest in gs.WorldState.DeleteHealthPowerUpReques) { var id = healthRequest.Key; gs.WorldState.DelHealthPowerUp(id); gs.WorldState.DelTransform(id); gs.WorldState.DelMovement(id); deleter.Delete(id); } } } 

HealthPowerUpPickUpSystem рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред DeleteHealthPowerUpSystem рд╕рд┐рд╕реНрдЯрдо рдРрд╕реЗ рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рд╛рдердорд┐рдХ рдЪрд┐рдХрд┐рддреНрд╕рд╛ рдХрд┐рдЯ рдХреЗ рд╕рд╛рд░ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╕рднреА рдШрдЯрдХреЛрдВ рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИред

рд╣реЛ рдЧрдпрд╛ред рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ рд╕рднреА рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдИрд╕реАрдПрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдмрд┐рдВрджреБ рд╣реИ - рд╕рднреА рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЛ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдЖрджреЗрд╢ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред

рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдХреНрд░рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:

 _systems = new List<ExecutableSystem> { new SpawnPlayerSystem(), new SpawnHealthPowerUpSystem(), new MovementControlSystem(), new HealthPowerUpMovementSystem(), new MovementSystem(), new RotationSystem(), new HealthPowerUpPickUpSystem(), new HealingSystem(), new DeleteHealthPowerUpSystem() }; 

рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдирдИ рд╕рдВрд╕реНрдерд╛рдПрдВ рдФрд░ рдШрдЯрдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╕рд┐рд╕реНрдЯрдо рдкрд╣рд▓реЗ рдЖрддреЗ рд╣реИрдВред рдлрд┐рд░ рдЙрдкрдЪрд╛рд░ рдкреНрд░рдгрд╛рд▓реА, рдФрд░ рдЕрдВрдд рдореЗрдВ рд╣рдЯрд╛рдиреЗ рдФрд░ рд╕рдлрд╛рдИ рдкреНрд░рдгрд╛рд▓реАред

рдЙрдЪрд┐рдд рдЕрдкрдШрдЯрди рдХреЗ рд╕рд╛рде, ECS рдореЗрдВ рдмрд╣реБрдд рд▓рдЪреАрд▓рд╛рдкрди рд╣реЛрддрд╛ рд╣реИред рд╣рд╛рдВ, рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рд╣реА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЖрдкрдХреЛ рдереЛрдбрд╝реЗ рд╕рдордп рдореЗрдВ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЖрдзреБрдирд┐рдХ рдореЛрдмрд╛рдЗрд▓ рдЙрдкрдХрд░рдгреЛрдВ рдкрд░ рдЕрдЪреНрдЫрд╛ рдкреНрд░рджрд░реНрд╢рди рднреА рдХрд░рддрд╛ рд╣реИред рдЖрдк ECS рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдпрд╣рд╛рдБ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ:

Source: https://habr.com/ru/post/hi431660/


All Articles