Compare commits
53 Commits
Author | SHA1 | Date |
---|---|---|
Syntriax | 73ae55e1d4 | |
Syntriax | a35e25eb31 | |
Syntriax | 775f24c560 | |
Syntriax | 257e414c2a | |
Syntriax | 0cb8170530 | |
Syntriax | bbf71f0be6 | |
Syntriax | 41a17219b6 | |
Syntriax | 29e79cdf26 | |
Syntriax | b7a4fe9cb0 | |
Syntriax | da83802427 | |
Syntriax | 364c383e08 | |
Syntriax | 1fd8060857 | |
Syntriax | 35933dfd14 | |
Syntriax | d66b119119 | |
Syntriax | e7ee460323 | |
Syntriax | e86cf71010 | |
Syntriax | a357f0fdcb | |
Syntriax | ff3202eda9 | |
Syntriax | 8929d3282f | |
Syntriax | bc7925dbab | |
Syntriax | 80ee5d760a | |
Syntriax | de2d5fb446 | |
Syntriax | 753c0031cd | |
Syntriax | a734f52b38 | |
Syntriax | 4cb9c7dc8d | |
Syntriax | fe4618abd3 | |
Syntriax | 283556d329 | |
Syntriax | 5ef3d491c3 | |
Syntriax | 46f589d3aa | |
Syntriax | b7d49e41c3 | |
Syntriax | 677fec7acc | |
Syntriax | a9c7b8b660 | |
Syntriax | 958a75552f | |
Syntriax | 3717701171 | |
Syntriax | 4e95a3a420 | |
Syntriax | ad60412d5f | |
Syntriax | 0b2158cc7b | |
Syntriax | 3580469a07 | |
Syntriax | a7e8787579 | |
Syntriax | 45df32dabb | |
Syntriax | b3af693678 | |
Syntriax | c87827d1ef | |
Syntriax | c2d2e1fd52 | |
Syntriax | 7ad2cc5912 | |
Syntriax | ca92b12833 | |
Syntriax | fbe3087502 | |
Syntriax | ef347320fd | |
Syntriax | 1207d04d50 | |
Syntriax | 26f11b5cc0 | |
Syntriax | 481a49bb52 | |
Syntriax | ffe4fc044e | |
Syntriax | 91b05c97c4 | |
Syntriax | 11074b89d5 |
2
Engine
2
Engine
|
@ -1 +1 @@
|
||||||
Subproject commit 6a104d8abd013334ed2787c4b4c6fa6481e4c6a4
|
Subproject commit ef21cdf2138a2f5107a628c0fe970b88bc03dcfd
|
|
@ -1,6 +1,6 @@
|
||||||
using Apos.Shapes;
|
using Apos.Shapes;
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
public interface IDisplayableShape
|
public interface IDisplayableShape
|
||||||
{
|
{
|
|
@ -2,7 +2,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
namespace Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
public interface IDisplayable
|
public interface IDisplayableSprite
|
||||||
{
|
{
|
||||||
public void Draw(SpriteBatch spriteBatch);
|
public void Draw(SpriteBatch spriteBatch);
|
||||||
}
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Physics2D;
|
||||||
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
|
public class BallBehaviour : BehaviourOverride
|
||||||
|
{
|
||||||
|
public Vector2D StartDirection { get; private set; } = Vector2D.Zero;
|
||||||
|
public float Speed { get; set; } = 500f;
|
||||||
|
public float SpeedUpMultiplier { get; set; } = .0125f;
|
||||||
|
|
||||||
|
private readonly Random random = new();
|
||||||
|
private IRigidBody2D rigidBody = null!;
|
||||||
|
|
||||||
|
protected override void OnFirstActiveFrame()
|
||||||
|
{
|
||||||
|
if (!BehaviourController.TryGetBehaviour(out IRigidBody2D? foundRigidBody))
|
||||||
|
throw new Exception($"{nameof(IRigidBody2D)} is missing on {GameObject.Name}.");
|
||||||
|
if (!BehaviourController.TryGetBehaviour(out ICollider2D? foundCollider))
|
||||||
|
throw new Exception($"{nameof(ICollider2D)} is missing on {GameObject.Name}.");
|
||||||
|
|
||||||
|
foundCollider.OnCollisionDetected += OnCollisionDetected;
|
||||||
|
|
||||||
|
rigidBody = foundRigidBody;
|
||||||
|
|
||||||
|
if (GameObject.GameManager.TryFindBehaviour(out PongManagerBehaviour? pongManager))
|
||||||
|
{
|
||||||
|
pongManager.OnReset += ResetBall;
|
||||||
|
pongManager.OnScored += ResetBall;
|
||||||
|
pongManager.OnFinished += DisableBall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisableBall(PongManagerBehaviour pongManager)
|
||||||
|
{
|
||||||
|
BehaviourController.GameObject.Transform.Position = Vector2D.Zero;
|
||||||
|
rigidBody.Velocity = Vector2D.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetBall(PongManagerBehaviour pongManager)
|
||||||
|
{
|
||||||
|
StateEnable.Enabled = true;
|
||||||
|
BehaviourController.GameObject.Transform.Position = Vector2D.Zero;
|
||||||
|
rigidBody.Velocity = GetRandomDirection() * Speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector2D GetRandomDirection()
|
||||||
|
{
|
||||||
|
const float AllowedRadians = 45f * Syntriax.Engine.Core.Math.DegreeToRadian;
|
||||||
|
float rotation = (float)random.NextDouble() * 2f * AllowedRadians - AllowedRadians;
|
||||||
|
bool isBackwards = (random.Next() % 2) == 1;
|
||||||
|
return Vector2D.Right.Rotate(isBackwards ? rotation + Syntriax.Engine.Core.Math.PI : rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate()
|
||||||
|
{
|
||||||
|
if (rigidBody.Velocity.MagnitudeSquared <= 0.01f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vector2D speedUp = rigidBody.Velocity.Normalized * Time.DeltaTimeFrame;
|
||||||
|
rigidBody.Velocity += speedUp * SpeedUpMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCollisionDetected(ICollider2D collider2D, CollisionDetectionInformation information)
|
||||||
|
{
|
||||||
|
if (Syntriax.Engine.Core.Math.Abs(information.Normal.Dot(Vector2D.Right)) > .25)
|
||||||
|
rigidBody.Velocity = information.Left.Transform.Position.FromTo(information.Right.Transform.Position).Normalized * rigidBody.Velocity.Magnitude;
|
||||||
|
else
|
||||||
|
rigidBody.Velocity = rigidBody.Velocity.Reflect(information.Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BallBehaviour() { }
|
||||||
|
public BallBehaviour(Vector2D startDirection, float speed)
|
||||||
|
{
|
||||||
|
StartDirection = Vector2D.Normalize(startDirection);
|
||||||
|
Speed = speed;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Input;
|
||||||
|
|
||||||
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
|
public class CameraController : BehaviourOverride
|
||||||
|
{
|
||||||
|
private MonoGameCamera2DBehaviour cameraBehaviour = null!;
|
||||||
|
private IButtonInputs<Keys> buttonInputs = null!;
|
||||||
|
|
||||||
|
private float defaultZoomLevel = 1f;
|
||||||
|
|
||||||
|
protected override void OnFirstActiveFrame()
|
||||||
|
{
|
||||||
|
if (BehaviourController.TryGetBehaviour(out MonoGameCamera2DBehaviour? foundCameraBehaviour))
|
||||||
|
cameraBehaviour = foundCameraBehaviour;
|
||||||
|
|
||||||
|
cameraBehaviour ??= BehaviourController.AddBehaviour<MonoGameCamera2DBehaviour>();
|
||||||
|
|
||||||
|
if (BehaviourController.TryGetBehaviour(out IButtonInputs<Keys>? foundButtonInputs))
|
||||||
|
buttonInputs = foundButtonInputs;
|
||||||
|
|
||||||
|
buttonInputs ??= BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
|
||||||
|
buttonInputs.RegisterOnPress(Keys.F, SwitchToFullScreen);
|
||||||
|
buttonInputs.RegisterOnPress(Keys.R, ResetCamera);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate()
|
||||||
|
{
|
||||||
|
if (buttonInputs.IsPressed(Keys.U))
|
||||||
|
cameraBehaviour.Zoom += Time.Elapsed.Nanoseconds * 0.00025f;
|
||||||
|
if (buttonInputs.IsPressed(Keys.J))
|
||||||
|
cameraBehaviour.Zoom -= Time.Elapsed.Nanoseconds * 0.00025f;
|
||||||
|
|
||||||
|
|
||||||
|
if (buttonInputs.IsPressed(Keys.NumPad8)) cameraBehaviour.BehaviourController.GameObject.Transform.Position += Vector2D.Up.Rotate(Transform.Rotation * Math.DegreeToRadian) * Time.DeltaTimeFrame;
|
||||||
|
if (buttonInputs.IsPressed(Keys.NumPad2)) cameraBehaviour.BehaviourController.GameObject.Transform.Position -= Vector2D.Up.Rotate(Transform.Rotation * Math.DegreeToRadian) * Time.DeltaTimeFrame;
|
||||||
|
if (buttonInputs.IsPressed(Keys.NumPad6)) cameraBehaviour.BehaviourController.GameObject.Transform.Position += Vector2D.Right.Rotate(Transform.Rotation * Math.DegreeToRadian) * Time.DeltaTimeFrame;
|
||||||
|
if (buttonInputs.IsPressed(Keys.NumPad4)) cameraBehaviour.BehaviourController.GameObject.Transform.Position -= Vector2D.Right.Rotate(Transform.Rotation * Math.DegreeToRadian) * Time.DeltaTimeFrame;
|
||||||
|
|
||||||
|
|
||||||
|
if (buttonInputs.IsPressed(Keys.Q))
|
||||||
|
cameraBehaviour.BehaviourController.GameObject.Transform.Rotation += Time.Elapsed.Nanoseconds * 0.0025f;
|
||||||
|
if (buttonInputs.IsPressed(Keys.E))
|
||||||
|
cameraBehaviour.BehaviourController.GameObject.Transform.Rotation -= Time.Elapsed.Nanoseconds * 0.0025f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SwitchToFullScreen(IButtonInputs<Keys> inputs, Keys keys)
|
||||||
|
{
|
||||||
|
if (cameraBehaviour.Graphics.IsFullScreen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cameraBehaviour.Graphics.PreferMultiSampling = false;
|
||||||
|
cameraBehaviour.Graphics.PreferredBackBufferWidth = cameraBehaviour.Graphics.GraphicsDevice.Adapter.CurrentDisplayMode.Width;
|
||||||
|
cameraBehaviour.Graphics.PreferredBackBufferHeight = cameraBehaviour.Graphics.GraphicsDevice.Adapter.CurrentDisplayMode.Height;
|
||||||
|
cameraBehaviour.Graphics.IsFullScreen = true;
|
||||||
|
cameraBehaviour.Graphics.ApplyChanges();
|
||||||
|
|
||||||
|
float previousScreenSize = Math.Sqrt(Math.Sqr(cameraBehaviour.Viewport.Width) + Math.Sqr(cameraBehaviour.Viewport.Height));
|
||||||
|
float currentScreenSize = Math.Sqrt(Math.Sqr(cameraBehaviour.Graphics.GraphicsDevice.Viewport.Width) + Math.Sqr(cameraBehaviour.Graphics.GraphicsDevice.Viewport.Height));
|
||||||
|
defaultZoomLevel /= previousScreenSize / currentScreenSize;
|
||||||
|
cameraBehaviour.Zoom /= previousScreenSize / currentScreenSize;
|
||||||
|
cameraBehaviour.Viewport = cameraBehaviour.Graphics.GraphicsDevice.Viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetCamera(IButtonInputs<Keys> inputs, Keys keys)
|
||||||
|
{
|
||||||
|
cameraBehaviour.Zoom = defaultZoomLevel;
|
||||||
|
Transform.Position = Vector2D.Zero;
|
||||||
|
Transform.Rotation = 0f;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,22 +2,28 @@ using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
using Apos.Shapes;
|
using Apos.Shapes;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Primitives;
|
using Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
public class CircleBehaviour : Syntriax.Engine.Physics2D.Collider2DCircleBehaviour, IDisplayableShape
|
public class CircleBehaviour : Syntriax.Engine.Physics2D.Collider2DCircleBehaviour, IDisplayableShape
|
||||||
{
|
{
|
||||||
public CircleBehaviour(Circle circle) { this.CircleLocal = circle; }
|
|
||||||
public CircleBehaviour(Circle circle, float Thickness) { this.CircleLocal = circle; this.Thickness = Thickness; }
|
|
||||||
public CircleBehaviour(Circle circle, Color color) { this.CircleLocal = circle; Color = color; }
|
|
||||||
public CircleBehaviour(Circle circle, Color color, float Thickness) { this.CircleLocal = circle; this.Thickness = Thickness; Color = color; }
|
|
||||||
|
|
||||||
public Color Color { get; set; } = Color.White;
|
public Color Color { get; set; } = Color.White;
|
||||||
public float Thickness { get; set; } = .5f;
|
public float Thickness { get; set; } = .5f;
|
||||||
|
|
||||||
public void Draw(ShapeBatch shapeBatch)
|
public void Draw(ShapeBatch shapeBatch)
|
||||||
{
|
{
|
||||||
|
if (!IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Recalculate();
|
||||||
|
|
||||||
shapeBatch.BorderCircle(CircleWorld.Center.ToDisplayVector2(), CircleWorld.Radius, Color);
|
shapeBatch.BorderCircle(CircleWorld.Center.ToDisplayVector2(), CircleWorld.Radius, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CircleBehaviour(Circle circle) : base(circle) { }
|
||||||
|
public CircleBehaviour(Circle circle, float thickness) : base(circle) { Thickness = thickness; }
|
||||||
|
public CircleBehaviour(Circle circle, Color color) : base(circle) { Color = color; }
|
||||||
|
public CircleBehaviour(Circle circle, Color color, float thickness) : base(circle) { Thickness = thickness; Color = color; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
|
public class MonoGameCamera2DBehaviour(GraphicsDeviceManager Graphics) : BehaviourOverride, ICamera2D
|
||||||
|
{
|
||||||
|
public event OnMatrixTransformChangedDelegate? OnMatrixTransformChanged = null;
|
||||||
|
public event OnViewportChangedDelegate? OnViewportChanged = null;
|
||||||
|
public event OnZoomChangedDelegate? OnZoomChanged = null;
|
||||||
|
|
||||||
|
private Matrix _matrixTransform = Matrix.Identity;
|
||||||
|
|
||||||
|
private Viewport _viewport = default;
|
||||||
|
private float _zoom = 1f;
|
||||||
|
|
||||||
|
public GraphicsDeviceManager Graphics { get; } = Graphics;
|
||||||
|
|
||||||
|
public Matrix MatrixTransform
|
||||||
|
{
|
||||||
|
get => _matrixTransform;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_matrixTransform == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_matrixTransform = value;
|
||||||
|
OnMatrixTransformChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2D Position
|
||||||
|
{
|
||||||
|
get => Transform.Position;
|
||||||
|
set => Transform.Position = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Viewport Viewport
|
||||||
|
{
|
||||||
|
get => _viewport;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_viewport.Equals(value))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_viewport = value;
|
||||||
|
OnViewportChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Zoom
|
||||||
|
{
|
||||||
|
get => _zoom;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
float newValue = Math.Max(0.1f, value);
|
||||||
|
|
||||||
|
if (_zoom == newValue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_zoom = newValue;
|
||||||
|
OnZoomChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Rotation
|
||||||
|
{
|
||||||
|
get => Transform.Rotation;
|
||||||
|
set => Transform.Rotation = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event IAssignableTransform.OnTransformAssignedDelegate? OnTransformAssigned { add => GameObject.OnTransformAssigned += value; remove => GameObject.OnTransformAssigned -= value; }
|
||||||
|
ITransform IAssignableTransform.Transform => GameObject.Transform;
|
||||||
|
bool IAssignableTransform.Assign(ITransform transform) => GameObject.Assign(transform);
|
||||||
|
|
||||||
|
// TODO This causes delay since OnPreDraw calls assuming this is called in in Update
|
||||||
|
public Vector2D ScreenToWorldPosition(Vector2D screenPosition)
|
||||||
|
{
|
||||||
|
Vector2D worldPosition = Vector2.Transform(screenPosition.ToVector2(), Matrix.Invert(MatrixTransform)).ToVector2D();
|
||||||
|
return worldPosition.Scale(EngineConverter.screenScale);
|
||||||
|
}
|
||||||
|
public Vector2D WorldToScreenPosition(Vector2D worldPosition)
|
||||||
|
{
|
||||||
|
Vector2D screenPosition = Vector2.Transform(worldPosition.ToVector2(), MatrixTransform).ToVector2D();
|
||||||
|
return screenPosition.Scale(EngineConverter.screenScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFirstActiveFrame()
|
||||||
|
=> Viewport = Graphics.GraphicsDevice.Viewport;
|
||||||
|
|
||||||
|
protected override void OnPreDraw()
|
||||||
|
{
|
||||||
|
MatrixTransform =
|
||||||
|
Matrix.CreateTranslation(new Vector3(-Position.X, Position.Y, 0f)) *
|
||||||
|
Matrix.CreateRotationZ(Rotation * Math.DegreeToRadian) *
|
||||||
|
Matrix.CreateScale(Zoom) *
|
||||||
|
Matrix.CreateTranslation(new Vector3(_viewport.Width * .5f, _viewport.Height * .5f, 0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void OnMatrixTransformChangedDelegate(MonoGameCamera2DBehaviour sender);
|
||||||
|
public delegate void OnViewportChangedDelegate(MonoGameCamera2DBehaviour sender);
|
||||||
|
public delegate void OnZoomChangedDelegate(MonoGameCamera2DBehaviour sender);
|
||||||
|
}
|
|
@ -1,106 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
|
||||||
|
|
||||||
public class MonoGameCameraBehaviour : BehaviourOverride, ICamera
|
|
||||||
{
|
|
||||||
public Action<ICamera>? OnPositionChanged { get; set; } = null;
|
|
||||||
public Action<ICamera>? OnMatrixTransformChanged { get; set; } = null;
|
|
||||||
public Action<ICamera>? OnViewportChanged { get; set; } = null;
|
|
||||||
public Action<ICamera>? OnRotationChanged { get; set; } = null;
|
|
||||||
public Action<ICamera>? OnZoomChanged { get; set; } = null;
|
|
||||||
|
|
||||||
private Matrix _matrixTransform = Matrix.Identity;
|
|
||||||
|
|
||||||
private Viewport _viewport = default;
|
|
||||||
|
|
||||||
private float _zoom = 1f;
|
|
||||||
|
|
||||||
public Matrix MatrixTransform
|
|
||||||
{
|
|
||||||
get => _matrixTransform;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_matrixTransform == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_matrixTransform = value;
|
|
||||||
OnMatrixTransformChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2D Position
|
|
||||||
{
|
|
||||||
get => Transform.Position;
|
|
||||||
set => Transform.Position = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Viewport Viewport
|
|
||||||
{
|
|
||||||
get => _viewport;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_viewport.Equals(value))
|
|
||||||
return;
|
|
||||||
|
|
||||||
_viewport = value;
|
|
||||||
OnViewportChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Zoom
|
|
||||||
{
|
|
||||||
get => _zoom;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
float newValue = value >= .1f ? value : .1f;
|
|
||||||
|
|
||||||
if (_zoom == newValue)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_zoom = newValue;
|
|
||||||
OnZoomChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Rotation
|
|
||||||
{
|
|
||||||
get => Transform.Rotation;
|
|
||||||
set => Transform.Rotation = value;
|
|
||||||
}
|
|
||||||
public Action<IAssignableTransform>? OnTransformAssigned { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
|
||||||
|
|
||||||
ITransform IAssignableTransform.Transform => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public void Update()
|
|
||||||
{
|
|
||||||
MatrixTransform =
|
|
||||||
Matrix.CreateTranslation(new Vector3(-Position.X, Position.Y, 0f)) *
|
|
||||||
Matrix.CreateRotationZ(Rotation) *
|
|
||||||
Matrix.CreateScale(Zoom) *
|
|
||||||
Matrix.CreateTranslation(new Vector3(_viewport.Width * .5f, _viewport.Height * .5f, 0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnInitialize()
|
|
||||||
{
|
|
||||||
Transform.OnRotationChanged += OnTransformRotationChanged;
|
|
||||||
Transform.OnPositionChanged += OnTransformPositionChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnFinalize()
|
|
||||||
{
|
|
||||||
Transform.OnRotationChanged -= OnTransformRotationChanged;
|
|
||||||
Transform.OnPositionChanged -= OnTransformPositionChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnTransformRotationChanged(ITransform _) => OnRotationChanged?.Invoke(this);
|
|
||||||
private void OnTransformPositionChanged(ITransform _) => OnPositionChanged?.Invoke(this);
|
|
||||||
|
|
||||||
public bool Assign(ITransform transform) => GameObject.Assign(transform);
|
|
||||||
}
|
|
|
@ -1,50 +1,53 @@
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Input;
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Input;
|
using Syntriax.Engine.Physics2D;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
namespace Pong.Behaviours;
|
||||||
public class MovementBallBehaviour(Vector2D StartDirection, float Speed) : BehaviourOverride
|
|
||||||
|
public class MovementBallBehaviour : BehaviourOverride
|
||||||
{
|
{
|
||||||
public Vector2D StartDirection { get; private set; } = Vector2D.Normalize(StartDirection);
|
public Vector2D StartDirection { get; private set; } = Vector2D.Zero;
|
||||||
public float Speed { get; set; } = Speed;
|
public float Speed { get; set; } = 500f;
|
||||||
|
public float SpeedUpMultiplier { get; set; } = .0125f;
|
||||||
|
|
||||||
|
private IRigidBody2D rigidBody = null!;
|
||||||
|
|
||||||
protected override void OnFirstActiveFrame()
|
protected override void OnFirstActiveFrame()
|
||||||
{
|
{
|
||||||
if (!BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidBody))
|
if (!BehaviourController.TryGetBehaviour(out IRigidBody2D? foundRigidBody))
|
||||||
throw new Exception($"Where's my {nameof(IRigidBody2D)}????");
|
throw new Exception($"{nameof(IRigidBody2D)} is missing on {GameObject.Name}.");
|
||||||
|
if (!BehaviourController.TryGetBehaviour(out ICollider2D? foundCollider))
|
||||||
|
throw new Exception($"{nameof(ICollider2D)} is missing on {GameObject.Name}.");
|
||||||
|
|
||||||
rigidBody.Velocity = StartDirection * Speed;
|
foundRigidBody.Velocity = StartDirection * Speed;
|
||||||
|
foundCollider.OnCollisionDetected += OnCollisionDetected;
|
||||||
|
|
||||||
|
rigidBody = foundRigidBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
// protected override void OnUpdate(GameTime time)
|
protected override void OnUpdate()
|
||||||
// {
|
{
|
||||||
// GameObject.Transform.Position += StartDirection * (time.ElapsedGameTime.Nanoseconds * .001f) * Speed;
|
if (rigidBody.Velocity.MagnitudeSquared <= 0.01f)
|
||||||
|
return;
|
||||||
|
|
||||||
// float absY = MathF.Abs(GameObject.Transform.Position.Y);
|
Vector2D speedUp = rigidBody.Velocity.Normalized * Time.DeltaTimeFrame;
|
||||||
// float differenceY = absY - PlayAreaBehaviour.PlayArea.Y * 0.5f;
|
rigidBody.Velocity += speedUp * SpeedUpMultiplier;
|
||||||
// if (differenceY > 0f)
|
}
|
||||||
// {
|
|
||||||
// if (GameObject.Transform.Position.Y > 0f)
|
private void OnCollisionDetected(ICollider2D collider2D, CollisionDetectionInformation information)
|
||||||
// GameObject.Transform.Position -= Vector2.UnitY * differenceY * 2f;
|
{
|
||||||
// else
|
if (Syntriax.Engine.Core.Math.Abs(information.Normal.Dot(Vector2D.Right)) > .25)
|
||||||
// GameObject.Transform.Position += Vector2.UnitY * differenceY * 2f;
|
rigidBody.Velocity = information.Left.Transform.Position.FromTo(information.Right.Transform.Position).Normalized * rigidBody.Velocity.Magnitude;
|
||||||
|
else
|
||||||
// StartDirection = new(StartDirection.X, -StartDirection.Y);
|
rigidBody.Velocity = rigidBody.Velocity.Reflect(information.Normal);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// float absX = MathF.Abs(GameObject.Transform.Position.X);
|
public MovementBallBehaviour() { }
|
||||||
// float differenceX = absX - PlayAreaBehaviour.PlayArea.X * 0.5f;
|
public MovementBallBehaviour(Vector2D startDirection, float speed)
|
||||||
// if (differenceX > 0f)
|
{
|
||||||
// {
|
StartDirection = Vector2D.Normalize(startDirection);
|
||||||
// if (GameObject.Transform.Position.X > 0f)
|
Speed = speed;
|
||||||
// GameObject.Transform.Position -= Vector2.UnitX * differenceX * 2f;
|
}
|
||||||
// else
|
|
||||||
// GameObject.Transform.Position += Vector2.UnitX * differenceX * 2f;
|
|
||||||
|
|
||||||
// StartDirection = new(-StartDirection.X, StartDirection.Y);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.Xna.Framework.Input;
|
|
||||||
using Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
|
||||||
|
|
||||||
public class MovementMouseBehaviour : BehaviourOverride
|
|
||||||
{
|
|
||||||
protected override void OnUpdate()
|
|
||||||
{
|
|
||||||
GameObject.Transform.Position = Mouse.GetState().Position.ToVector2D().ApplyDisplayScale();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
using Syntriax.Engine.Input;
|
using Syntriax.Engine.Input;
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
public class MovementBoxBehaviour(Keys Up, Keys Down, float High, float Low, float Speed) : BehaviourOverride
|
public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Speed) : BehaviourOverride
|
||||||
{
|
{
|
||||||
private Keys Up { get; } = Up;
|
private Keys Up { get; } = Up;
|
||||||
private Keys Down { get; } = Down;
|
private Keys Down { get; } = Down;
|
||||||
|
@ -35,9 +36,7 @@ public class MovementBoxBehaviour(Keys Up, Keys Down, float High, float Low, flo
|
||||||
protected override void OnFirstActiveFrame()
|
protected override void OnFirstActiveFrame()
|
||||||
{
|
{
|
||||||
if (!BehaviourController.TryGetBehaviour<IButtonInputs<Keys>>(out var behaviourResult))
|
if (!BehaviourController.TryGetBehaviour<IButtonInputs<Keys>>(out var behaviourResult))
|
||||||
throw new Exception($"{nameof(IButtonInputs<Keys>)} is missing on ${GameObject.Name}.");
|
inputs = behaviourResult ?? BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
|
||||||
|
|
||||||
inputs = behaviourResult;
|
|
||||||
|
|
||||||
inputs.RegisterOnPress(Up, OnUpPressed);
|
inputs.RegisterOnPress(Up, OnUpPressed);
|
||||||
inputs.RegisterOnRelease(Up, OnUpReleased);
|
inputs.RegisterOnRelease(Up, OnUpReleased);
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
|
||||||
|
|
||||||
public class PlayAreaBehaviour : BehaviourOverride
|
|
||||||
{
|
|
||||||
public Action<PlayAreaBehaviour>? OnPlayAreaChanged { get; set; } = null;
|
|
||||||
|
|
||||||
private Vector2 _playArea = Vector2.Zero;
|
|
||||||
|
|
||||||
public Vector2 PlayArea
|
|
||||||
{
|
|
||||||
get => _playArea;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_playArea == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_playArea = value;
|
|
||||||
OnPlayAreaChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
|
public class PongManagerBehaviour : BehaviourOverride
|
||||||
|
{
|
||||||
|
public Action<PongManagerBehaviour>? OnReset { get; set; } = null;
|
||||||
|
public Action<PongManagerBehaviour>? OnFinished { get; set; } = null;
|
||||||
|
public Action<PongManagerBehaviour>? OnScored { get; set; } = null;
|
||||||
|
|
||||||
|
public int ScoreLeft { get; private set; } = 0;
|
||||||
|
public int ScoreRight { get; private set; } = 0;
|
||||||
|
public int ScoreSum => ScoreLeft + ScoreRight;
|
||||||
|
|
||||||
|
public int WinScore { get; } = 5;
|
||||||
|
|
||||||
|
public PongManagerBehaviour() => WinScore = 5;
|
||||||
|
public PongManagerBehaviour(int winScore) => WinScore = winScore;
|
||||||
|
|
||||||
|
protected override void OnFirstActiveFrame()
|
||||||
|
{
|
||||||
|
KeyboardInputsBehaviour? buttonInputs = null!;
|
||||||
|
|
||||||
|
if (!BehaviourController.TryGetBehaviour(out buttonInputs))
|
||||||
|
buttonInputs = BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
|
||||||
|
|
||||||
|
buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => Reset());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void ScoreToLeft()
|
||||||
|
{
|
||||||
|
ScoreLeft++;
|
||||||
|
OnScored?.Invoke(this);
|
||||||
|
|
||||||
|
CheckFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ScoreToRight()
|
||||||
|
{
|
||||||
|
ScoreRight++;
|
||||||
|
OnScored?.Invoke(this);
|
||||||
|
|
||||||
|
CheckFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
ScoreLeft = ScoreRight = 0;
|
||||||
|
OnReset?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckFinish()
|
||||||
|
{
|
||||||
|
int halfwayScore = (int)(WinScore * .5f);
|
||||||
|
|
||||||
|
if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore)
|
||||||
|
OnFinished?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
using Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
|
||||||
|
|
||||||
public class RotatableBehaviour : BehaviourOverride
|
|
||||||
{
|
|
||||||
private KeyboardInputsBehaviour? inputs = null;
|
|
||||||
|
|
||||||
protected override void OnFirstActiveFrame()
|
|
||||||
{
|
|
||||||
if (!BehaviourController.TryGetBehaviour(out inputs))
|
|
||||||
inputs = BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnUpdate()
|
|
||||||
{
|
|
||||||
if (inputs is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (inputs.IsPressed(Microsoft.Xna.Framework.Input.Keys.NumPad4))
|
|
||||||
Transform.Rotation += Time.Elapsed.Nanoseconds * 0.0025f;
|
|
||||||
if (inputs.IsPressed(Microsoft.Xna.Framework.Input.Keys.NumPad6))
|
|
||||||
Transform.Rotation -= Time.Elapsed.Nanoseconds * 0.0025f;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,7 @@ using Microsoft.Xna.Framework;
|
||||||
using Apos.Shapes;
|
using Apos.Shapes;
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Input;
|
using Syntriax.Engine.Input;
|
||||||
using Syntriax.Engine.Physics2D.Abstract;
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Primitives;
|
using Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
@ -13,11 +14,6 @@ public class ShapeAABBBehaviour : BehaviourOverride, IDisplayableShape
|
||||||
{
|
{
|
||||||
private IShapeCollider2D? shapeCollider = null;
|
private IShapeCollider2D? shapeCollider = null;
|
||||||
|
|
||||||
public ShapeAABBBehaviour() { }
|
|
||||||
public ShapeAABBBehaviour(float Thickness) { this.Thickness = Thickness; }
|
|
||||||
public ShapeAABBBehaviour(Color color) { Color = color; }
|
|
||||||
public ShapeAABBBehaviour(Color color, float Thickness) { this.Thickness = Thickness; Color = color; }
|
|
||||||
|
|
||||||
public Color Color { get; set; } = Color.White;
|
public Color Color { get; set; } = Color.White;
|
||||||
public float Thickness { get; set; } = .5f;
|
public float Thickness { get; set; } = .5f;
|
||||||
public bool display = true;
|
public bool display = true;
|
||||||
|
@ -44,4 +40,9 @@ public class ShapeAABBBehaviour : BehaviourOverride, IDisplayableShape
|
||||||
|
|
||||||
shapeBatch.DrawRectangle(aabb.Center.ApplyDisplayScale().Subtract(aabb.SizeHalf).ToVector2(), aabb.Size.ToVector2(), Color.Transparent, Color.Blue);
|
shapeBatch.DrawRectangle(aabb.Center.ApplyDisplayScale().Subtract(aabb.SizeHalf).ToVector2(), aabb.Size.ToVector2(), Color.Transparent, Color.Blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ShapeAABBBehaviour() { }
|
||||||
|
public ShapeAABBBehaviour(float Thickness) { this.Thickness = Thickness; }
|
||||||
|
public ShapeAABBBehaviour(Color color) { Color = color; }
|
||||||
|
public ShapeAABBBehaviour(Color color, float Thickness) { this.Thickness = Thickness; Color = color; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,32 @@ using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
using Apos.Shapes;
|
using Apos.Shapes;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
using Syntriax.Engine.Physics2D.Primitives;
|
using Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
|
||||||
namespace Pong.Behaviours;
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
public class ShapeBehaviour : Syntriax.Engine.Physics2D.Collider2DShapeBehaviour, IDisplayableShape
|
public class ShapeBehaviour : Syntriax.Engine.Physics2D.Collider2DShapeBehaviour, IDisplayableShape
|
||||||
{
|
{
|
||||||
public ShapeBehaviour(Shape Shape) { this.ShapeLocal = Shape; }
|
|
||||||
public ShapeBehaviour(Shape Shape, float Thickness) { this.ShapeLocal = Shape; this.Thickness = Thickness; }
|
|
||||||
public ShapeBehaviour(Shape Shape, Color color) { this.ShapeLocal = Shape; Color = color; }
|
|
||||||
public ShapeBehaviour(Shape Shape, Color color, float Thickness) { this.ShapeLocal = Shape; this.Thickness = Thickness; Color = color; }
|
|
||||||
|
|
||||||
public Color Color { get; set; } = Color.White;
|
public Color Color { get; set; } = Color.White;
|
||||||
public float Thickness { get; set; } = .5f;
|
public float Thickness { get; set; } = .5f;
|
||||||
|
|
||||||
public void Draw(ShapeBatch shapeBatch)
|
public void Draw(ShapeBatch shapeBatch)
|
||||||
{
|
{
|
||||||
int count = ShapeWorld.Vertices.Count;
|
if (!IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
shapeBatch.BorderCircle(Transform.Position.ToDisplayVector2(), 5f, Color.DarkRed);
|
Recalculate();
|
||||||
|
|
||||||
|
int count = ShapeWorld.Vertices.Count;
|
||||||
|
|
||||||
for (int i = 0; i < count - 1; i++)
|
for (int i = 0; i < count - 1; i++)
|
||||||
shapeBatch.DrawLine(ShapeWorld[i].ToDisplayVector2(), ShapeWorld[i + 1].ToDisplayVector2(), Thickness, Color, Color);
|
shapeBatch.DrawLine(ShapeWorld[i].ToDisplayVector2(), ShapeWorld[i + 1].ToDisplayVector2(), Thickness, Color, Color);
|
||||||
shapeBatch.DrawLine(ShapeWorld[0].ToDisplayVector2(), ShapeWorld[^1].ToDisplayVector2(), Thickness, Color, Color);
|
shapeBatch.DrawLine(ShapeWorld[0].ToDisplayVector2(), ShapeWorld[^1].ToDisplayVector2(), Thickness, Color, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ShapeBehaviour(Shape shape) : base(shape) { }
|
||||||
|
public ShapeBehaviour(Shape shape, float thickness) : base(shape) { Thickness = thickness; }
|
||||||
|
public ShapeBehaviour(Shape shape, Color color) : base(shape) { Color = color; }
|
||||||
|
public ShapeBehaviour(Shape shape, Color color, float thickness) : base(shape) { Thickness = thickness; Color = color; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
|
||||||
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
|
public class TextBehaviour : BehaviourOverride, IDisplayableSprite
|
||||||
|
{
|
||||||
|
public SpriteFont? Font { get; set; } = null;
|
||||||
|
public int Size { get; set; } = 16;
|
||||||
|
public string Text { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public void Draw(SpriteBatch spriteBatch)
|
||||||
|
{
|
||||||
|
if (!IsActive || Font is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
spriteBatch.DrawString(Font, Text, Transform.Position.ToDisplayVector2(), Color.White, Transform.Rotation, Vector2.One * .5f, Transform.Scale.Magnitude, SpriteEffects.None, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextBehaviour() { }
|
||||||
|
public TextBehaviour(SpriteFont font) => Font = font;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
|
||||||
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
|
public class TextScoreBehaviour : TextBehaviour
|
||||||
|
{
|
||||||
|
public bool IsLeft { get; }
|
||||||
|
|
||||||
|
private PongManagerBehaviour? pongManager = null;
|
||||||
|
|
||||||
|
protected override void OnFirstActiveFrame()
|
||||||
|
{
|
||||||
|
if (!GameObject.GameManager.TryFindBehaviour(out pongManager))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pongManager.OnScored += UpdateScores;
|
||||||
|
pongManager.OnReset += UpdateScores;
|
||||||
|
|
||||||
|
UpdateScores(pongManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateScores(PongManagerBehaviour pongManager)
|
||||||
|
{
|
||||||
|
if (IsLeft)
|
||||||
|
Text = pongManager.ScoreLeft.ToString();
|
||||||
|
else
|
||||||
|
Text = pongManager.ScoreRight.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextScoreBehaviour(bool IsLeft) => this.IsLeft = IsLeft;
|
||||||
|
public TextScoreBehaviour(bool IsLeft, SpriteFont font) : base(font) => this.IsLeft = IsLeft;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
namespace Pong.Behaviours;
|
||||||
|
|
||||||
|
public class WallScoreBehaviour(Action OnCollision) : BehaviourOverride
|
||||||
|
{
|
||||||
|
private Action OnCollision { get; } = OnCollision;
|
||||||
|
|
||||||
|
protected override void OnFirstActiveFrame()
|
||||||
|
{
|
||||||
|
if (!BehaviourController.TryGetBehaviour(out ICollider2D? collider2D))
|
||||||
|
return;
|
||||||
|
|
||||||
|
collider2D.OnCollisionDetected += (_, _1) => OnCollision?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,51 +13,10 @@
|
||||||
|
|
||||||
#---------------------------------- Content ---------------------------------#
|
#---------------------------------- Content ---------------------------------#
|
||||||
|
|
||||||
#begin Sprites/Circle.png
|
#begin UbuntuMono.spritefont
|
||||||
/importer:TextureImporter
|
/importer:FontDescriptionImporter
|
||||||
/processor:TextureProcessor
|
/processor:FontDescriptionProcessor
|
||||||
/processorParam:ColorKeyColor=255,0,255,255
|
|
||||||
/processorParam:ColorKeyEnabled=True
|
|
||||||
/processorParam:GenerateMipmaps=False
|
|
||||||
/processorParam:PremultiplyAlpha=True
|
/processorParam:PremultiplyAlpha=True
|
||||||
/processorParam:ResizeToPowerOfTwo=False
|
/processorParam:TextureFormat=Compressed
|
||||||
/processorParam:MakeSquare=False
|
/build:UbuntuMono.spritefont
|
||||||
/processorParam:TextureFormat=Color
|
|
||||||
/build:Sprites/Circle.png
|
|
||||||
|
|
||||||
#begin Sprites/Circle.png
|
|
||||||
/importer:TextureImporter
|
|
||||||
/processor:TextureProcessor
|
|
||||||
/processorParam:ColorKeyColor=255,0,255,255
|
|
||||||
/processorParam:ColorKeyEnabled=True
|
|
||||||
/processorParam:GenerateMipmaps=False
|
|
||||||
/processorParam:PremultiplyAlpha=True
|
|
||||||
/processorParam:ResizeToPowerOfTwo=False
|
|
||||||
/processorParam:MakeSquare=False
|
|
||||||
/processorParam:TextureFormat=Color
|
|
||||||
/build:Sprites/Circle.png
|
|
||||||
|
|
||||||
#begin Sprites/Pixel.png
|
|
||||||
/importer:TextureImporter
|
|
||||||
/processor:TextureProcessor
|
|
||||||
/processorParam:ColorKeyColor=255,0,255,255
|
|
||||||
/processorParam:ColorKeyEnabled=True
|
|
||||||
/processorParam:GenerateMipmaps=False
|
|
||||||
/processorParam:PremultiplyAlpha=True
|
|
||||||
/processorParam:ResizeToPowerOfTwo=False
|
|
||||||
/processorParam:MakeSquare=False
|
|
||||||
/processorParam:TextureFormat=Color
|
|
||||||
/build:Sprites/Pixel.png
|
|
||||||
|
|
||||||
#begin Sprites/Pixel.png
|
|
||||||
/importer:TextureImporter
|
|
||||||
/processor:TextureProcessor
|
|
||||||
/processorParam:ColorKeyColor=255,0,255,255
|
|
||||||
/processorParam:ColorKeyEnabled=True
|
|
||||||
/processorParam:GenerateMipmaps=False
|
|
||||||
/processorParam:PremultiplyAlpha=True
|
|
||||||
/processorParam:ResizeToPowerOfTwo=False
|
|
||||||
/processorParam:MakeSquare=False
|
|
||||||
/processorParam:TextureFormat=Color
|
|
||||||
/build:Sprites/Pixel.png
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 546 B |
|
@ -0,0 +1,60 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
This file contains an xml description of a font, and will be read by the XNA
|
||||||
|
Framework Content Pipeline. Follow the comments to customize the appearance
|
||||||
|
of the font in your game, and to change the characters which are available to draw
|
||||||
|
with.
|
||||||
|
-->
|
||||||
|
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
|
||||||
|
<Asset Type="Graphics:FontDescription">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Modify this string to change the font that will be imported.
|
||||||
|
-->
|
||||||
|
<FontName>Ubuntu Mono</FontName>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Size is a float value, measured in points. Modify this value to change
|
||||||
|
the size of the font.
|
||||||
|
-->
|
||||||
|
<Size>144</Size>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Spacing is a float value, measured in pixels. Modify this value to change
|
||||||
|
the amount of spacing in between characters.
|
||||||
|
-->
|
||||||
|
<Spacing>0</Spacing>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
UseKerning controls the layout of the font. If this value is true, kerning information
|
||||||
|
will be used when placing characters.
|
||||||
|
-->
|
||||||
|
<UseKerning>true</UseKerning>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
|
||||||
|
and "Bold, Italic", and are case sensitive.
|
||||||
|
-->
|
||||||
|
<Style>Bold</Style>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
If you uncomment this line, the default character will be substituted if you draw
|
||||||
|
or measure text that contains characters which were not included in the font.
|
||||||
|
-->
|
||||||
|
<!-- <DefaultCharacter>*</DefaultCharacter> -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
CharacterRegions control what letters are available in the font. Every
|
||||||
|
character from Start to End will be built and made available for drawing. The
|
||||||
|
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
|
||||||
|
character set. The characters are ordered according to the Unicode standard.
|
||||||
|
See the documentation for more information.
|
||||||
|
-->
|
||||||
|
<CharacterRegions>
|
||||||
|
<CharacterRegion>
|
||||||
|
<Start> </Start>
|
||||||
|
<End>~</End>
|
||||||
|
</CharacterRegion>
|
||||||
|
</CharacterRegions>
|
||||||
|
</Asset>
|
||||||
|
</XnaContent>
|
245
Game/Game1.cs
245
Game/Game1.cs
|
@ -1,245 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
using Microsoft.Xna.Framework.Input;
|
|
||||||
|
|
||||||
using Pong.Behaviours;
|
|
||||||
using Apos.Shapes;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
using Syntriax.Engine.Physics2D;
|
|
||||||
using Syntriax.Engine.Physics2D.Primitives;
|
|
||||||
|
|
||||||
namespace Pong;
|
|
||||||
|
|
||||||
public class Game1 : Game
|
|
||||||
{
|
|
||||||
private GraphicsDeviceManager _graphics = null!;
|
|
||||||
private PhysicsEngine2D engine;
|
|
||||||
private SpriteBatch _spriteBatch = null!;
|
|
||||||
private ShapeBatch _shapeBatch = null!;
|
|
||||||
public static GameManager gameManager = null!;
|
|
||||||
public static Sprite spriteBox = null!;
|
|
||||||
private MonoGameCameraBehaviour cameraBehaviour = null!;
|
|
||||||
|
|
||||||
|
|
||||||
public Game1()
|
|
||||||
{
|
|
||||||
engine = new PhysicsEngine2D();
|
|
||||||
|
|
||||||
_graphics = new GraphicsDeviceManager(this)
|
|
||||||
{
|
|
||||||
PreferredBackBufferWidth = 1024,
|
|
||||||
PreferredBackBufferHeight = 576,
|
|
||||||
GraphicsProfile = GraphicsProfile.HiDef
|
|
||||||
};
|
|
||||||
|
|
||||||
Content.RootDirectory = "Content";
|
|
||||||
IsMouseVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
gameManager = new();
|
|
||||||
|
|
||||||
// TODO: Add your initialization logic here
|
|
||||||
gameManager.Initialize();
|
|
||||||
|
|
||||||
base.Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadContent()
|
|
||||||
{
|
|
||||||
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
|
||||||
_shapeBatch = new ShapeBatch(GraphicsDevice, Content);
|
|
||||||
|
|
||||||
// spriteBox = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Pixel") };
|
|
||||||
// Sprite spriteBall = new Sprite() { Texture2D = Content.Load<Texture2D>("Sprites/Circle") };
|
|
||||||
|
|
||||||
IGameObject gameObjectCamera = gameManager.InstantiateGameObject<GameObject>();
|
|
||||||
gameObjectCamera.Name = "Camera";
|
|
||||||
gameObjectCamera.Transform.Position = Vector2D.Zero;
|
|
||||||
|
|
||||||
cameraBehaviour = gameObjectCamera.BehaviourController.AddBehaviour<MonoGameCameraBehaviour>();
|
|
||||||
cameraBehaviour.Viewport = GraphicsDevice.Viewport;
|
|
||||||
gameManager.Camera = cameraBehaviour;
|
|
||||||
|
|
||||||
|
|
||||||
// IGameObject gameObjectCircle = gameManager.InstantiateGameObject<GameObject>();
|
|
||||||
// gameObjectCircle.Name = "Circle";
|
|
||||||
// gameObjectCircle.Transform.Position = new Vector2D(0f, -50f);
|
|
||||||
// gameObjectCircle.Transform.Scale = new Vector2D(25f, 25f);
|
|
||||||
// gameObjectCircle.BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
|
|
||||||
// gameObjectCircle.BehaviourController.AddBehaviour<MovementBoxBehaviour>(Keys.W, Keys.S, 268f, -268f, 400f);
|
|
||||||
// gameObjectCircle.BehaviourController.AddBehaviour<CircleBehaviour>(new Circle(Vector2D.Zero, 1f));
|
|
||||||
// engine.AddRigidBody(gameObjectCircle.BehaviourController.AddBehaviour<RigidBody2D>());
|
|
||||||
|
|
||||||
IGameObject gameObjectCircle2 = gameManager.InstantiateGameObject<GameObject>();
|
|
||||||
gameObjectCircle2.Name = "Circle2";
|
|
||||||
gameObjectCircle2.Transform.Position = new Vector2D(5f, 50f);
|
|
||||||
gameObjectCircle2.Transform.Scale = new Vector2D(25f, 25f);
|
|
||||||
gameObjectCircle2.BehaviourController.AddBehaviour<MovementMouseBehaviour>();
|
|
||||||
gameObjectCircle2.BehaviourController.AddBehaviour<CircleBehaviour>(new Circle(Vector2D.Zero, 1f));
|
|
||||||
engine.AddRigidBody(gameObjectCircle2.BehaviourController.AddBehaviour<RigidBody2D>());
|
|
||||||
|
|
||||||
IGameObject gameObjectDiamond = gameManager.InstantiateGameObject<GameObject>();
|
|
||||||
gameObjectDiamond.Name = "Diamond";
|
|
||||||
gameObjectDiamond.Transform.Position = new Vector2D(-150f, -150f);
|
|
||||||
gameObjectDiamond.Transform.Scale = new Vector2D(50f, 50f);
|
|
||||||
gameObjectDiamond.BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
|
|
||||||
gameObjectDiamond.BehaviourController.AddBehaviour<MovementBoxBehaviour>(Keys.W, Keys.S, 268f, -268f, 400f);
|
|
||||||
gameObjectDiamond.BehaviourController.AddBehaviour<RotatableBehaviour>();
|
|
||||||
gameObjectDiamond.BehaviourController.AddBehaviour<ShapeBehaviour>(new Shape([Vector2D.Up, Vector2D.One, Vector2D.Right, Vector2D.Down, -Vector2D.One, Vector2D.Left]));
|
|
||||||
gameObjectDiamond.BehaviourController.AddBehaviour<ShapeAABBBehaviour>();
|
|
||||||
engine.AddRigidBody(gameObjectDiamond.BehaviourController.AddBehaviour<RigidBody2D>());
|
|
||||||
|
|
||||||
IGameObject gameObjectBox = gameManager.InstantiateGameObject<GameObject>();
|
|
||||||
gameObjectBox.Name = "Box";
|
|
||||||
gameObjectBox.Transform.Position = new Vector2D(150f, -150f);
|
|
||||||
gameObjectBox.Transform.Scale = new Vector2D(100f, 100f);
|
|
||||||
gameObjectBox.BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
|
|
||||||
gameObjectBox.BehaviourController.AddBehaviour<MovementBoxBehaviour>(Keys.W, Keys.S, 268f, -268f, 400f);
|
|
||||||
gameObjectBox.BehaviourController.AddBehaviour<RotatableBehaviour>();
|
|
||||||
gameObjectBox.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Pentagon);
|
|
||||||
gameObjectBox.BehaviourController.AddBehaviour<ShapeAABBBehaviour>();
|
|
||||||
engine.AddRigidBody(gameObjectBox.BehaviourController.AddBehaviour<RigidBody2D>());
|
|
||||||
|
|
||||||
for (int i = 3; i < 10; i++)
|
|
||||||
{
|
|
||||||
IGameObject Test = gameManager.InstantiateGameObject<GameObject>();
|
|
||||||
Test.Name = i.ToString();
|
|
||||||
Test.Transform.Position = new Vector2D((i - 6) * 150, 0f);
|
|
||||||
Test.Transform.Scale = new Vector2D(75f, 75f);
|
|
||||||
Test.BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
|
|
||||||
Test.BehaviourController.AddBehaviour<MovementBoxBehaviour>(Keys.W, Keys.S, 268f, -268f, 400f);
|
|
||||||
Test.BehaviourController.AddBehaviour<RotatableBehaviour>();
|
|
||||||
Test.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.CreateNgon(i));
|
|
||||||
Test.BehaviourController.AddBehaviour<ShapeAABBBehaviour>();
|
|
||||||
RigidBody2D rigidBody = Test.BehaviourController.AddBehaviour<RigidBody2D>();
|
|
||||||
rigidBody.AngularVelocity = 90f;
|
|
||||||
engine.AddRigidBody(rigidBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// IGameObject gameObjectShape = gameManager.InstantiateGameObject<GameObject>();
|
|
||||||
// gameObjectShape.Name = "Shape";
|
|
||||||
// gameObjectShape.Transform.Position = new Vector2D(250f, 0f);
|
|
||||||
// gameObjectShape.Transform.Scale = new Vector2D(100f, 100f);
|
|
||||||
// gameObjectShape.BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
|
|
||||||
// gameObjectShape.BehaviourController.AddBehaviour<MovementBoxBehaviour>(Keys.W, Keys.S, 268f, -268f, 400f);
|
|
||||||
// gameObjectShape.BehaviourController.AddBehaviour<RotatableBehaviour>();
|
|
||||||
// gameObjectShape.BehaviourController.AddBehaviour<ShapeBehaviour>(new Shape([Vector2D.Up, Vector2D.One, Vector2D.Right, Vector2D.Down, Vector2D.Zero, Vector2D.Left]));
|
|
||||||
// gameObjectShape.BehaviourController.AddBehaviour<ShapeAABBBehaviour>();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update(GameTime gameTime)
|
|
||||||
{
|
|
||||||
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
|
||||||
Exit();
|
|
||||||
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.F))
|
|
||||||
{
|
|
||||||
if (_graphics.IsFullScreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_graphics.PreferMultiSampling = false;
|
|
||||||
_graphics.PreferredBackBufferWidth = GraphicsDevice.Adapter.CurrentDisplayMode.Width;
|
|
||||||
_graphics.PreferredBackBufferHeight = GraphicsDevice.Adapter.CurrentDisplayMode.Height;
|
|
||||||
_graphics.IsFullScreen = true;
|
|
||||||
_graphics.ApplyChanges();
|
|
||||||
|
|
||||||
float previousScreenSize = MathF.Sqrt(MathF.Pow(cameraBehaviour.Viewport.Width, 2f) + MathF.Pow(cameraBehaviour.Viewport.Height, 2f));
|
|
||||||
float currentScreenSize = MathF.Sqrt(MathF.Pow(GraphicsDevice.Viewport.Width, 2f) + MathF.Pow(GraphicsDevice.Viewport.Height, 2f));
|
|
||||||
cameraBehaviour.Zoom /= previousScreenSize / currentScreenSize;
|
|
||||||
cameraBehaviour.Viewport = GraphicsDevice.Viewport;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.U))
|
|
||||||
cameraBehaviour.Zoom += gameTime.ElapsedGameTime.Nanoseconds * 0.00025f;
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.J))
|
|
||||||
cameraBehaviour.Zoom -= gameTime.ElapsedGameTime.Nanoseconds * 0.00025f;
|
|
||||||
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.Q))
|
|
||||||
cameraBehaviour.BehaviourController.GameObject.Transform.Rotation += gameTime.ElapsedGameTime.Nanoseconds * 0.000025f;
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.E))
|
|
||||||
cameraBehaviour.BehaviourController.GameObject.Transform.Rotation -= gameTime.ElapsedGameTime.Nanoseconds * 0.000025f;
|
|
||||||
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.N))
|
|
||||||
{
|
|
||||||
seconds = 70f;
|
|
||||||
while (physicsTimer + 0.01f < seconds)
|
|
||||||
{
|
|
||||||
physicsTimer += 0.01f;
|
|
||||||
engine.Step(.01f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.M))
|
|
||||||
{
|
|
||||||
seconds = 0f;
|
|
||||||
while (physicsTimer - 0.01f > seconds)
|
|
||||||
{
|
|
||||||
physicsTimer -= 0.01f;
|
|
||||||
engine.Step(-.01f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.Space))
|
|
||||||
{
|
|
||||||
seconds += gameTime.ElapsedGameTime.Milliseconds * .005f;
|
|
||||||
while (physicsTimer + 0.01f < seconds)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Physics Timer: {physicsTimer}");
|
|
||||||
physicsTimer += 0.01f;
|
|
||||||
engine.Step(.01f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Keyboard.GetState().IsKeyDown(Keys.B))
|
|
||||||
{
|
|
||||||
seconds -= gameTime.ElapsedGameTime.Milliseconds * .005f;
|
|
||||||
while (physicsTimer - 0.01f > seconds)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Physics Timer: {physicsTimer}");
|
|
||||||
physicsTimer -= 0.01f;
|
|
||||||
engine.Step(-.01f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
while (physicsTimer + 0.01f < gameTime.TotalGameTime.TotalMilliseconds * .001f)//seconds)
|
|
||||||
{
|
|
||||||
// Console.WriteLine($"Physics Timer: {physicsTimer}");
|
|
||||||
physicsTimer += 0.01f;
|
|
||||||
engine.Step(.01f);
|
|
||||||
}
|
|
||||||
gameManager.Update(gameTime.ToEngineTime());
|
|
||||||
base.Update(gameTime);
|
|
||||||
}
|
|
||||||
static float physicsTimer = 0f;
|
|
||||||
static float seconds = 0f;
|
|
||||||
|
|
||||||
protected override void Draw(GameTime gameTime)
|
|
||||||
{
|
|
||||||
GraphicsDevice.Clear(new Color() { R = 32, G = 32, B = 32 });
|
|
||||||
|
|
||||||
// gameManager.Camera.Position = gameObjectBall.Transform.Position;
|
|
||||||
// Console.WriteLine($"Pos: {gameManager.Camera.Position}");
|
|
||||||
|
|
||||||
// TODO: Add your drawing code here
|
|
||||||
gameManager.PreDraw();
|
|
||||||
gameManager.Camera.Update();
|
|
||||||
|
|
||||||
_spriteBatch.Begin(SpriteSortMode.Deferred, transformMatrix: cameraBehaviour.MatrixTransform);
|
|
||||||
foreach (IGameObject gameObject in gameManager)
|
|
||||||
foreach (var displayable in gameObject.BehaviourController.GetBehaviours<IDisplayable>())
|
|
||||||
displayable.Draw(_spriteBatch);
|
|
||||||
_spriteBatch.End();
|
|
||||||
|
|
||||||
_shapeBatch.Begin(cameraBehaviour.MatrixTransform);
|
|
||||||
foreach (IGameObject gameObject in gameManager)
|
|
||||||
foreach (var displayableShape in gameObject.BehaviourController.GetBehaviours<IDisplayableShape>())
|
|
||||||
displayableShape.Draw(_shapeBatch);
|
|
||||||
_shapeBatch.End();
|
|
||||||
|
|
||||||
base.Draw(gameTime);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
|
||||||
|
using Pong.Behaviours;
|
||||||
|
using Apos.Shapes;
|
||||||
|
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Core.Abstract;
|
||||||
|
using Syntriax.Engine.Physics2D;
|
||||||
|
using Syntriax.Engine.Physics2D.Primitives;
|
||||||
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
namespace Pong;
|
||||||
|
|
||||||
|
public class GamePong : Game
|
||||||
|
{
|
||||||
|
private readonly GraphicsDeviceManager graphics = null!;
|
||||||
|
private IPhysicsEngine2D physicsEngine = null!;
|
||||||
|
private SpriteBatch spriteBatch = null!;
|
||||||
|
private ShapeBatch shapeBatch = null!;
|
||||||
|
|
||||||
|
private GameManager gameManager = null!;
|
||||||
|
private BehaviourCollector<IDisplayableSprite> displayableCollector = null!;
|
||||||
|
private BehaviourCollector<IDisplayableShape> displayableShapeCollector = null!;
|
||||||
|
private MonoGameCamera2DBehaviour cameraBehaviour = null!;
|
||||||
|
|
||||||
|
private PongManagerBehaviour pongManager = null!;
|
||||||
|
|
||||||
|
private float physicsTimer = 0f;
|
||||||
|
|
||||||
|
public GamePong()
|
||||||
|
{
|
||||||
|
graphics = new GraphicsDeviceManager(this)
|
||||||
|
{
|
||||||
|
PreferredBackBufferWidth = 1024,
|
||||||
|
PreferredBackBufferHeight = 576,
|
||||||
|
GraphicsProfile = GraphicsProfile.HiDef
|
||||||
|
};
|
||||||
|
|
||||||
|
Content.RootDirectory = "Content";
|
||||||
|
IsMouseVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Initialize()
|
||||||
|
{
|
||||||
|
// TODO: Add your initialization logic here
|
||||||
|
gameManager = new();
|
||||||
|
displayableCollector = new(gameManager);
|
||||||
|
displayableShapeCollector = new(gameManager);
|
||||||
|
physicsEngine = new PhysicsEngine2DCollector(gameManager) { IterationPerStep = 3 };
|
||||||
|
|
||||||
|
gameManager.Initialize();
|
||||||
|
|
||||||
|
base.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadContent()
|
||||||
|
{
|
||||||
|
spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||||
|
shapeBatch = new ShapeBatch(GraphicsDevice, Content);
|
||||||
|
SpriteFont spriteFont = Content.Load<SpriteFont>("UbuntuMono");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
IGameObject gameObjectCamera = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Camera"); ;
|
||||||
|
gameObjectCamera.BehaviourController.AddBehaviour<CameraController>();
|
||||||
|
cameraBehaviour = gameObjectCamera.BehaviourController.AddBehaviour<MonoGameCamera2DBehaviour>(graphics);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
IGameObject gameObjectPongManager = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Pong Game Manager");
|
||||||
|
pongManager = gameObjectPongManager.BehaviourController.AddBehaviour<PongManagerBehaviour>(5);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
IGameObject gameObjectBall = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Ball");
|
||||||
|
gameObjectBall.Transform.SetTransform(position: new Vector2D(0, 0f), scale: new Vector2D(10f, 10f));
|
||||||
|
|
||||||
|
gameObjectBall.BehaviourController.AddBehaviour<CircleBehaviour>(new Circle(Vector2D.Zero, 1f));
|
||||||
|
gameObjectBall.BehaviourController.AddBehaviour<BallBehaviour>();
|
||||||
|
gameObjectBall.BehaviourController.AddBehaviour<RigidBody2D>();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
IGameObject gameObjectLeftPaddle = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Left Paddle");
|
||||||
|
gameObjectLeftPaddle.Transform.SetTransform(position: new Vector2D(-468f, 0f), scale: new Vector2D(15f, 60f));
|
||||||
|
|
||||||
|
gameObjectLeftPaddle.BehaviourController.AddBehaviour<PaddleBehaviour>(Keys.W, Keys.S, 228f, -228f, 400f);
|
||||||
|
gameObjectLeftPaddle.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box);
|
||||||
|
gameObjectLeftPaddle.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
|
||||||
|
|
||||||
|
IGameObject gameObjectRightPaddle = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Right Paddle");
|
||||||
|
gameObjectRightPaddle.Transform.SetTransform(position: new Vector2D(468f, 0f), scale: new Vector2D(15f, 60f));
|
||||||
|
gameObjectRightPaddle.BehaviourController.AddBehaviour<PaddleBehaviour>(Keys.Up, Keys.Down, 228f, -228f, 400f);
|
||||||
|
gameObjectRightPaddle.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box);
|
||||||
|
gameObjectRightPaddle.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
IGameObject gameObjectWallTop = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Wall Top");
|
||||||
|
gameObjectWallTop.Transform.SetTransform(position: new Vector2D(0f, 308f), scale: new Vector2D(552f, 20f));
|
||||||
|
gameObjectWallTop.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box);
|
||||||
|
gameObjectWallTop.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
|
||||||
|
|
||||||
|
IGameObject gameObjectWallBottom = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Wall Bottom");
|
||||||
|
gameObjectWallBottom.Transform.SetTransform(position: new Vector2D(0f, -308f), scale: new Vector2D(552f, 20f));
|
||||||
|
gameObjectWallBottom.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box);
|
||||||
|
gameObjectWallBottom.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
|
||||||
|
|
||||||
|
IGameObject gameObjectWallRight = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Wall Right");
|
||||||
|
gameObjectWallRight.Transform.SetTransform(position: new Vector2D(532f, 0f), scale: new Vector2D(20f, 328f));
|
||||||
|
gameObjectWallRight.BehaviourController.AddBehaviour<WallScoreBehaviour>((Action)pongManager.ScoreToLeft);
|
||||||
|
gameObjectWallRight.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box);
|
||||||
|
gameObjectWallRight.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
|
||||||
|
|
||||||
|
IGameObject gameObjectWallLeft = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Wall Left");
|
||||||
|
gameObjectWallLeft.Transform.SetTransform(position: new Vector2D(-532f, 0f), scale: new Vector2D(20f, 328f));
|
||||||
|
gameObjectWallLeft.BehaviourController.AddBehaviour<WallScoreBehaviour>((Action)pongManager.ScoreToRight);
|
||||||
|
gameObjectWallLeft.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape.Box);
|
||||||
|
gameObjectWallLeft.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
IGameObject gameObjectLeftScoreText = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Score Left");
|
||||||
|
gameObjectLeftScoreText.Transform.SetTransform(position: new Vector2D(-250f, 250f), scale: Vector2D.One * .25f);
|
||||||
|
gameObjectLeftScoreText.BehaviourController.AddBehaviour<TextScoreBehaviour>(true, spriteFont);
|
||||||
|
|
||||||
|
IGameObject gameObjectRightScoreText = gameManager.InstantiateGameObject<GameObject>().SetGameObject("Score Right");
|
||||||
|
gameObjectRightScoreText.Transform.SetTransform(position: new Vector2D(250f, 250f), scale: Vector2D.One * .25f);
|
||||||
|
gameObjectRightScoreText.BehaviourController.AddBehaviour<TextScoreBehaviour>(false, spriteFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update(GameTime gameTime)
|
||||||
|
{
|
||||||
|
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
||||||
|
Exit();
|
||||||
|
|
||||||
|
gameManager.Update(gameTime.ToEngineTime());
|
||||||
|
while (physicsTimer + 0.01f < gameTime.TotalGameTime.TotalMilliseconds * .001f)//seconds)
|
||||||
|
{
|
||||||
|
physicsTimer += 0.01f;
|
||||||
|
physicsEngine.Step(.01f);
|
||||||
|
}
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(GameTime gameTime)
|
||||||
|
{
|
||||||
|
GraphicsDevice.Clear(new Color() { R = 32, G = 32, B = 32 });
|
||||||
|
|
||||||
|
// TODO: Add your drawing code here
|
||||||
|
gameManager.PreDraw();
|
||||||
|
|
||||||
|
spriteBatch.Begin(SpriteSortMode.Deferred, transformMatrix: cameraBehaviour.MatrixTransform);
|
||||||
|
foreach (var displayable in displayableCollector)
|
||||||
|
displayable.Draw(spriteBatch);
|
||||||
|
spriteBatch.End();
|
||||||
|
|
||||||
|
shapeBatch.Begin(cameraBehaviour.MatrixTransform);
|
||||||
|
foreach (var displayableShape in displayableShapeCollector)
|
||||||
|
displayableShape.Draw(shapeBatch);
|
||||||
|
shapeBatch.End();
|
||||||
|
|
||||||
|
base.Draw(gameTime);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates the object is an <see cref="IAssignable"/> with an assignable <see cref="ISprite"/> field.
|
|
||||||
/// </summary>
|
|
||||||
public interface IAssignableSprite : IAssignable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Callback triggered when the <see cref="ISprite"/> value has has been assigned a new value.
|
|
||||||
/// </summary>
|
|
||||||
Action<IAssignableSprite>? OnSpriteAssigned { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ISprite" />
|
|
||||||
ISprite Sprite { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Assign a value to the <see cref="ISprite"/> field of this object
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sprite">New <see cref="ISprite"/> to assign.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// <see cref="true"/>, if the value given assigned successfully assigned, <see cref="false"/> if not.
|
|
||||||
/// </returns>
|
|
||||||
bool Assign(ISprite sprite);
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
// TODO Probably gonna have to rethink this
|
|
||||||
public interface ISprite
|
|
||||||
{
|
|
||||||
Action<ISprite>? OnTextureChanged { get; set; }
|
|
||||||
|
|
||||||
Texture2D Texture2D { get; set; }
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Core;
|
|
||||||
|
|
||||||
public class Sprite : ISprite
|
|
||||||
{
|
|
||||||
public Action<ISprite>? OnTextureChanged { get; set; }
|
|
||||||
|
|
||||||
private Texture2D _texture = null!;
|
|
||||||
|
|
||||||
public Texture2D Texture2D
|
|
||||||
{
|
|
||||||
get => _texture;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_texture == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_texture = value;
|
|
||||||
OnTextureChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Graphics.TwoDimensional.Abstract;
|
|
||||||
public interface IDisplayableSprite : IDisplayable, IAssignableSprite
|
|
||||||
{
|
|
||||||
Action<IDisplayableSprite>? OnSpriteEffectsChanged { get; set; }
|
|
||||||
Action<IDisplayableSprite>? OnOriginChanged { get; set; }
|
|
||||||
Action<IDisplayableSprite>? OnColorChanged { get; set; }
|
|
||||||
Action<IDisplayableSprite>? OnDepthChanged { get; set; }
|
|
||||||
|
|
||||||
SpriteEffects SpriteEffects { get; set; }
|
|
||||||
Vector2 Origin { get; set; }
|
|
||||||
Color Color { get; set; }
|
|
||||||
float Depth { get; set; }
|
|
||||||
}
|
|
|
@ -1,117 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
|
|
||||||
using Syntriax.Engine.Core;
|
|
||||||
using Syntriax.Engine.Core.Abstract;
|
|
||||||
using Syntriax.Engine.Graphics.TwoDimensional.Abstract;
|
|
||||||
|
|
||||||
namespace Syntriax.Engine.Graphics.TwoDimensional;
|
|
||||||
|
|
||||||
public class DisplayableSpriteBehaviour : Behaviour, IDisplayableSprite, IAssignableSprite
|
|
||||||
{
|
|
||||||
public Action<IAssignableSprite>? OnSpriteAssigned { get; set; } = null;
|
|
||||||
public Action<IDisplayableSprite>? OnSpriteEffectsChanged { get; set; } = null;
|
|
||||||
public Action<IDisplayableSprite>? OnOriginChanged { get; set; } = null;
|
|
||||||
public Action<IDisplayableSprite>? OnColorChanged { get; set; } = null;
|
|
||||||
public Action<IDisplayableSprite>? OnDepthChanged { get; set; } = null;
|
|
||||||
|
|
||||||
private ISprite _sprite = null!;
|
|
||||||
private Color _color = Color.White;
|
|
||||||
private float _depth = 0f;
|
|
||||||
private SpriteEffects _spriteEffects = SpriteEffects.None;
|
|
||||||
private Vector2 _origin = Vector2.One * .5f;
|
|
||||||
|
|
||||||
|
|
||||||
public ISprite Sprite => _sprite;
|
|
||||||
|
|
||||||
public SpriteEffects SpriteEffects
|
|
||||||
{
|
|
||||||
get => _spriteEffects;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_spriteEffects == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_spriteEffects = value;
|
|
||||||
OnSpriteEffectsChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 Origin
|
|
||||||
{
|
|
||||||
get => _origin;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_origin == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_origin = value;
|
|
||||||
OnOriginChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color Color
|
|
||||||
{
|
|
||||||
get => _color;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_color == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_color = value;
|
|
||||||
OnColorChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Depth
|
|
||||||
{
|
|
||||||
get => _depth;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_depth == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_depth = value;
|
|
||||||
OnDepthChanged?.Invoke(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch)
|
|
||||||
{
|
|
||||||
if (!BehaviourController.GameObject.StateEnable.Enabled || !StateEnable.Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ITransform transform = BehaviourController.GameObject.Transform;
|
|
||||||
Vector2D position = transform.Position;
|
|
||||||
Vector2D scale = transform.Scale;
|
|
||||||
|
|
||||||
Rectangle rectangle = new((int)position.X, -(int)position.Y, (int)(Sprite.Texture2D.Width * scale.X), (int)(Sprite.Texture2D.Height * scale.Y));
|
|
||||||
|
|
||||||
spriteBatch.Draw(Sprite.Texture2D, rectangle, null, Color, transform.Rotation, new Vector2(Sprite.Texture2D.Width, Sprite.Texture2D.Height) * Origin, SpriteEffects, Depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Assign(ISprite sprite)
|
|
||||||
{
|
|
||||||
_sprite = sprite;
|
|
||||||
OnSpriteAssigned?.Invoke(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DisplayableSpriteBehaviour() => OnUnassigned += OnUnassign;
|
|
||||||
public DisplayableSpriteBehaviour(
|
|
||||||
Color? color = null,
|
|
||||||
float? depth = null,
|
|
||||||
SpriteEffects? spriteEffects = null,
|
|
||||||
Vector2? origin = null)
|
|
||||||
{
|
|
||||||
OnUnassigned += OnUnassign;
|
|
||||||
|
|
||||||
_color = color ?? _color;
|
|
||||||
_depth = depth ?? _depth;
|
|
||||||
_spriteEffects = spriteEffects ?? _spriteEffects;
|
|
||||||
_origin = origin ?? _origin;
|
|
||||||
}
|
|
||||||
private void OnUnassign(IAssignable assignable) => _sprite = null!;
|
|
||||||
}
|
|
|
@ -1,3 +1,3 @@
|
||||||
|
|
||||||
using var game = new Pong.Game1();
|
using var game = new Pong.GamePong();
|
||||||
game.Run();
|
game.Run();
|
||||||
|
|
Loading…
Reference in New Issue