ruby_rpg 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1bb1056bb375c7c3ebbbdf7b2b23f1b5ad1fd6ddec9c0f2e63713aef56f345f7
4
- data.tar.gz: bead66754d17fafe491808aa0cef827cbc789ea718e61e114b53599b2c619b43
3
+ metadata.gz: b56f66eb45701f903472f4d948d42e1a67a9bf051c59e0515ee8df1195503d7e
4
+ data.tar.gz: 35e50569d84181202098fd7425025ef73bdc54d0d7eae16bef0ad0acbe1fb6fb
5
5
  SHA512:
6
- metadata.gz: c3560e6b6aad6e80b3ace11b49c86a671eea0634b05b57383358921520502c476f0147f4aa39a21852149a8c4c866888cdd23aeee28fcb90517d5da975f385a5
7
- data.tar.gz: 55c62ec5c13331a3bef15c3badac233bb23d66fca4c3d3cd273161e66c256ba6032ccc47c552c1c474ba9f3ff21e12fb0211de215aaa10e200283829f19a85fb
6
+ metadata.gz: '08ec8719dae3c6788e4aa692059706ed9635b540974164339c4a5887dc0a0a420b48d8b7abc4022f87b899b8e2c02674d060107ec8c3dad06dcd6431add8f433'
7
+ data.tar.gz: a65cadf65c339c7b656c825dfa1ea6365e6fb2c94f090396b3e11c4e515d78b45819447bd186ebfb79424ed5fc25689d66cb4ed4a59b76c7e0ad7b5d943a187d
data/README.md CHANGED
@@ -5,10 +5,12 @@ It is designed to be easy to use and easy to extend.
5
5
  It is still in the early stages of development, but it is already capable of rendering both 2D and 3D graphics.
6
6
 
7
7
  ## Installation
8
- TODO: Write installation instructions here
8
+ You can find full instructions on th [wiki](https://github.com/rubyrpg/ruby_rpg/wiki/Installation).
9
9
 
10
10
  ## Usage
11
- TODO: Write usage instructions here
11
+ You can find docs and guides on the [wiki](https://github.com/rubyrpg/ruby_rpg/wiki).
12
+ For a basic example to get you up off the ground take a look at [hello_ruby_rpg](https://github.com/rubyrpg/hello_ruby_rpg).
13
+ For some more complex examples you can take a look in the samples folder of this repo.
12
14
 
13
15
  ## Contributing
14
16
  1. Fork it
@@ -5,8 +5,9 @@ output_file=$2
5
5
 
6
6
  export BUILDING=true
7
7
 
8
+ parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
9
+ glfw_path=$parent_path/../glfw-3.4.bin.WIN64
10
+
8
11
  ocran $input_file \
9
- **/*.png **/*.obj **/*.glsl **/*.vertex_data **/*.index_data **/*.json **/*.csv glfw-3.4.bin.WIN64/**/* src/**/*.rb \
12
+ **/*.png **/*.obj **/*.glsl **/*.vertex_data **/*.index_data **/*.json **/*.csv $glfw_path/**/* src/**/*.rb \
10
13
  --output $output_file
11
-
12
-
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Engine
4
+ module AutoLoader
5
+ def self.load(load_path = nil)
6
+ base_dir = File.expand_path(load_path || File.dirname($PROGRAM_NAME))
7
+ Dir[File.join(base_dir, "components", "**/*.rb")].each { |file| require file }
8
+ Dir[File.join(base_dir, "game_objects", "**/*.rb")].each { |file| require file }
9
+ end
10
+ end
11
+ end
@@ -30,8 +30,12 @@ module Engine
30
30
  end
31
31
 
32
32
  def destroy!
33
+ Component.destroyed_components << self unless @destroyed
34
+ destroy unless @destroyed
33
35
  @destroyed = true
34
- destroy
36
+ end
37
+
38
+ def _erase!
35
39
  game_object.components.delete(self)
36
40
  class_name = self.class.name.split('::').last
37
41
  self.class.instance_variable_get(:@methods).each do |method|
@@ -42,7 +46,18 @@ module Engine
42
46
  end
43
47
  end
44
48
 
49
+ def self.erase_destroyed_components
50
+ destroyed_components.each do |object|
51
+ object._erase!
52
+ end
53
+ @destroyed_components = []
54
+ end
55
+
45
56
  def destroy
46
57
  end
58
+
59
+ def self.destroyed_components
60
+ @destroyed_components ||= []
61
+ end
47
62
  end
48
63
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Engine::Components
4
+ class AudioSource < Engine::Component
5
+ def initialize(clip, radius: 1000)
6
+ @clip = clip
7
+ @radius = radius
8
+ @source = NativeAudio::AudioSource.new(clip)
9
+ end
10
+
11
+ def play
12
+ @source.play
13
+ end
14
+
15
+ def stop
16
+ @source.stop
17
+ end
18
+
19
+ def pause
20
+ @source.pause
21
+ end
22
+
23
+ def resume
24
+ @source.resume
25
+ end
26
+
27
+ def volume=(volume)
28
+ @source.set_volume(volume)
29
+ end
30
+
31
+ def update(delta_time)
32
+ camera = Engine::Camera.instance
33
+ local_pos = camera.game_object.world_to_local_coordinate(game_object.pos)
34
+ angle = Math.atan2(local_pos[0], -local_pos[2]) * 180 / Math::PI
35
+ angle = (angle + 360) % 360
36
+ distance = (local_pos.magnitude * 255 / @radius).clamp(0, 255)
37
+
38
+ @source.set_pos(angle, distance)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Engine
4
+ module Debugging
5
+
6
+ # Hit a breakpoint within the context of where the breakpoint is defined, assuming a block is passed
7
+ # with a `binding.pry` (or an alternative debugger), otherwise hit a breakpoint within this method.
8
+ def self.breakpoint(&block)
9
+ orig_fullscreen = Window.full_screen?
10
+ if orig_fullscreen
11
+ Window.set_to_windowed
12
+ GLFW.PollEvents # Required to trigger the switch from fullscreen to windowed within this breakpoint
13
+ end
14
+
15
+ orig_cursor_mode = Cursor.get_input_mode
16
+ Cursor.enable
17
+
18
+ block_given? ? yield : binding.pry
19
+ Cursor.restore_input_mode(orig_cursor_mode)
20
+ Window.set_to_full_screen if orig_fullscreen
21
+ Window.focus_window
22
+
23
+ # Reset the time, otherwise delta_time will be off for the next frame, and teleporting occurs
24
+ @time = Time.now
25
+ end
26
+
27
+ def self.debug_opengl_call
28
+ errors = []
29
+ until GL.GetError == 0; end
30
+ yield
31
+ until (error = GL.GetError) == 0
32
+ errors += error.to_s(16)
33
+ end
34
+ end
35
+
36
+ def self.print_opengl_version
37
+ puts "OpenGL Version: #{GL.GetString(GL::VERSION)}"
38
+ puts "GLSL Version: #{GL.GetString(GL::SHADING_LANGUAGE_VERSION)}"
39
+ end
40
+ end
41
+ end
data/lib/engine/engine.rb CHANGED
@@ -1,55 +1,10 @@
1
- require 'opengl'
2
- require 'glfw'
3
- require 'concurrent'
4
- require 'os'
5
-
6
- require_relative 'rendering/render_pipeline'
7
- require_relative 'rendering/instance_renderer'
8
- require_relative 'screenshoter'
9
- require_relative 'input'
10
- require_relative "quaternion"
11
- require_relative 'game_object'
12
- require_relative 'texture'
13
- require_relative 'material'
14
- require_relative 'mesh'
15
- require_relative "font"
16
- require_relative 'path'
17
- require_relative 'polygon_mesh'
18
- require_relative 'importers/obj_file'
19
- require_relative 'tangent_calculator'
20
- require_relative 'shader'
21
- require_relative 'component'
22
- require_relative "camera"
23
- require_relative "window"
24
- require_relative "video_mode"
25
- require_relative "cursor"
26
-
27
- require_relative "components/orthographic_camera"
28
- require_relative "components/perspective_camera"
29
- require_relative "components/sprite_renderer"
30
- require_relative "components/ui_sprite_renderer"
31
- require_relative "components/mesh_renderer"
32
- require_relative "components/font_renderer"
33
- require_relative "components/ui_font_renderer"
34
- require_relative "components/point_light"
35
- require_relative "components/direction_light"
36
-
37
- require_relative "physics/physics_resolver"
38
- require_relative 'physics/collision'
39
- require_relative "physics/components/sphere_collider"
40
- require_relative "physics/components/cube_collider"
41
- require_relative "physics/components/rigidbody"
42
-
43
- if OS.windows?
44
- GLFW.load_lib(File.expand_path(File.join(__dir__, "..", "..", "glfw-3.4.bin.WIN64", "lib-static-ucrt", "glfw3.dll")))
45
- elsif OS.mac?
46
- GLFW.load_lib(File.expand_path(File.join(__dir__, "..", "..", "glfw-3.3.9.bin.MACOS", "lib-arm64", "libglfw.3.dylib")))
47
- end
48
- GLFW.Init
1
+ # frozen_string_literal: true
2
+
3
+ GAME_DIR = File.expand_path(File.dirname($PROGRAM_NAME))
49
4
 
50
5
  module Engine
51
- def self.start(base_dir:, &first_frame_block)
52
- load(base_dir)
6
+ def self.start(&first_frame_block)
7
+ Engine::AutoLoader.load
53
8
  return if ENV["BUILDING"] == "true"
54
9
 
55
10
  open_window
@@ -61,12 +16,6 @@ module Engine
61
16
  @engine_started
62
17
  end
63
18
 
64
- def self.load(base_dir)
65
- base_dir = File.expand_path(base_dir)
66
- Dir[File.join(base_dir, "components", "**/*.rb")].each { |file| require file }
67
- Dir[File.join(base_dir, "game_objects", "**/*.rb")].each { |file| require file }
68
- end
69
-
70
19
  def self.open_window
71
20
  @old_time = Time.now
72
21
  @time = Time.now
@@ -144,13 +93,10 @@ module Engine
144
93
  @fps
145
94
  end
146
95
 
147
- def self.terminate
148
- GLFW.DestroyWindow(Window.window)
149
- GLFW.Terminate
150
- end
151
-
152
96
  def self.close
153
97
  GameObject.destroy_all
98
+ Component.erase_destroyed_components
99
+ GameObject.erase_destroyed_objects
154
100
  GLFW.SetWindowShouldClose(Window.window, 1)
155
101
  end
156
102
 
@@ -158,31 +104,17 @@ module Engine
158
104
  @game_stopped = true
159
105
  @swap_buffers_promise.wait! if @swap_buffers_promise && !@swap_buffers_promise.complete?
160
106
  GameObject.destroy_all
107
+ Component.erase_destroyed_components
108
+ GameObject.erase_destroyed_objects
161
109
  end
162
110
 
163
- # Hit a breakpoint within the context of where the breakpoint is defined, assuming a block is passed
164
- # with a `binding.pry` (or an alternative debugger), otherwise hit a breakpoint within this method.
165
- def self.breakpoint(&block)
166
- orig_fullscreen = Window.full_screen?
167
- if orig_fullscreen
168
- Window.set_to_windowed
169
- GLFW.PollEvents # Required to trigger the switch from fullscreen to windowed within this breakpoint
170
- end
171
-
172
- orig_cursor_mode = Cursor.get_input_mode
173
- Cursor.enable
174
-
175
- block_given? ? yield : binding.pry
176
- Cursor.restore_input_mode(orig_cursor_mode)
177
- Window.set_to_full_screen if orig_fullscreen
178
- Window.focus_window
111
+ private
179
112
 
180
- # Reset the time, otherwise delta_time will be off for the next frame, and teleporting occurs
181
- @time = Time.now
113
+ def self.terminate
114
+ GLFW.DestroyWindow(Window.window)
115
+ GLFW.Terminate
182
116
  end
183
117
 
184
- private
185
-
186
118
  def self.print_fps(delta_time)
187
119
  @time_since_last_fps_print = (@time_since_last_fps_print || 0) + delta_time
188
120
  @frame = (@frame || 0) + 1
@@ -204,18 +136,4 @@ module Engine
204
136
  Input.key_callback(key, action)
205
137
  end
206
138
  end
207
-
208
- def self.debug_opengl_call
209
- errors = []
210
- until GL.GetError == 0; end
211
- yield
212
- until (error = GL.GetError) == 0
213
- errors += error.to_s(16)
214
- end
215
- end
216
-
217
- def self.print_opengl_version
218
- puts "OpenGL Version: #{GL.GetString(GL::VERSION)}"
219
- puts "GLSL Version: #{GL.GetString(GL::SHADING_LANGUAGE_VERSION)}"
220
- end
221
139
  end
data/lib/engine/font.rb CHANGED
@@ -15,7 +15,7 @@ module Engine
15
15
  def texture
16
16
  @texture ||=
17
17
  begin
18
- path = File.expand_path(File.join(ROOT, "_imported", @font_file_path.gsub(".ttf", ".png")))
18
+ path = File.join("_imported", @font_file_path.gsub(".ttf", ".png"))
19
19
  Engine::Texture.for(path)
20
20
  end
21
21
  end
@@ -35,7 +35,7 @@ module Engine
35
35
  scale_factor = 1 / (1024.0 * 2)
36
36
  horizontal_offset = 0.0
37
37
  vertical_offset = 0.0
38
- font_path = File.expand_path(File.join(ROOT, "_imported", @font_file_path.gsub(".ttf", ".json")))
38
+ font_path = File.expand_path(File.join(GAME_DIR, "_imported", @font_file_path.gsub(".ttf", ".json")))
39
39
  font_metrics = JSON.parse File.read(font_path)
40
40
  string.chars.each do |char|
41
41
  if char == "\n"
@@ -132,17 +132,30 @@ module Engine
132
132
 
133
133
  def destroy!
134
134
  return unless GameObject.objects.include?(self)
135
- @destroyed = true
135
+ children.each(&:destroy!)
136
136
  components.each(&:destroy!)
137
137
  ui_renderers.each(&:destroy!)
138
138
  renderers.each(&:destroy!)
139
+
140
+ GameObject.destroyed_objects << self unless @destroyed
141
+ @destroyed = true
142
+ end
143
+
144
+ def _erase!
139
145
  GameObject.objects.delete(self)
140
146
  parent.children.delete(self) if parent
141
- children.each(&:destroy!)
147
+ name = @name
142
148
  self.class.instance_variable_get(:@methods).each do |method|
143
149
  singleton_class.send(:undef_method, method)
144
- singleton_class.send(:define_method, method) { raise "This object has been destroyed. Object ID: #{self.object_id}" }
150
+ singleton_class.send(:define_method, method) { raise "This object has been destroyed: #{name}" }
151
+ end
152
+ end
153
+
154
+ def self.erase_destroyed_objects
155
+ destroyed_objects.each do |object|
156
+ object._erase!
145
157
  end
158
+ @destroyed_objects = []
146
159
  end
147
160
 
148
161
  def up
@@ -173,6 +186,9 @@ module Engine
173
186
  GameObject.objects.each do |object|
174
187
  object.components.each { |component| component.update(delta_time) }
175
188
  end
189
+
190
+ Component.erase_destroyed_components
191
+ GameObject.erase_destroyed_objects
176
192
  end
177
193
 
178
194
  def self.mesh_renderers
@@ -194,5 +210,9 @@ module Engine
194
210
  def self.objects
195
211
  @objects ||= []
196
212
  end
213
+
214
+ def self.destroyed_objects
215
+ @destroyed_objects ||= []
216
+ end
197
217
  end
198
218
  end
data/lib/engine/input.rb CHANGED
@@ -21,7 +21,7 @@ module Engine
21
21
  end
22
22
 
23
23
  if key == GLFW::KEY_BACKSPACE
24
- Engine.breakpoint { binding.pry }
24
+ Engine::Debugging.breakpoint { binding.pry }
25
25
  # Engine.breakpoint { debugger }
26
26
  end
27
27
 
data/lib/engine/mesh.rb CHANGED
@@ -21,7 +21,7 @@ module Engine
21
21
  end
22
22
 
23
23
  def self.open_vertex(mesh_file)
24
- vertex_cache[File.join(ROOT, "_imported", mesh_file + ".vertex_data")]
24
+ vertex_cache[File.join(GAME_DIR, "_imported", mesh_file + ".vertex_data")]
25
25
  end
26
26
 
27
27
  def self.vertex_cache
@@ -31,7 +31,7 @@ module Engine
31
31
  end
32
32
 
33
33
  def self.open_index(mesh_file)
34
- index_cache[File.join(ROOT, "_imported", mesh_file + ".index_data")]
34
+ index_cache[File.join(GAME_DIR, "_imported", mesh_file + ".index_data")]
35
35
  end
36
36
 
37
37
  def self.index_cache
@@ -12,8 +12,9 @@ module Engine
12
12
  load_texture
13
13
  end
14
14
 
15
- def self.for(file_path, flip: false)
16
- texture_cache[[file_path, flip]]
15
+ def self.for(path, flip: false)
16
+ full_path = File.expand_path(File.join(GAME_DIR, path))
17
+ texture_cache[[full_path, flip]]
17
18
  end
18
19
 
19
20
  def self.texture_cache
data/lib/ruby_rpg.rb CHANGED
@@ -1,3 +1,56 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'opengl'
4
+ require 'glfw'
5
+ require 'concurrent'
6
+ require 'os'
7
+ require 'native_audio'
8
+
9
+ require_relative 'engine/autoloader'
10
+ require_relative "engine/debugging"
11
+ require_relative 'engine/rendering/render_pipeline'
12
+ require_relative 'engine/rendering/instance_renderer'
13
+ require_relative 'engine/screenshoter'
14
+ require_relative 'engine/input'
15
+ require_relative "engine/quaternion"
16
+ require_relative 'engine/game_object'
17
+ require_relative 'engine/texture'
18
+ require_relative 'engine/material'
19
+ require_relative 'engine/mesh'
20
+ require_relative "engine/font"
21
+ require_relative 'engine/path'
22
+ require_relative 'engine/polygon_mesh'
23
+ require_relative 'engine/importers/obj_file'
24
+ require_relative 'engine/tangent_calculator'
25
+ require_relative 'engine/shader'
26
+ require_relative 'engine/component'
27
+ require_relative "engine/camera"
28
+ require_relative "engine/window"
29
+ require_relative "engine/video_mode"
30
+ require_relative "engine/cursor"
31
+
32
+ require_relative "engine/components/orthographic_camera"
33
+ require_relative "engine/components/perspective_camera"
34
+ require_relative "engine/components/sprite_renderer"
35
+ require_relative "engine/components/ui_sprite_renderer"
36
+ require_relative "engine/components/mesh_renderer"
37
+ require_relative "engine/components/font_renderer"
38
+ require_relative "engine/components/ui_font_renderer"
39
+ require_relative "engine/components/point_light"
40
+ require_relative "engine/components/direction_light"
41
+ require_relative "engine/components/audio_source"
42
+
43
+ require_relative "engine/physics/physics_resolver"
44
+ require_relative 'engine/physics/collision'
45
+ require_relative "engine/physics/components/sphere_collider"
46
+ require_relative "engine/physics/components/cube_collider"
47
+ require_relative "engine/physics/components/rigidbody"
48
+
49
+ if OS.windows?
50
+ GLFW.load_lib(File.expand_path(File.join(__dir__, "..", "glfw-3.4.bin.WIN64", "lib-static-ucrt", "glfw3.dll")))
51
+ elsif OS.mac?
52
+ GLFW.load_lib(File.expand_path(File.join(__dir__, "..", "glfw-3.3.9.bin.MACOS", "lib-arm64", "libglfw.3.dylib")))
53
+ end
54
+ GLFW.Init
55
+
3
56
  require_relative 'engine/engine'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_rpg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Hatfull
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-27 00:00:00.000000000 Z
11
+ date: 2024-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: native_audio
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: opengl-bindings2
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +122,7 @@ extensions: []
108
122
  extra_rdoc_files: []
109
123
  files:
110
124
  - README.md
125
+ - bin/build.bash
111
126
  - bin/import
112
127
  - glfw-3.3.9.bin.MACOS/LICENSE.md
113
128
  - glfw-3.3.9.bin.MACOS/README.md
@@ -537,9 +552,10 @@ files:
537
552
  - glfw-3.4.bin.WIN64/lib-vc2022/glfw3.lib
538
553
  - glfw-3.4.bin.WIN64/lib-vc2022/glfw3_mt.lib
539
554
  - glfw-3.4.bin.WIN64/lib-vc2022/glfw3dll.lib
540
- - lib/build.bash
555
+ - lib/engine/autoloader.rb
541
556
  - lib/engine/camera.rb
542
557
  - lib/engine/component.rb
558
+ - lib/engine/components/audio_source.rb
543
559
  - lib/engine/components/direction_light.rb
544
560
  - lib/engine/components/font_renderer.rb
545
561
  - lib/engine/components/mesh_renderer.rb
@@ -550,6 +566,7 @@ files:
550
566
  - lib/engine/components/ui_font_renderer.rb
551
567
  - lib/engine/components/ui_sprite_renderer.rb
552
568
  - lib/engine/cursor.rb
569
+ - lib/engine/debugging.rb
553
570
  - lib/engine/engine.rb
554
571
  - lib/engine/font.rb
555
572
  - lib/engine/game_object.rb