summaryrefslogtreecommitdiffhomepage
path: root/dragon
diff options
context:
space:
mode:
authorAmir Rajan <[email protected]>2020-10-13 00:45:16 -0500
committerAmir Rajan <[email protected]>2020-10-13 00:48:54 -0500
commit05cbef7fb8224332795e5685be499d81d20e7d93 (patch)
tree13ec5f1755c2f45618741f2f016ed8729dbedd41 /dragon
parentabad948c1154d88d79b9f891e3b7315540e0b0a3 (diff)
downloaddragonruby-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.rb6
-rw-r--r--dragon/assert.rb2
-rw-r--r--dragon/console.rb48
-rw-r--r--dragon/console_menu.rb1
-rw-r--r--dragon/docs.rb47
-rw-r--r--dragon/draw.rb223
-rw-r--r--dragon/framerate_diagnostics.rb7
-rw-r--r--dragon/inputs.rb4
-rw-r--r--dragon/kernel_docs.rb2
-rw-r--r--dragon/numeric.rb2
-rw-r--r--dragon/readme_docs.rb83
-rw-r--r--dragon/string.rb4
-rw-r--r--dragon/trace.rb3
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 = [