belts_engine 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/belts_engine/application.rb +21 -0
- data/lib/belts_engine/components/mat4.rb +88 -0
- data/lib/belts_engine/components/transform.rb +28 -0
- data/lib/belts_engine/components/vec3.rb +29 -0
- data/lib/belts_engine/ecs/collection.rb +28 -0
- data/lib/belts_engine/ecs/collection_manager.rb +13 -0
- data/lib/belts_engine/ecs/entity.rb +11 -0
- data/lib/belts_engine/ecs/entity_manager.rb +57 -0
- data/lib/belts_engine/ecs/system_manager.rb +34 -0
- data/lib/belts_engine/game.rb +32 -0
- data/lib/belts_engine/prefab/component_mixin.rb +28 -0
- data/lib/belts_engine/prefab.rb +10 -0
- data/lib/belts_engine/scene.rb +27 -0
- data/lib/belts_engine/system/collection_mixin.rb +33 -0
- data/lib/belts_engine/system.rb +23 -0
- data/lib/belts_engine/tools/input/keyboard.rb +25 -0
- data/lib/belts_engine/tools/input/mouse.rb +32 -0
- data/lib/belts_engine/tools/input.rb +18 -0
- data/lib/belts_engine/tools/scene_manager.rb +19 -0
- data/lib/belts_engine/tools/time.rb +26 -0
- data/lib/belts_engine/tools/window.rb +22 -0
- data/lib/belts_engine/tools_manager.rb +25 -0
- data/lib/belts_engine.rb +12 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 96110da4df4e213c5a54284cfee9210bc0426105e6c7b20f0891742189d49bae
|
4
|
+
data.tar.gz: 6aab3aa5dd2c03b7fceae17c6232b24c3f266b15cfe1d56874c107c7804f5b2a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bbd1af8726a3962be1228108a636f2c90857f60f0eed61605b09fd2379b26be80f315c8bf21cf727f33d240c5068f7d9264d428c24674133449e878c92ac52d9
|
7
|
+
data.tar.gz: ad4c75ec48c4c360137e1ca462f47bf5952bf98b74e39c5367dd9e61cef2e5928e147a64ec1d7a4d08f5a414cc9a5908b50c568a7bda71d2866015a8ca411821
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
class Application
|
3
|
+
include BeltsSupport::Configuration
|
4
|
+
|
5
|
+
config.plugins = []
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@game = ::Game.new
|
9
|
+
|
10
|
+
config.plugins.each do |plugin_class|
|
11
|
+
@game.use plugin_class
|
12
|
+
end
|
13
|
+
|
14
|
+
@game.start
|
15
|
+
|
16
|
+
while true
|
17
|
+
@game.update
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
Mat4 = Struct.new(:m) do
|
2
|
+
class << self
|
3
|
+
def identity = Matrix.identity(4)
|
4
|
+
|
5
|
+
def translation(x, y, z)
|
6
|
+
Matrix[
|
7
|
+
[1, 0, 0, x],
|
8
|
+
[0, 1, 0, y],
|
9
|
+
[0, 0, 1, z],
|
10
|
+
[0, 0, 0, 1]
|
11
|
+
]
|
12
|
+
end
|
13
|
+
|
14
|
+
def rotation(x, y, z)
|
15
|
+
x = x * Math::PI / 180
|
16
|
+
y = y * Math::PI / 180
|
17
|
+
z = z * Math::PI / 180
|
18
|
+
|
19
|
+
rotation_x = Matrix[
|
20
|
+
[1, 0, 0, 0],
|
21
|
+
[0, Math.cos(x), -Math.sin(x), 0],
|
22
|
+
[0, Math.sin(x), Math.cos(x), 0],
|
23
|
+
[0, 0, 0, 1]
|
24
|
+
]
|
25
|
+
|
26
|
+
rotation_y = Matrix[
|
27
|
+
[Math.cos(y), 0, Math.sin(y), 0],
|
28
|
+
[0, 1, 0, 0],
|
29
|
+
[-Math.sin(y), 0, Math.cos(y), 0],
|
30
|
+
[0, 0, 0, 1]
|
31
|
+
]
|
32
|
+
|
33
|
+
rotation_z = Matrix[
|
34
|
+
[Math.cos(z), -Math.sin(z), 0, 0],
|
35
|
+
[Math.sin(z), Math.cos(z), 0, 0],
|
36
|
+
[0, 0, 1, 0],
|
37
|
+
[0, 0, 0, 1]
|
38
|
+
]
|
39
|
+
|
40
|
+
rotation_x * rotation_y * rotation_z
|
41
|
+
end
|
42
|
+
|
43
|
+
def scale(x, y, z)
|
44
|
+
Matrix[
|
45
|
+
[x, 0, 0, 0],
|
46
|
+
[0, y, 0, 0],
|
47
|
+
[0, 0, z, 0],
|
48
|
+
[0, 0, 0, 1]
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
def perspective(fov, aspect, near, far)
|
53
|
+
fov_rad = fov * Math::PI / 180
|
54
|
+
|
55
|
+
y_scale = 1 / Math.tan(fov_rad)
|
56
|
+
x_scale = y_scale / aspect
|
57
|
+
frustumLength = far - near
|
58
|
+
|
59
|
+
Matrix[
|
60
|
+
[x_scale, 0, 0, 0],
|
61
|
+
[0, y_scale, 0, 0],
|
62
|
+
[0, 0, -(far + near) / frustumLength, -1],
|
63
|
+
[0, 0, 2 * -(far * near) / frustumLength, 0]
|
64
|
+
].transpose
|
65
|
+
end
|
66
|
+
|
67
|
+
def orthographic(left, right, bottom, top, near, far)
|
68
|
+
scale = scale(2.0 / (right - left), 2.0 / (top - bottom), 2.0 / (far - near))
|
69
|
+
centerer = translation(- (right + left) / (right - left), - (top + bottom) / (top - bottom), (far - near) / 2.0)
|
70
|
+
inverter = scale(1, 1, -1)
|
71
|
+
|
72
|
+
scale * centerer# * inverter
|
73
|
+
end
|
74
|
+
|
75
|
+
def look_at(eye, target, up)
|
76
|
+
z_axis = (eye - target).normalize
|
77
|
+
x_axis = up.cross(z_axis).normalize
|
78
|
+
y_axis = z_axis.cross(x_axis)
|
79
|
+
|
80
|
+
Matrix[
|
81
|
+
[x_axis[0], x_axis[1], x_axis[2], -x_axis.dot(eye)],
|
82
|
+
[y_axis[0], y_axis[1], y_axis[2], -y_axis.dot(eye)],
|
83
|
+
[z_axis[0], z_axis[1], z_axis[2], -z_axis.dot(eye)],
|
84
|
+
[0, 0, 0, 1]
|
85
|
+
]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Transform = Struct.new(:position, :rotation, :scale) do
|
2
|
+
def initialize(position: Vec3.zero, rotation: Vec3.zero, scale: Vec3.one) = super(position, rotation, scale)
|
3
|
+
|
4
|
+
def to_matrix
|
5
|
+
Mat4.translation(*position) *
|
6
|
+
Mat4.rotation(*rotation) *
|
7
|
+
Mat4.scale(*scale)
|
8
|
+
end
|
9
|
+
|
10
|
+
def forward
|
11
|
+
matrix = to_matrix
|
12
|
+
Vec3[matrix[0, 2], matrix[1, 2], matrix[2, 2]]
|
13
|
+
end
|
14
|
+
|
15
|
+
def right
|
16
|
+
matrix = to_matrix
|
17
|
+
Vec3[matrix[0, 0], matrix[1, 0], matrix[2, 0]]
|
18
|
+
end
|
19
|
+
|
20
|
+
def up
|
21
|
+
matrix = to_matrix
|
22
|
+
Vec3[matrix[0, 1], matrix[1, 1], matrix[2, 1]]
|
23
|
+
end
|
24
|
+
|
25
|
+
def back = -forward
|
26
|
+
def left = -right
|
27
|
+
def down = -up
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Vec3 < Vector
|
2
|
+
class << self
|
3
|
+
def [](x = 0, y = 0, z = 0) = super(x, y, z)
|
4
|
+
|
5
|
+
def zero = Vec3[0, 0, 0]
|
6
|
+
def one = Vec3[1, 1, 1]
|
7
|
+
def up = Vec3[0, 1, 0]
|
8
|
+
def down = Vec3[0, -1, 0]
|
9
|
+
def left = Vec3[-1, 0, 0]
|
10
|
+
def right = Vec3[1, 0, 0]
|
11
|
+
def forward = Vec3[0, 0, 1]
|
12
|
+
def back = Vec3[0, 0, -1]
|
13
|
+
end
|
14
|
+
|
15
|
+
def x = self[0]
|
16
|
+
def x=(value)
|
17
|
+
self[0] = value
|
18
|
+
end
|
19
|
+
|
20
|
+
def y = self[1]
|
21
|
+
def y=(value)
|
22
|
+
self[1] = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def z = self[2]
|
26
|
+
def z=(value)
|
27
|
+
self[2] = value
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module BeltsEngine::Ecs
|
2
|
+
class Collection < Hash
|
3
|
+
attr_reader :key
|
4
|
+
|
5
|
+
def initialize(with: [], without: [])
|
6
|
+
@with = with.sort
|
7
|
+
@without = without.sort
|
8
|
+
@key = {with: with, without: without}
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_entity(entity)
|
12
|
+
return if (@with - entity.keys).any?
|
13
|
+
return if (@without & entity.keys).any?
|
14
|
+
|
15
|
+
self[entity[:id]] = entity.slice(:id, *@with)
|
16
|
+
end
|
17
|
+
|
18
|
+
def remove_entity(entity_id)
|
19
|
+
self.delete(entity_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def each_with_components
|
23
|
+
each do |k, v|
|
24
|
+
yield **v
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module BeltsEngine::Ecs
|
2
|
+
class CollectionManager < Hash
|
3
|
+
def register(**filters)
|
4
|
+
collection = Collection.new(**filters)
|
5
|
+
self[collection.key] ||= collection
|
6
|
+
end
|
7
|
+
|
8
|
+
def get(key)
|
9
|
+
raise "Collection not registered: #{key}" unless self.key?(key)
|
10
|
+
self[key]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module BeltsEngine::Ecs
|
2
|
+
class EntityManager < Hash
|
3
|
+
def initialize(game)
|
4
|
+
@game = game
|
5
|
+
@next_id = 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def instantiate(prefab_class, position = Vec3.zero, rotation = Vec3.zero, scale = Vec3.one)
|
9
|
+
id = @next_id
|
10
|
+
entity = self[id] = Entity.new(id)
|
11
|
+
@next_id += 1
|
12
|
+
|
13
|
+
components = Marshal.load(Marshal.dump(prefab_class.to_s.constantize.components)) # deep copy
|
14
|
+
components[:transform].position = position if position
|
15
|
+
components[:transform].rotation = rotation if rotation
|
16
|
+
add_components(id, components)
|
17
|
+
|
18
|
+
id
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_components(id, components)
|
22
|
+
entity = self[id]
|
23
|
+
entity.merge!(**components)
|
24
|
+
|
25
|
+
@game.collections.values.each do |collection|
|
26
|
+
collection.add_entity(entity)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_components(id, keys)
|
31
|
+
entity = self[id]
|
32
|
+
|
33
|
+
keys.each do |key|
|
34
|
+
entity.delete(key)
|
35
|
+
end
|
36
|
+
|
37
|
+
@game.collections.values.each do |collection|
|
38
|
+
collection.remove_entity(id)
|
39
|
+
collection.add_entity(entity)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy(id)
|
44
|
+
@game.collections.values.each do |collection|
|
45
|
+
collection.remove_entity(id)
|
46
|
+
end
|
47
|
+
|
48
|
+
self.delete(id)
|
49
|
+
end
|
50
|
+
|
51
|
+
def destroy_all
|
52
|
+
keys.each do |id|
|
53
|
+
destroy(id)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module BeltsEngine::Ecs
|
2
|
+
class SystemManager
|
3
|
+
def initialize(game)
|
4
|
+
@game = game
|
5
|
+
@systems = []
|
6
|
+
|
7
|
+
register_app_systems
|
8
|
+
end
|
9
|
+
|
10
|
+
def update
|
11
|
+
@systems.each(&:update)
|
12
|
+
end
|
13
|
+
|
14
|
+
def register_system(klass)
|
15
|
+
@systems << klass.new(@game) # TODO: Avoid duplicates
|
16
|
+
|
17
|
+
klass.collection_keys.each do |key|
|
18
|
+
@game.collections.register(**key)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def register_app_systems
|
25
|
+
klasses = Dir["app/systems/*.rb"].map do |file|
|
26
|
+
File.basename(file, ".rb").camelize.constantize
|
27
|
+
end
|
28
|
+
|
29
|
+
klasses.each do |klass|
|
30
|
+
register_system(klass)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
class Game
|
3
|
+
include BeltsSupport::Configuration
|
4
|
+
include BeltsEngine::ToolsManager
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
register_tool(:time, Tools::Time.new)
|
8
|
+
register_tool(:input, Tools::Input.new)
|
9
|
+
register_tool(:window, Tools::Window.new)
|
10
|
+
register_tool(:collections, Ecs::CollectionManager.new)
|
11
|
+
register_tool(:entities, Ecs::EntityManager.new(self))
|
12
|
+
register_tool(:scenes, Tools::SceneManager.new(self))
|
13
|
+
register_tool(:systems, Ecs::SystemManager.new(self))
|
14
|
+
end
|
15
|
+
|
16
|
+
def use(extension)
|
17
|
+
extension.install(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def start
|
21
|
+
main_scene_class = config.main_scene.to_s.constantize
|
22
|
+
raise 'Main scene not specified' unless main_scene_class
|
23
|
+
|
24
|
+
scenes.load_scene(main_scene_class)
|
25
|
+
end
|
26
|
+
|
27
|
+
def update
|
28
|
+
time.update
|
29
|
+
systems.update
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
class Prefab
|
3
|
+
module ComponentMixin
|
4
|
+
class << self
|
5
|
+
def included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def components
|
12
|
+
@components ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def component(name, val)
|
16
|
+
set_component(name, val)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def set_component(name, data)
|
22
|
+
@components ||= {}
|
23
|
+
@components[name] = data
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
class Scene
|
3
|
+
attr_reader :game
|
4
|
+
|
5
|
+
self.instance_eval do
|
6
|
+
extend Module.new {
|
7
|
+
def prefab(class_name, **options)
|
8
|
+
@@prefabs ||= []
|
9
|
+
@@prefabs << options.merge(class_name: class_name)
|
10
|
+
end
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(game)
|
15
|
+
@game = game
|
16
|
+
init_entities
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def init_entities
|
22
|
+
@@prefabs.each do |prefab|
|
23
|
+
@game.entities.instantiate(prefab[:class_name], prefab[:position], prefab[:rotation], prefab[:scale])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
class System
|
3
|
+
module CollectionMixin
|
4
|
+
class << self
|
5
|
+
def included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def collection_keys
|
12
|
+
@collection_keys ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
def collection(name, **filters)
|
16
|
+
key = Ecs::Collection.new(**filters).key
|
17
|
+
register_collection_key(key)
|
18
|
+
|
19
|
+
define_method(name) do
|
20
|
+
@collections.get(key)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def register_collection_key(key)
|
27
|
+
@collection_keys ||= []
|
28
|
+
@collection_keys << key
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
class System
|
3
|
+
include System::CollectionMixin
|
4
|
+
|
5
|
+
def initialize(game)
|
6
|
+
@game = game
|
7
|
+
register_tool_shortcuts
|
8
|
+
|
9
|
+
start
|
10
|
+
end
|
11
|
+
|
12
|
+
def start
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def register_tool_shortcuts
|
18
|
+
@game.tools.each do |key, value|
|
19
|
+
instance_variable_set("@#{key}", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
module Tools
|
3
|
+
class Input
|
4
|
+
module Keyboard
|
5
|
+
KEYS = [:w, :a, :s, :d].freeze
|
6
|
+
|
7
|
+
def key?(key) = @keyboard_state[key]
|
8
|
+
def key_down?(key) = @keyboard_state[key] && !@keyboard_previous_state[key]
|
9
|
+
def key_up?(key) = !@keyboard_state[key] && @keyboard_previous_state[key]
|
10
|
+
|
11
|
+
def update_keys(changes)
|
12
|
+
@keyboard_previous_state = @keyboard_state.dup
|
13
|
+
@keyboard_state.merge!(changes)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def reset_keyboard_state
|
19
|
+
@keyboard_state = KEYS.map { |key| [key, false] }.to_h
|
20
|
+
@keyboard_previous_state = @keyboard_state.dup
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
module Tools
|
3
|
+
class Input
|
4
|
+
module Mouse
|
5
|
+
BUTTONS = [:mouse_1, :mouse_2, :mouse_3].freeze
|
6
|
+
|
7
|
+
def button?(button) = @mouse_state[button]
|
8
|
+
def button_down?(button) = @mouse_state[button] && !@mouse_previous_state[button]
|
9
|
+
def button_up?(button) = !@mouse_state[button] && @mouse_previous_state[button]
|
10
|
+
def mouse(axis) = @mouse_state[axis]
|
11
|
+
|
12
|
+
def update_buttons(changes)
|
13
|
+
@mouse_previous_state = @mouse_state.dup
|
14
|
+
@mouse_state.merge!(changes)
|
15
|
+
end
|
16
|
+
|
17
|
+
def update_position(x, y)
|
18
|
+
@mouse_state[:x] = x
|
19
|
+
@mouse_state[:y] = y
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def reset_mouse_state
|
25
|
+
@mouse_state = BUTTONS.map { |button| [button, false] }.to_h
|
26
|
+
@mouse_state[:x] = @mouse_state[:y] = 0
|
27
|
+
@mouse_previous_state = @mouse_state.dup
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
module Tools
|
3
|
+
class Input
|
4
|
+
include Keyboard
|
5
|
+
include Mouse
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
reset_keyboard_state
|
9
|
+
# reset_mouse_state
|
10
|
+
#@current_keys[:mouse_x] = @current_keys[:mouse_y] = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def update(changes)
|
14
|
+
update_keys(changes)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module BeltsEngine::Tools
|
2
|
+
class SceneManager
|
3
|
+
attr_reader :current_scene
|
4
|
+
|
5
|
+
def initialize(game)
|
6
|
+
@game = game
|
7
|
+
@current_scene = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def unload_scene
|
11
|
+
@game.entities.destroy_all
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_scene(scene_class)
|
15
|
+
unload_scene
|
16
|
+
@current_scene = scene_class.new(@game)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
module Tools
|
3
|
+
class Time
|
4
|
+
attr_reader :delta_time, :uptime
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@start_time = system_time
|
8
|
+
@last_time = @start_time
|
9
|
+
@uptime = 0
|
10
|
+
@delta_time = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def update
|
14
|
+
@delta_time = system_time - @last_time
|
15
|
+
@last_time = system_time
|
16
|
+
@uptime += @delta_time
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def system_time
|
22
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
module Tools
|
3
|
+
class Window
|
4
|
+
attr_reader :ratio, :width, :height, :title
|
5
|
+
|
6
|
+
DEFAULT_WIDTH = 640
|
7
|
+
DEFAULT_HEIGHT = 480
|
8
|
+
DEFAULT_TITLE = 'Belts Demo'.freeze
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@title = DEFAULT_TITLE
|
12
|
+
resize(DEFAULT_WIDTH, DEFAULT_HEIGHT)
|
13
|
+
end
|
14
|
+
|
15
|
+
def resize(width, height)
|
16
|
+
@width = width
|
17
|
+
@height = height
|
18
|
+
@ratio = @width.to_f / @height.to_f
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module BeltsEngine
|
2
|
+
module ToolsManager
|
3
|
+
def tools
|
4
|
+
@_tools ||= {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def register_tool(name, obj)
|
8
|
+
raise "Tool #{name} already in use" if tools.key?(name)
|
9
|
+
|
10
|
+
tools[name] = obj
|
11
|
+
end
|
12
|
+
|
13
|
+
def respond_to?(name, include_private = false)
|
14
|
+
super || tools.key?(name.to_sym)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def method_missing(name, *args, &blk)
|
20
|
+
raise "Tool #{name} not registered" unless tools.key?(name)
|
21
|
+
|
22
|
+
tools[name]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/belts_engine.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'belts_support'
|
2
|
+
|
3
|
+
# TODO: Load with zeitwerk
|
4
|
+
require_relative './belts_engine/components/vec3'
|
5
|
+
require_relative './belts_engine/components/mat4'
|
6
|
+
require_relative './belts_engine/components/transform'
|
7
|
+
|
8
|
+
loader = Zeitwerk::Loader.for_gem
|
9
|
+
loader.setup
|
10
|
+
|
11
|
+
module BeltsEngine
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: belts_engine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Guilherme Graca
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-06-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: belts_support
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.1
|
27
|
+
description:
|
28
|
+
email:
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/belts_engine.rb
|
34
|
+
- lib/belts_engine/application.rb
|
35
|
+
- lib/belts_engine/components/mat4.rb
|
36
|
+
- lib/belts_engine/components/transform.rb
|
37
|
+
- lib/belts_engine/components/vec3.rb
|
38
|
+
- lib/belts_engine/ecs/collection.rb
|
39
|
+
- lib/belts_engine/ecs/collection_manager.rb
|
40
|
+
- lib/belts_engine/ecs/entity.rb
|
41
|
+
- lib/belts_engine/ecs/entity_manager.rb
|
42
|
+
- lib/belts_engine/ecs/system_manager.rb
|
43
|
+
- lib/belts_engine/game.rb
|
44
|
+
- lib/belts_engine/prefab.rb
|
45
|
+
- lib/belts_engine/prefab/component_mixin.rb
|
46
|
+
- lib/belts_engine/scene.rb
|
47
|
+
- lib/belts_engine/system.rb
|
48
|
+
- lib/belts_engine/system/collection_mixin.rb
|
49
|
+
- lib/belts_engine/tools/input.rb
|
50
|
+
- lib/belts_engine/tools/input/keyboard.rb
|
51
|
+
- lib/belts_engine/tools/input/mouse.rb
|
52
|
+
- lib/belts_engine/tools/scene_manager.rb
|
53
|
+
- lib/belts_engine/tools/time.rb
|
54
|
+
- lib/belts_engine/tools/window.rb
|
55
|
+
- lib/belts_engine/tools_manager.rb
|
56
|
+
homepage: https://github.com/ggraca/belts
|
57
|
+
licenses:
|
58
|
+
- MIT
|
59
|
+
metadata: {}
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.1.2
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubygems_version: 3.3.7
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: The core functionality of the Belts game engine
|
79
|
+
test_files: []
|