belts_engine 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|