diff options
| author | Amir Rajan <[email protected]> | 2020-10-13 00:45:16 -0500 |
|---|---|---|
| committer | Amir Rajan <[email protected]> | 2020-10-13 00:48:54 -0500 |
| commit | 05cbef7fb8224332795e5685be499d81d20e7d93 (patch) | |
| tree | 13ec5f1755c2f45618741f2f016ed8729dbedd41 /dragon | |
| parent | abad948c1154d88d79b9f891e3b7315540e0b0a3 (diff) | |
| download | dragonruby-game-toolkit-contrib-05cbef7fb8224332795e5685be499d81d20e7d93.tar.gz dragonruby-game-toolkit-contrib-05cbef7fb8224332795e5685be499d81d20e7d93.zip | |
Synced with 1.26.
Diffstat (limited to 'dragon')
| -rw-r--r-- | dragon/args.rb | 6 | ||||
| -rw-r--r-- | dragon/assert.rb | 2 | ||||
| -rw-r--r-- | dragon/console.rb | 48 | ||||
| -rw-r--r-- | dragon/console_menu.rb | 1 | ||||
| -rw-r--r-- | dragon/docs.rb | 47 | ||||
| -rw-r--r-- | dragon/draw.rb | 223 | ||||
| -rw-r--r-- | dragon/framerate_diagnostics.rb | 7 | ||||
| -rw-r--r-- | dragon/inputs.rb | 4 | ||||
| -rw-r--r-- | dragon/kernel_docs.rb | 2 | ||||
| -rw-r--r-- | dragon/numeric.rb | 2 | ||||
| -rw-r--r-- | dragon/readme_docs.rb | 83 | ||||
| -rw-r--r-- | dragon/string.rb | 4 | ||||
| -rw-r--r-- | dragon/trace.rb | 3 |
13 files changed, 384 insertions, 48 deletions
diff --git a/dragon/args.rb b/dragon/args.rb index 38a28b7..ecb7040 100644 --- a/dragon/args.rb +++ b/dragon/args.rb @@ -21,6 +21,11 @@ module GTK # @return [Outputs] attr_accessor :outputs + # Contains the means to interact with the audio mixer. + # + # @return [Hash] + attr_accessor :audio + # Contains display size information to assist in positioning things on the screen. # # @return [Grid] @@ -54,6 +59,7 @@ module GTK def initialize runtime, recording @inputs = Inputs.new @outputs = Outputs.new args: self + @audio = {} @passes = [] @state = OpenEntity.new @state.tick_count = -1 diff --git a/dragon/assert.rb b/dragon/assert.rb index 0c26f29..67fc0dd 100644 --- a/dragon/assert.rb +++ b/dragon/assert.rb @@ -98,7 +98,7 @@ end @assertion_performed = true if actual != expected actual_string = "#{actual}#{actual.nil? ? " (nil) " : " " }".strip - message = "actual:\n#{actual_string} did not equal\nexpected:\n#{expected}.\n#{message}" + message = "actual:\n#{actual_string}\n\ndid not equal\n\nexpected:\n#{expected}.\n#{message}" raise message end nil diff --git a/dragon/console.rb b/dragon/console.rb index 32deb15..90fd8a9 100644 --- a/dragon/console.rb +++ b/dragon/console.rb @@ -47,12 +47,12 @@ module GTK end def save_history - $gtk.ffi_file.storefile(@history_fname, @command_history.reverse.join("\n")) + $gtk.ffi_file.write_root @history_fname, (@command_history.reverse.join "\n") end def load_history @command_history.clear - str = $gtk.ffi_file.loadfile(@history_fname) + str = $gtk.ffi_file.read @history_fname return if str.nil? # no history to load. str.chomp!("\n") # Don't let endlines at the end cause extra blank line. @@ -265,6 +265,36 @@ S args.inputs.keyboard.key_down.any? console_toggle_keys end + def try_search_docs exception + string_e = "#{exception}" + @last_command_errored = true + + if (string_e.include? "wrong number of arguments") + method_name = ((string_e.split ":")[0].gsub "'", "") + if !(method_name.include? " ") + results = (Kernel.__docs_search_results__ method_name) + if !results.include? "* DOCS: No results found." + puts (results.join "\n") + puts <<-S +* INFO: #{results.length} matches(s) found in DOCS for ~#{method_name}~ (see above). +You can search the documentation yourself using the following command in the Console: +#+begin_src ruby + docs_search \"#{method_name}\" +#+end_src +S + log_once_info :exported_search_results, "The search results above has been seen in logs/puts.txt and docs/search_results.txt." + end + end + end + rescue Exception => se + puts <<-S +* FATAL: ~GTK::Console#try_search_docs~ +There was an exception searching for docs (~GTK::Console#try_search_docs~). You might want to let DragonRuby know about this. +** INNER EXCEPTION +#{se} +S + end + def eval_the_set_command cmd = current_input_str.strip if cmd.length != 0 @@ -291,18 +321,8 @@ S end @last_command_errored = false rescue Exception => e - string_e = "#{e}" - puts "* EXCEPTION: #{e}" - log "* EXCEPTION: #{e}" - @last_command_errored = true - if (string_e.include? "wrong number of arguments") - method_name = (string_e.split ":")[0].gsub "'", "" - results = (Kernel.docs_search method_name).strip - if !results.include? "* DOCS: No results found." - puts results - log results - end - end + try_search_docs e + puts "* EXCEPTION: #{e}" end end end diff --git a/dragon/console_menu.rb b/dragon/console_menu.rb index 7449f4a..d10ceeb 100644 --- a/dragon/console_menu.rb +++ b/dragon/console_menu.rb @@ -107,6 +107,7 @@ module GTK if args.inputs.mouse.click clicked = @buttons.find { |b| args.inputs.mouse.inside_rect? b[:rect] } if clicked + args.inputs.mouse.click = nil send clicked[:method] end end diff --git a/dragon/docs.rb b/dragon/docs.rb index 67a50e0..049ff81 100644 --- a/dragon/docs.rb +++ b/dragon/docs.rb @@ -151,17 +151,8 @@ S end - def docs_search words = nil, &block - words ||= "" - if words.strip.length != 0 - each_word = words.split(' ').find_all { |w| w.strip.length > 0 } - block = lambda do |entry| - each_word.any? { |w| entry.downcase.include? w.downcase } - end - end - - if !block - return <<-S + def __docs_search_help_text__ + <<-S * DOCS: How To Search The Docs To search docs you can use Kernel.docs_search (or just ~docs_search~) by providing it a search term. For example: @@ -178,30 +169,52 @@ You can do more advanced searches by providing a block: end #+end_src S + end + + def __docs_search_results__ words = nil, &block + words ||= "" + + if words.strip.length != 0 + each_word = words.split(' ').find_all { |w| w.strip.length > 3 } + block = lambda do |entry| + each_word.any? { |w| entry.downcase.include? w.downcase } + end end + return [__docs_search_help_text__] if !block + DocsOrganizer.sort_docs_classes! + this_block = block - final_string = "" + + search_results = [] + if self == Kernel $docs_classes.each do |k| DocsOrganizer.find_methods_with_docs(k).each do |m| s = k.send m - final_string += s + "\n" if block.call s + search_results << s if block.call s end end else DocsOrganizer.find_methods_with_docs(self).each do |m| s = send m - final_string += s + "\n" if block.call s + search_results << s if block.call s end end - if final_string.strip.length == 0 - final_string = "* DOCS: No results found." - end + search_results + end + + def docs_search words = nil, &block + results = __docs_search_results__ words, &block + + final_string = results.join "\n" + + final_string = "* DOCS: No results found." if final_string.strip.length == 0 $gtk.write_file_root "docs/search_results.txt", final_string + if !final_string.include? "* DOCS: No results found." log "* INFO: Search results have been written to docs/search_results.txt." end diff --git a/dragon/draw.rb b/dragon/draw.rb new file mode 100644 index 0000000..231ad02 --- /dev/null +++ b/dragon/draw.rb @@ -0,0 +1,223 @@ +# Copyright 2019 DragonRuby LLC +# MIT License +# draw.rb has been released under MIT (*only this file*). + +module GTK + class Runtime + module Draw + def primitives pass + if $top_level.respond_to? :primitives_override + return $top_level.tick_render @args, pass + end + + # Don't change this draw order unless you understand + # the implications. + + # pass.solids.each { |s| draw_solid s } + # while loops are faster than each with block + idx = 0 + while idx < pass.solids.length + draw_solid (pass.solids.value idx) # accessing an array using .value instead of [] is faster + idx += 1 + end + + # pass.static_solids.each { |s| draw_solid s } + idx = 0 + while idx < pass.static_solids.length + draw_solid (pass.static_solids.value idx) + idx += 1 + end + + # pass.sprites.each { |s| draw_sprite s } + idx = 0 + while idx < pass.sprites.length + draw_sprite (pass.sprites.value idx) + idx += 1 + end + + # pass.static_sprites.each { |s| draw_sprite s } + idx = 0 + while idx < pass.static_sprites.length + draw_sprite (pass.static_sprites.value idx) + idx += 1 + end + + # pass.primitives.each { |p| draw_primitive p } + idx = 0 + while idx < pass.primitives.length + draw_primitive (pass.primitives.value idx) + idx += 1 + end + + # pass.static_primitives.each { |p| draw_primitive p } + idx = 0 + while idx < pass.static_primitives.length + draw_primitive (pass.static_primitives.value idx) + idx += 1 + end + + # pass.labels.each { |l| draw_label l } + idx = 0 + while idx < pass.labels.length + draw_label (pass.labels.value idx) + idx += 1 + end + + # pass.static_labels.each { |l| draw_label l } + idx = 0 + while idx < pass.static_labels.length + draw_label (pass.static_labels.value idx) + idx += 1 + end + + # pass.lines.each { |l| draw_line l } + idx = 0 + while idx < pass.lines.length + draw_line (pass.lines.value idx) + idx += 1 + end + + # pass.static_lines.each { |l| draw_line l } + idx = 0 + while idx < pass.static_lines.length + draw_line (pass.static_lines.value idx) + idx += 1 + end + + # pass.borders.each { |b| draw_border b } + idx = 0 + while idx < pass.borders.length + draw_border (pass.borders.value idx) + idx += 1 + end + + # pass.static_borders.each { |b| draw_border b } + idx = 0 + while idx < pass.static_borders.length + draw_border (pass.static_borders.value idx) + idx += 1 + end + + if !$gtk.production + # pass.debug.each { |r| draw_primitive r } + idx = 0 + while idx < pass.debug.length + draw_primitive (pass.debug.value idx) + idx += 1 + end + + # pass.static_debug.each { |r| draw_primitive r } + idx = 0 + while idx < pass.static_debug.length + draw_primitive (pass.static_debug.value idx) + idx += 1 + end + end + + # pass.reserved.each { |r| draw_primitive r } + idx = 0 + while idx < pass.reserved.length + draw_primitive (pass.reserved.value idx) + idx += 1 + end + + # pass.static_reserved.each { |r| draw_primitive r } + idx = 0 + while idx < pass.static_reserved.length + draw_primitive (pass.static_reserved.value idx) + idx += 1 + end + rescue Exception => e + pause! + pretty_print_exception_and_export! e + end + + def draw_solid s + return unless s + if s.respond_to? :draw_override + s.draw_override @ffi_draw + else + @ffi_draw.draw_solid s.x, s.y, s.w, s.h, s.r, s.g, s.b, s.a + end + rescue Exception => e + raise_conversion_for_rendering_failed s, e, :solid + end + + def draw_sprite s + return unless s + if s.respond_to? :draw_override + s.draw_override @ffi_draw + else + @ffi_draw.draw_sprite_3 s.x, s.y, s.w, s.h, + s.path.s_or_default, + s.angle, + s.a, s.r, s.g, s.b, + s.tile_x, s.tile_y, s.tile_w, s.tile_h, + !!s.flip_horizontally, !!s.flip_vertically, + s.angle_anchor_x, s.angle_anchor_y, + s.source_x, s.source_y, s.source_w, s.source_h + end + rescue Exception => e + raise_conversion_for_rendering_failed s, e, :sprite + end + + def draw_screenshot s + return unless s + if s.respond_to? :draw_override + s.draw_override @ffi_draw + else + @ffi_draw.draw_screenshot s.path.s_or_default, + s.x, s.y, s.w, s.h, + s.angle, + s.a, s.r, s.g, s.b, + s.tile_x, s.tile_y, s.tile_w, s.tile_h, + !!s.flip_horizontally, !!s.flip_vertically, + s.angle_anchor_x, s.angle_anchor_y, + s.source_x, s.source_y, s.source_w, s.source_h + end + rescue Exception => e + raise_conversion_for_rendering_failed s, e, :screenshot + end + + def draw_label l + return unless l + if l.respond_to? :draw_override + l.draw_override @ffi_draw + else + @ffi_draw.draw_label l.x, l.y, l.text.s_or_default, + l.size_enum, l.alignment_enum, + l.r, l.g, l.b, l.a, + l.font.s_or_default(nil) + end + rescue Exception => e + raise_conversion_for_rendering_failed l, e, :label + end + + def draw_line l + return unless l + if l.respond_to? :draw_override + l.draw_override @ffi_draw + else + @ffi_draw.draw_line l.x, l.y, l.x2, l.y2, l.r, l.g, l.b, l.a + end + rescue Exception => e + raise_conversion_for_rendering_failed l, e, :line + end + + def draw_border s + return unless s + if s.respond_to? :draw_override + s.draw_override @ffi_draw + else + @ffi_draw.draw_border s.x, s.y, s.w, s.h, s.r, s.g, s.b, s.a + end + rescue Exception => e + raise_conversion_for_rendering_failed s, e, :border + end + + def draw_screenshots + @args.outputs.screenshots.each { |s| draw_screenshot s } + end + end + end +end diff --git a/dragon/framerate_diagnostics.rb b/dragon/framerate_diagnostics.rb index 6b952bd..7a04efc 100644 --- a/dragon/framerate_diagnostics.rb +++ b/dragon/framerate_diagnostics.rb @@ -12,7 +12,12 @@ module GTK You can display these diagnostics using: #+begin_src - args.outputs.debug << args.gtk.framerate_diagnostics_primitives + def tick args + # .... + + # IMPORTANT: Put this at the END of the ~tick~ method. + args.outputs.debug << args.gtk.framerate_diagnostics_primitives + end #+end_src ** Draw Calls: ~<<~ Invocation Perf Counter diff --git a/dragon/inputs.rb b/dragon/inputs.rb index a4ef40f..befb0e5 100644 --- a/dragon/inputs.rb +++ b/dragon/inputs.rb @@ -502,6 +502,10 @@ module GTK point.inside_rect? rect end + def inside_circle? center, radius + point.point_inside_circle? center, radius + end + alias_method :position, :point def clear diff --git a/dragon/kernel_docs.rb b/dragon/kernel_docs.rb index 95e35be..7ef9470 100644 --- a/dragon/kernel_docs.rb +++ b/dragon/kernel_docs.rb @@ -53,7 +53,7 @@ S final_string += k.docs_all end - final_string += "\n" + (($gtk.read_file_root "docs/source.txt") || "") + final_string += "\n" + (($gtk.read_file "docs/source.txt") || "") html_parse_result = (__docs_to_html__ final_string) diff --git a/dragon/numeric.rb b/dragon/numeric.rb index 6d8b84d..f090360 100644 --- a/dragon/numeric.rb +++ b/dragon/numeric.rb @@ -146,6 +146,8 @@ S if definitions.include?(:ratio) result = rand * result + elsif definitions.include?(:int) + result = (rand result) end result diff --git a/dragon/readme_docs.rb b/dragon/readme_docs.rb index f4d3696..98284d6 100644 --- a/dragon/readme_docs.rb +++ b/dragon/readme_docs.rb @@ -10,13 +10,15 @@ module GTK :docs_usage, :docs_hello_world, :docs_deployment, + :docs_deployment_mobile, :docs_dragonruby_philosophy, + :docs_faq, :docs_ticks_and_frames, :docs_sprites, :docs_labels, :docs_sounds, :docs_game_state, - :docs_faq + :docs_troubleshooting_performance ] end @@ -452,6 +454,35 @@ update the downloads for you. S end + def docs_deployment_mobile +<<-S + +* Deploying To Mobile Devices + +If you have a Pro subscription, you also have the capability to deploy +to mobile devices. + +To deploy to iOS, you need to have a Mac running MacOS Catalina, an +iOS device, and an active/paid Developer Account with Apple. From the +Console type: ~$wizards.ios.start~ and you will be guided through the +deployment process. + +To deploy to Android, you need to have an Android emulator/device, and +a environment that is able to run Android SDK. ~dragonruby-publish~ +will create an APK for you. From there, you can sign the APK and +install it to your device. The signing and installation procedure +varies from OS to OS. Here's an example of what the command might look +like: + +#+begin_src + > adb logcat -e mygame # you'll want to run this in a separate terminal + > keytool -genkey -v -keystore mygame.keystore -alias mygame -keyalg RSA -keysize 2048 -validity 10000 + > apksigner sign --ks mygame.keystore mygame-android.apk + > adb install mygame-android.apk +#+end_src +S + end + def docs_dragonruby_philosophy <<-S * DragonRuby's Philosophy @@ -559,7 +590,7 @@ S def docs_ticks_and_frames <<-S -* How To Determine What Frame You Are On +* CHEATSHEET: How To Determine What Frame You Are On There is a property on ~state~ called ~tick_count~ that is incremented by DragonRuby every time the ~tick~ method is called. The following @@ -571,7 +602,7 @@ code renders a label that displays the current ~tick_count~. end #+end_src -* How To Get Current Framerate +* CHEATSHEET: How To Get Current Framerate Current framerate is a top level property on the Game Toolkit Runtime and is accessible via ~args.gtk.current_framerate~. @@ -586,7 +617,7 @@ S def docs_sprites <<-S -* How To Render A Sprite Using An Array +* CHEATSHEET: How To Render A Sprite Using An Array All file paths should use the forward slash ~/~ *not* backslash ~\~. Game Toolkit includes a number of sprites in the ~sprites~ @@ -609,7 +640,7 @@ The following code renders a sprite with a ~width~ and ~height~ of end #+end_src -* More Sprite Properties As An Array +* CHEATSHEET: More Sprite Properties As An Array Here are all the properties you can set on a sprite. @@ -630,7 +661,7 @@ Here are all the properties you can set on a sprite. end #+end_src -* Different Sprite Representations +* CHEATSHEET: Different Sprite Representations Using ordinal positioning can get a little unruly given so many properties you have control over. @@ -700,7 +731,7 @@ S def docs_labels <<-S -* How To Render A Label +* CHEATSHEET: How To Render A Label ~args.outputs.labels~ is used to render labels. @@ -716,7 +747,7 @@ Here is the minimum code: end #+end_src -* A Colored Label +* CHEATSHEET: A Colored Label #+begin_src def tick args @@ -726,7 +757,7 @@ Here is the minimum code: end #+end_src -* Extended Label Properties +* CHEATSHEET: Extended Label Properties #+begin_src def tick args @@ -754,7 +785,7 @@ label's size. An ~ALIGNMENT_ENUM~ of ~0~ represents "left aligned". ~1~ represents "center aligned". ~2~ represents "right aligned". -* Rendering A Label As A ~Hash~ +* CHEATSHEET: Rendering A Label As A ~Hash~ You can add additional metadata about your game within a label, which requires you to use a `Hash` instead. @@ -782,7 +813,7 @@ You can add additional metadata about your game within a label, which requires y end #+end_src -* Getting The Size Of A Piece Of Text +* CHEATSHEET: Getting The Size Of A Piece Of Text You can get the render size of any string using ~args.gtk.calcstringbox~. @@ -807,7 +838,7 @@ S def docs_sounds <<-S -* How To Play A Sound +* CHEATSHEET: How To Play A Sound Sounds that end ~.wav~ will play once: @@ -846,7 +877,7 @@ S def docs_game_state <<-S -* Using ~args.state~ To Store Your Game State +* CHEATSHEET: Using ~args.state~ To Store Your Game State ~args.state~ is a open data structure that allows you to define properties that are arbitrarily nested. You don't need to define any kind of @@ -888,7 +919,7 @@ S def animate_a_sprite <<-S -* How To Animate A Sprite Using Separate PNGs +* CHEATSHEET: How To Animate A Sprite Using Separate PNGs DragonRuby has a property on ~Numeric~ called ~frame_index~ that can be used to determine what frame of an animation to show. Here is an @@ -920,6 +951,30 @@ example of how to cycle through 6 sprites every 4 frames. S end + def docs_troubleshooting_performance +<<-S +* CHEATSHEET: Troubleshoot Performance + +1. If you're using ~Array~s for your primitives (~args.outputs.sprites << []~), use ~Hash~ instead (~args.outputs.sprites << { x: ... }~). +2. If you're using ~Entity~ for your primitives (~args.outputs.sprites << args.state.new_entity~), use ~StrictEntity~ instead (~args.outputs.sprites << args.state.new_entity_strict~). +3. Use ~.each~ instead of ~.map~ if you don't care about the return value. +4. When concatenating primitives to outputs, do them in bulk. Instead of: +#+begin_src ruby + args.state.bullets.each do |bullet| + args.outputs.sprites << bullet.sprite + end +#+end_src +do +#+begin_src + args.outputs.sprites << args.state.bullets.map do |b| + b.sprite + end +#+end_src +5. Use ~args.outputs.static_~ variant for things that don't change often (take a look at the Basic Gorillas sample app and Dueling Starships sample app to see how ~static_~ is leveraged. +6. Consider using a ~render_target~ if you're doing some form of a camera that moves a lot of primitives (take a look at the Render Target sample apps for more info). +S + end + def docs_faq <<-S * Frequently Asked Questions, Comments, and Concerns diff --git a/dragon/string.rb b/dragon/string.rb index 5fa273c..121c3f3 100644 --- a/dragon/string.rb +++ b/dragon/string.rb @@ -98,4 +98,8 @@ S def rtrim! rstrip! end + + def serialize + self + end end diff --git a/dragon/trace.rb b/dragon/trace.rb index 3d92ba2..db5abda 100644 --- a/dragon/trace.rb +++ b/dragon/trace.rb @@ -3,6 +3,9 @@ # MIT License # trace.rb has been released under MIT (*only this file*). +# Contributors outside of DragonRuby who also hold Copyright: +# - Dan Healy: https://github.com/danhealy + module GTK module Trace IGNORED_METHODS = [ |
