示例#1
0
 public AudioSystem(int maxSoundEffects, Map map = null, RayCaster rayCaster = null)
 {
     Map             = map;
     RayCaster       = rayCaster;
     Sounds          = new List <SoundBuffer>();
     MaxSoundEffects = maxSoundEffects;
     inPlaySounds    = new Sound[MaxSoundEffects];
 }
示例#2
0
        private bool CanSeeTarget(Entity target)
        {
            var vector      = target.Location - Location;
            var maxDistance = (int)Math.Min(vector.Length, 500);

            var result = RayCaster.CastRay(Services.Game.Level, Location, vector, CollisionCheckType.BlocksProjectiles, maxDistance);

            return(!result.Hit);
        }
示例#3
0
        public Renderer(RayCaster rayCaster, RenderWindow renderWindow, RenderTexture drawBuffer, Map map, float fov, Color ambientLight)
        {
            //Assign local variables
            Caster       = rayCaster;
            Screen       = renderWindow;
            Buffer       = drawBuffer;
            Map          = map;
            Fov          = fov;
            AmbientLight = ambientLight;

            //Calculate inital values for some variables
            HalfFov = fov / 2;
            DistanceToProjectionPlane = (Buffer.Size.X / 2f) / TanD(HalfFov);
            Textures        = new List <Texture>();
            DepthPerStrip   = new float[Buffer.Size.X];
            AtlasTileSize   = new Vector2f(Caster.CellSize, Caster.CellSize);
            Angles          = new float[Buffer.Size.X];
            LightMultiplier = 4000;

            for (int x = 0; x < Buffer.Size.X; x++)
            {
                Angles[x] = AtanD((x - Buffer.Size.X / 2.0f) / DistanceToProjectionPlane);
            }

            FloorVertices = new Vertex[Buffer.Size.X * Buffer.Size.Y];
            WallVertices  = new Vertex[Buffer.Size.X * 2];

            float aspectRatio = Buffer.Size.X / (float)Buffer.Size.Y;

            DisplayVertices = new Vertex[] {
                new Vertex
                {
                    Position  = new Vector2f(Screen.Size.X / 2 - (Screen.Size.Y * aspectRatio) / 2, 0),
                    TexCoords = new Vector2f(0, Buffer.Size.Y - 1),
                    Color     = Color.White
                },
                new Vertex
                {
                    Position  = new Vector2f(Screen.Size.X / 2 - (Screen.Size.Y * aspectRatio) / 2, Screen.Size.Y - 1),
                    TexCoords = new Vector2f(0, 0),
                    Color     = Color.White
                },
                new Vertex
                {
                    Position  = new Vector2f(Screen.Size.X / 2 + (Screen.Size.Y * aspectRatio) / 2, Screen.Size.Y - 1),
                    TexCoords = new Vector2f(Buffer.Size.X - 1, 0),
                    Color     = Color.White
                },
                new Vertex
                {
                    Position  = new Vector2f(Screen.Size.X / 2 + (Screen.Size.Y * aspectRatio) / 2, 0),
                    TexCoords = new Vector2f(Buffer.Size.X - 1, Buffer.Size.Y - 1),
                    Color     = Color.White
                },
            };
        }
        public Tuple <IInteractable, RaycastHit> GetInteractableFromRay(Ray ray, float range)
        {
            if (!RayCaster.CastRay(ray, range, out RaycastHit hit))
            {
                return(null);
            }
            var interactable = hit.transform.GetComponent <IInteractable>();

            return(interactable == null ? null : new Tuple <IInteractable, RaycastHit>(interactable, hit));
        }
        public Tuple <IInteractable, RaycastHit> GetInteractableFromRay(Ray ray, float range)
        {
            _distanceToClosestTarget = range;
            SetAllInteractables();

            foreach (Transform t in _interactables)
            {
                // Don't hit yourself :|
                if (t == _self)
                {
                    continue;
                }

                Vector3 rayVector         = ray.direction;
                Vector3 rayToTargetVector = t.position - ray.origin;

                float distance = rayToTargetVector.magnitude;

                if (_distanceToClosestTarget <= distance)
                {
                    continue;
                }

                float lookPercentage = Vector3.Dot(rayVector.normalized, rayToTargetVector.normalized);

                if (lookPercentage < Threshold)
                {
                    continue;
                }


                // if (lookPercentage < _bestLookPercentage) return;

                _closestTarget           = t;
                _distanceToClosestTarget = rayToTargetVector.magnitude;
            }

            if (_closestTarget == null)
            {
                return(null);
            }

            // TODO: Implement a "Closest point" method; Basically, if you're aiming slightly above the head, then the point should be the top of the head.
            // If you're aiming slightly top-left, then the point should be the upper-left-most area of the object etc..

            // Currently it simply rays to the middle of the object.
            RayCaster.LineCast(ray.origin, _closestTarget.position, out RaycastHit hit);

            var result = new Tuple <IInteractable, RaycastHit>(_closestTarget.GetComponent <IInteractable>(), hit);

            _closestTarget = null;

            return(result);
        }
示例#6
0
 private void Awake()
 {
     if (instance == null || instance == this)
     {
         instance = this;
         Initialise();
     }
     else
     {
         Destroy(this);
     }
 }
示例#7
0
	// Use this for initialization
	void Start () {
        //Obtain agent controller
        controller = GetComponent<Controller>();

        //Obtain agent sensors
        foreach(RayCaster ray in GetComponents<RayCaster>()) {
            if (ray.id.Equals("FRONT"))
                front = ray;
            else if (ray.id.Equals("LEFT")) 
                left = ray;
            else if (ray.id.Equals("RIGHT"))
                right = ray;
        }
    }
        public void Update(GameTime gameTime)
        {
            if (InputManager.IsKeyPressed(Keys.F4))
            {
                ScreenManager.PopScreen();
            }

            MouseState currentState = Mouse.GetState();

            if (currentState != previousState)
            {
                float deltaX = currentState.X - previousState.X;
                angle += deltaX * 20.0f * (float)gameTime.ElapsedGameTime.TotalSeconds;
            }

            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;

            Mouse.SetPosition(viewport.Width / 2, viewport.Height / 2);

            Vector2 forward = new Vector2((float)Math.Cos(angle * Math.PI / 180),
                                          (float)Math.Sin(angle * Math.PI / 180));
            Vector2 right = new Vector2(-forward.Y, forward.X);

            Vector2 movementDirection = forward * InputManager.VerticalAxis + right * InputManager.HorizontalAxis;

            if (movementDirection != Vector2.Zero)
            {
                movementDirection.Normalize();

                Vector2 velocity = movementDirection * movementSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;

                // do collision detection
                RayCaster.HitData hitData;
                float             dirAngle = (float)Math.Atan2(velocity.Y, velocity.X);
                if (RayCaster.RayIntersectsGrid(position, dirAngle, 32, out hitData,
                                                currentMap.GetIsTileOccupiedFunction("walls1"), 16))
                {
                    if (hitData.rayLength >= 0)
                    {
                        float vel = velocity.Length();
                        velocity.Normalize();
                    }
                }


                player.position = position;
                velocity        = currentMap.Move(velocity, player);
                position       += velocity;
            }
        }
        protected override int CreateMarker(float xPos, int rowIndex, Transform newColumn, int columnIndex)
        {
            float zPos = MarkerSizeAdjustedZStartPos - (distanceBetweenCreatedMarkers * rowIndex);

            var markerPos = new Vector3(xPos, creationHeightAboveFloor, zPos);

            Vector3 checkPos = markerPos;

            checkPos.y += grid.minimumOpenAreaAroundMarkers.y / 2;
            if (RayCaster.CheckBox(checkPos, grid.minimumOpenAreaAroundMarkers * 0.5f, Quaternion.identity))
            {
                return(0);
            }

            InstantiateMarker("Column " + rowIndex, markerPos, newColumn);
            return(1);
        }
示例#10
0
        /// <summary>
        /// Returns false if the object was found to be inside another object (and was therefore moved from inside this method)
        /// </summary>
        private bool GetCollisions(ref Vector3 currPos, ref Vector3 currSize, out bool collForward, out bool collLeft, out bool collBack, out bool collRight)
        {
            collForward = false;
            collLeft    = false;
            collBack    = false;
            collRight   = false;



            Collider[] colliders     = RayCaster.OverLapBox(currPos, currSize, Quaternion.identity);
            int        collidersSize = colliders.Length;

            if (collidersSize == 0)
            {
                currSize.x += boxCheckDistanceIncreasePerAttempt;
                currSize.z += boxCheckDistanceIncreasePerAttempt;
            }


            var collNames = "";

            foreach (Collider coll in colliders)
            {
                bool isNotInsideOtherObject = CheckCollidingDirections(ref currPos, coll, ref collForward, ref collLeft, ref collBack, ref collRight, false, true);

                if (!isNotInsideOtherObject)
                {
                    DoSubCollisionChecking(ref currPos, ref currSize, collidersSize);
                    return(false);
                }

                if (collNames != "")
                {
                    collNames += ",";
                }
                collNames += " " + coll.name;
            }

            Logging.Log($"Collided with {collNames}");

            return(true);
        }
示例#11
0
    // Use this for initialization
    void Start()
    {
        // rCaster = GameObject.FindGameObjectWithTag("EditorOnly").GetComponent<RayCastF>();
        rCaster = Camera.main.GetComponent <RayCaster>();

        //if the upleftpos target is at 0.0.0 we put back the targets at the last calibration
        if (FovStatic.upLeftPos != new Vector3(0, 0, 0))
        {
            ResumeLastCalibration();
        }

        //logs name and scenetimer
        LoggerBehavior.sceneName  = "Fov calibration";
        LoggerBehavior.sceneTimer = 0;

        //change text on the targets
        RandomizeText();

        //disable targets
        UpRight.SetActive(false);
        DownRight.SetActive(false);
        DownLeft.SetActive(false);
    }
示例#12
0
    void SetupEngines()
    {
        // "The core of Svelto.ECS" ???
        m_EnginesRoot = new EnginesRoot(new UnitySumbmissionEntityViewScheduler());

        // Factory for creating all entities (?)
        m_EntityFactory = m_EnginesRoot.GenerateEntityFactory();

        // ???
        IEntityFunctions entityFunctions = m_EnginesRoot.GenerateEntityFunctions();

        // Factory used to create Unity GameObjects (wrapper around GameObject.Instantiate)
        GameObjectFactory gameObjectFactory = new GameObjectFactory();

        IRayCaster rayCaster = new RayCaster();
        ITime      time      = new FrameTimer();

        PlayerInputEngine     playerInputEngine     = new PlayerInputEngine();
        AimingEngine          aimingEngine          = new AimingEngine();
        GunShootingEngine     gunShootingEngine     = new GunShootingEngine(rayCaster);
        GunEffectsEngine      gunEffectsEngine      = new GunEffectsEngine(gameObjectFactory);
        ZombieSpawnerEngine   zombieSpawnerEngine   = new ZombieSpawnerEngine(gameObjectFactory, m_EntityFactory);
        ZombieMovementEngine  zombieMovementEngine  = new ZombieMovementEngine(time);
        ZombieAnimationEngine zombieAnimationEngine = new ZombieAnimationEngine();
        HUDEngine             hudEngine             = new HUDEngine();
        DeathEngine           deathEngine           = new DeathEngine(entityFunctions);

        m_EnginesRoot.AddEngine(playerInputEngine);
        m_EnginesRoot.AddEngine(aimingEngine);
        m_EnginesRoot.AddEngine(gunShootingEngine);
        m_EnginesRoot.AddEngine(gunEffectsEngine);
        m_EnginesRoot.AddEngine(zombieSpawnerEngine);
        m_EnginesRoot.AddEngine(zombieMovementEngine);
        m_EnginesRoot.AddEngine(zombieAnimationEngine);
        m_EnginesRoot.AddEngine(hudEngine);
        m_EnginesRoot.AddEngine(deathEngine);
    }
示例#13
0
        public void StartSFMLProgram()
        {
            #region Initialization
            Map Map = new Map(_m.GetLength(0), _m.GetLength(1));

            for (int y = 0; y < _m.GetLength(1); y++)
            {
                for (int x = 0; x < _m.GetLength(0); x++)
                {
                    switch (_m[y, x])
                    {
                    case 1:
                        Map[x, y] = new Tile
                        {
                            Solid      = true,
                            DownAtlas  = new Vector2i(1, 0),
                            UpAtlas    = new Vector2i(1, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0)
                        };
                        break;

                    case 2:
                        Map[x, y] = new CircleTile
                        {
                            Solid      = true,
                            DownAtlas  = new Vector2i(1, 0),
                            UpAtlas    = new Vector2i(1, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0),
                            CeilAtlas  = new Vector2i(0, 0),
                            FloorAtlas = new Vector2i(2, 0),
                            //IsCeilMap = true
                        };
                        break;

                    case 5:
                        Map[x, y] = new Tile
                        {
                            Solid      = false,
                            DownAtlas  = new Vector2i(0, 0),
                            UpAtlas    = new Vector2i(0, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0),
                            CeilAtlas  = new Vector2i(0, 0),
                            FloorAtlas = new Vector2i(5, 0)
                        };
                        break;

                    case 0:
                        Map[x, y] = new Tile
                        {
                            Solid      = false,
                            DownAtlas  = new Vector2i(0, 0),
                            UpAtlas    = new Vector2i(0, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0),
                            CeilAtlas  = new Vector2i(0, 0),
                            FloorAtlas = new Vector2i(5, 0)
                        };
                        break;

                    case 6:
                        Map[x, y] = new Tile
                        {
                            Solid      = false,
                            DownAtlas  = new Vector2i(0, 0),
                            UpAtlas    = new Vector2i(0, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0),
                            CeilAtlas  = new Vector2i(0, 0),
                            FloorAtlas = new Vector2i(5, 0),
                            IsCeilMap  = true
                        };
                        break;
                    }
                }
            }


            window = new RenderWindow(new VideoMode(800, 600), "SFML window", Styles.Default);
            window.SetVisible(true);
            window.Closed     += new EventHandler(OnClosed);
            window.KeyPressed += new EventHandler <KeyEventArgs>(OnKeyPressed);
            window.MouseMoved += Window_MouseMoved;

            //Vector2f screen = new Vector2f(200, 100);

            Vector2f screen = new Vector2f(window.Size.X, window.Size.Y);
            screen *= 0.3f;
            rs      = new RenderTexture((uint)screen.X, (uint)screen.Y);

            caster = new RayCaster(Map, 32);

            Renderer ren = new Renderer(caster, window, rs, Map, fov, new Color(16, 16, 16));
            ren.Textures.Add(new Texture("Texture.png"));
            ren.MapAtlasInUse = 0;
            #endregion

            Vector2f player = new Vector2f(caster.CellSize * 6 + 8, caster.CellSize * 5 + 8);
            Vector2f sp1    = player + new Vector2f(70, 15);
            Vector2f sp2    = player + new Vector2f(50, 70);

            Vector2f sp3  = new Vector2f(caster.CellSize * 6 + 8, caster.CellSize * 5 + 8) + new Vector2f(30, -30);
            Vector2f scen = sp1 + new Vector2f(60, 60);

            Vector2f M;

            font = new Font("Perfect DOS VGA 437 Win.ttf");
            Text t          = new Text("Fps: ", font, 16);
            int  fps        = 0;
            int  fpsCounter = 0;
            int  ticks      = Environment.TickCount;
            int  ticksFps   = Environment.TickCount;


            int timeDelta = 0;

            var lamps = new List <Light>();
            //{
            //    new Light (
            //        new Vector2f(sp1.X,sp1.Y),
            //        new Color(255,255,255)
            //    ),
            //    new Light (
            //        new Vector2f(sp2.X,sp2.Y),
            //        new Color(128,128,0)
            //    )
            //};



            List <Sprite> sprites = new List <Sprite>();
            Random        r       = new Random();

            for (int i = 0; i < 5; i++)
            {
                sprites.Add(new Sprite
                            (
                                new Vector2f((float)r.NextDouble() * caster.CellSize * Map.Tiles.GetLength(0), (float)r.NextDouble() * caster.CellSize * Map.Tiles.GetLength(1)),
                                new Vector2i(3, 0)
                            ));
            }
            Random rand = new Random();
            lamps = sprites.Select(s => new Light(s.Position, new Color((byte)(rand.NextDouble() * 80), 0, (byte)(rand.NextDouble() * 80)))).ToList();


            ren.GenerateLightMap(lamps, 0.5f);
            //sprites.Add(new Sprite
            //(
            //    sp2,
            //    new Vector2i(3, 0)
            //));

            //Sprite p = new Sprite
            //(
            //    sp1,
            //    new Vector2i(3, 0)
            //);
            //sprites.Add(p);

            AudioSystem audio        = new AudioSystem(32, Map, caster);
            Sprite      playerSprite = new Sprite(player, new Vector2i(0, 0));
            audio.Listener = playerSprite;
            int a = audio.LoadSound("ts.wav");
            audio.PlaySound(a, true, sp1);

            float look   = rs.Size.Y / 2;
            float height = caster.CellSize / 2;
            ren.SkyPosition = new Vector2f(5, 5);
            ren.SkyAtlas    = new Vector2i(6, 0);

            window.MouseWheelScrolled += (o, e) =>
            {
                height += e.Delta / 1;
                if (height > caster.CellSize)
                {
                    height = caster.CellSize;
                }

                if (height < 0)
                {
                    height = 0;
                }
            };

            while (window.IsOpen)
            {
                if (Environment.TickCount - ticksFps >= timeDelta)
                {
                    ticksFps = Environment.TickCount;
                    if (Environment.TickCount - ticks >= 1000)
                    {
                        fps        = fpsCounter;
                        fpsCounter = 0;
                        ticks      = Environment.TickCount;
                    }

                    angle -= (window.Size.X / 2 - Mouse.GetPosition(window).X) / 4f;
                    look  += (window.Size.Y / 2 - Mouse.GetPosition(window).Y) / 3f;

                    if (look < 0)
                    {
                        look = 0;
                    }
                    if (look > rs.Size.Y)
                    {
                        look = rs.Size.Y;
                    }

                    ren.SkyPosition += new Vector2f(0.01f, 0.05f);


                    if (Keyboard.IsKeyPressed(Keyboard.Key.P))
                    {
                        lamps.Add(
                            new Light(player, new Color(255, 255, 255)));
                    }

                    angle -= Keyboard.IsKeyPressed(Keyboard.Key.Left) ? 2 : 0;
                    angle += Keyboard.IsKeyPressed(Keyboard.Key.Right) ? 2 : 0;

                    M = new Vector2f(0, 0);

                    if (Keyboard.IsKeyPressed(Keyboard.Key.W))
                    {
                        M += new Vector2f(CosD(angle) * 2, SinD(angle) * 2);
                    }

                    if (Keyboard.IsKeyPressed(Keyboard.Key.S))
                    {
                        M -= new Vector2f(CosD(angle) * 2, SinD(angle) * 2);
                    }

                    if (Keyboard.IsKeyPressed(Keyboard.Key.D))
                    {
                        M += new Vector2f(CosD(angle + 90) * 2, SinD(angle + 90) * 2);
                    }

                    if (Keyboard.IsKeyPressed(Keyboard.Key.A))
                    {
                        M += new Vector2f(CosD(angle - 90) * 2, SinD(angle - 90) * 2);
                    }


                    RayResult R = caster.RayCast(player, 0);
                    if (R.Magnitude < Math.Abs(M.X) + 10 && Math.Sign(M.X) == 1)
                    {
                        M.X = 0;
                    }

                    R = caster.RayCast(player, 180);
                    if (R.Magnitude < Math.Abs(M.X) + 10 && Math.Sign(M.X) == -1)
                    {
                        M.X = 0;
                    }

                    R = caster.RayCast(player, 90);
                    if (R.Magnitude < Math.Abs(M.Y) + 10 && Math.Sign(M.Y) == 1)
                    {
                        M.Y = 0;
                    }

                    R = caster.RayCast(player, 270);
                    if (R.Magnitude < Math.Abs(M.Y) + 10 && Math.Sign(M.Y) == -1)
                    {
                        M.Y = 0;
                    }

                    player += M;



                    Mouse.SetPosition(new Vector2i((int)window.Size.X / 2, (int)window.Size.Y / 2), window);

                    window.DispatchEvents();
                    rs.Clear(Color.Black);



                    playerSprite.Position = player;
                    playerSprite.Angle    = angle;
                    audio.UpdateAudio();
                    ren.Render(player, angle, height, look, sprites, lamps);
                    t.DisplayedString = $"Fps: {fps} - Lights: {lamps.Count}";
                    rs.Draw(t);
                    ren.ShowBuffer();
                    Thread.Sleep(0);

                    fpsCounter++;
                }
            }
        }
示例#14
0
        private static bool CheckIfCollidingVertical(Vector3 pos, float dist)
        {
            var ray = new Ray(pos, dist > 0 ? Vector3.up : Vector3.down);

            return(RayCaster.CastRay(ray, Mathf.Abs(dist)));
        }
示例#15
0
 // Use this for initialization
 void Start()
 {
     displaySelection = 0;
     CamCaster        = GetComponent <RayCaster>();
 }
示例#16
0
        /// <summary>
/// Before to start a review of Svelto.ECS terminologies:
/// - Entity:
///     it must be a real and concrete entity that you can explain
///     in terms of game design. The name of each entity should reflect
///     a specific concept from the game design domain
/// - Engines (Systems):
///     Where all the logic lies. Engines operates on EntityViews or EntityStructs
/// - EntityViews and EntitiyViewStructs:
///     EntityViews maps Entity Components. The Engines can't
///     access directly to each entity (as a single set of components), but
///     through component sets defined by the EntityView.
///     They act as component filters and expose only the entity components
///     that the Engine is interested in.
///     EntityViews are actually defined with the Engine so they
///     come together with the engine and in the same namespace of the engine.
///     EntityViewStructs should always be used, while EntityViews as
///     class use should be considered an exception.
/// - Component Interfaces:
///     Components must be seen as data holders. There may be implementation
///     exceptions, but the interface must declare a group
///     of readable and/or writeable data.
///     In Svelto.ECS components are always interfaces declaring
///     Setters and Getters of Value Types. DispatchOnSet
///     and DispatchOnChange must not be seen as events, but
///     as pushing of data instead of data polling, similar
///     to the concept of DataBinding.
/// - Implementors:
///     Being components interfaces, they must be implemented through
///     Implementors. The relation Implementors to Components
///     is not 1:1 so that you can group several
///     components into fewer implementors. This allows to easily
///     share data between components. Implementors also act
///     as bridge between the platform and Svelto.ECS.
///     Since Components can hold only value types, Implementors
///     are the objects that can interact directly with the platform
///     objects, I.E.: RigidBody, Transform and so on.
///     Note: IComponents must hold only valuetypes for
///     code design purposes and not optmization purposes.
///     The reason is that all the logic must lie in the engines
///     so Components cannot hold references to instances that can
///     expose functions with logic.
/// - EntityStructs:
///     In order to write Data Oriented Cache Friendly and allocation 0 code, Svelto.ECS
///     also supports EntityStructs.
/// - EntityDescriptors:
///     Gives a way to formalize your Entity in svelto.ECS, it also
///     defoines the EntityViews, EntityStructs and EntityViewStructs that must be generated once the
///     Entity is built
/// </summary>
        void SetupEngines()
        {
            //The Engines Root is the core of Svelto.ECS. You must NEVER inject the EngineRoot
            //as it is, therefore the composition root must hold a reference or it will be
            //GCed.
            //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know
            //when to inject the EntityViews. You shouldn't use a custom one unless you know what you
            //are doing or you are not working with Unity.
            _enginesRoot = new EnginesRoot(new UnityEntitySubmissionScheduler());
            //Engines root can never be held by anything else than the context itself to avoid leaks
            //That's why the EntityFactory and EntityFunctions are generated.
            //The EntityFactory can be injected inside factories (or engine acting as factories)
            //to build new entities dynamically
            _entityFactory = _enginesRoot.GenerateEntityFactory();
            //The entity functions is a set of utility operations on Entities, including
            //removing an entity. I couldn't find a better name so far.
            var entityFunctions = _enginesRoot.GenerateEntityFunctions();

            //the ISequencer is one of the 2 official ways available in Svelto.ECS
            //to communicate. They are mainly used for two specific cases:
            //1) specify a strict execution order between engines (engine logic
            //is executed horizontally instead than vertically, I will talk about this
            //in my articles). 2) filter a data token passed as parameter through
            //engines. The ISequencer is also not the common way to communicate
            //between engines
            PlayerDeathSequencer playerDeathSequence = new PlayerDeathSequencer();
            EnemyDeathSequencer  enemyDeathSequence  = new EnemyDeathSequencer();

            //wrap non testable unity static classes, so that
            //can be mocked if needed.
            IRayCaster rayCaster = new RayCaster();
            ITime      time      = new Time();

            //Player related engines. ALL the dependencies must be solved at this point
            //through constructor injection.
            var playerShootingEngine  = new PlayerGunShootingEngine(rayCaster, time);
            var playerMovementEngine  = new PlayerMovementEngine(rayCaster, time);
            var playerAnimationEngine = new PlayerAnimationEngine();
            var playerDeathEngine     = new PlayerDeathEngine(playerDeathSequence, entityFunctions);

            //Enemy related engines
            var enemyAnimationEngine = new EnemyAnimationEngine(time, enemyDeathSequence, entityFunctions);
            var enemyAttackEngine    = new EnemyAttackEngine(time);
            var enemyMovementEngine  = new EnemyMovementEngine();

            //GameObjectFactory allows to create GameObjects without using the Static
            //method GameObject.Instantiate. While it seems a complication
            //it's important to keep the engines testable and not
            //coupled with hard dependencies references (read my articles to understand
            //how dependency injection works and why solving dependencies
            //with static classes and singletons is a terrible mistake)
            GameObjectFactory factory = new GameObjectFactory();
            //Factory is one of the few patterns that work very well with ECS. Its use is highly encouraged
            IEnemyFactory enemyFactory       = new EnemyFactory(factory, _entityFactory);
            var           enemySpawnerEngine = new EnemySpawnerEngine(enemyFactory, entityFunctions);
            var           enemyDeathEngine   = new EnemyDeathEngine(entityFunctions, enemyDeathSequence);

            //hud and sound engines
            var hudEngine         = new HUDEngine(time);
            var damageSoundEngine = new DamageSoundEngine();
            var scoreEngine       = new ScoreEngine();

            //The ISequencer implementation is very simple, but allows to perform
            //complex concatenation including loops and conditional branching.
            //These two sequencers are a real stretch and are shown only for explanatory purposes.
            //Please do not see sequencers as a way to dispatch or broadcast events, they are meant only and exclusively
            //to guarantee the order of execution of the involved engines.
            //For this reason the use of sequencers is and must be actually rare, as perfectly encapsulated engines
            //do not need to be executed in specific order.
            //a Sequencer can:
            //- ensure the order of execution through one step only (one step executes in order several engines)
            //- ensure the order of execution through several steps. Each engine inside each step has the responsibility
            //to trigger the next step through the use of the Next() function
            //- create paths with branches and loop using the Condition parameter.
            playerDeathSequence.SetSequence(
                new Steps //sequence of steps, this is a dictionary!
            {
                {
                    /*from: */ playerDeathEngine,    //when the player dies
                    /*to:   */ new To <PlayerDeathCondition>
                    //all these engines in the list will be called in order (which in this
                    //case was not important at all, so stretched!!)
                    {
                        { PlayerDeathCondition.Death, playerMovementEngine, playerAnimationEngine, enemyAnimationEngine, damageSoundEngine, hudEngine }
                    }
                }
            }
                );

            enemyDeathSequence.SetSequence(
                new Steps
            {
                {     //first step
                    enemyDeathEngine,
                    new To <EnemyDeathCondition>
                    {
                        //TIP: use GO To Type Declaration to go directly to the Class code of the
                        //engine instance
                        { EnemyDeathCondition.Death, scoreEngine, enemyAnimationEngine }
                    }
                },
                {                         //second step
                    enemyAnimationEngine, //after the death animation is actually finished
                    new To <EnemyDeathCondition>
                    {
                        { EnemyDeathCondition.Death, enemySpawnerEngine }    //call the spawner engine
                    }
                }
            }
                );

            //All the logic of the game must lie inside engines
            //Player engines
            _enginesRoot.AddEngine(playerMovementEngine);
            _enginesRoot.AddEngine(playerAnimationEngine);
            _enginesRoot.AddEngine(playerShootingEngine);
            _enginesRoot.AddEngine(new PlayerInputEngine());
            _enginesRoot.AddEngine(new PlayerGunShootingFXsEngine());
            _enginesRoot.AddEngine(playerDeathEngine);

            //enemy engines
            _enginesRoot.AddEngine(enemySpawnerEngine);
            _enginesRoot.AddEngine(enemyAttackEngine);
            _enginesRoot.AddEngine(enemyMovementEngine);
            _enginesRoot.AddEngine(enemyAnimationEngine);
            _enginesRoot.AddEngine(enemyDeathEngine);
            //other engines
            _enginesRoot.AddEngine(new ApplyingDamageToTargetsEngine());
            _enginesRoot.AddEngine(new CameraFollowTargetEngine(time));
            _enginesRoot.AddEngine(new CharactersDeathEngine());
            _enginesRoot.AddEngine(damageSoundEngine);
            _enginesRoot.AddEngine(hudEngine);
            _enginesRoot.AddEngine(scoreEngine);
        }
示例#17
0
 void Start()
 {
     gc = GetComponent <GameController>();
     rc = GetComponent <RayCaster>();
 }
示例#18
0
        private static bool CheckIfCollidingOnZ(Vector3 pos, float dist)
        {
            var ray = new Ray(pos, dist > 0 ? Vector3.forward : Vector3.back);

            return(RayCaster.CastRay(ray, Mathf.Abs(dist)));
        }
示例#19
0
 void Start()
 {
     // rCaster = GameObject.FindGameObjectWithTag("EditorOnly").GetComponent<RayCastF>();
     rCaster = Camera.main.GetComponent <RayCaster>();
 }
示例#20
0
        /// <summary>
        ///     Before to start, let's review some of the Svelto.ECS terms:
        ///     - Entity:
        ///     it must be a real and concrete entity that you can explain in terms of game design. The name of each
        ///     entity should reflect a specific concept from the game design domain
        ///     - Engines (Systems):
        ///     Where all the logic lies. Engines operates on EntityViewStructs and EntityStructs
        ///     - EntityStructs:
        ///     EntityStructs is the preferred way to store entity data. They are just plain structs of pure data (no
        ///     objects)
        ///     - EntityViewStructs:
        ///     EntityViewStructs are used to wrap Objects that come from OOP libraries. You will never use it unless
        ///     you are forced to mix your ECS code with OOP code because of external libraries or platforms.
        ///     The Objects are known to svelto through Component Interfaces.
        ///     - Component Interfaces:
        ///     Components must be seen as data holders. In Svelto.ECS components are always interfaces declaring
        ///     Setters and Getters of Value Types coming from the Objects they wrap
        ///     - Implementors:
        ///     The components interfaces must be implemented through Implementors and the implementors are the
        ///     Objects you need to wrap.
        ///     - EntityDescriptors:
        ///     Gives a way to formalise your Entity, it also defines the EntityStructs and EntityViewStructs that must
        ///     be generated once the Entity is built
        /// </summary>
        void SetupEngines()
        {
            //The Engines Root is the core of Svelto.ECS. You shouldn't inject the EngineRoot,
            //therefore the composition root must hold a reference or it will be GCed.
            //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know
            //when to submit the entities. Custom ones can be created for special cases.
            _unityEntitySubmissionScheduler = new UnityEntitySubmissionScheduler();
            _enginesRoot = new EnginesRoot(_unityEntitySubmissionScheduler);
            //The EntityFactory can be injected inside factories (or engine acting as factories) to build new entities
            //dynamically
            _entityFactory = _enginesRoot.GenerateEntityFactory();
            //The entity functions is a set of utility operations on Entities, including removing an entity. I couldn't
            //find a better name so far.
            var entityFunctions = _enginesRoot.GenerateEntityFunctions();

            //Sequencers are the official way to guarantee order between engines, but may not be the best way for
            //your product.
            var playerDeathSequence = new PlayerDeathSequencer();
            var enemyDeathSequence  = new EnemyDeathSequencer();

            //wrap non testable unity static classes, so that can be mocked if needed.
            IRayCaster rayCaster = new RayCaster();
            ITime      time      = new Time();

            //Player related engines. ALL the dependencies must be solved at this point through constructor injection.
            var playerShootingEngine  = new PlayerGunShootingEngine(rayCaster, time);
            var playerMovementEngine  = new PlayerMovementEngine(rayCaster, time);
            var playerAnimationEngine = new PlayerAnimationEngine();
            var playerDeathEngine     = new PlayerDeathEngine(playerDeathSequence, entityFunctions);

            //Enemy related engines
            var enemyAnimationEngine = new EnemyAnimationEngine(time, enemyDeathSequence, entityFunctions);
            var enemyAttackEngine    = new EnemyAttackEngine(time);
            var enemyMovementEngine  = new EnemyMovementEngine();

            //GameObjectFactory allows to create GameObjects without using the Static method GameObject.Instantiate.
            //While it seems a complication it's important to keep the engines testable and not coupled with hard
            //dependencies
            var gameObjectFactory = new GameObjectFactory();
            //Factory is one of the few patterns that work very well with ECS. Its use is highly encouraged
            var enemyFactory       = new EnemyFactory(gameObjectFactory, _entityFactory);
            var enemySpawnerEngine = new EnemySpawnerEngine(enemyFactory, entityFunctions);
            var enemyDeathEngine   = new EnemyDeathEngine(entityFunctions, enemyDeathSequence);

            //hud and sound engines
            var hudEngine         = new HUDEngine(time);
            var damageSoundEngine = new DamageSoundEngine();
            var scoreEngine       = new ScoreEngine();

            //The ISequencer implementation is very simple, but allows to perform
            //complex concatenation including loops and conditional branching.
            //These two sequencers are a real stretch and are shown only for explanatory purposes.
            //Please do not see sequencers as a way to dispatch or broadcast events, they are meant only and exclusively
            //to guarantee the order of execution of the involved engines.
            //For this reason the use of sequencers is and must be actually rare, as perfectly encapsulated engines
            //do not need to be executed in specific order.
            //a Sequencer can:
            //- ensure the order of execution through one step only (one step executes in order several engines)
            //- ensure the order of execution through several steps. Each engine inside each step has the responsibility
            //to trigger the next step through the use of the Next() function
            //- create paths with branches and loop using the Condition parameter.
            playerDeathSequence.SetSequence(playerDeathEngine, playerMovementEngine, playerAnimationEngine,
                                            enemyAnimationEngine, damageSoundEngine, hudEngine);

            enemyDeathSequence.SetSequence(enemyDeathEngine, scoreEngine, damageSoundEngine, enemyAnimationEngine,
                                           enemySpawnerEngine);


            //All the logic of the game must lie inside engines
            //Player engines
            _enginesRoot.AddEngine(playerMovementEngine);
            _enginesRoot.AddEngine(playerAnimationEngine);
            _enginesRoot.AddEngine(playerShootingEngine);
            _enginesRoot.AddEngine(new PlayerInputEngine());
            _enginesRoot.AddEngine(new PlayerGunShootingFXsEngine());
            _enginesRoot.AddEngine(playerDeathEngine);
            _enginesRoot.AddEngine(new PlayerSpawnerEngine(gameObjectFactory, _entityFactory));


            //enemy engines
            _enginesRoot.AddEngine(enemySpawnerEngine);
            _enginesRoot.AddEngine(enemyAttackEngine);
            _enginesRoot.AddEngine(enemyMovementEngine);
            _enginesRoot.AddEngine(enemyAnimationEngine);
            _enginesRoot.AddEngine(enemyDeathEngine);
            //other engines
            _enginesRoot.AddEngine(new ApplyingDamageToTargetsEngine());
            _enginesRoot.AddEngine(new CameraFollowTargetEngine(time));
            _enginesRoot.AddEngine(new CharactersDeathEngine());
            _enginesRoot.AddEngine(damageSoundEngine);
            _enginesRoot.AddEngine(hudEngine);
            _enginesRoot.AddEngine(scoreEngine);
        }
示例#21
0
 private void InitializeRayCaster()
 {
     _rayCaster = new RayCaster(PutPixel, (x, y, width, height) => { });
 }
/// <summary>
/// Before to start a review of Svelto.ECS terminologies:
/// - Entity:
///     it must be a real and concrete entity that you can explain
///     in terms of game design. The name of each entity should reflect
///     a specific concept from the game design domain
/// - IComponents:
///     Components must be seen as data holders. There are implementing
///     exceptions, but logically it must be still see as a group
///     of readable or writeable data.
///     In Svelto.ECS components are always interfaces declaring
///     Setters and Getters of ValueTypes. DispatchOnSet
///     and DispatchOnChange must not be seen as events, but
///     as pushing of data instead of data polling, similar
///     to the concept of DataBinding.
/// - Implementors:
///     Being components interfaces, they must be implemented through
///     Implementors. The relation Implementors to Components
///     is not 1:1 so that you can, if logic, group several
///     components in one implementor. This allows to easily
///     share data between components. Implementors also act
///     as bridge between the platform and Svelto.ECS.
///     Since Components can hold only value types, Implementors
///     are the objects that can interact directly with the platform
///     objects, I.E.: RigidBody, Transform and so on.
///     Note: IComponents must hold only valuetypes for
///     code design purposes and not optmization purposes.
///     The reason is that all the logic must lie in the engines
///     so Components cannot hold references to instances that can
///     expose functions with logic.
/// - Engines:
///     Where all the logic lies. Engines operates on EntityViews
/// - EntityViews:
///     EntityViews maps EntityComponents. The Engines can't
///     access directly to each entity (as a single set of components), but
///     through a component sets defined by EntityView.
///     They act as a component filters and expose only the entity components
///     that the Engine is interested in.
///     EntityViews are actually defined by the need of the Engine so they
///     come together with the engine and in the same namespace of the engine.
/// - EntityStructs:
///     In order to write Data Oriented Cache Friendly code, Svelto.ECS
///     also support EntityStructs. Please check other examples to
///     understand how to use them. However know that this kind of
///     optimizations is very limited to special circumstances
///     so the flexibility of EntityViews is most of the times what you need.
/// - EntityDescriptors:
///     Gives a way to formalize your Entity in svelto.ECS, it also
///     groups the EntityViews that must be generated once the
///     Entity is built
/// </summary>
        void SetupEnginesAndEntities()
        {
            //The Engines Root is the core of Svelto.ECS. You must NEVER inject the EngineRoot
            //as it is, therefore the composition root must hold a reference or it will be
            //GCed.
            //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know
            //when to inject the EntityViews. You shouldn't use a custom one unless you know what you
            //are doing or you are not working with Unity.
            _enginesRoot = new EnginesRoot(new UnitySumbmissionEntityViewScheduler());
            //Engines root can never be held by anything else than the context itself to avoid leaks
            //That's why the EntityFactory and EntityFunctions are generated.
            //The EntityFactory can be injected inside factories (or engine acting as factories)
            //to build new entities dynamically
            _entityFactory = _enginesRoot.GenerateEntityFactory();
            //The entity functions is a set of utility operations on Entities, including
            //removing an entity. I couldn't find a better name so far.
            var entityFunctions = _enginesRoot.GenerateEntityFunctions();
            //GameObjectFactory allows to create GameObjects without using the Static
            //method GameObject.Instantiate. While it seems a complication
            //it's important to keep the engines testable and not
            //coupled with hard dependencies references (read my articles to understand
            //how dependency injection works and why solving dependencies
            //with static classes and singletons is a terrible mistake)
            GameObjectFactory factory = new GameObjectFactory();
            //the ISequencer is one of the 3 official ways available in Svelto.ECS
            //to communicate. They are mainly used for two specific cases:
            //1) specify a strict execution order between engines (engine logic
            //is executed horizontally instead than vertically, I will talk about this
            //in my articles). 2) filter a data token passed as parameter through
            //engines. The ISequencer is also not the common way to communicate
            //between engines
            Sequencer playerDamageSequence = new Sequencer();
            Sequencer enemyDamageSequence  = new Sequencer();

            //wrap non testable unity static classes, so that
            //can be mocked if needed.
            IRayCaster rayCaster = new RayCaster();
            ITime      time      = new Time();

            //Player related engines. ALL the dependecies must be solved at this point
            //through constructor injection.
            var playerHealthEngine    = new HealthEngine(playerDamageSequence);
            var playerShootingEngine  = new PlayerGunShootingEngine(enemyDamageSequence, rayCaster, time);
            var playerMovementEngine  = new PlayerMovementEngine(rayCaster, time);
            var playerAnimationEngine = new PlayerAnimationEngine();
            var playerDeathEngine     = new PlayerDeathEngine(entityFunctions);

            //Enemy related engines
            var enemyAnimationEngine = new EnemyAnimationEngine(time);
            //HealthEngine is a different object for the enemy because it uses a different sequence
            var enemyHealthEngine   = new HealthEngine(enemyDamageSequence);
            var enemyAttackEngine   = new EnemyAttackEngine(playerDamageSequence, time);
            var enemyMovementEngine = new EnemyMovementEngine();
            var enemySpawnerEngine  = new EnemySpawnerEngine(factory, _entityFactory);
            var enemyDeathEngine    = new EnemyDeathEngine(entityFunctions);

            //hud and sound engines
            var hudEngine         = new HUDEngine(time);
            var damageSoundEngine = new DamageSoundEngine();
            var scoreEngine       = new ScoreEngine();

            //The ISequencer implementaton is very simple, but allows to perform
            //complex concatenation including loops and conditional branching.
            playerDamageSequence.SetSequence(
                new Steps              //sequence of steps, this is a dictionary!
            {
                {                      //first step
                    enemyAttackEngine, //this step can be triggered only by this engine through the Next function
                    new To             //this step can lead only to one branch
                    {
                        //this is the only engine that will be called when enemyAttackEngine triggers Next()
                        new IStep[] { playerHealthEngine }
                    }
                },
                {                       //second step
                    playerHealthEngine, //this step can be triggered only by this engine through the Next function
                    new To              //once the playerHealthEngine calls step, all these engines will be called at once
                                        //depending by the condition a different set of engines will be triggered. The
                                        //order of the engines triggered is guaranteed.
                    {
                        //these engines will be called when the Next function is called with the DamageCondition.damage set
                        { DamageCondition.Damage, new IStep[] { hudEngine, damageSoundEngine } },
                        //these engines will be called when the Next function is called with the DamageCondition.dead set
                        { DamageCondition.Dead, new IStep[] {
                              hudEngine, damageSoundEngine,
                              playerMovementEngine, playerAnimationEngine,
                              enemyAnimationEngine, playerDeathEngine
                          } }
                    }
                }
            }
                );

            enemyDamageSequence.SetSequence(
                new Steps
            {
                {
                    playerShootingEngine,
                    new To
                    {
                        //in every case go to enemyHealthEngine
                        new IStep[] { enemyHealthEngine }
                    }
                },
                {
                    enemyHealthEngine,
                    new To
                    {
                        { DamageCondition.Damage, new IStep[] { enemyAnimationEngine, damageSoundEngine } },
                        { DamageCondition.Dead, new IStep[] { scoreEngine, enemyMovementEngine,
                                                              enemyAnimationEngine, enemySpawnerEngine,
                                                              damageSoundEngine, enemyDeathEngine } },
                    }
                }
            }
                );

            //Mandatory step to make engines work
            //Player engines
            _enginesRoot.AddEngine(playerMovementEngine);
            _enginesRoot.AddEngine(playerAnimationEngine);
            _enginesRoot.AddEngine(playerShootingEngine);
            _enginesRoot.AddEngine(playerHealthEngine);
            _enginesRoot.AddEngine(new PlayerInputEngine());
            _enginesRoot.AddEngine(new PlayerGunShootingFXsEngine());
            //enemy engines
            _enginesRoot.AddEngine(enemySpawnerEngine);
            _enginesRoot.AddEngine(enemyAttackEngine);
            _enginesRoot.AddEngine(enemyMovementEngine);
            _enginesRoot.AddEngine(enemyAnimationEngine);
            _enginesRoot.AddEngine(enemyHealthEngine);
            _enginesRoot.AddEngine(enemyDeathEngine);
            //other engines
            _enginesRoot.AddEngine(new CameraFollowTargetEngine(time));
            _enginesRoot.AddEngine(damageSoundEngine);
            _enginesRoot.AddEngine(hudEngine);
            _enginesRoot.AddEngine(scoreEngine);
        }
示例#23
0
        private static bool CheckIfCollidingOnX(Vector3 pos, float dist)
        {
            var ray = new Ray(pos, dist > 0 ? Vector3.right : Vector3.left);

            return(RayCaster.CastRay(ray, Mathf.Abs(dist)));
        }
示例#24
0
        public override RayResult OnIntersection(RayResult original, Vector2f O, float angle, RayCaster caster)
        {
            int points = LineCircleIntersections(caster.CellSize * original.Tile.X + (caster.CellSize / 2),
                                                 caster.CellSize * original.Tile.Y + (caster.CellSize / 2),
                                                 caster.CellSize / 2,
                                                 original.Position,
                                                 original.Position + new Vector2f(300 * CosD(angle), 300 * SinD(angle)),
                                                 out Vector2f p1, out Vector2f p2);

            switch (points)
            {
            case 0:
                original.Valid = false;
                return(original);

            case 1:
                return(new RayResult
                {
                    Valid = true,
                    Magnitude = Distance(O, p1),
                    Side = Side.None,
                    Position = p1,
                    Tile = original.Tile
                });

            case 2:
                Vector2f final = Distance(O, p1) <= Distance(O, p2) ? p1 : p2;
                return(new RayResult
                {
                    Valid = true,
                    Magnitude = Distance(O, final),
                    Side = Side.None,
                    Position = final,
                    Tile = original.Tile
                });
            }

            original.Valid = true;
            return(original);
        }
示例#25
0
        /// <summary>
        ///     Before to start, let's review some of the Svelto.ECS terms:
        ///     - Entity:
        ///     it must be a real and concrete entity that you can explain in terms of game design. The name of each
        ///     entity should reflect a specific concept from the game design domain
        ///     - Engines (Systems):
        ///     Where all the logic lies. Engines operates on Entity Components
        ///     - IEntityComponent:
        ///     It's an Entity Component which can be used with Pure ECS
        ///     - IEntityViewComponent:
        ///     structs implementing this are used to wrap Objects that come from OOP libraries. You will never use it unless
        ///     you are forced to mix your ECS code with OOP code because of external libraries or platforms. These special
        ///     "Hybrid" component can hold only interfaces
        ///     - Implementors:
        ///     The EntityViewComponent exposed interfaces must be implemented by Implementors that are actually the
        ///     Objects you need to wrap.
        ///     - EntityDescriptors:
        ///     Gives a way to formalise your Entity, it also defines the components that must
        ///     be generated once the Entity is built
        /// </summary>
        void CompositionRoot(UnityContext contextHolder)
        {
            //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know
            //when to submit the entities. Custom ones can be created for special cases.
            var unityEntitySubmissionScheduler = new UnityEntitiesSubmissionScheduler("survival");

            //The Engines Root is the core of Svelto.ECS. You shouldn't inject the EngineRoot,
            //therefore the composition root class must hold a reference or it will be garbage collected.
            _enginesRoot = new EnginesRoot(unityEntitySubmissionScheduler);
            //The EntityFactory can be injected inside factories (or engine acting as factories) to build new entities
            //dynamically
            var entityFactory = _enginesRoot.GenerateEntityFactory();
            //The entity functions is a set of utility operations on Entities, including removing an entity. I couldn't
            //find a better name so far.
            var entityFunctions             = _enginesRoot.GenerateEntityFunctions();
            var entityStreamConsumerFactory = _enginesRoot.GenerateConsumerFactory();

            //wrap non testable unity static classes, so that can be mocked if needed (or implementation can change in general, without changing the interface).
            IRayCaster rayCaster = new RayCaster();
            ITime      time      = new Time();
            //GameObjectFactory allows to create GameObjects without using the Static method GameObject.Instantiate.
            //While it seems a complication it's important to keep the engines testable and not coupled with hard
            //dependencies
            var gameObjectFactory = new GameObjectFactory();

            //Player related engines. ALL the dependencies must be solved at this point through constructor injection.
            var playerShootingEngine       = new PlayerGunShootingEngine(rayCaster, time);
            var playerMovementEngine       = new PlayerMovementEngine(rayCaster);
            var playerAnimationEngine      = new PlayerAnimationEngine();
            var playerDeathEngine          = new PlayerDeathEngine(entityFunctions, entityStreamConsumerFactory);
            var playerInputEngine          = new PlayerInputEngine();
            var playerGunShootingFXsEngine = new PlayerGunShootingFXsEngine(entityStreamConsumerFactory);
            //Spawner engines are factories engines that can build entities
            var playerSpawnerEngine      = new PlayerSpawnerEngine(gameObjectFactory, entityFactory);
            var restartGameOnPlayerDeath = new RestartGameOnPlayerDeathEngine();

            //Player engines
            _enginesRoot.AddEngine(playerMovementEngine);
            _enginesRoot.AddEngine(playerAnimationEngine);
            _enginesRoot.AddEngine(playerShootingEngine);
            _enginesRoot.AddEngine(playerInputEngine);
            _enginesRoot.AddEngine(playerGunShootingFXsEngine);
            _enginesRoot.AddEngine(playerDeathEngine);
            _enginesRoot.AddEngine(playerSpawnerEngine);
            _enginesRoot.AddEngine(restartGameOnPlayerDeath);

            //Factory is one of the few OOP patterns that work very well with ECS. Its use is highly encouraged
            var enemyFactory = new EnemyFactory(gameObjectFactory, entityFactory);
            //Enemy related engines
            var enemyAnimationEngine = new EnemyChangeAnimationOnPlayerDeath();
            var enemyDamageFX        = new EnemySpawnEffectOnDamage(entityStreamConsumerFactory);
            var enemyAttackEngine    = new EnemyAttackEngine(time);
            var enemyMovementEngine  = new EnemyMovementEngine();
            //Spawner engines are factories engines that can build entities
            var enemySpawnerEngine = new EnemySpawnerEngine(enemyFactory, entityFunctions);
            var enemyDeathEngine   = new EnemyDeathEngine(entityFunctions, entityStreamConsumerFactory, time
                                                          , new WaitForSubmissionEnumerator(
                                                              unityEntitySubmissionScheduler));

            //enemy engines
            _enginesRoot.AddEngine(enemySpawnerEngine);
            _enginesRoot.AddEngine(enemyAttackEngine);
            _enginesRoot.AddEngine(enemyMovementEngine);
            _enginesRoot.AddEngine(enemyAnimationEngine);
            _enginesRoot.AddEngine(enemyDeathEngine);
            _enginesRoot.AddEngine(enemyDamageFX);

            //abstract engines
            var applyDamageEngine        = new ApplyDamageToDamageableEntitiesEngine(entityStreamConsumerFactory);
            var cameraFollowTargetEngine = new CameraFollowingTargetEngine(time);
            var deathEngine = new DispatchKilledEntitiesEngine();

            //abstract engines (don't need to know the entity type)
            _enginesRoot.AddEngine(applyDamageEngine);
            _enginesRoot.AddEngine(deathEngine);
            _enginesRoot.AddEngine(cameraFollowTargetEngine);

            //hud and sound engines
            var hudEngine         = new HUDEngine(entityStreamConsumerFactory);
            var damageSoundEngine = new DamageSoundEngine(entityStreamConsumerFactory);
            var scoreEngine       = new UpdateScoreEngine(entityStreamConsumerFactory);

            //other engines
            _enginesRoot.AddEngine(damageSoundEngine);
            _enginesRoot.AddEngine(hudEngine);
            _enginesRoot.AddEngine(scoreEngine);

            var unsortedEngines = new SurvivalUnsortedEnginesGroup(new FasterList <IStepEngine>(
                                                                       new IStepEngine[]
            {
                playerMovementEngine,
                playerInputEngine,
                playerGunShootingFXsEngine,
                playerSpawnerEngine,
                playerAnimationEngine,
                enemySpawnerEngine,
                enemyMovementEngine,
                cameraFollowTargetEngine,
                hudEngine,
                restartGameOnPlayerDeath
            }
                                                                       ));

            var unsortedDamageEngines = new DamageUnsortedEngines(new FasterList <IStepEngine>(
                                                                      new IStepEngine[]
            {
                applyDamageEngine,
                damageSoundEngine,
                deathEngine
            }
                                                                      ));

            //Svelto ECS doesn't provide a tick system, hence it doesn't provide a solution to solve the order of execution
            //However it provides some option if you want to use them like the SortedEnginesGroup.
            _enginesRoot.AddEngine(new TickEnginesGroup(new FasterList <IStepEngine>(new IStepEngine[]
            {
                unsortedEngines
                , playerShootingEngine
                , enemyDamageFX
                , enemyAttackEngine
                , unsortedDamageEngines
                , playerDeathEngine
                , enemyDeathEngine
                , scoreEngine
            })));

            BuildGUIEntitiesFromScene(contextHolder, entityFactory);
        }
示例#26
0
        public override (Vector2f top, Vector2f bottom) CalculateTextureCoords(RayResult original, Vector2f O, float angle, RayCaster caster)
        {
            float tx = Atan2(caster.CellSize * original.Tile.Y + (caster.CellSize / 2) - original.Position.Y,
                             caster.CellSize * original.Tile.X + (caster.CellSize / 2) - original.Position.X) + (float)Math.PI;

            tx  = (float)((tx * caster.CellSize) / (Math.PI * 2));
            tx *= 4;
            tx %= (float)(Math.PI * 2);
            Vector2f top = new Vector2f(
                DownAtlas.X * caster.CellSize + tx,
                DownAtlas.Y * caster.CellSize);
            Vector2f bottom = new Vector2f(
                top.X,
                top.Y + caster.CellSize);

            return(top, bottom);
        }
示例#27
0
 protected virtual void Awake()
 {
     objectCollider = GetComponent <BoxCollider2D>();
     rayCaster      = GetComponent <RayCaster>();
     thisTransform  = transform;
 }
示例#28
0
 //Public interface
 public virtual RayResult OnIntersection(RayResult original, Vector2f O, float angle, RayCaster caster)
 {
     original.Valid = true;
     return(original);
 }
示例#29
0
        public virtual (Vector2f top, Vector2f bottom) CalculateTextureCoords(RayResult original, Vector2f O, float angle, RayCaster caster)
        {
            Vector2f textureCordUp;
            Vector2f textureCordDown;

            switch (original.Side)
            {
            case Side.Down:
                textureCordUp = new Vector2f(
                    DownAtlas.X * caster.CellSize + (original.Position.X % caster.CellSize),
                    DownAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize);
                break;

            case Side.Up:
                textureCordUp = new Vector2f(
                    UpAtlas.X * caster.CellSize + (original.Position.X % caster.CellSize),
                    UpAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize);
                break;

            case Side.Left:
                textureCordUp = new Vector2f(
                    LeftAtlas.X * caster.CellSize + (original.Position.Y % caster.CellSize),
                    LeftAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize);
                break;

            case Side.Right:
                textureCordUp = new Vector2f(
                    RightAtlas.X * caster.CellSize + (original.Position.Y % caster.CellSize),
                    RightAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize);
                break;

            default:
                textureCordUp = new Vector2f(
                    (original.Position.Y % caster.CellSize),
                    RightAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize - 1);
                break;
            }

            return(textureCordUp, textureCordDown);
        }
示例#30
0
 private Collider[] GetMarkersWithinArea(Vector3 point, Vector3 currSize)
 {
     Collider[] overlaps = RayCaster.OverLapBoxTriggersIncludeMarkers(point, currSize, Quaternion.identity, markerLayerMask);
     return(overlaps);
 }