Source

Bricle / Bricle / Bricle / Screens / PlayScreen.cs

Full commit
using Bricle.Entities.Systems;
using Bricle.Entities.Templates;
using Bricle.Screens.Components;
using Engine;
using Engine.EntitySystems;
using Engine.Screens;
using Engine.Screens.Components;
using Engine.Tools.Cameras;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using Bricle.Entities.Components;
using FarseerPhysics.Dynamics.Contacts;
using System;

namespace Bricle.Screens
{
    class PlayScreen : Screen
    {
        EntityManager _entities;

        readonly float _width = 500;
        readonly float _height = 800;
        
        // Managers
        CameraManager _cameras;
        TimerManager _timers;

        // Systems
        Drawables _drawables;
        InputMoveables _movement;
        Physics _physics;
        World _world;

        // Entities
        Entity _ball;
        Entity _paddle;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="game"></param>
        public PlayScreen(Core game) 
            : base(game)
        {
            _game = game;
            _entities = new EntityManager();
            _world = new World(Vector2.Zero);
            FarseerPhysics.Settings.EnableDiagnostics = false;
            FarseerPhysics.Settings.ContinuousPhysics = false;
            FarseerPhysics.Settings.AllowSleep = true;

            // Basic components
            _timers = new TimerManager();
            _cameras = new CameraManager(game);
            _cameras.Active = new OrthographicCamera(game.GraphicsDevice);

            // Components
            _drawables = new Drawables(_entities, game.GraphicsDevice, _cameras);
            _movement = new InputMoveables(_entities);
            _physics = new Physics(_entities, _world);

            Components.Add(
                _cameras,
                _timers,
                _movement,
                _physics,
                _drawables);


            // Create entities
            _entities.Create(new Wall(_world, _width, 10, new Vector2(_width / 2, 0)));
            _entities.Create(new Wall(_world, 10, _height, new Vector2(0, _height / 2)));
            _entities.Create(new Wall(_world, 10, _height, new Vector2(_width, _height / 2)));

            // Paddle
            _paddle = _entities.Create(new Paddle(_world, 100, 10, new Vector2(_width / 2, _height - 30)));

            // Exit
            _entities.Create(new Exit(_world, _width, 30, new Vector2(_width / 2, _height), CollisionHander));

            // Ball
            _ball = _entities.Create(new Ball(_world, 10, CollisionHander));
            //_ball.IsActive = false;
        }

        public override void Update(GameTime time)
        {
            if (Core.Input.Keyboard.IsNewKeyPress(Microsoft.Xna.Framework.Input.Keys.Space))
            {
                //if (!_ball.IsActive)
                {
                    _ball.IsActive = true;
                    _ball.As<Physical>().Body.ResetDynamics();
                    _ball.As<Physical>().Body.Position = _paddle.As<Physical>().Body.Position - new Vector2(0, 15);

                    _ball.As<Physical>().Body.ApplyLinearImpulse(new Vector2(0, -100000));
                }
            }

            base.Update(time);
        }

        public override void Draw(GameTime time)
        {
            _game.GraphicsDevice.Clear(new Color(30, 30, 30));
            base.Draw(time);
        }

        /// <summary>
        /// Handle entity collisions
        /// </summary>
        /// <param name="fixtureA"></param>
        /// <param name="fixtureB"></param>
        /// <param name="contact"></param>
        /// <returns></returns>
        private bool CollisionHander(Fixture a, Fixture b, Contact contact)
        {
            if (FixturesAre<Paddle, Ball>(a, b))
            {
                System.Diagnostics.Debug.WriteLine("Paddle - ball.");
            }
            else if (FixturesAre<Exit, Ball>(a, b))
            {
                System.Diagnostics.Debug.WriteLine("Exit - ball.");
                _ball.IsActive = false;
                return false;
            }

            return true;
        }

        private bool FixtureIs<T>(Fixture f)
        {
            if (f == null)
                return false;

            ulong? e = (ulong?)f.Body.UserData;

            if (e == null)
                return false;

            return _entities[(ulong)e].Template == typeof(T);
        }

        private bool FixturesAre<T1, T2>(Fixture fixtureA, Fixture fixtureB)
        {
            if (fixtureA == null || fixtureB == null)
                return false;

            ulong? e1 = (ulong?)fixtureA.Body.UserData;
            ulong? e2 = (ulong?)fixtureB.Body.UserData;

            if (e1 == null || e2 == null)
                return false;

            if (_entities[(ulong)e1].Template == typeof(T1) &&
                _entities[(ulong)e2].Template == typeof(T2))
                return true;

            if (_entities[(ulong)e1].Template == typeof(T2) &&
                _entities[(ulong)e2].Template == typeof(T1))
                return true;

            return false;
        }
    }
}