├── .gitignore
├── Examples.SampleGame
├── Assets
│ └── Textures
│ │ ├── background_0.png
│ │ ├── background_1.png
│ │ ├── background_2.png
│ │ ├── background_3.png
│ │ ├── border.png
│ │ ├── color_palette.ai
│ │ ├── color_palette.png
│ │ ├── n8dev.png
│ │ ├── player.png
│ │ ├── spike_d.png
│ │ ├── spike_u.png
│ │ └── sprite_sheet.ai
├── Examples.SampleGame.csproj
├── Examples.SampleGame.csproj.DotSettings
└── Source
│ ├── Components
│ ├── Body.cs
│ ├── Parallax.cs
│ ├── Player.cs
│ ├── PlayerStart.cs
│ ├── RestartScene.cs
│ └── Scrolling.cs
│ ├── Globals
│ ├── Events.cs
│ └── Scenes.cs
│ ├── Program.cs
│ ├── Scenes
│ └── MainScene.cs
│ └── Utilities
│ └── Event.cs
├── LICENSE
├── N8Engine.Core
├── Assets
│ ├── Shaders
│ │ ├── colors.frag
│ │ ├── colors.vert
│ │ ├── sprite.frag
│ │ └── sprite.vert
│ └── Textures
│ │ └── n8dev.png
├── N8Engine.Core.csproj
├── N8Engine.Core.csproj.DotSettings
└── Source
│ ├── Core
│ ├── Component.cs
│ ├── Debug.cs
│ ├── Exceptions
│ │ ├── ComponentAlreadyAttachedException.cs
│ │ ├── ComponentNotAttachedException.cs
│ │ ├── GameObjectIsDestroyedException.cs
│ │ └── ModuleNotFoundException.cs
│ ├── Frame.cs
│ ├── Game.cs
│ ├── GameObject.cs
│ ├── GameStart.cs
│ ├── Loop.cs
│ ├── Module.cs
│ ├── Modules.cs
│ ├── Ticks.cs
│ ├── Transform.cs
│ └── UpdateDebugger.cs
│ ├── InputSystem
│ ├── Input.cs
│ ├── InputDebugger.cs
│ ├── InputExtensions.cs
│ ├── Key.cs
│ └── KeyExtensions.cs
│ ├── Rendering
│ ├── BufferObject.cs
│ ├── Camera.cs
│ ├── CameraController.cs
│ ├── Exceptions
│ │ ├── MissingUniformOnShaderException.cs
│ │ ├── ShaderFailedCompilationException.cs
│ │ └── ShaderProgramFailedLinkException.cs
│ ├── Graphics.cs
│ ├── Shader.cs
│ ├── Sprite.cs
│ ├── SpriteRenderer.cs
│ ├── Texture.cs
│ └── VertexArrayObject.cs
│ ├── SceneManagement
│ ├── Element.cs
│ ├── ElementNotFoundException.cs
│ ├── Elements.cs
│ ├── EmptyScene.cs
│ ├── Scene.cs
│ └── SceneManager.cs
│ ├── Utilities
│ ├── Bounds.cs
│ ├── MathExtensions.cs
│ ├── PathExtensions.cs
│ ├── ServiceLocator.cs
│ └── ServiceNotFoundException.cs
│ └── Windowing
│ ├── Window.cs
│ ├── WindowEvents.cs
│ ├── WindowOptions.cs
│ ├── WindowSize.cs
│ └── WindowState.cs
├── N8Engine.Tests
├── Assets
│ └── dummy.txt
├── N8Engine.Tests.csproj
├── N8Engine.Tests.csproj.DotSettings
└── Source
│ ├── BoundsTests.cs
│ ├── DebugTests.cs
│ ├── GameObjectTests.cs
│ ├── InputSystemTests.cs
│ ├── PathExtensionsTests.cs
│ ├── SceneManagementTests.cs
│ └── ServiceLocatorTests.cs
├── N8Engine.sln
├── N8Engine.sln.DotSettings
└── N8Engine.sln.DotSettings.user
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | obj/
3 | /packages/
4 | riderModule.iml
5 | /_ReSharper.Caches/
6 | .idea/
7 |
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/background_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/background_0.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/background_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/background_1.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/background_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/background_2.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/background_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/background_3.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/border.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/border.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/color_palette.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/color_palette.ai
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/color_palette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/color_palette.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/n8dev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/n8dev.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/player.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/player.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/spike_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/spike_d.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/spike_u.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/spike_u.png
--------------------------------------------------------------------------------
/Examples.SampleGame/Assets/Textures/sprite_sheet.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/Examples.SampleGame/Assets/Textures/sprite_sheet.ai
--------------------------------------------------------------------------------
/Examples.SampleGame/Examples.SampleGame.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | latest
7 | SampleGame
8 | Release;Debug
9 | AnyCPU
10 |
11 |
12 |
13 | x64
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Examples.SampleGame/Examples.SampleGame.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
5 | True
6 | True
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Components/Body.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 | using N8Engine;
3 |
4 | namespace SampleGame;
5 |
6 | sealed class Body : Component
7 | {
8 | readonly float _gravity;
9 |
10 | public Vector2 Velocity { get; set; }
11 | public bool UseGravity { get; set; }
12 |
13 | public Body(float gravity, bool useGravity = true)
14 | {
15 | _gravity = gravity;
16 | UseGravity = useGravity;
17 | }
18 |
19 | public override void EarlyUpdate(Frame frame)
20 | {
21 | if (!UseGravity)
22 | return;
23 | var vel = Velocity;
24 | // V = 1/2g * t^2
25 | vel.Y += _gravity * frame.DeltaTime;
26 | Velocity = vel;
27 | }
28 | }
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Components/Parallax.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 | using N8Engine;
3 | using N8Engine.SceneManagement;
4 |
5 | namespace SampleGame;
6 |
7 | sealed class Parallax : Component
8 | {
9 | // Values 0-1 work best.
10 | readonly float _speed;
11 | readonly Scrolling _scrolling;
12 |
13 | Transform _transform;
14 | float _length;
15 | float _startingPosition;
16 |
17 | public Parallax(float speed, Scrolling scrolling)
18 | {
19 | _speed = speed;
20 | _scrolling = scrolling;
21 | }
22 |
23 | public override void Create(GameObject gameObject, Scene scene)
24 | {
25 | _transform = gameObject.GetComponent();
26 | _length = _transform.Bounds().Size.X;
27 | _startingPosition = _transform.Position.X;
28 | }
29 |
30 | public override void LateUpdate(Frame frame)
31 | {
32 | _transform.Position -= new Vector2(_scrolling.Speed * frame.DeltaTime * (1 - _speed), 0f);
33 | var distance = _startingPosition - _transform.Position.X;
34 | if (distance > _length)
35 | _transform.Position = new(_startingPosition, _transform.Position.Y);
36 | }
37 | }
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Components/Player.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using N8Engine;
3 | using N8Engine.SceneManagement;
4 |
5 | namespace SampleGame;
6 |
7 | sealed class Player : Component
8 | {
9 | readonly float _jump;
10 | readonly Func _whenToJump;
11 |
12 | Transform _transform;
13 | Body _body;
14 |
15 | public bool IsEnabled { get; set; }
16 |
17 | public Player(float jump, Func whenToJump)
18 | {
19 | _jump = jump;
20 | _whenToJump = whenToJump;
21 | }
22 |
23 | public override void Create(GameObject gameObject, Scene scene)
24 | {
25 | _transform = gameObject.GetComponent();
26 | _body = gameObject.GetComponent();
27 | Events.OnPlayerStart.Add(Enable);
28 | }
29 |
30 | public override void Destroy() => Events.OnPlayerStart.Remove(Enable);
31 |
32 | public override void Update(Frame frame)
33 | {
34 | if (!IsEnabled)
35 | return;
36 | if (_whenToJump())
37 | _body.Velocity = new(0, _jump);
38 | _transform.Position += _body.Velocity * frame.DeltaTime;
39 | }
40 |
41 | void Enable()
42 | {
43 | IsEnabled = true;
44 | _body.UseGravity = true;
45 | }
46 | }
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Components/PlayerStart.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using N8Engine;
3 | using N8Engine.SceneManagement;
4 |
5 | namespace SampleGame;
6 |
7 | sealed class PlayerStart : Component
8 | {
9 | readonly Func _whenToStart;
10 | GameObject _gameObject;
11 |
12 | public PlayerStart(Func whenToStart) => _whenToStart = whenToStart;
13 |
14 | public override void Create(GameObject gameObject, Scene scene) => _gameObject = gameObject;
15 |
16 | public override void Update(Frame frame)
17 | {
18 | if (_whenToStart())
19 | {
20 | Events.OnPlayerStart.Raise();
21 | _gameObject.RemoveComponent();
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Components/RestartScene.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using N8Engine;
3 | using N8Engine.SceneManagement;
4 |
5 | namespace SampleGame;
6 |
7 | sealed class RestartScene : Component
8 | {
9 | readonly Func _whenToRestart;
10 | readonly SceneManager _sceneManager;
11 |
12 | public RestartScene(Func whenToRestart)
13 | {
14 | _whenToRestart = whenToRestart;
15 | _sceneManager = Modules.Get();
16 | }
17 |
18 | public override void LateUpdate(Frame frame)
19 | {
20 | if (_whenToRestart())
21 | _sceneManager.Load(_sceneManager.CurrentScene);
22 | }
23 | }
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Components/Scrolling.cs:
--------------------------------------------------------------------------------
1 | namespace SampleGame;
2 |
3 | sealed class Scrolling
4 | {
5 | public bool IsScrolling { get; private set; }
6 | public float Speed { get; }
7 |
8 | public Scrolling(float speed) => Speed = speed;
9 |
10 | public void Start() => IsScrolling = true;
11 | public void Stop() => IsScrolling = false;
12 | }
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Globals/Events.cs:
--------------------------------------------------------------------------------
1 | namespace SampleGame;
2 |
3 | static class Events
4 | {
5 | public static readonly Event OnPlayerStart = new();
6 | }
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Globals/Scenes.cs:
--------------------------------------------------------------------------------
1 | namespace SampleGame;
2 |
3 | static class Scenes
4 | {
5 | public static readonly MainScene Main = new();
6 | }
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Program.cs:
--------------------------------------------------------------------------------
1 | using N8Engine;
2 | using SampleGame;
3 |
4 | new Game()
5 | .WithFirstScene(Scenes.Main)
6 | .WithWindowTitle("Flappo")
7 | .WithWindowSize(1300, 700)
8 | .WithNotResizableWindow()
9 | .Run();
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Scenes/MainScene.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 | using N8Engine;
3 | using N8Engine.InputSystem;
4 | using N8Engine.Rendering;
5 | using N8Engine.SceneManagement;
6 | using N8Engine.Utilities;
7 |
8 | namespace SampleGame;
9 |
10 | sealed class MainScene : Scene
11 | {
12 | public override string Name => "Main";
13 |
14 | protected override void Load()
15 | {
16 | var input = Modules.Get();
17 | var camera = Get();
18 | camera.Zoom = 0.5f;
19 |
20 | Create("background_wall")
21 | .AddComponent(new Transform().WithScale(1920 * 2, 1080 * 2))
22 | .AddComponent(new Sprite("Assets/Textures/background_3.png".Find()));
23 |
24 | var scrolling = new Scrolling(1000f);
25 | var scrollSpeeds = new[] { 0f, 0.5f, 0.8f };
26 | var scrollPositions = new[] {-500f, -210, 60f};
27 | var duplicateScrollPositions = new[] {-3918f, 0, 3918f};
28 | var backgroundScales = new Vector2[] {new(3918, 395), new(3918, 518), new(3918, 743)};
29 | for (var s = 2; s >= 0; s--)
30 | {
31 | for (var d = 0; d < 3; d++)
32 | {
33 | Create($"background_{s}_{d}")
34 | .AddComponent(new Parallax(scrollSpeeds[s], scrolling))
35 | .AddComponent(new Sprite($"Assets/Textures/background_{s}.png".Find()))
36 | .AddComponent(new Transform()
37 | .AtPosition(duplicateScrollPositions[d], scrollPositions[s])
38 | .WithScale(backgroundScales[s]));
39 | }
40 | }
41 |
42 | Create("player")
43 | .AddComponent(new PlayerStart(() => input.WasJustPressed(Key.Space)))
44 | .AddComponent(new Player(1000f, () => input.WasJustPressed(Key.Space)))
45 | .AddComponent(new Body(-2300))
46 | .AddComponent(new Sprite("Assets/Textures/player.png".Find()))
47 | .AddComponent(new Transform()
48 | .AtPosition(-100, 0)
49 | .WithScale(199, 178), out var player)
50 | .AddComponent(new RestartScene(() => !camera.Bounds().Contains(player.Position)));
51 | }
52 | }
--------------------------------------------------------------------------------
/Examples.SampleGame/Source/Utilities/Event.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SampleGame;
4 |
5 | sealed class Event
6 | {
7 | event Action OnEvent;
8 | public void Add(Action action) => OnEvent += action;
9 | public void Remove(Action action) => OnEvent -= action;
10 | public void Raise() => OnEvent?.Invoke();
11 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Nathan Curtiss
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/N8Engine.Core/Assets/Shaders/colors.frag:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec4 fColor;
4 | out vec4 FragColor;
5 |
6 | void main()
7 | {
8 | FragColor = fColor;
9 | }
--------------------------------------------------------------------------------
/N8Engine.Core/Assets/Shaders/colors.vert:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | layout (location = 0) in vec3 vPos;
4 | layout (location = 1) in vec4 vColor;
5 |
6 | uniform float uBlue;
7 |
8 | out vec4 fColor;
9 |
10 | void main()
11 | {
12 | gl_Position = vec4(vPos, 1.0);
13 | fColor = vColor;
14 | }
--------------------------------------------------------------------------------
/N8Engine.Core/Assets/Shaders/sprite.frag:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec2 fUv;
3 |
4 | uniform sampler2D uTexture0;
5 |
6 | out vec4 FragColor;
7 |
8 | void main()
9 | {
10 | if (texture(uTexture0, fUv).a != 1.0f)
11 | {
12 | discard;
13 | }
14 | FragColor = texture(uTexture0, fUv);
15 | }
--------------------------------------------------------------------------------
/N8Engine.Core/Assets/Shaders/sprite.vert:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | layout (location = 0) in vec3 vPos;
3 | layout (location = 1) in vec2 vUv;
4 |
5 | uniform mat4 uModel;
6 | uniform mat4 uProjection;
7 |
8 | out vec2 fUv;
9 |
10 | void main()
11 | {
12 | gl_Position = uProjection * uModel * vec4(vPos, 1.0);
13 | fUv = vUv;
14 | }
--------------------------------------------------------------------------------
/N8Engine.Core/Assets/Textures/n8dev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natecurtiss/n8engine/4148c2b2328acb846f8a6c063776662bd21e0ecd/N8Engine.Core/Assets/Textures/n8dev.png
--------------------------------------------------------------------------------
/N8Engine.Core/N8Engine.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Library
5 | net6.0
6 | true
7 | true
8 | n8engine
9 | n8dev
10 | An open-source C# terminal game engine.
11 | https://github.com/N-8-D-e-v/n8engine
12 | n8engine
13 | https://www.mit.edu/~amini/LICENSE.md
14 | true
15 | 2.1.0
16 | true
17 | latest
18 | N8Engine
19 | Release;Debug
20 | AnyCPU
21 |
22 |
23 |
24 |
25 | true
26 |
27 |
28 |
29 |
30 | <_Parameter1>N8Engine.Tests
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/N8Engine.Core/N8Engine.Core.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
5 | False
6 | True
7 | True
8 | True
--------------------------------------------------------------------------------
/N8Engine.Core/Source/Core/Component.cs:
--------------------------------------------------------------------------------
1 | using N8Engine.SceneManagement;
2 |
3 | namespace N8Engine;
4 |
5 | public abstract class Component
6 | {
7 | public virtual void Destroy() { }
8 | public virtual void Create(GameObject gameObject, Scene scene) { }
9 | public virtual void Start() { }
10 | public virtual void EarlyUpdate(Frame frame) { }
11 | public virtual void Update(Frame frame) { }
12 | public virtual void LateUpdate(Frame frame) { }
13 | public virtual void Render() { }
14 | }
--------------------------------------------------------------------------------
/N8Engine.Core/Source/Core/Debug.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace N8Engine;
4 |
5 | public static class Debug
6 | {
7 | static Action