ruby2d 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,36 +1,59 @@
1
1
  # Ruby2D module and native extension loader, adds DSL
2
2
 
3
- require 'ruby2d/colorize'
4
- require 'ruby2d/exceptions'
5
- require 'ruby2d/renderable'
6
- require 'ruby2d/color'
7
- require 'ruby2d/window'
8
- require 'ruby2d/dsl'
9
- require 'ruby2d/quad'
10
- require 'ruby2d/line'
11
- require 'ruby2d/circle'
12
- require 'ruby2d/rectangle'
13
- require 'ruby2d/square'
14
- require 'ruby2d/triangle'
15
- require 'ruby2d/image'
16
- require 'ruby2d/sprite'
17
- require 'ruby2d/font'
18
- require 'ruby2d/text'
19
- require 'ruby2d/sound'
20
- require 'ruby2d/music'
21
-
22
- if RUBY_PLATFORM =~ /mingw/
23
- # When using the Windows CI AppVeyor
24
- if ENV['APPVEYOR']
25
- s2d_dll_path = 'C:\msys64\usr\local\bin'
26
- # When in a standard MinGW shell
27
- else
28
- s2d_dll_path = '~/../../usr/local/bin'
3
+ unless RUBY_ENGINE == 'mruby'
4
+ require 'ruby2d/colorize'
5
+ require 'ruby2d/exceptions'
6
+ require 'ruby2d/renderable'
7
+ require 'ruby2d/color'
8
+ require 'ruby2d/window'
9
+ require 'ruby2d/dsl'
10
+ require 'ruby2d/quad'
11
+ require 'ruby2d/line'
12
+ require 'ruby2d/circle'
13
+ require 'ruby2d/rectangle'
14
+ require 'ruby2d/square'
15
+ require 'ruby2d/triangle'
16
+ require 'ruby2d/image'
17
+ require 'ruby2d/sprite'
18
+ require 'ruby2d/font'
19
+ require 'ruby2d/text'
20
+ require 'ruby2d/sound'
21
+ require 'ruby2d/music'
22
+
23
+ if RUBY_PLATFORM =~ /mingw/
24
+ # When using the Windows CI AppVeyor
25
+ if ENV['APPVEYOR']
26
+ s2d_dll_path = 'C:\msys64\usr\local\bin'
27
+ # When in a standard MinGW shell
28
+ else
29
+ s2d_dll_path = '~/../../usr/local/bin'
30
+ end
31
+ RubyInstaller::Runtime.add_dll_directory(File.expand_path(s2d_dll_path))
29
32
  end
30
- RubyInstaller::Runtime.add_dll_directory(File.expand_path(s2d_dll_path))
33
+
34
+ require 'ruby2d/ruby2d' # load native extension
31
35
  end
32
36
 
33
- require 'ruby2d/ruby2d' # load native extension
37
+
38
+ module Ruby2D
39
+
40
+ @assets = nil
41
+
42
+ class << self
43
+ def assets
44
+ unless @assets
45
+ if RUBY_ENGINE == 'mruby'
46
+ @assets = Ruby2D.ext_base_path + 'assets'
47
+ else
48
+ @assets = './assets'
49
+ end
50
+ end
51
+ @assets
52
+ end
53
+
54
+ def assets=(path); @assets = path end
55
+ end
56
+ end
34
57
 
35
58
  include Ruby2D
36
59
  extend Ruby2D::DSL
@@ -4,8 +4,7 @@ module Ruby2D
4
4
  class Circle
5
5
  include Renderable
6
6
 
7
- attr_reader :color
8
- attr_accessor :x, :y, :radius, :sectors
7
+ attr_accessor :radius, :sectors
9
8
 
10
9
  def initialize(opts = {})
11
10
  @x = opts[:x] || 25
@@ -14,13 +13,10 @@ module Ruby2D
14
13
  @radius = opts[:radius] || 25
15
14
  @sectors = opts[:sectors] || 20
16
15
  self.color = opts[:color] || 'white'
16
+ self.opacity = opts[:opacity] if opts[:opacity]
17
17
  add
18
18
  end
19
19
 
20
- def color=(c)
21
- @color = Color.from(c)
22
- end
23
-
24
20
  def contains?(x, y)
25
21
  Math.sqrt((x - @x)**2 + (y - @y)**2) <= @radius
26
22
  end
@@ -0,0 +1,226 @@
1
+ # Build a Ruby 2D app natively and for the web
2
+
3
+ require 'fileutils'
4
+
5
+ # The installed gem directory
6
+ @gem_dir = "#{Gem::Specification.find_by_name('ruby2d').gem_dir}"
7
+
8
+ # The Ruby 2D library files
9
+ @lib_files = [
10
+ 'colorize',
11
+ 'exceptions',
12
+ 'renderable',
13
+ 'color',
14
+ 'window',
15
+ 'dsl',
16
+ 'quad',
17
+ 'line',
18
+ 'circle',
19
+ 'rectangle',
20
+ 'square',
21
+ 'triangle',
22
+ 'image',
23
+ 'sprite',
24
+ 'font',
25
+ 'text',
26
+ 'sound',
27
+ 'music',
28
+ '../ruby2d'
29
+ ]
30
+
31
+
32
+ # Check if source file provided is good
33
+ def check_build_src_file(rb_file)
34
+ if !rb_file
35
+ puts "Please provide a Ruby file to build"
36
+ exit
37
+ elsif !File.exist? rb_file
38
+ puts "Can't find file: #{rb_file}"
39
+ exit
40
+ end
41
+ end
42
+
43
+
44
+ # Assemble the Ruby 2D library in one `.rb` file
45
+ def make_lib
46
+ FileUtils.mkdir_p 'build'
47
+
48
+ lib_dir = "#{@gem_dir}/lib/ruby2d/"
49
+
50
+ lib = ''
51
+ @lib_files.each do |f|
52
+ lib << File.read("#{lib_dir + f}.rb") + "\n\n"
53
+ end
54
+
55
+ File.write('build/lib.rb', lib)
56
+ end
57
+
58
+
59
+ # Remove `require 'ruby2d'` from source file
60
+ def strip_require(file)
61
+ output = ''
62
+ File.foreach(file) do |line|
63
+ output << line unless line =~ /require ('|")ruby2d('|")/
64
+ end
65
+ return output
66
+ end
67
+
68
+
69
+ # Build a native version of the provided Ruby application
70
+ def build_native(rb_file)
71
+ check_build_src_file(rb_file)
72
+
73
+ # Check if MRuby exists; if not, quit
74
+ if `which mruby`.empty?
75
+ puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n"
76
+ exit
77
+ end
78
+
79
+ # Add debugging information to produce backtrace
80
+ if @debug then debug_flag = '-g' end
81
+
82
+ # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode
83
+ make_lib
84
+ `mrbc #{debug_flag} -Bruby2d_lib -obuild/lib.c build/lib.rb`
85
+
86
+ # Read the provided Ruby source file, copy to build dir and compile to bytecode
87
+ File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) }
88
+ `mrbc #{debug_flag} -Bruby2d_app -obuild/src.c build/src.rb`
89
+
90
+ # Combine contents of C source files and bytecode into one file
91
+ open('build/app.c', 'w') do |f|
92
+ f << "#define MRUBY 1" << "\n\n"
93
+ f << File.read("build/lib.c") << "\n\n"
94
+ f << File.read("build/src.c") << "\n\n"
95
+ f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c")
96
+ end
97
+
98
+ # Compile to a native executable
99
+ `cc build/app.c -lmruby \`simple2d --libs\` -o build/app`
100
+
101
+ # Clean up
102
+ clean_up unless @debug
103
+
104
+ # Success!
105
+ puts "Native app created at `build/app`"
106
+ end
107
+
108
+
109
+ # Build a web-based version of the provided Ruby application
110
+ def build_web(rb_file)
111
+ puts "Warning: ".warn + "This feature is currently disabled while it's being upgraded."
112
+ end
113
+
114
+
115
+ # Build an app bundle for macOS
116
+ def build_macos(rb_file)
117
+
118
+ # Build native app for macOS
119
+ build_native(rb_file)
120
+
121
+ # Property list source for the bundle
122
+ info_plist = %(
123
+ <?xml version="1.0" encoding="UTF-8"?>
124
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
125
+ <plist version="1.0">
126
+ <dict>
127
+ <key>CFBundleExecutable</key>
128
+ <string>app</string>
129
+ <key>CFBundleIconFile</key>
130
+ <string>app.icns</string>
131
+ <key>CFBundleInfoDictionaryVersion</key>
132
+ <string>6.0</string>
133
+ <key>CFBundlePackageType</key>
134
+ <string>APPL</string>
135
+ <key>CFBundleVersion</key>
136
+ <string>1</string>
137
+ <key>NSHighResolutionCapable</key>
138
+ <string>True</string>
139
+ </dict>
140
+ </plist>
141
+ )
142
+
143
+ # Create directories
144
+ FileUtils.mkpath 'build/App.app/Contents/MacOS'
145
+ FileUtils.mkpath 'build/App.app/Contents/Resources'
146
+
147
+ # Create Info.plist and copy over assets
148
+ File.open('build/App.app/Contents/Info.plist', 'w') { |f| f.write(info_plist) }
149
+ FileUtils.cp 'build/app', 'build/App.app/Contents/MacOS/'
150
+ # Consider using an icon:
151
+ # FileUtils.cp "#{@gem_dir}/assets/app.icns", 'build/App.app/Contents/Resources'
152
+
153
+ # Clean up
154
+ FileUtils.rm_f 'build/app' unless @debug
155
+
156
+ # Success!
157
+ puts 'macOS app bundle created: `build/App.app`'
158
+ end
159
+
160
+
161
+ # Build an iOS or tvOS app
162
+ def build_ios_tvos(rb_file, device)
163
+ check_build_src_file(rb_file)
164
+
165
+ # Check for Simple 2D framework,
166
+ unless File.exist?('/usr/local/Frameworks/Simple2D/iOS/Simple2D.framework') && File.exist?('/usr/local/Frameworks/Simple2D/tvOS/Simple2D.framework')
167
+ puts "#{'Error:'.error} Simple 2D iOS and tvOS frameworks not found. Install them and try again.\n"
168
+ exit
169
+ end
170
+
171
+ # Check if MRuby exists; if not, quit
172
+ if `which mruby`.empty?
173
+ puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n"
174
+ exit
175
+ end
176
+
177
+ # Add debugging information to produce backtrace
178
+ if @debug then debug_flag = '-g' end
179
+
180
+ # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode
181
+ make_lib
182
+ `mrbc #{debug_flag} -Bruby2d_lib -obuild/lib.c build/lib.rb`
183
+
184
+ # Read the provided Ruby source file, copy to build dir and compile to bytecode
185
+ File.open('build/src.rb', 'w') { |file| file << strip_require(rb_file) }
186
+ `mrbc #{debug_flag} -Bruby2d_app -obuild/src.c build/src.rb`
187
+
188
+ # Copy over iOS project
189
+ FileUtils.cp_r "#{@gem_dir}/assets/#{device}", "build"
190
+
191
+ # Combine contents of C source files and bytecode into one file
192
+ File.open("build/#{device}/main.c", 'w') do |f|
193
+ f << "#define RUBY2D_IOS_TVOS 1" << "\n\n"
194
+ f << "#define MRUBY 1" << "\n\n"
195
+ f << File.read("build/lib.c") << "\n\n"
196
+ f << File.read("build/src.c") << "\n\n"
197
+ f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c")
198
+ end
199
+
200
+ # Build the Xcode project
201
+ `simple2d build --#{device} build/#{device}/MyApp.xcodeproj`
202
+
203
+ # Clean up
204
+ clean_up unless @debug
205
+
206
+ # Success!
207
+ puts "App created: `build/#{device}`"
208
+ end
209
+
210
+
211
+ # Clean up unneeded build files
212
+ def clean_up(cmd = nil)
213
+ FileUtils.rm(
214
+ Dir.glob('build/{src,lib}.{rb,c,js}') +
215
+ Dir.glob('build/app.c')
216
+ )
217
+ if cmd == :all
218
+ puts "cleaning up..."
219
+ FileUtils.rm_f 'build/app'
220
+ FileUtils.rm_f 'build/app.js'
221
+ FileUtils.rm_f 'build/app.html'
222
+ FileUtils.rm_rf 'build/App.app'
223
+ FileUtils.rm_rf 'build/ios'
224
+ FileUtils.rm_rf 'build/tvos'
225
+ end
226
+ end
@@ -0,0 +1,49 @@
1
+ rb_file = ARGV[1]
2
+
3
+ # Check if source file provided is good
4
+ if !rb_file
5
+ puts "Provide a Ruby file to run"
6
+ exit 1
7
+ elsif !File.exist? rb_file
8
+ puts "Can't find file: #{rb_file}"
9
+ exit 1
10
+ end
11
+
12
+ # Add libraries
13
+ require 'open3'
14
+ require 'readline'
15
+ require 'io/wait'
16
+
17
+ line = 1 # the current line number, to be incremented
18
+
19
+ # Open a new process for the Ruby file
20
+ stdin, stdout, stderr, wait_thr = Open3.popen3("ruby -r 'ruby2d/cli/enable_console' #{rb_file}")
21
+
22
+ loop do
23
+
24
+ # Read the next command
25
+ cmd = Readline.readline("ruby2d:#{line}> ", true)
26
+
27
+ # Quit if command is 'exit'
28
+ if cmd == 'exit'
29
+ Process.kill 'INT', wait_thr.pid
30
+ wait_thr.value
31
+ exit
32
+ end
33
+
34
+ # Skip if command is an empty string
35
+ unless cmd.empty?
36
+
37
+ # Send command to the Ruby file
38
+ stdin.puts cmd
39
+
40
+ # Read and print output from the Ruby file
41
+ puts stdout.gets
42
+ while stdout.ready? do
43
+ puts stdout.gets
44
+ end
45
+ end
46
+
47
+ # Advance to next line
48
+ line += 1
49
+ end
@@ -0,0 +1,5 @@
1
+ # Enable the interactive console
2
+
3
+ require 'io/wait'
4
+
5
+ $ruby2d_console_mode = true
@@ -0,0 +1,50 @@
1
+ # Launch a built Ruby 2D app
2
+
3
+ # Launch a native app
4
+ def launch_native
5
+ if !File.exist? 'build/app'
6
+ puts "No native app built!"
7
+ exit
8
+ end
9
+ `( cd build && ./app )`
10
+ end
11
+
12
+
13
+ # Launch a web app
14
+ def launch_web
15
+ if !File.exist? 'build/app.html'
16
+ puts "No web app built!"
17
+ exit
18
+ end
19
+ open_cmd = 'open'
20
+ case RUBY_PLATFORM
21
+ when /linux/
22
+ open_cmd = "xdg-#{open_cmd}"
23
+ when /mingw/
24
+ open_cmd = "start"
25
+ end
26
+ system "#{open_cmd} build/app.html"
27
+ end
28
+
29
+
30
+ # Launch an iOS or tvOS app in a simulator
31
+ def launch_apple(device)
32
+ case device
33
+ when 'ios'
34
+ if !File.exist? 'build/ios/build/Release-iphonesimulator/MyApp.app'
35
+ puts "No iOS app built!"
36
+ exit
37
+ end
38
+ puts `simple2d simulator --open "iPhone XR" &&
39
+ simple2d simulator --install "build/ios/build/Release-iphonesimulator/MyApp.app" &&
40
+ simple2d simulator --launch "Ruby2D.MyApp"`
41
+ when 'tvos'
42
+ if !File.exist? 'build/tvos/build/Release-appletvsimulator/MyApp.app'
43
+ puts "No tvOS app built!"
44
+ exit
45
+ end
46
+ puts `simple2d simulator --open "Apple TV 4K" &&
47
+ simple2d simulator --install "build/tvos/build/Release-appletvsimulator/MyApp.app" &&
48
+ simple2d simulator --launch "Ruby2D.MyApp"`
49
+ end
50
+ end
@@ -66,10 +66,23 @@ module Ruby2D
66
66
  end
67
67
  when Array
68
68
  @r, @g, @b, @a = [c[0], c[1], c[2], c[3]]
69
+ when Color
70
+ @r, @g, @b, @a = [c.r, c.g, c.b, c.a]
69
71
  end
70
72
  end
71
73
  end
72
74
 
75
+ # Return a color set if an array of valid colors
76
+ def self.set(colors)
77
+ # If a valid array of colors, return a `Color::Set` with those colors
78
+ if colors.is_a?(Array) && colors.all? { |el| Color.is_valid? el }
79
+ Color::Set.new(colors)
80
+ # Otherwise, return single color
81
+ else
82
+ Color.new(colors)
83
+ end
84
+ end
85
+
73
86
  # Check if string is a proper hex value
74
87
  def self.is_hex?(s)
75
88
  # MRuby doesn't support regex, otherwise we'd do:
@@ -79,6 +92,7 @@ module Ruby2D
79
92
 
80
93
  # Check if the color is valid
81
94
  def self.is_valid?(c)
95
+ c.is_a?(Color) || # color object
82
96
  @@colors.key?(c) || # keyword
83
97
  self.is_hex?(c) || # hexadecimal value
84
98
 
@@ -87,17 +101,6 @@ module Ruby2D
87
101
  c.all? { |el| el.is_a?(Numeric) }
88
102
  end
89
103
 
90
- # Create a color from whatever is provided
91
- def self.from(input)
92
- # If a valid array of colors, return a `Color::Set` with those colors
93
- if input.is_a? Array and input.all? { |el| Color.is_valid? el }
94
- Color::Set.new(input)
95
- # Otherwise, return single color
96
- else
97
- Color.new(input)
98
- end
99
- end
100
-
101
104
  # Convenience methods to alias `opacity` to `@a`
102
105
  def opacity; @a end
103
106
  def opacity=(opacity); @a = opacity end
@@ -105,7 +108,6 @@ module Ruby2D
105
108
  private
106
109
 
107
110
  # Convert from Fixnum (0..255) to Float (0.0..1.0)
108
- # TODO: Only `Number` is supported in JS
109
111
  def to_f(a)
110
112
  b = []
111
113
  a.each do |n|