ruby2d 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Ruby 2D App</title>
6
+ <style>
7
+ body { background-color: #ccc }
8
+ canvas {
9
+ display: block;
10
+ margin: auto;
11
+ }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <div id="ruby2d-app"></div>
16
+ <script src="app.js"></script>
17
+ </body>
18
+ </html>
data/bin/ruby2d CHANGED
@@ -1,48 +1,155 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'ruby2d/version'
3
+ require 'fileutils'
3
4
 
5
+ # Extending `String` to include some fancy colors
4
6
  class String
5
7
  def colorize(c); "\e[#{c}m#{self}\e[0m" end
6
- def error; colorize('1;31') end
7
- def bold; colorize('1') end
8
+ def bold; colorize('1') end
9
+ def error; colorize('4;31') end
8
10
  end
9
11
 
12
+ # The installed gem directory
13
+ @gem_dir = "#{Gem::Specification.find_by_name('ruby2d').gem_dir}"
10
14
 
15
+ # The Ruby 2D library files
16
+ @lib_files = [
17
+ 'exceptions',
18
+ 'color',
19
+ 'window',
20
+ 'application',
21
+ 'dsl',
22
+ 'quad',
23
+ 'rectangle',
24
+ 'square',
25
+ 'triangle',
26
+ 'image',
27
+ 'sprite',
28
+ 'text',
29
+ 'sound',
30
+ 'music'
31
+ ]
32
+
33
+
34
+ # Check if source file provided is good
35
+ def check_build_src_file(rb_file)
36
+ if !rb_file
37
+ puts "Please provide a Ruby file to build."
38
+ exit
39
+ elsif !File.exists? rb_file
40
+ puts "Can't find file: #{rb_file}"
41
+ exit
42
+ end
43
+ end
44
+
45
+
46
+ # Assemble the Ruby 2D library in one `.rb` file
47
+ def make_lib
48
+ FileUtils.mkdir_p 'build'
49
+
50
+ lib_dir = "#{@gem_dir}/lib/ruby2d/"
51
+
52
+ lib = ""
53
+ @lib_files.each do |f|
54
+ lib << File.read("#{lib_dir + f}.rb") + "\n\n"
55
+ end
56
+
57
+ lib << "
58
+ include Ruby2D::DSL
59
+ include Ruby2D\n"
60
+
61
+ File.write('build/lib.rb', lib)
62
+ end
63
+
64
+
65
+ # Remove `require 'ruby2d'` from source file
66
+ def strip_require(file)
67
+ output = ''
68
+ File.foreach(file) do |line|
69
+ output << line unless line =~ /require ('|")ruby2d('|")/
70
+ end
71
+ return output
72
+ end
73
+
74
+
75
+ # Build a native version of the provided Ruby application
11
76
  def build_native(rb_file)
77
+
78
+ # Check if MRuby exists; if not, quit
12
79
  if `which mruby`.empty?
13
- puts "",
14
- " mruby not found!".error, "",
15
- " mruby is needed to build a native Ruby 2D applications.".bold, "",
16
- " Install using Homebrew on OS X:",
17
- " brew install mruby", ""
80
+ puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n"
18
81
  exit
19
82
  end
20
83
 
21
- `mkdir -p build`
22
- `mrbc -Bruby2d_app_symbol -obuild/app.c #{rb_file}`
23
-
24
- open('build/app.c', 'a') do |f|
25
- f << %(
26
- #include "mruby.h"
27
- #include "mruby/irep.h"
28
-
29
- int main(void) {
30
- mrb_state *mrb = mrb_open();
31
- if (!mrb) { /* handle error */ }
32
- mrb_load_irep(mrb, ruby2d_app_symbol);
33
- mrb_close(mrb);
34
- }
35
- )
84
+ # Assemble the Ruby 2D library in one `.rb` file and compile to bytecode
85
+ make_lib
86
+ `mrbc -Bruby2d_lib -obuild/lib.c build/lib.rb`
87
+
88
+ # Read the provided Ruby source file, copy to build dir and compile to bytecode
89
+
90
+ File.open('build/src.rb', 'w') do |file|
91
+ file << strip_require(rb_file)
36
92
  end
37
93
 
38
- `cc -std=c99 -lmruby build/app.c -o build/app`
94
+ `mrbc -Bruby2d_app -obuild/src.c build/src.rb`
95
+
96
+ # Combine contents of C source files and bytecode into one file
97
+ open('build/app.c', 'w') do |f|
98
+ f << "#define MRUBY 1" << "\n\n"
99
+ f << File.read("build/lib.c") << "\n\n"
100
+ f << File.read("build/src.c") << "\n\n"
101
+ f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c")
102
+ end
103
+
104
+ # Compile to native executable
105
+ `cc build/app.c -lmruby \`simple2d --libs\` -o build/app`
106
+
107
+ # Success!
108
+ puts "Native app created at `build/app`"
39
109
  end
40
110
 
41
111
 
112
+ # Build a web-based version of the provided Ruby application
113
+ def build_web(rb_file)
114
+
115
+ # Assemble the Ruby 2D library in one `.rb` file and compile to JS
116
+ make_lib
117
+ `opal --compile --no-opal build/lib.rb > build/lib.js`
118
+
119
+ # Read the provided Ruby source file, copy to build dir, and compile to JS
120
+
121
+ File.open('build/src.rb', 'w') do |file|
122
+ file << strip_require(rb_file)
123
+ end
124
+
125
+ `opal --compile --no-opal build/src.rb > build/src.js`
126
+
127
+ FileUtils.cp "#{@gem_dir}/ext/ruby2d/ruby2d-opal.rb", "build/"
128
+ `opal --compile --no-opal build/ruby2d-opal.rb > build/ruby2d-opal.js`
129
+
130
+ # Combine contents of JS source files and compiled JS into one file
131
+ open('build/app.js', 'w') do |f|
132
+ f << File.read("#{@gem_dir}/assets/simple2d.js") << "\n\n"
133
+ f << File.read("#{@gem_dir}/assets/opal.js") << "\n\n"
134
+ f << File.read("build/lib.js") << "\n\n"
135
+ f << File.read("build/ruby2d-opal.js") << "\n\n"
136
+ f << File.read("build/src.js") << "\n\n"
137
+ end
138
+
139
+ # Copy over HTML template
140
+ FileUtils.cp "#{@gem_dir}/assets/template.html", "build/app.html"
141
+
142
+ # Success!
143
+ puts "Web app created at `build/app.js`",
144
+ " Run by opening `build/app.html`"
145
+ end
146
+
147
+
148
+ # Build an application package for the current platform
42
149
  def build_package
43
150
  require 'fileutils'
44
151
 
45
- icon_path = "#{Gem::Specification.find_by_name('ruby2d').gem_dir}/assets/app.icns"
152
+ icon_path = "#{@gem_dir}/assets/app.icns"
46
153
 
47
154
  FileUtils.mkpath "build/App.app/Contents/MacOS"
48
155
  FileUtils.mkpath "build/App.app/Contents/Resources"
@@ -70,40 +177,50 @@ def build_package
70
177
  )
71
178
 
72
179
  File.open("build/App.app/Contents/Info.plist", 'w') { |f| f.write(info_plist) }
73
-
74
180
  FileUtils.cp "build/app", "build/App.app/Contents/MacOS/"
75
-
76
181
  puts "App written to `build/App.app`."
77
182
  end
78
183
 
79
184
 
80
- # Command line usage and tree ##################################################
185
+ # Clean up unneeded build files
186
+ def clean_up
187
+ FileUtils.rm(
188
+ Dir.glob('build/{src,lib}.{rb,c,js}') +
189
+ Dir.glob('build/ruby2d-opal.{rb,js}') +
190
+ Dir.glob('build/app.c')
191
+ )
192
+ end
81
193
 
82
- usage = "
83
- Usage: ruby2d [-v|--version]
84
- <command> <options>
85
194
 
86
- Summary of commands and options:
87
- build Build the application...
88
- native ...compile with mruby.
89
- web ...for web platform.
90
- package Create application package.
91
- -v|--version Prints the installed version.
195
+ # Check Command-line Arguments #################################################
92
196
 
93
- "
197
+ usage = "Ruby 2D: Make cross-platform 2D applications in Ruby".bold + "\n
198
+ Usage: ruby2d <command> <options>
199
+ [-v|--version]
200
+
201
+ Summary of commands and options:
202
+ build Build the application both natively and for the web
203
+ --native Build only native
204
+ --web Build only web
205
+ --debug Build native and web, keeping all intermediate files
206
+ package Create application package for distribution (experimental)
207
+ -v|--version Prints the installed version\n\n"
94
208
 
95
209
  case ARGV[0]
96
210
  when 'build'
97
- puts "Running build..."
211
+ puts "Building..."
98
212
  case ARGV[1]
99
- when 'native'
100
- puts "Running build native..."
101
- build_native ARGV[2]
102
- when 'web'
103
- puts "Running build web..."
213
+ when '--native'
214
+ build_native(ARGV[2])
215
+ when '--web'
216
+ build_web(ARGV[2])
104
217
  else
105
- puts usage
218
+ if ARGV[2]; puts usage; exit end
219
+ check_build_src_file(ARGV[1])
220
+ build_native(ARGV[1])
221
+ build_web(ARGV[1])
106
222
  end
223
+ unless ARGV.include? '--debug'; clean_up end
107
224
  when 'package'
108
225
  puts "Running package..."
109
226
  build_package
@@ -112,5 +229,3 @@ when '-v', '--version'
112
229
  else
113
230
  puts usage
114
231
  end
115
-
116
- exit
@@ -1,12 +1,12 @@
1
1
  require 'mkmf'
2
2
 
3
- S2D_VERSION = '0.2.1' # Minimum Simple 2D version required
3
+ S2D_VERSION = '0.5.1' # Simple 2D minimum version required
4
4
  $errors = []
5
5
 
6
6
  class String
7
7
  def colorize(c); "\e[#{c}m#{self}\e[0m" end
8
- def bold; colorize('1') end
9
- def red; colorize('1;31') end
8
+ def bold; colorize('1') end
9
+ def red; colorize('1;31') end
10
10
  end
11
11
 
12
12
  def print_errors
@@ -69,15 +69,24 @@ elsif RUBY_PLATFORM =~ /linux/
69
69
  exit
70
70
  end
71
71
 
72
- $CFLAGS << ' -std=c99'
72
+ $CFLAGS << ' -std=c11'
73
+
74
+ # Windows / MinGW
75
+ elsif RUBY_PLATFORM =~ /mingw/
76
+ # Add flags
77
+ $CFLAGS << ' -std=c11 -I/usr/local/include'
78
+ $LDFLAGS << ' -Dmain=SDL_main -L/usr/local/lib -lmingw32 -lsimple2d -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lopengl32 -lglew32 -mwindows'
73
79
  end
74
80
 
75
- # Simple 2D installed, check version
76
- check_s2d_version
81
+ unless RUBY_PLATFORM =~ /mingw/
82
+ # Simple 2D installed, check version
83
+ check_s2d_version
84
+
85
+ # Add flags
86
+ $LDFLAGS << ' ' << `simple2d --libs`
87
+ end
77
88
 
78
- # Configure Simple 2D and create Makefile
79
89
 
80
- $LDFLAGS << ' ' << `simple2d --libs`
81
90
  $LDFLAGS.gsub!(/\n/, ' ') # Remove newlines in flags, they cause problems
82
91
 
83
92
  create_makefile('ruby2d/ruby2d')
@@ -0,0 +1,219 @@
1
+ # ruby2d-opal.rb
2
+
3
+ # Ruby 2D window
4
+ $R2D_WINDOW = nil
5
+
6
+ # Simple 2D window
7
+ `var win;`
8
+
9
+
10
+ `// ruby2d.js
11
+
12
+ // @type_id values for rendering
13
+ const $R2D_TRIANGLE = 1;
14
+ const $R2D_QUAD = 2;
15
+ const $R2D_IMAGE = 3;
16
+ const $R2D_SPRITE = 4;
17
+ const $R2D_TEXT = 5;
18
+
19
+
20
+ function on_key(e, key) {
21
+ switch (e) {
22
+ case S2D.KEYDOWN:
23
+ #{$R2D_WINDOW.key_down_callback(`key`)};
24
+ break;
25
+
26
+ case S2D.KEY:
27
+ #{$R2D_WINDOW.key_callback(`key`)};
28
+ break;
29
+
30
+ case S2D.KEYUP:
31
+ #{$R2D_WINDOW.key_up_callback(`key`)};
32
+ break;
33
+ }
34
+ }
35
+
36
+
37
+ function on_mouse(x, y) {
38
+ #{$R2D_WINDOW.mouse_callback("any", `x`, `y`)};
39
+ }
40
+
41
+
42
+ function update() {
43
+ #{$R2D_WINDOW.mouse_x = `win.mouse.x`};
44
+ #{$R2D_WINDOW.mouse_y = `win.mouse.y`};
45
+ #{$R2D_WINDOW.frames = `win.frames`};
46
+ #{$R2D_WINDOW.fps = `win.fps`};
47
+ #{$R2D_WINDOW.update_callback};
48
+ }
49
+
50
+
51
+ function render() {
52
+
53
+ // Set background color
54
+ win.background.r = #{$R2D_WINDOW.get(:background).r};
55
+ win.background.g = #{$R2D_WINDOW.get(:background).g};
56
+ win.background.b = #{$R2D_WINDOW.get(:background).b};
57
+ win.background.a = #{$R2D_WINDOW.get(:background).a};
58
+
59
+ var objects = #{$R2D_WINDOW.objects};
60
+
61
+ for (var i = 0; i < objects.length; i++) {
62
+
63
+ var el = objects[i];
64
+
65
+ switch (el.type_id) {
66
+
67
+ case $R2D_TRIANGLE:
68
+
69
+ S2D.DrawTriangle(
70
+ el.x1, el.y1, el.c1.r, el.c1.g, el.c1.b, el.c1.a,
71
+ el.x2, el.y2, el.c2.r, el.c2.g, el.c2.b, el.c2.a,
72
+ el.x3, el.y3, el.c3.r, el.c3.g, el.c3.b, el.c3.a
73
+ );
74
+ break;
75
+
76
+ case $R2D_QUAD:
77
+ S2D.DrawQuad(
78
+ el.x1, el.y1, el.c1.r, el.c1.g, el.c1.b, el.c1.a,
79
+ el.x2, el.y2, el.c2.r, el.c2.g, el.c2.b, el.c2.a,
80
+ el.x3, el.y3, el.c3.r, el.c3.g, el.c3.b, el.c3.a,
81
+ el.x4, el.y4, el.c4.r, el.c4.g, el.c4.b, el.c4.a
82
+ );
83
+ break;
84
+
85
+ case $R2D_IMAGE:
86
+ el.data.x = el.x;
87
+ el.data.y = el.y;
88
+
89
+ if (el.width != Opal.nil) el.data.width = el.width;
90
+ if (el.height != Opal.nil) el.data.height = el.height;
91
+
92
+ el.data.color.r = el.color.r;
93
+ el.data.color.g = el.color.g;
94
+ el.data.color.b = el.color.b;
95
+ el.data.color.a = el.color.a;
96
+
97
+ S2D.DrawImage(el.data);
98
+ break;
99
+
100
+ case $R2D_SPRITE:
101
+ el.data.x = el.x;
102
+ el.data.y = el.y;
103
+
104
+ S2D.ClipSprite(
105
+ el.data,
106
+ el.clip_x,
107
+ el.clip_y,
108
+ el.clip_w,
109
+ el.clip_h
110
+ );
111
+
112
+ S2D.DrawSprite(el.data);
113
+ break;
114
+
115
+ case $R2D_TEXT:
116
+ el.data.x = el.x;
117
+ el.data.y = el.y;
118
+
119
+ el.data.color.r = el.color.r;
120
+ el.data.color.g = el.color.g;
121
+ el.data.color.b = el.color.b;
122
+ el.data.color.a = el.color.a;
123
+
124
+ S2D.DrawText(el.data);
125
+ break;
126
+ }
127
+
128
+ }
129
+ }`
130
+
131
+
132
+ module Ruby2D
133
+
134
+ class Image
135
+ def init(path)
136
+ `#{self}.data = S2D.CreateImage(path);`
137
+ end
138
+ end
139
+
140
+ class Sprite
141
+ def init(path)
142
+ `#{self}.data = S2D.CreateSprite(path);`
143
+ end
144
+ end
145
+
146
+ class Text
147
+ def init
148
+ `#{self}.data = S2D.CreateText(#{self}.font, #{self}.text, #{self}.size);`
149
+ end
150
+
151
+ def text=(t)
152
+ @text = t
153
+ `S2D.SetText(#{self}.data, #{self}.text);`
154
+ end
155
+ end
156
+
157
+ class Sound
158
+ def init(path)
159
+ `#{self}.data = S2D.CreateSound(path);`
160
+ end
161
+
162
+ def play
163
+ `S2D.PlaySound(#{self}.data);`
164
+ end
165
+ end
166
+
167
+ class Music
168
+ def init(path)
169
+ `#{self}.data = S2D.CreateMusic(path);`
170
+ end
171
+
172
+ def play
173
+ `S2D.PlayMusic(#{self}.data, #{self}.loop);`
174
+ end
175
+
176
+ def pause
177
+ `S2D.PauseMusic();`
178
+ end
179
+
180
+ def resume
181
+ `S2D.ResumeMusic();`
182
+ end
183
+
184
+ def stop
185
+ `S2D.StopMusic();`
186
+ end
187
+
188
+ def fadeout(ms)
189
+ `S2D.FadeOutMusic(ms);`
190
+ end
191
+ end
192
+
193
+ class Window
194
+ def show
195
+ $R2D_WINDOW = self
196
+
197
+ `
198
+ var width = #{$R2D_WINDOW.get(:width)};
199
+ var height = #{$R2D_WINDOW.get(:height)};
200
+
201
+ var vp_w = #{$R2D_WINDOW.get(:viewport_width)};
202
+ var viewport_width = vp_w != Opal.nil ? vp_w : width;
203
+
204
+ var vp_h = #{$R2D_WINDOW.get(:viewport_height)};
205
+ var viewport_height = vp_h != Opal.nil ? vp_h : height;
206
+
207
+ win = S2D.CreateWindow(
208
+ #{$R2D_WINDOW.get(:title)}, width, height, update, render, "ruby2d-app", {}
209
+ );
210
+
211
+ win.viewport.width = viewport_width;
212
+ win.viewport.height = viewport_height;
213
+ win.on_key = on_key;
214
+ win.on_mouse = on_mouse;
215
+
216
+ S2D.Show(win);`
217
+ end
218
+ end
219
+ end