Compare commits

..

No commits in common. "main" and "physics" have entirely different histories.

51 changed files with 1361 additions and 1370 deletions

2
Engine

@ -1 +1 @@
Subproject commit 5c1c025fe3fa6330ff7a9fb4426ad864dca994f7
Subproject commit 6a104d8abd013334ed2787c4b4c6fa6481e4c6a4

View File

@ -3,31 +3,31 @@
"isRoot": true,
"tools": {
"dotnet-mgcb": {
"version": "3.8.2.1105",
"version": "3.8.1.303",
"commands": [
"mgcb"
]
},
"dotnet-mgcb-editor": {
"version": "3.8.2.1105",
"version": "3.8.1.303",
"commands": [
"mgcb-editor"
]
},
"dotnet-mgcb-editor-linux": {
"version": "3.8.2.1105",
"version": "3.8.1.303",
"commands": [
"mgcb-editor-linux"
]
},
"dotnet-mgcb-editor-windows": {
"version": "3.8.2.1105",
"version": "3.8.1.303",
"commands": [
"mgcb-editor-windows"
]
},
"dotnet-mgcb-editor-mac": {
"version": "3.8.2.1105",
"version": "3.8.1.303",
"commands": [
"mgcb-editor-mac"
]

View File

27
Game/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,27 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/bin/Debug/net8.0/${workspaceFolderBasename}.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

7
Game/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"cSpell.words": [
"AABB",
"DAABB",
"Syntriax"
]
}

15
Game/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "dotnet",
"task": "build",
"problemMatcher": ["$msCompile"],
"group": {
"kind": "build",
"isDefault": true
},
"label": "build"
}
]
}

View File

@ -0,0 +1,23 @@
using Microsoft.Xna.Framework;
using Apos.Shapes;
using Syntriax.Engine.Physics2D.Primitives;
namespace Pong.Behaviours;
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 float Thickness { get; set; } = .5f;
public void Draw(ShapeBatch shapeBatch)
{
shapeBatch.BorderCircle(CircleWorld.Center.ToDisplayVector2(), CircleWorld.Radius, Color);
}
}

View File

@ -1,6 +1,6 @@
using Apos.Shapes;
namespace Syntriax.Engine.Core.Abstract;
namespace Pong.Behaviours;
public interface IDisplayableShape
{

View File

@ -4,14 +4,14 @@ using System.Collections.Generic;
using Microsoft.Xna.Framework.Input;
using Syntriax.Engine.Core;
using Syntriax.Engine.Systems.Input;
using Syntriax.Engine.Input;
namespace Pong.Platforms.Desktop;
namespace Pong.Behaviours;
public class KeyboardInputsBehaviour : Behaviour, IButtonInputs<Keys>
public class KeyboardInputsBehaviour : BehaviourOverride, IButtonInputs<Keys>
{
private readonly Dictionary<Keys, IButtonInputs<Keys>.ButtonCallbackEventHandler> OnPressed = new(256);
private readonly Dictionary<Keys, IButtonInputs<Keys>.ButtonCallbackEventHandler> OnReleased = new(256);
private readonly Dictionary<Keys, Action<IButtonInputs<Keys>, Keys>> OnPressed = new(256);
private readonly Dictionary<Keys, Action<IButtonInputs<Keys>, Keys>> OnReleased = new(256);
private int cachePressedCurrentlyCount = 0;
private readonly Keys[] cachePressedCurrently = new Keys[256];
@ -19,10 +19,7 @@ public class KeyboardInputsBehaviour : Behaviour, IButtonInputs<Keys>
private int cachePressedPreviouslyCount = 0;
private readonly Keys[] cachePressedPreviously = new Keys[256];
public event IButtonInputs<Keys>.ButtonCallbackEventHandler? OnAnyButtonPressed = null;
public event IButtonInputs<Keys>.ButtonCallbackEventHandler? OnAnyButtonReleased = null;
public void RegisterOnPress(Keys key, IButtonInputs<Keys>.ButtonCallbackEventHandler callback)
public void RegisterOnPress(Keys key, Action<IButtonInputs<Keys>, Keys> callback)
{
if (OnPressed.TryGetValue(key, out var action))
{
@ -33,13 +30,13 @@ public class KeyboardInputsBehaviour : Behaviour, IButtonInputs<Keys>
OnPressed.Add(key, callback);
}
public void UnregisterOnPress(Keys key, IButtonInputs<Keys>.ButtonCallbackEventHandler callback)
public void UnregisterOnPress(Keys key, Action<IButtonInputs<Keys>, Keys> callback)
{
if (OnPressed.TryGetValue(key, out var action))
action -= callback;
}
public void RegisterOnRelease(Keys key, IButtonInputs<Keys>.ButtonCallbackEventHandler callback)
public void RegisterOnRelease(Keys key, Action<IButtonInputs<Keys>, Keys> callback)
{
if (OnReleased.TryGetValue(key, out var action))
{
@ -50,7 +47,7 @@ public class KeyboardInputsBehaviour : Behaviour, IButtonInputs<Keys>
OnReleased.Add(key, callback);
}
public void UnregisterOnRelease(Keys key, IButtonInputs<Keys>.ButtonCallbackEventHandler callback)
public void UnregisterOnRelease(Keys key, Action<IButtonInputs<Keys>, Keys> callback)
{
if (OnReleased.TryGetValue(key, out var action))
action -= callback;
@ -72,8 +69,7 @@ public class KeyboardInputsBehaviour : Behaviour, IButtonInputs<Keys>
if (WasPressed(currentlyPressedKey))
continue;
action.InvokeSafe(this, currentlyPressedKey);
OnAnyButtonPressed?.InvokeSafe(this, currentlyPressedKey);
action.Invoke(this, currentlyPressedKey);
}
for (int i = 0; i < cachePressedPreviouslyCount; i++)
@ -86,8 +82,7 @@ public class KeyboardInputsBehaviour : Behaviour, IButtonInputs<Keys>
if (IsPressed(previouslyPressedKey))
continue;
action.InvokeSafe(this, previouslyPressedKey);
OnAnyButtonReleased?.InvokeSafe(this, previouslyPressedKey);
action.Invoke(this, previouslyPressedKey);
}
Array.Copy(cachePressedCurrently, cachePressedPreviously, cachePressedCurrentlyCount);

View File

@ -0,0 +1,106 @@
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);
}

View File

@ -0,0 +1,50 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Syntriax.Engine.Core;
using Syntriax.Engine.Input;
using Syntriax.Engine.Physics2D.Abstract;
namespace Pong.Behaviours;
public class MovementBallBehaviour(Vector2D StartDirection, float Speed) : BehaviourOverride
{
public Vector2D StartDirection { get; private set; } = Vector2D.Normalize(StartDirection);
public float Speed { get; set; } = Speed;
protected override void OnFirstActiveFrame()
{
if (!BehaviourController.TryGetBehaviour(out IRigidBody2D? rigidBody))
throw new Exception($"Where's my {nameof(IRigidBody2D)}????");
rigidBody.Velocity = StartDirection * Speed;
}
// protected override void OnUpdate(GameTime time)
// {
// GameObject.Transform.Position += StartDirection * (time.ElapsedGameTime.Nanoseconds * .001f) * Speed;
// float absY = MathF.Abs(GameObject.Transform.Position.Y);
// float differenceY = absY - PlayAreaBehaviour.PlayArea.Y * 0.5f;
// if (differenceY > 0f)
// {
// if (GameObject.Transform.Position.Y > 0f)
// GameObject.Transform.Position -= Vector2.UnitY * differenceY * 2f;
// else
// GameObject.Transform.Position += Vector2.UnitY * differenceY * 2f;
// StartDirection = new(StartDirection.X, -StartDirection.Y);
// }
// float absX = MathF.Abs(GameObject.Transform.Position.X);
// float differenceX = absX - PlayAreaBehaviour.PlayArea.X * 0.5f;
// if (differenceX > 0f)
// {
// if (GameObject.Transform.Position.X > 0f)
// GameObject.Transform.Position -= Vector2.UnitX * differenceX * 2f;
// else
// GameObject.Transform.Position += Vector2.UnitX * differenceX * 2f;
// StartDirection = new(-StartDirection.X, StartDirection.Y);
// }
// }
}

View File

@ -1,13 +1,12 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Syntriax.Engine.Core;
using Syntriax.Engine.Systems.Input;
using Syntriax.Engine.Input;
namespace Pong.Behaviours;
public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Speed) : Behaviour2D
public class MovementBoxBehaviour(Keys Up, Keys Down, float High, float Low, float Speed) : BehaviourOverride
{
private Keys Up { get; } = Up;
private Keys Down { get; } = Down;
@ -26,16 +25,19 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
return;
if (isUpPressed)
Transform.Position = Transform.Position + Vector2D.Up * Universe.Time.DeltaTime * Speed;
GameObject.Transform.Position = GameObject.Transform.Position + Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed;
else if (isDownPressed)
Transform.Position = Transform.Position + -Vector2D.Up * Universe.Time.DeltaTime * Speed;
GameObject.Transform.Position = GameObject.Transform.Position + -Vector2D.Up * (float)Time.Elapsed.TotalSeconds * Speed;
Transform.Position = new Vector2D(Transform.Position.X, MathF.Max(MathF.Min(Transform.Position.Y, High), Low));
GameObject.Transform.Position = new Vector2D(GameObject.Transform.Position.X, MathF.Max(MathF.Min(GameObject.Transform.Position.Y, High), Low));
}
protected override void OnFirstActiveFrame()
{
inputs = Universe.FindRequiredBehaviour<IButtonInputs<Keys>>();
if (!BehaviourController.TryGetBehaviour<IButtonInputs<Keys>>(out var behaviourResult))
throw new Exception($"{nameof(IButtonInputs<Keys>)} is missing on ${GameObject.Name}.");
inputs = behaviourResult;
inputs.RegisterOnPress(Up, OnUpPressed);
inputs.RegisterOnRelease(Up, OnUpReleased);

View File

@ -0,0 +1,13 @@
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();
}
}

View File

@ -0,0 +1,26 @@
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);
}
}
}

View File

@ -0,0 +1,25 @@
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;
}
}

View File

@ -3,16 +3,21 @@ using Microsoft.Xna.Framework;
using Apos.Shapes;
using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Input;
using Syntriax.Engine.Physics2D.Abstract;
using Syntriax.Engine.Systems.Input;
using Syntriax.Engine.Physics2D.Primitives;
namespace Pong.Behaviours;
public class ShapeAABBBehaviour : Behaviour2D, IDisplayableShape
public class ShapeAABBBehaviour : BehaviourOverride, IDisplayableShape
{
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 float Thickness { get; set; } = .5f;
public bool display = true;
@ -39,9 +44,4 @@ public class ShapeAABBBehaviour : Behaviour2D, IDisplayableShape
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; }
}

View File

@ -2,32 +2,28 @@ using Microsoft.Xna.Framework;
using Apos.Shapes;
using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract;
using Syntriax.Engine.Physics2D.Primitives;
namespace Pong.Behaviours;
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 float Thickness { get; set; } = .5f;
public void Draw(ShapeBatch shapeBatch)
{
if (!IsActive)
return;
Recalculate();
int count = ShapeWorld.Vertices.Count;
shapeBatch.BorderCircle(Transform.Position.ToDisplayVector2(), 5f, Color.DarkRed);
for (int i = 0; i < count - 1; i++)
shapeBatch.DrawLine(ShapeWorld[i].ToDisplayVector2(), ShapeWorld[i + 1].ToDisplayVector2(), Thickness, Color, Color);
shapeBatch.DrawLine(ShapeWorld[0].ToDisplayVector2(), ShapeWorld[^1].ToDisplayVector2(), Thickness, Color, Color);
}
public ShapeBehaviour(Shape2D shape) : base(shape) { }
public ShapeBehaviour(Shape2D shape, float thickness) : base(shape) { Thickness = thickness; }
public ShapeBehaviour(Shape2D shape, Color color) : base(shape) { Color = color; }
public ShapeBehaviour(Shape2D shape, Color color, float thickness) : base(shape) { Thickness = thickness; Color = color; }
}

63
Game/Content/Content.mgcb Normal file
View File

@ -0,0 +1,63 @@
#----------------------------- Global Properties ----------------------------#
/outputDir:bin/$(Platform)
/intermediateDir:obj/$(Platform)
/platform:DesktopGL
/config:
/profile:Reach
/compress:False
#-------------------------------- References --------------------------------#
#---------------------------------- Content ---------------------------------#
#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/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.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

View File

@ -9,7 +9,7 @@ public static class EngineConverter
public readonly static Vector2D screenScale = Vector2D.Down + Vector2D.Right;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static UniverseTime ToUniverseTime(this GameTime gameTime) => new(gameTime.TotalGameTime, gameTime.ElapsedGameTime);
public static EngineTime ToEngineTime(this GameTime gameTime) => new(gameTime.TotalGameTime, gameTime.ElapsedGameTime);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2D ToVector2D(this Vector2 vector) => new(vector.X, vector.Y);
[MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@ -6,7 +6,6 @@
<PublishReadyToRun>false</PublishReadyToRun>
<TieredCompilation>false</TieredCompilation>
<Nullable>enable</Nullable>
<RootNamespace>Pong.Platforms.Desktop</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
@ -17,28 +16,18 @@
<None Remove="Icon.bmp" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Icon.ico">
<LogicalName>Icon.ico</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="Icon.bmp">
<LogicalName>Icon.bmp</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="Icon.ico" />
<EmbeddedResource Include="Icon.bmp" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.2.1105" />
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.2.1105" />
<PackageReference Include="Apos.Shapes" Version="0.2.3" />
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../Shared/Shared.csproj" />
</ItemGroup>
<ItemGroup>
<MonoGameContentReference Include="../../Shared/Content/Content.mgcb">
<Link>Content/Content.mgcb</Link>
</MonoGameContentReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../Shared/Shared.csproj" />
<ProjectReference Include="..\Engine\Engine.Core\Engine.Core.csproj" />
<ProjectReference Include="..\Engine\Engine.Input\Engine.Input.csproj" />
<ProjectReference Include="..\Engine\Engine.Physics2D\Engine.Physics2D.csproj" />
</ItemGroup>
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
<Message Text="Restoring dotnet tools" Importance="High" />

245
Game/Game1.cs Normal file
View File

@ -0,0 +1,245 @@
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);
}
}

View File

@ -0,0 +1,26 @@
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);
}

View File

@ -0,0 +1,13 @@
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; }
}

27
Game/Graphics/Sprite.cs Normal file
View File

@ -0,0 +1,27 @@
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);
}
}
}

View File

@ -2,7 +2,7 @@ using Microsoft.Xna.Framework.Graphics;
namespace Syntriax.Engine.Core.Abstract;
public interface IDisplayableSprite
public interface IDisplayable
{
public void Draw(SpriteBatch spriteBatch);
}

View File

@ -0,0 +1,20 @@
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; }
}

View File

@ -0,0 +1,117 @@
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!;
}

View File

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

View File

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 144 KiB

3
Game/Program.cs Normal file
View File

@ -0,0 +1,3 @@

using var game = new Pong.Game1();
game.Run();

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="Desktop"/>
<assemblyIdentity version="1.0.0.0" name="Game"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">

View File

@ -1,15 +0,0 @@
#----------------------------- Global Properties ----------------------------#
/outputDir:bin/$(Platform)
/intermediateDir:obj/$(Platform)
/platform:DesktopGL
/config:
/profile:Reach
/compress:False
#-------------------------------- References --------------------------------#
#---------------------------------- Content ---------------------------------#

View File

@ -1,7 +0,0 @@
using Pong.Platforms.Desktop;
using Syntriax.Engine.Core;
Syntriax.Engine.Core.Abstract.IUniverseObject universeObject = Syntriax.Engine.Core.Factory.UniverseObjectFactory.Instantiate().SetUniverseObject("Desktop HO");
universeObject.BehaviourController.AddBehaviour<KeyboardInputsBehaviour>();
using var game = new Pong.GamePong(universeObject);
game.Run();

View File

@ -7,57 +7,41 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine", "Engine", "{F7F626
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Core", "Engine\Engine.Core\Engine.Core.csproj", "{990CA10C-1EBB-4395-A43A-456B7029D8C9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Game", "Game\Game.csproj", "{500E1B05-39D7-4232-8051-E7351D745306}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Input", "Engine\Engine.Input\Engine.Input.csproj", "{7EED4EC3-79D5-4C6C-A54D-1B396213C0E4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Physics2D", "Engine\Engine.Physics2D\Engine.Physics2D.csproj", "{0D97F83C-B043-48B1-B155-7354C4E84FC0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine", "Engine\Engine\Engine.csproj", "{2F6B1E26-1217-4EFD-874C-05ADEE4C7969}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{590E392E-9FB3-49FA-B4DA-6C8F7126FFE5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{FECFFD54-338F-4060-9161-1E5770D1DC33}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Desktop", "Platforms\Desktop\Desktop.csproj", "{2B627F66-5A61-4F69-B479-62EEAB603D01}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Systems", "Engine\Engine.Systems\Engine.Systems.csproj", "{8863A1BA-2E83-419F-BACB-D4A4156EC71C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{990CA10C-1EBB-4395-A43A-456B7029D8C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{990CA10C-1EBB-4395-A43A-456B7029D8C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{990CA10C-1EBB-4395-A43A-456B7029D8C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{990CA10C-1EBB-4395-A43A-456B7029D8C9}.Release|Any CPU.Build.0 = Release|Any CPU
{500E1B05-39D7-4232-8051-E7351D745306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{500E1B05-39D7-4232-8051-E7351D745306}.Debug|Any CPU.Build.0 = Debug|Any CPU
{500E1B05-39D7-4232-8051-E7351D745306}.Release|Any CPU.ActiveCfg = Release|Any CPU
{500E1B05-39D7-4232-8051-E7351D745306}.Release|Any CPU.Build.0 = Release|Any CPU
{7EED4EC3-79D5-4C6C-A54D-1B396213C0E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EED4EC3-79D5-4C6C-A54D-1B396213C0E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EED4EC3-79D5-4C6C-A54D-1B396213C0E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EED4EC3-79D5-4C6C-A54D-1B396213C0E4}.Release|Any CPU.Build.0 = Release|Any CPU
{0D97F83C-B043-48B1-B155-7354C4E84FC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D97F83C-B043-48B1-B155-7354C4E84FC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D97F83C-B043-48B1-B155-7354C4E84FC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D97F83C-B043-48B1-B155-7354C4E84FC0}.Release|Any CPU.Build.0 = Release|Any CPU
{2F6B1E26-1217-4EFD-874C-05ADEE4C7969}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F6B1E26-1217-4EFD-874C-05ADEE4C7969}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F6B1E26-1217-4EFD-874C-05ADEE4C7969}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F6B1E26-1217-4EFD-874C-05ADEE4C7969}.Release|Any CPU.Build.0 = Release|Any CPU
{590E392E-9FB3-49FA-B4DA-6C8F7126FFE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{590E392E-9FB3-49FA-B4DA-6C8F7126FFE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{590E392E-9FB3-49FA-B4DA-6C8F7126FFE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{590E392E-9FB3-49FA-B4DA-6C8F7126FFE5}.Release|Any CPU.Build.0 = Release|Any CPU
{2B627F66-5A61-4F69-B479-62EEAB603D01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B627F66-5A61-4F69-B479-62EEAB603D01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B627F66-5A61-4F69-B479-62EEAB603D01}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B627F66-5A61-4F69-B479-62EEAB603D01}.Release|Any CPU.Build.0 = Release|Any CPU
{8863A1BA-2E83-419F-BACB-D4A4156EC71C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8863A1BA-2E83-419F-BACB-D4A4156EC71C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8863A1BA-2E83-419F-BACB-D4A4156EC71C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8863A1BA-2E83-419F-BACB-D4A4156EC71C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{990CA10C-1EBB-4395-A43A-456B7029D8C9} = {F7F62670-237A-4C93-A30E-CE661C6FC401}
{7EED4EC3-79D5-4C6C-A54D-1B396213C0E4} = {F7F62670-237A-4C93-A30E-CE661C6FC401}
{0D97F83C-B043-48B1-B155-7354C4E84FC0} = {F7F62670-237A-4C93-A30E-CE661C6FC401}
{2F6B1E26-1217-4EFD-874C-05ADEE4C7969} = {F7F62670-237A-4C93-A30E-CE661C6FC401}
{2B627F66-5A61-4F69-B479-62EEAB603D01} = {FECFFD54-338F-4060-9161-1E5770D1DC33}
{8863A1BA-2E83-419F-BACB-D4A4156EC71C} = {F7F62670-237A-4C93-A30E-CE661C6FC401}
EndGlobalSection
EndGlobal

View File

@ -1,36 +0,0 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-mgcb": {
"version": "3.8.2.1105",
"commands": [
"mgcb"
]
},
"dotnet-mgcb-editor": {
"version": "3.8.2.1105",
"commands": [
"mgcb-editor"
]
},
"dotnet-mgcb-editor-linux": {
"version": "3.8.2.1105",
"commands": [
"mgcb-editor-linux"
]
},
"dotnet-mgcb-editor-windows": {
"version": "3.8.2.1105",
"commands": [
"mgcb-editor-windows"
]
},
"dotnet-mgcb-editor-mac": {
"version": "3.8.2.1105",
"commands": [
"mgcb-editor-mac"
]
}
}
}

View File

@ -1,75 +0,0 @@
using System;
using Syntriax.Engine.Core;
using Syntriax.Engine.Physics2D;
using Syntriax.Engine.Physics2D.Abstract;
namespace Pong.Behaviours;
public class BallBehaviour : Behaviour2D
{
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()
{
BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected += OnCollisionDetected;
rigidBody = BehaviourController.GetRequiredBehaviour<IRigidBody2D>();
if (UniverseObject.Universe.TryFindBehaviour(out PongManagerBehaviour? pongManager))
{
pongManager.OnReset += ResetBall;
pongManager.OnScored += ResetBall;
pongManager.OnFinished += DisableBall;
}
}
private void DisableBall(PongManagerBehaviour pongManager)
{
Transform.Position = Vector2D.Zero;
rigidBody.Velocity = Vector2D.Zero;
}
private void ResetBall(PongManagerBehaviour pongManager)
{
StateEnable.Enabled = true;
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 * Universe.Time.DeltaTime;
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.Detected.Transform.Position.FromTo(information.Detector.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;
}
}

View File

@ -1,68 +0,0 @@
using Microsoft.Xna.Framework.Input;
using Syntriax.Engine.Core;
using Syntriax.Engine.Systems.Input;
namespace Pong.Behaviours;
public class CameraController : Behaviour
{
private MonoGameCamera2DBehaviour cameraBehaviour = null!;
private IButtonInputs<Keys> buttonInputs = null!;
private float defaultZoomLevel = 1f;
protected override void OnFirstActiveFrame()
{
cameraBehaviour ??= BehaviourController.GetRequiredBehaviour<MonoGameCamera2DBehaviour>();
buttonInputs = Universe.FindRequiredBehaviour<IButtonInputs<Keys>>();
buttonInputs.RegisterOnPress(Keys.F, SwitchToFullScreen);
buttonInputs.RegisterOnPress(Keys.R, ResetCamera);
}
protected override void OnUpdate()
{
if (buttonInputs.IsPressed(Keys.U))
cameraBehaviour.Zoom += Universe.Time.DeltaTime * 5f;
if (buttonInputs.IsPressed(Keys.J))
cameraBehaviour.Zoom -= Universe.Time.DeltaTime * 5f;
if (buttonInputs.IsPressed(Keys.NumPad8)) cameraBehaviour.Transform.LocalPosition += Vector2D.Up * Universe.Time.DeltaTime * 500f;
if (buttonInputs.IsPressed(Keys.NumPad2)) cameraBehaviour.Transform.LocalPosition -= Vector2D.Up * Universe.Time.DeltaTime * 500f;
if (buttonInputs.IsPressed(Keys.NumPad6)) cameraBehaviour.Transform.LocalPosition += Vector2D.Right * Universe.Time.DeltaTime * 500f;
if (buttonInputs.IsPressed(Keys.NumPad4)) cameraBehaviour.Transform.LocalPosition -= Vector2D.Right * Universe.Time.DeltaTime * 500f;
if (buttonInputs.IsPressed(Keys.Q))
cameraBehaviour.Transform.Rotation += Universe.Time.DeltaTime * 45f;
if (buttonInputs.IsPressed(Keys.E))
cameraBehaviour.Transform.Rotation -= Universe.Time.DeltaTime * 45f;
}
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;
cameraBehaviour.Transform.LocalPosition = Vector2D.Zero;
cameraBehaviour.Transform.LocalRotation = 0f;
}
}

View File

@ -1,29 +0,0 @@
using Microsoft.Xna.Framework;
using Apos.Shapes;
using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract;
namespace Pong.Behaviours;
public class CircleBehaviour : Syntriax.Engine.Physics2D.Collider2DCircleBehaviour, IDisplayableShape
{
public Color Color { get; set; } = Color.White;
public float Thickness { get; set; } = .5f;
public void Draw(ShapeBatch shapeBatch)
{
if (!IsActive)
return;
Recalculate();
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; }
}

View File

@ -1,102 +0,0 @@
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) : Behaviour2D, 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?.InvokeSafe(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?.InvokeSafe(this);
}
}
public float Zoom
{
get => _zoom;
set
{
float newValue = Math.Max(0.1f, value);
if (_zoom == newValue)
return;
_zoom = newValue;
OnZoomChanged?.InvokeSafe(this);
}
}
public float Rotation
{
get => Transform.Rotation;
set => Transform.Rotation = value;
}
// 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);
}

View File

@ -1,48 +0,0 @@
using System;
using Syntriax.Engine.Core;
using Syntriax.Engine.Physics2D;
using Syntriax.Engine.Physics2D.Abstract;
namespace Pong.Behaviours;
public class MovementBallBehaviour : Behaviour2D
{
public Vector2D StartDirection { get; private set; } = Vector2D.Zero;
public float Speed { get; set; } = 500f;
public float SpeedUpMultiplier { get; set; } = .0125f;
private IRigidBody2D rigidBody = null!;
protected override void OnFirstActiveFrame()
{
rigidBody = BehaviourController.GetRequiredBehaviour<IRigidBody2D>();
rigidBody.Velocity = StartDirection * Speed;
BehaviourController.GetRequiredBehaviour<ICollider2D>().OnCollisionDetected += OnCollisionDetected;
}
protected override void OnUpdate()
{
if (rigidBody.Velocity.MagnitudeSquared <= 0.01f)
return;
Vector2D speedUp = rigidBody.Velocity.Normalized * Universe.Time.DeltaTime;
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.Detector.Transform.Position.FromTo(information.Detected.Transform.Position).Normalized * rigidBody.Velocity.Magnitude;
else
rigidBody.Velocity = rigidBody.Velocity.Reflect(information.Normal);
}
public MovementBallBehaviour() { }
public MovementBallBehaviour(Vector2D startDirection, float speed)
{
StartDirection = Vector2D.Normalize(startDirection);
Speed = speed;
}
}

View File

@ -1,61 +0,0 @@
using System;
using Microsoft.Xna.Framework.Input;
using Syntriax.Engine.Core;
using Syntriax.Engine.Systems.Input;
namespace Pong.Behaviours;
public class PongManagerBehaviour : Behaviour
{
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()
{
var buttonInputs = Universe.FindRequiredBehaviour<IButtonInputs<Keys>>();
buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => Reset());
}
public void ScoreToLeft()
{
ScoreLeft++;
OnScored?.InvokeSafe(this);
CheckFinish();
}
public void ScoreToRight()
{
ScoreRight++;
OnScored?.InvokeSafe(this);
CheckFinish();
}
public void Reset()
{
ScoreLeft = ScoreRight = 0;
OnReset?.InvokeSafe(this);
}
private void CheckFinish()
{
int halfwayScore = (int)(WinScore * .5f);
if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore)
OnFinished?.InvokeSafe(this);
}
}

View File

@ -1,25 +0,0 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Syntriax.Engine.Core;
using Syntriax.Engine.Core.Abstract;
namespace Pong.Behaviours;
public class TextBehaviour : Behaviour2D, 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;
}

View File

@ -1,33 +0,0 @@
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 (!UniverseObject.Universe.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;
}

View File

@ -1,19 +0,0 @@
using System;
using Syntriax.Engine.Core;
using Syntriax.Engine.Physics2D.Abstract;
namespace Pong.Behaviours;
public class WallScoreBehaviour(Action OnCollision) : Behaviour2D
{
private Action OnCollision { get; } = OnCollision;
protected override void OnFirstActiveFrame()
{
if (!BehaviourController.TryGetBehaviour(out ICollider2D? collider2D))
return;
collider2D.OnCollisionDetected += (_, _1) => OnCollision?.InvokeSafe();
}
}

View File

@ -1,22 +0,0 @@
#----------------------------- Global Properties ----------------------------#
/outputDir:bin/$(Platform)
/intermediateDir:obj/$(Platform)
/platform:DesktopGL
/config:
/profile:Reach
/compress:False
#-------------------------------- References --------------------------------#
#---------------------------------- Content ---------------------------------#
#begin UbuntuMono.spritefont
/importer:FontDescriptionImporter
/processor:FontDescriptionProcessor
/processorParam:PremultiplyAlpha=True
/processorParam:TextureFormat=Compressed
/build:UbuntuMono.spritefont

Binary file not shown.

View File

@ -1,60 +0,0 @@
<?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>&#32;</Start>
<End>&#126;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>

View File

@ -1,165 +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;
namespace Pong;
public class GamePong : Game
{
private readonly IUniverseObject platformSpecificUniverseObject = null!;
private readonly GraphicsDeviceManager graphics = null!;
private SpriteBatch spriteBatch = null!;
private ShapeBatch shapeBatch = null!;
private Universe universe = null!;
private BehaviourCollector<IDisplayableSprite> displayableCollector = null!;
private BehaviourCollector<IDisplayableShape> displayableShapeCollector = null!;
private MonoGameCamera2DBehaviour cameraBehaviour = null!;
private PongManagerBehaviour pongManager = null!;
public GamePong(IUniverseObject platformSpecificUniverseObject)
{
this.platformSpecificUniverseObject = platformSpecificUniverseObject;
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
universe = new();
displayableCollector = new(universe);
displayableShapeCollector = new(universe);
universe.Initialize();
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
shapeBatch = new ShapeBatch(GraphicsDevice, Content);
SpriteFont spriteFont = Content.Load<SpriteFont>("UbuntuMono");
universe.Register(platformSpecificUniverseObject);
universe.InstantiateUniverseObject<PhysicsEngine2D>().SetUniverseObject("Physics Engine 2D");
////////////////////////////////////////////////////////////////////////////////////
IUniverseObject UniverseObjectCamera = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Camera"); ;
UniverseObjectCamera.BehaviourController.AddBehaviour<Transform2D>();
UniverseObjectCamera.BehaviourController.AddBehaviour<CameraController>();
cameraBehaviour = UniverseObjectCamera.BehaviourController.AddBehaviour<MonoGameCamera2DBehaviour>(graphics);
////////////////////////////////////////////////////////////////////////////////////
IUniverseObject UniverseObjectPongManager = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Pong Game Manager");
pongManager = UniverseObjectPongManager.BehaviourController.AddBehaviour<PongManagerBehaviour>(5);
////////////////////////////////////////////////////////////////////////////////////
IUniverseObject UniverseObjectBall = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Ball");
UniverseObjectBall.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(0, 0f), scale: new Vector2D(10f, 10f));
UniverseObjectBall.BehaviourController.AddBehaviour<CircleBehaviour>(new Circle(Vector2D.Zero, 1f));
UniverseObjectBall.BehaviourController.AddBehaviour<BallBehaviour>();
UniverseObjectBall.BehaviourController.AddBehaviour<RigidBody2D>();
////////////////////////////////////////////////////////////////////////////////////
IUniverseObject UniverseObjectLeftPaddle = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Left Paddle");
UniverseObjectLeftPaddle.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(-468f, 0f), scale: new Vector2D(15f, 60f));
UniverseObjectLeftPaddle.BehaviourController.AddBehaviour<PaddleBehaviour>(Keys.W, Keys.S, 228f, -228f, 400f);
UniverseObjectLeftPaddle.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape2D.Square);
UniverseObjectLeftPaddle.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
IUniverseObject UniverseObjectRightPaddle = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Right Paddle");
UniverseObjectRightPaddle.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(468f, 0f), scale: new Vector2D(15f, 60f));
UniverseObjectRightPaddle.BehaviourController.AddBehaviour<PaddleBehaviour>(Keys.Up, Keys.Down, 228f, -228f, 400f);
UniverseObjectRightPaddle.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape2D.Square);
UniverseObjectRightPaddle.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
////////////////////////////////////////////////////////////////////////////////////
IUniverseObject UniverseObjectWallTop = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Wall Top");
UniverseObjectWallTop.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(0f, 308f), scale: new Vector2D(552f, 20f));
UniverseObjectWallTop.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape2D.Square);
UniverseObjectWallTop.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
IUniverseObject UniverseObjectWallBottom = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Wall Bottom");
UniverseObjectWallBottom.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(0f, -308f), scale: new Vector2D(552f, 20f));
UniverseObjectWallBottom.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape2D.Square);
UniverseObjectWallBottom.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
IUniverseObject UniverseObjectWallRight = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Wall Right");
UniverseObjectWallRight.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(532f, 0f), scale: new Vector2D(20f, 328f));
UniverseObjectWallRight.BehaviourController.AddBehaviour<WallScoreBehaviour>((Action)pongManager.ScoreToLeft);
UniverseObjectWallRight.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape2D.Square);
UniverseObjectWallRight.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
IUniverseObject UniverseObjectWallLeft = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Wall Left");
UniverseObjectWallLeft.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(-532f, 0f), scale: new Vector2D(20f, 328f));
UniverseObjectWallLeft.BehaviourController.AddBehaviour<WallScoreBehaviour>((Action)pongManager.ScoreToRight);
UniverseObjectWallLeft.BehaviourController.AddBehaviour<ShapeBehaviour>(Shape2D.Square);
UniverseObjectWallLeft.BehaviourController.AddBehaviour<RigidBody2D>().IsStatic = true;
////////////////////////////////////////////////////////////////////////////////////
IUniverseObject UniverseObjectLeftScoreText = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Score Left");
UniverseObjectLeftScoreText.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(-250f, 250f), scale: Vector2D.One * .25f);
UniverseObjectLeftScoreText.BehaviourController.AddBehaviour<TextScoreBehaviour>(true, spriteFont);
IUniverseObject UniverseObjectRightScoreText = universe.InstantiateUniverseObject<UniverseObject>().SetUniverseObject("Score Right");
UniverseObjectRightScoreText.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(250f, 250f), scale: Vector2D.One * .25f);
UniverseObjectRightScoreText.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();
universe.Update(gameTime.ToUniverseTime());
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
universe.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);
}
}

View File

@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Apos.Shapes" Version="0.2.3" />
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.2.1105">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../Engine/Engine/Engine.csproj" />
</ItemGroup>
</Project>