2005-10-13
[開発ログ] ASR でプリミティブの描画テスト
2D プリミティブ(文字、画像、長方形)は表示出来た。 現状で Tk よりよいと思う点は
- 画像の拡大縮小表示ができる
- アニメーションに GIF アニメが使える
- HTML なので馴染みやすい
- IE の安定感
- HTML なのでフラッシュムービーとか音も簡単に組み込めそう
- 最終的に JavaScript に移植すれば非常に多くの環境で動く
あたりだろうか。デメリットとしては Tk は多角形(ポリゴン)が表示できたが HTML ではできなそう。
上記 2 つが嬉しくて、これができるとドラクエ 7 のような 3D っぽいキャラクタ表示が可能。
この手の実験的なコードを日記に張っておくと後にたいへん役立つので実験用スクリプトを張っておく。 Prim のインターフェースはまだまだいい加減。
test.hta
<html> <head> <HTA:APPLICATION ID="ERProt" ApplicationName="ERProtOnASR" /> <script language="RubyScript"> $KCODE = "SJIS" require 'main.rb' </script> </head> <body onload="init" language="RubyScript"> <div id="top_div"></div> </body> </html>
main.rb
require 'er.rb' def main_loop @counter += 1 @font.elm.style.top = @counter * 4 % 480 end def init @screen = init_window(640, 480, '#ccccff') @counter = 0 @cwin = @screen.create_prim Box, :box01, 0,@screen.h-100,0, @screen.w-16, 100-16, '#ffcccc' @cwin.margin = "8 8" @cwin.padding = "8 8" @cwin.onmouseover = "__self__.test00" @cwin.create_prim Font, :id00, 0,0,0, 16, 'ABC'*20 @font = Font.new :id01, 100,120,0, 16, 'ABC' @screen.add_prim @font @font.create_prim Font, :id02, 100,140,0, 16, 'ABC' @screen.create_prim Image, :image00, 140,100,0, 'i_31.gif' start_window(50, :main_loop)if @window end if $0 == __FILE__ init puts @screen.html end
er.rb
class Prim attr_accessor :id, :str, :src attr_accessor :margin, :padding, :bgcolor attr_accessor :position_type, :x, :y, :z, :w, :h, :size attr_accessor :onmouseover @@prims = {} @@window = nil def self.find(id) @@prims[id] end def self.window=(win) @@window = win end def initialize *arg @prims = [] @html_tag = 'div' @position_type = 'absolute' ([:id] + initialize_params).each do |meth| break unless v = arg.shift __send__ "#{meth}=", v end raise unless id.is_a? Symbol raise id.inspect if @@prims[id] @@prims[id] = self end def initialize_params [:x, :y, :z, :size, :str] end def create_prim klass, *arg @prims << klass.new(*arg) @prims.last end def add_prim prim @prims << prim end def inside_of_html str end def style_params params = [] { :margin => 'margin', :padding => 'padding', :position_type => 'position', :y => 'top', :x => 'left', :w => 'width', :h => 'height', :bgcolor => 'background-color', }.each do |k, v| if __send__ k params << "#{v}:#{__send__ k}; " end end params end def events params = [] { :onmouseover => 'onmouseover', #:setInterval => 'setInterval', }.each do |k, v| value = __send__ k if value params << %Q|#{v}="#{value.gsub('__self__', "Prim.find(:#{id})")}" | end end params end def html %Q|<#{@html_tag} id="#{id}" language="RubyScript" #{events.join}style="#{style_params.join}">\n#{inside_of_html}#{children_html}</#{@html_tag}>| end def children_html @prims.map{|prim| prim.html}.join("\n") end def elm @elm ||= @@window.__send__ id end def test00 elm.style.width = "200" elm.style.backgroundColor = "#FF0000" end end class Font < Prim end class Box < Prim def initialize_params [:x, :y, :z, :w, :h, :bgcolor] end end class Image < Prim def initialize_params [:x, :y, :z, :src] end def inside_of_html %Q|<img src="#{src}">| end end def init_window(w, h, bgcolor) if @window Prim.window = @window @top_div = @window.top_div @window.resizeTo w+40, h+40 end Box.new :__screen__, 0,0,0, w,h, bgcolor end def start_window(interval, func) @top_div.innerHTML = @screen.html @timer = @window.setInterval func.to_s, interval, "RubyScript" end