mieki256's diary



2018/02/01(木) [n年前の日記]

#1 [gimp] SFだかメカだかそれっぽいテクスチャを生成するGIMPスクリプトを修正

以前、メカの壁面っぽいテクスチャ(Sci-Fi, Hard surface)を生成する GIMP のScript-fu を書いたのだけど。

_mieki256's diary - GIMPでメカっぽいテクスチャ画像を生成するスクリプトを書いた
_mieki256's diary - メカっぽいテクスチャを作るツールを書いた

GIMP 2.8 上ではブラシ選択部分が正常に動いてなかったので、修正して github にアップロードしてみたり。

_mieki256/sci-fi-texture-generator: Sci-Fi bump mapping texture generator with GIMP Script-fu.

以下のようなテクスチャが作れます。

screenshot01.png

screenshot02.png

License は CC0 / Public Domain ってことで。

使い方は、以下。
  1. 3つの *.scm を GIMPユーザフォルダ\scripts\ にコピーしてインストール。
  2. GIMPを起動。
  3. 新規画像を作成。1024x1024 ぐらいが妥当。
  4. Scrip-Fu → Utils → Sci-Fi texture。白黒のバンプマッピング用画像が得られる。
  5. Scrip-Fu → Utils → Sci-Fi texture makeup。エンボスフィルタ等で立体感をつけた画像が得られる。

アルゴリズム。 :

やってる処理は簡単で…。矩形を横方向、または縦方向でいくつか分割して、更に分割してできた各矩形に対しても分割を繰り返して。つまり、プログラム的には再帰を使って処理をして。

scifi_texture_algo.png

指定した深さで分割が終わったら、出来上がった小さい矩形群を、以下のどれかのパターンで描画するだけ。

scifi_pattern.png

後は、矩形の四隅にリベット相当を描画したりする程度。

各矩形を描画する際のパターン種類を増やしていけば、もうちょっと複雑な見た目のテクスチャも作れそうな予感。

まあ、それらしいブラシをいくつか作成しておいて、最後にスタンプ感覚で好きなように描き加えていったり、ざっくりと直線や四角をつけ加えて整えれば、もうちょっとそれらしくなるような予感も。

今思いついたけど、レイヤーに1つ小さい矩形でパターンを描いて、そういうレイヤーをたくさん作って、全レイヤーのオフセット値をランダムに変更していけば乱雑な感じのテクスチャが作れたりしないかな。どうかな。

ブラシ種類について。 :

Script-fu絡みについてメモ。

昔の GIMP は、「Circle (01)」「Circle Fuzzy (05)」等のブラシ種類を選べて、自分が以前書いたスクリプトもそれに従って処理を書いてたのだけど。それらのブラシは、GIMPがブラシサイズを自由に変更できない仕様だった頃のブラシ種類で…。

_廃止された定義ブラシ(Circle系)を GIMP2.8.18 で再現 - 分室の分室

「Circle」が丸いブラシ形状を示していて、「(01)」「(05)」がブラシサイズを示してたわけだけど、サイズが異なるブラシを使いたいときは、一々異なるブラシ種類を用意して対応してた時期があるわけで。

しかし、今の GIMP はブラシサイズを自由に変更できるので、それらのブラシは標準インストール状態で使えなくなっていた模様。当然、Script-fu 内でそれらのブラシ種類を選択しようとしても選択できない。だから、自分が作った前述のスクリプトでは、描画がちょっとおかしくなっていたわけで。
; failure

(gimp-brushes-set-brush "Circle (13)")

(gimp-brushes-set-brush "Circle Fuzzy (11)")

ということで、今回、GIMP 2.8 に標準で入ってる、「2. Hardness 100」「2. Hardness 075」等のブラシを選んでから、サイズも別途指定するように修正してみたり。
; success

(gimp-context-set-brush "2. Hardness 100")
(gimp-context-set-brush-size 13)

(gimp-context-set-brush "2. Hardness 075")
(gimp-context-set-brush-size 11)

ちなみに、昔は Script-fu 内で gimp-brushes-set-brush を使ってブラシを選んでいたけど、「その命令は将来的に削除されるので gimp-context-set-brush を使え」ということになってる模様。

余談。 :

こういうメカっぽいソレを、海外では「hard surface」と呼んでたりするようで。また、SFっぽい何かしらは「Sci-Fi」という単語がつけられてたりするっぽい。

_「hard surface」_「sci-fi texture」 でGoogle画像検索すると、ちょっと絶望的な気分に…。やはり人が手を動かしながらカッコよさや気持ちよさを感覚的に追求して作ったそれぞれには全然敵わんなあ、みたいな。

#2 [nitijyou] 日記を少しずつアップロード

気付いたら、2017/12/21を最後に、日記をアップロードしてなかった…ので少しずつアップロードを始めたり。

2018/02/02(金) [n年前の日記]

#1 [gimp][python] GIMPのScript-fuスクリプトをPython-fuで書き直し中

昨日 github にアップロードした Script-fu を、Python-fu で書き直し中。

Script-fu をいくつか書いてきたものの、lisp系はどうも分からん…。分からんから、なかなか改造・改良のしようがない…。せめて Python で書いてあれば、もうちょっとサクサクと改良できるのではないか。と思えてきたので、この際書き直そうと。

気のせいかもしれないけれど、Script-fu (TinyScheme)で処理するより、Python-fu で処理するほうがなんとなく体感的に処理が速いような気がする。いや、気のせいだと思うけど。たぶん気のせい。

選択範囲の中で矩形塗り潰し。 :

せっかくだから、Python-fu に書き直すついでに、各矩形内に描画するパターンの種類も増やそうとしているのだけど。既に選択範囲がある状態で、その中で矩形塗り潰しをするには、どんなスクリプトを書いたらいいのやら。GIMPに矩形塗り潰し機能があれば楽なのだけど、ちょっと見つからない感じで。

現在の選択範囲をどこかに記憶しておいてから、新たに矩形の選択範囲を作って、塗り潰しをして、先ほど記憶しておいた以前の選択範囲を再設定…するしかないのかな。選択範囲はチャンネルに保存・読み出しができるけど、使い終わったチャンネルを削除する命令が見つからない…。いや、コレかな…。たぶんコレだろう…。

>>> # python-fu を使う際のお約束
>>> from gimpfu import *

>>> # 画像を取得
>>> image = gimp.image_list()[0]
>>> image
<gimp.Image '[名称未設定]'>

>>> # レイヤーを作成・追加
>>> layer = gimp.Layer(image, "Layer Name", image.width, image.height, RGBA_IMAGE, 100, NORMAL_MODE)
>>> image.add_layer(layer, 0)

>>> # 矩形の選択範囲を作成。x,y,w,hを指定
>>> pdb.gimp_image_select_rectangle(image, 2, 16, 32, 256, 512)

>>> # 選択範囲をチャンネルに保存
>>> channel = pdb.gimp_selection_save(image)
>>> channel
<gimp.Channel '選択マスク コピー'>

>>> # 矩形の選択範囲を作成。
>>> pdb.gimp_image_select_rectangle(image, 2, 24, 48, 128, 256)

>>> # 描画色を指定。python-fuの場合、0.0 - 1.0 で指定
>>> gimp.set_foreground(1.0, 0.5, 0.0)

>>> # 塗り潰し
>>> pdb.gimp_edit_fill(layer, FOREGROUND_FILL)

>>> # 選択範囲解除
>>> pdb.gimp_selection_none(image)

>>> # 選択範囲をチャンネルから読み出す
>>> pdb.gimp_selection_load(channel)

>>> # チャンネルを削除
>>> pdb.gimp_image_remove_channel(image, channel)

もっと上手い方法がありそうな気もする。

#2 [nitijyou] トイレの便座が壊れた

朝方、親父さんが、「トイレの便座が割れた」と騒いでいて。前々からヒビは入っていたけど、とうとう割れちゃったか…。おそらく親父さんが勢いよく座ってしまったりしたんだろう…。

奥の裏側に型番が記載されたシールが貼ってあった。松下電工 CH52、製品ジャンルとしては暖房便座、になるらしい。

親父さんが、この手の商品を扱ってるリホーム関係のお店に出向いて確認したところ、該当製品は廃番らしい。というか、松下電工自体がこの手のジャンルから撤退してるという話も聞いたそうで。一応、TOTO、INAXから代わりになる製品が販売されてる状態ではあるのだとか。

ということで、近所のホーマックで、親父さんが TOTOの製品を買ってきた。まだ、取り付けはしていない状態。

2018/02/03() [n年前の日記]

#1 [gimp] メカっぽいテクスチャを生成するGIMPスクリプトをPython-fuで書き直した

SFメカっぽい壁等に使えそうなテクスチャを生成する、Script-fu で書いたGIMPスクリプトを、Python-fu で書き直してみた。

_mieki256/sci-fi-texture-generator: Sci-Fi bump mapping texture generator with GIMP Script-fu.

インストールして、フィルタ → 下塗り → Sci-Fi texture 2 で呼び出せる。

Python-fu で書いたから、修正も今までより楽になる、といいな。

#2 [nitijyou] トイレの便座を交換

親父さんがトイレの便座の交換作業をしてくれたらしい。新品だけあって見た目は奇麗。

今まで設置されてた松下電工 CH52 と比べると、奥部分にある暖房関係の回路部分が手前に出っ張っていて、全体の奥行きは今までより小さくなったような気がする…。

2018/02/04() [n年前の日記]

#1 [gimp][python] Python-fuを弄ってたり

先日書いた Python-fuスクリプトを弄っていたり。描画パターンをもう少し増やせないかなと。

塗り潰し矩形を重ならないように配置する良い方法はないものか…。妙案が思いつかなくて、結局は矩形領域を一旦いくつかに分割して、その中に入れる、というやり方をしてしまったけど。もっとヨサゲなアルゴリズムがありそうな気もする。

#2 [anime] 「宇宙戦隊キュウレンジャー」最終回を視聴

終わってしまった…。

昨今、宇宙を股にかける特撮ヒーローってほとんど存在してないので、その基本設定だけで個人的にはかなりお気に入りだったのだけど。やっぱり宇宙を舞台にした作品は、イイ。なんかイイ。

ただ、あまり玩具が売れなかったという話もどこかで聞いたので、そのあたりはちょっと残念で。宇宙で云々はウケないのだろうか…。いや、玩具の種類が多過ぎただけでは…。本編のアレコレと玩具の売れ方って、例えばライダー鎧武の件を思い返しても、さほど連動してないところがありそうな…。なので、「宇宙モノは売れないのだ」と決めつけるのは早計のような気も。

何にせよ、スタッフの方々、お疲れ様でした。壮大なハッタリの数々、実によかったです。

繰り返しのソレ。 :

ところで。1話で見せたシチュエーションを、最終回でも提示するソレは、見ていてなんだか燃えてくるなと感心を。いやまあ、アレ、赤の人も燃えてると思うけど…物理的に。

1話のソレがまた出てくると、見ていて燃えるのは何故かとつい考えてしまったのだけど。もしかすると、1話の時点では視聴者にとって未知のネタ・シチュエーションだけど、再度出すと既知のネタに変化して、そのことでネタに対する印象が変わるから、てなところがあるのかなと思えてきたり。例えば、「志村ーうしろうしろー」とか、水戸黄門の「ええい、静まれ静まれ!」に近いのかも。

最初は「何コレ?」だった印象が、2回目からは「このネタ知ってる!」的な受け止め方に変わる。知ってるネタは受け入れられやすいし、見る側も先が分かるから気分を乗せていける。ラピュタをTV放送するたびに「バルス!」があれだけ呟かれるのは何故か、みたいな。初見の人はそういう遊びができないわけで。

1回目と2回目で印象が変わることを利用したソレと言うと、ポプテピピックもソレだよなと。1回目の時点では、ぶっとんだ各ネタの内容を視聴者が知らない故に、場合によっては理解すらできないので、まずはあの手のキャラデザならこういう声を出すものだろう、という一般的なイメージを利用して、女性声優陣に声をあててもらって比較的ハードルを下げておいて…。しかし2回目は未知のネタから既知のネタに変化してるから、予想外の男性声優陣を起用してさらに飛躍してもOKだろう、みたいな。もし、最初に男性声優版が流れてしまうと、最初から飛躍し過ぎていて振り落とされてしまう。 *1 あの構成は、ネタを繰り返し提示すると、ネタの受け止められ方が視聴者の中で変化する、てなあたりを利用している構成だと思うわけで。

子供向け番組では、「3回繰り返して見せて、3回目をちょっと変える」みたいな技があるわけだけど。シリーズ構成や脚本でもそういう技は使えるんだろうなと。

まあ、そのあたりを考えてると、1話分の脚本の中で、同じ状況を2回繰り返して見せることで前後の変化を強調して見せた、ライダー響鬼の井上脚本回を思い出したりもするわけだけど。アレは実に見事だった…。しかも、ロケ場所への移動回数も節約できるあたりが…。

*1: いやまあ、1話はそれやってたから、終始「何コレ…」状態だったけど。

2018/02/05(月) [n年前の日記]

#1 [gimp][python] Python-fuをまだ弄ってたり

先日書いた Python-fuスクリプトをまだ弄ってたり。

BS11でガンダムOOの放送が始まったので眺めていたのだけど、メカっぽい背景を注意しながら見ていたら、パネルの隅に黒くて細長い四角が描き込まれていることに気づいたわけで。パネルの四隅に配置するものと言えば、丸いリベットぐらいしか思いつかなかったので、矩形を置くのもアリなのだなと目ウロコ。丸いリベットを置いてしまうと宮崎駿が描きそうなスチームパンクっぽいメカになってしまうけど、黒い四角を置くと、近未来っぽい、どこかソリッドな印象になるのだなと。

てなわけで、Python-fuスクリプトに対して、丸いリベット以外に黒い四角も選べるように処理を追加しているところ。ただ、小さいパネルにもびっしり描き込むと、ちょっとくどくて今一つな印象になるようで。ある程度大きいパネルにだけ描いたほうがヨサゲ。

2018/02/06(火) [n年前の日記]

#1 [gimp][python] Python-fu + pycairo で矩形をランダムに塗り潰す処理を書いてたり

SFっぽいテクスチャを生成する際、ランダムに矩形が塗り潰されてるテクスチャが欲しいなと。GIMPのプラグインでありそうな気もするけど、ちょっと見つからなかったので、Python-fu で書き始めたり。

矩形塗り潰し処理を、選択範囲作成 → 塗り潰し → 選択範囲解除を繰り返してやってたら遅くなりそうなので、pycairo (cairoという描画ライブラリをPythonから呼び出すモジュール)を使って処理してみようかと。

処理自体は書けたけど、cairo用の surface を GIMPのレイヤーに転送するあたりが遅い…。RGBAの順番を入れ替えつつ転送するためのループ処理がおそらく重い予感も。

#2 [zatta][neta] 静かな掃除機って作れないものだろうか

素人のバカ妄想をメモ。

掃除機と言えば「ドゥキュウウウーン」的な盛大な音を立てる家電だったりするわけだけど、真夜中でも使えるぐらいに静かな掃除機って作れないものかなー、などと部屋の隅に積もった埃を目にしながら妄想してしまったり。

そよ風程度の風量、というか吸引力でもOKなら、モータの回転数を落とすだけで静かになるだろうけど。それなりの吸引力を得ようとするとモータの回転数を上げないといけないから、どうしてもうるさくなっちゃうなと。いや、もしかすると風切り音のほうがうるさかったりするのかもしれないけど。

一つの大きいモータを高回転で使うのではなく、小型のモータをたくさん並べてみたらどうなるだろう。PCケースの静音化の場合も、高回転のファンを1つつけるより、複数のファンをつけたほうが全体の騒音は少なくなる、という話があったような…。いや、逆だったっけ? どうだったっけ? なんだか記憶が怪しい。それはともかく、掃除機で複数のモータを入れてしまうと、生産コストは高くなるし、故障も増えるというデメリットがありそうではあるなと。

デメリット云々は一旦横に置いといて。例えば、8cmファンを、2x2、3x3、4x4と並べたら、そこそこの風量=吸引力が得られたりしないか。もしそういう作りでもOKなら…これは超薄型の掃除機が作れるなと。もっとも、「掃除機を薄型にして何のメリットがあるんだ?」と言われそう。まあ、収納が楽になると思うのだけど。本棚・机の引き出しにしまえる掃除機、タンスとカラーボックスの隙間に押し込んでおける掃除機、みたいな。掃除機のイメージが変わりそうではあるなと。

しかし、本当に小型モータを並べたら静かになるのだろうか。例えばPCの世界では、8cmファン x 2 より、12cmファン x 1 を低速で回したほうが、似たような風量ながら静音性が得られるわけで。要は、羽が大きければ、その分モータを低速で回せるから、騒音も減るという。もし、掃除機内部の羽も、扇風機並みの大きさにすることが許されるなら、その分モータを低速で回せるから、より静音になりそうな予感も。

ということで、幅や高さは一般的な掃除機より一回り二回りほど大きくて一瞬ギョッとするけれど、厚さがわずか数cm、しかもそこそこの吸引力なのに真夜中でも使えるほどに静音、てな掃除機は作れないものかなー、と。

まあ、どうせ実験してみたら、「全然吸引力がねえ…」「しかも予想より音がうるせえ…」てなことが分かって実用化は無理、てなオチになるんだろうと想像したりもするのですが。

薄型掃除機は既にあった。 :

妄想を書き留めた後でググってみたら、薄型掃除機は既にフツーにゴロゴロ存在してた。考えてみたら、ロボットタイプのウロウロする掃除機って、ほとんどが薄型掃除機だったのだな…。ていうか「薄型掃除機」でググるとロボット掃除機しか出てこない。ロボット以外の薄型掃除機は無いのかな…。

でも、静音なのかというと、どうやらそうでもないらしい。

_うるさいと言う不満を持たせない音の静かなロボット掃除機6選 | ロボット掃除機でみんな幸せ

「昼間は使えるけど夜は無理」なのか…。どんな構造になってるのだろう。

ググってみたけど、家庭用の掃除機って羽を大きくしてどうこうという発想がまず無いみたいだなと。家庭で使うものだからできるだけ小型にせよ → 羽が小さくなる → モータを高速回転させて風量を稼ぐ → 騒音増加、という製品しか無いような。

どうも、「大きくなったら邪魔になるだろう。そんなの決まってるだろ」という思い込みがありそうな…。大きくなるけど薄くなるとか、大きくなるけど細くなるとか、色々ありそうな気もするのだけど。x,y,zの全方向に大きくしなきゃいけないわけでもあるまいに。

などと思ったりもしたけど、紙パック式云々の問題もあったりするから、形状を大きく変えることは許されない、みたいなところがありそうな気もしてきたわけで。

2018/02/07(水) [n年前の日記]

#1 [nitijyou] 自宅サーバ止まってました

AM02:00〜03:00頃からAM08:30頃まで自宅サーバ止まってました。申し訳ないです。

親父さんから「サーバ止まってないか?」と言われて確認してみたら無反応になっていて。電源ボタン押しのシャットダウンも走らず。たぶん寒すぎて電源あたりが正常動作しない状態になったのかなと…。

#2 [gimp][python] GIMPのPython-fu + pycairoで描いた画像をGIMPのレイヤー用に変換する処理について

GIMPのPython-fuスクリプトの中では、cairo (pycairo) を使った描画もできるっぽいのだけど。cairo が利用する ImageSurface は、1ドットが ARGB で並んでいるけど、GIMPのレイヤー側は、1ドットが RGBA で並んでいるので、ARGB から RGBA に変換する処理が必要で。ソレをしないと、cairo の ImageSurface を GIMPレイヤーに正常な色で転送できない。

一応、以前そういう処理を書いたのだけど。

_mieki256's diary - Ubuntu Linux 16.04LTS上でGIMPのPython-fuに関して試行錯誤中

どうも処理が遅いと言うか…。64x64ドットぐらいの処理なら気にならないけど、1024x1024 = 1048576回ループさせると数秒待たされる感じで。

もうちょっと高速化できないかと色々試して、結局、以下のようになったけれど…。

import struct

def get_rgba_str(src):
    """Convert cairo surface data to RGBA."""
    unpack = struct.Struct('=L').unpack_from
    pack = struct.Struct('>L').pack
    lmax = len(src) / 4
    rgba_buf = [None] * lmax
    for i in xrange(lmax):
        argb = unpack(src, i * 4)[0]
        rgba_buf[i] = pack(((argb & 0x00ffffff) << 8) | ((argb >> 24) & 0x0ff))
        if i & 0x3fff == 0:
            gimp.progress_update(0.5 + 0.5 * float(i + 1) / lmax)

    return ''.join(rgba_buf)

これでもまだ遅い。どうにかならんかな…。コレ以上は無理かな…。

ちなみに、cairo の ImageSurface の1ドットがバイト単位で ARGB の順に必ず並んでるかどうかは分からない。おそらく、CPUがビッグエンディアンかリトルエンディアンで並びが違ってくる可能性がある。GIMPレイヤー側はビッグエンディアンのRGBAで並んでるっぽいけど…。

関連する話をメモ。 :

Python の structモジュールを使うと、Cの構造体っぽいソレでまとめられたバイナリデータを扱うことができる。バイナリを読むときは struct.unpack() を使って、バイナリにする時は struct.pack() を使う。

で、ループ処理内で、以下のように書けなくもないのだけど。
argb = struct.unpack_from('=L', src, i * 4)[0]
何度も同じフォーマット文字列を使う場合は、struct.Struct(フォーマット文字列) を使って、ループ外でフォーマット文字列を与えたソレを事前に用意して使ったほうが速くなる、という話を見かけたので一応試してみたり。

Python は文字列結合が遅いので、リスト(配列)に追加していくほうが速い、という話も見かけた。ただ、Python 2.4以降は a += b のような文字列結合は最適化されてるので、現状ではそれほど効果は無いらしい…。

_Python文字列バッファいろいろ - 一番速い奴連れてこいシリーズ - HDEラボ
_Pythonの処理速度を上げる方法 その2 - とある誰かの覚え書き

リストの長さを事前に確保しておく際は、[ None ] * n が速い、という話があるらしいのでコレも試した。

_あなたのPythonを爆速にする7つの方法

以前は、一旦、a, r, g, b に分けてから、struct.pack('4B', r, g, b, a) でバイナリにしていたけど。考えてみたら、ARGB を RGBA にするのだから、A だけをずらせば済むのだなと。4行あった処理を1行で済ませることができた。

これは Python-fu特有の話だけど、どうも体感では、プログレスバーの表示を更新する gimp.progress_update( 0.0 〜 1.0 の値 ) を頻繁に呼ぶと、それだけで遅くなるようで。考えてみれば、更新されるたびに画面内の該当部分を描画し直すのだから、そこで処理がかかるのも当たり前か…。更新回数を減らしてみたら、それだけでも効果があった…ような気がする。

2018/02/08(木) [n年前の日記]

#1 [gimp][python] メカっぽいテクスチャを生成するGIMP Python-fuプラグインについて

ここ数日弄ってた、GIMP の Python-fuプラグインについて。

_mieki256/sci-fi-texture-generator: Sci-Fi bump mapping texture generator with GIMP Script-fu.

大体それっぽい感じになってきたかな…。以下のようなテクスチャが作れます、みたいな。

scifi_texture_01.png

scifi_texture_02.png

手描きのテクスチャに比べたらショボいけど、手っ取り早くなんだかそれっぽい画像が欲しいときは使えるだろう、みたいな。

課題。 :

TVアニメの背景等を眺めていると、どうも斜めに線を引いてあるメカっぽい背景が多いわけで。

tex01.png

自分の作ったスクリプトは、只の長方形でしか分割できないので、台形っぽい感じで分割できるようにするあたりは課題だなと…。例えばお絵かきソフトなどで、漫画のコマ割り機能がついてるものは、斜めに領域を分割できたりしているのだから、技術的に不可能というわけでは全くないのだろうけど。もっとも、斜めに分割した場合、その中を再分割するのはどうするのか、中に入れるパターンはどう整えたらいいのか、という問題は残りそう。今のところ、各パターンは長方形の中に収めることを前提にして作ってあるので…。

他にも、その手の背景は、何かが光ってる場合が多いわけで。LEDなのか窓なのか分からんけど…。

tex02.png

今回弄ってたスクリプトは、blender等3DCGソフト上でのバンプマッピング用テクスチャ画像を生成したい、てな用途で考えていたところがあるので、何かしら光ってる(ように見える)テクスチャを生成する、という話になると、やることがちょっと違ってくるよなと…。

まあ、斜めに分割するソレも、何かしら光らせるソレも、手を動かしてちょこっと描き加えてやれば済む話ではあるのだけど。そこらへんまでプログラムを描いて自動生成できたら楽になるよね、でもどうやればいいのだろうね、みたいな。

2018/02/09(金) [n年前の日記]

#1 [gimp][python] メカっぽいテクスチャを生成するPython-fuスクリプトを使ってる様子を動画キャプチャしてみた

先日作成したPython-fuスクリプトを実際に使ってる様子を、動画キャプチャしてアップロードしてみたり。

_mieki256/sci-fi-texture-generator



こんな感じで使える、ということで。

#2 [cg_tools] ドット絵素材をOpenGameArtにアップロードしておいた

love2d で _シューティングゲームっぽいサンプル を作成した際に作ったドット絵素材を、 _OpenGameArt.org にアップロードしておいた、とメモ。

_Sci-Fi Shoot 'em up object images | OpenGameArt.org
_Sci-Fi Shoot 'em up stage data | OpenGameArt.org

CC0 / Public Domain にしておくので自由に使ってもらえればと。

ちなみに、今までアップロードしたファイル群は以下。

_mieki256 | OpenGameArt.org

2018/02/10() [n年前の日記]

#1 [cg_tools] Poserを触ってたり

下絵用のCGを作るべくPoserを触っていたり。

両手で持つ銃のモデルが欲しいのだけど、それらしいモデルは同梱されてないようで。仕方なく戦車の砲台っぽいものを持たせてポーズをつけてるけど…。うーん。

2018/02/11() [n年前の日記]

#1 [windows] WSLについてちょっと調べてる

Windows 10 Fall Creators Update は、WSL(Windows Subsystem for Linux) という機能が正式に使えるようになって、Windows上で Ubuntu Linux 等のバイナリをそのまま動かせるようになっていて。以前も少し試したのだけど、何か使い道あるのかなとまた興味が湧いてきたのでインストールや設定方法等をググって眺めているところ。

2018/02/12(月) [n年前の日記]

#1 [windows] WSLを少し触ったけどアンインストールした

Windows10上でWSLを有効にして、Ubuntuを入れたり VcXsrv をインストールしたりして色々動作確認をしていたのだけど。FontForge が動くところまでは確認できたものの、love2d をインストールして動作確認したらさすがに動かなくて。そりゃまあそうだよな、OpenGL がどうとか要求されても動くわけが無い。

考えてみれば、WSLって、動作確認環境としてはほとんど意味が無いんだよな…。まだ、仮想PC上でLinuxを動かして動作確認するほうが意味があるというか…。もっともWSLは、Linux上の便利なツールを日常的に使えるあたりが売りで、そもそも動作確認用の環境の類じゃないわけで。

自分の場合…。 こういう環境では、WSL を使える有難味がちょっと薄いよなと。

ということで、HDDの空き容量が心許無いこともあって、WSL + Ubuntu はアンインストールすることにした。

ちなみに、作業の参考にしたページは以下に登録しておいた。とメモ。

_はてなブックマーク - WSLに関するmieki256のブックマーク

2018/02/13(火) [n年前の日記]

#1 [windows] WSL + MobaXtermを試用

昨日 WSL用のUbuntuをアンインストールしたものの、その後ググってたら、MobaXterm なら OpenGLを使ったアレコレも動く、てな話を見かけて。

_MobaXterm free Xserver and tabbed SSH client for Windows
_MobaXterm が便利
_MobaXtermを使いBash On Windowsで簡単にX11を使う - Qiita

OpenGL まで動くなんて、マジか…と興味が湧いたので、またWSLを触ってみようかなと。

それにしても自分、一体何回 WSL + Ubuntu のインストールとアンインストールを繰り返すのか…。

MobaXtermをインストール。 :

以前、Portable版を試用したことがあるけれど、今回はインストーラ版を利用。MobaXterm_Installer_v10.5.zip をDLして解凍。中に入ってる MobaXterm_installer_10.5.msi を実行してインストール。

ただ、Portable版も、インストーラ版も、起動に数分かかるのがちょっと厳しい。

起動して、session → shell と選んでいくと、WSL が選択項目として用意されてる。親切だな…。

X11アプリが動くかどうか確認。
sudo apt install x11-apps
xeyes &
目玉が表示された。

OpenGLのサンプルが動くかどうか確認。
sudo apt install mesa-utils mesa-utils-extra
glxgears -info
es2gears
OpenGL、OpenGLES を使った例のギアが表示された。たしかにOpenGLアプリも動くっぽい。

glmark2、glmark2-es2 も一部動いた。

_OpenGL / OpenGL ES2.0 のパフォーマンスを確認する(glmark2/glmark2-es2 を使う) - Qiita

love2dは動かなかった。 :

OpenGL が動くなら、love2d も動くのかな、と試してみたけど…。
sudo apt install love
love

これはやっぱりダメだった。
# 公式リポジトリ版 love (0.9.1-3ubuntu1)

$ love
Error: No available displays
stack traceback:
        [C]: at 0x00430780
        [C]: in function 'require'
        [string "boot.lua"]:324: in function <[string "boot.lua"]:241>
        [C]: in function 'xpcall'

Ubuntu 16.04 LTS の公式リポジトリにある SDL2 や love2d は古いので、SDL2のソースをダウンロードしてビルドしたり、リポジトリを追加してlove2dの現行版をインストールしてみたけど、結果は変わらず。

_mieki256's diary - Ubuntu 16.04 LTS上にlove2dをインストール
_mieki256's diary - Ubuntu 16.04にgolangとgo-sdl2をインストール

# PPA版

$ love
Error: Could not initialize SDL video subsystem (No available displays)
stack traceback:
        [C]: at 0x7f2a742d7f20
        [C]: in function 'require'
        [string "boot.lua"]:375: in function <[string "boot.lua"]:275>
        [C]: in function 'xpcall'

export DISPLAY=:0 だの、export DISPLAY=localhost:0.0 だのを打ってから試してみたりもしたのだけど、やっぱりダメ。ちなみに MobaXterm 上では、デフォルトでは DISPLAY=127.0.0.1:0.0 になってる模様。

まあ、そもそも、love2d は Windows用バイナリが存在するわけで。

_LoVE - Free 2D Game Engine

あえて WSL上で動かさないといけない理由は、どこにも無いのだけど…。いやまあ、SDL2を使ったアプリまで動いたらスゴイな、と期待しちゃったけど、さすがにそれは無理っスよ、てな状況らしいなと。

VMware + Ubuntuで試してみた。 :

実は Ubuntu 16.04上でSDL2は動かなかったりしないか、と不安になったので、以下のサンプルを使わせてもらって、VMware Player + Ubuntu 16.04上で動作確認してみたり。

_H4tch/Basic-SDL2-Demo: Game demo built on C++ and SDL2. Has Camera, Player, Timers, Spritesheets, and a basic Map functionality. MIT Licensed.

sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-net-dev libsdl2-gfx-dev
git clone https://github.com/H4tch/Basic-SDL2-Demo.git
cd Basic-SDL2-Demo
make
./sdl2-demo

フツーに画面が表示された。

もちろん、love2d も動く。
sudo apt install love
love

ということは、実機、もしくは仮想PC上なら SDL2 は動くけど、WSL + MobaXterm 上で SDL2 を動かすのは無理、ということだな…。

考えてみたら、MobaXterm が起動するまでの時間と、VMware Player + Ubuntu が利用可能になるまでの時間が、ほとんど変わらないのだよな…。それに、WSLはファイルアクセスが体感でも遅い…。現状では、LinuxのGUIアプリをどうしても使いたいなら、VMware + Ubuntu上で使ったほうがいい、ということになるのだろう。

もちろん、単にコマンドラインツールをパッと呼び出して使いたいという需要であれば、WSL(bash)だけならすぐに起動できるので、メリットはあるはず。

#2 [nitijyou] オリンピックの映像ばかりでゲンナリ

ニュースを見たいなとNHKにチャンネルを合わせると十中八九オリンピックの映像しか流れてなくて結構ゲンナリ。しかもコレ、受信料で権利買ってきて流してるはずで。こんなことのために受信料がザブザブ使われている状況は納得がいかない…。民放が流してるならまだしも…。

2018/02/14(水) [n年前の日記]

#1 [ruby][dxruby] DXOpalを試用してみようと思ったらインストールでハマった

DXOpal という、Rubyのソースをブラウザ上で動かせるゲームライブラリがあるのだけれど。

_DXOpal demo
_Rubyist Magazine - Rubyで始めるゲームプログラミング - DXOpal編 -

_以前少し試用した のだけど、現行版はテンプレートの出力ができたり、サーバを起動して動作確認できるようになっているようで。スゴイ。これはなんだか便利そう。

ということで、DXOpal を Windows10 x64 + Ruby mingw版の環境でインストールしてみようとしたものの、ちょっとハマった。

結論だけ先に書くと…。

Windows上でインストールできない。 :

Ruby 2.2.6 p 396 mingw版では、DXOpal をインストールしようとしても、以下のようなエラーが表示される。

> ruby -v
ruby 2.2.6p396 (2016-11-15 revision 56800) [i386-mingw32]

> gem install dxopal
Fetching: sourcemap-0.1.1.gem (100%)
Successfully installed sourcemap-0.1.1
Fetching: hike-1.2.3.gem (100%)
Successfully installed hike-1.2.3
Fetching: opal-0.11.0.gem (100%)
C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:388:in `symlink': symlink() function is unimplemented on this machine (NotImplementedError)
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:388:in `block (2 levels) in extract_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package/tar_reader.rb:65:in `each'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:365:in `block in extract_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:459:in `block in open_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:456:in `wrap'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:456:in `open_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:364:in `extract_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:345:in `block (2 levels) in extract_files'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package/tar_reader.rb:65:in `each'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:342:in `block in extract_files'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package/file_source.rb:30:in `open'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package/file_source.rb:30:in `with_read_io'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:339:in `extract_files'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/installer.rb:772:in `extract_files'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/installer.rb:302:in `install'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/resolver/specification.rb:97:in `install'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/request_set.rb:166:in `block in install'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/request_set.rb:156:in `each'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/request_set.rb:156:in `install'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:205:in `install_gem'

        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:255:in `block in install_gems'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:251:in `each'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:251:in `install_gems'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:158:in `execute'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/command.rb:310:in `invoke_with_build_args'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/command_manager.rb:169:in `process_args'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/command_manager.rb:139:in `run'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/gem_runner.rb:55:in `run'
        from C:/Ruby/Ruby22/bin/gem:21:in `<main>'

opal のインストールで失敗してるように見える。これはアレかな。Windows版の Ruby では使えない、というオチかな…。

Ruby 2.3.3 ではどうだろう。

> uru ls
    187mingw32  : ruby 1.8.7 (2013-06-27 patchlevel 374) [i386-mingw32]
    187mswin32  : ruby 1.8.7 (2010-12-23 patchlevel 330) [i386-mswin32]
    19          : ruby 1.9.3p551 (2014-11-13) [i386-mingw32]
    200         : ruby 2.0.0p648 (2015-12-16) [i386-mingw32]
    21          : ruby 2.1.9p490 (2016-03-30 revision 54437) [i386-mingw32]
    220mswin32  : ruby 2.2.0p0 (2014-12-25 revision 49005) [i386-mswin32_100]
    23          : ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]
    24          : ruby 2.4.3p205 (2017-12-14 revision 61247) [i386-mingw32]
 => system      : ruby 2.2.6p396 (2016-11-15 revision 56800) [i386-mingw32]

> uru 23
---> now using ruby 2.3.3-p222 tagged as `23`

> ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]

> gem install dxopal
Fetching: sourcemap-0.1.1.gem (100%)
Successfully installed sourcemap-0.1.1
Fetching: hike-1.2.3.gem (100%)
Successfully installed hike-1.2.3
Fetching: ast-2.4.0.gem (100%)
Successfully installed ast-2.4.0
Fetching: parser-2.3.3.1.gem (100%)
Successfully installed parser-2.3.3.1
Fetching: opal-0.11.0.gem (100%)
ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ rb_file_s_symlink - (./exe, D:/Ruby/Ruby23/lib/ruby/gems/2.3.0/gems/opal-0.11.0/bin)

Ruby 2.3.3 p222 上でもエラーが出るな…。Ruby 2.2.6 と比べたら、まだスルスルと進んでる気配もあるけれど。

ちなみに、uru というのは、Ruby の異なるバージョンを切り替えて使うことができるツール。

_uru - Windows用のRuby環境セレクター | ソフトアンテナブログ
_pikの替わりにuru〜windowsで複数バージョンのrubyを切り替える〜 - Qiita
_Windows7でRubyのバージョン管理!pikの代わりにuruを使う。 - 思い付くまでタイトル未定

他に、pik というツールを使っても、Rubyのバージョンを切り替えることができる。

_Windows7にRubyInstaller+Pikで複数バージョンのRuby環境を整える - ひろうぃんの雑記

さておき。Ruby 2.4.3 ではどうかな。

> uru 24
---> now using ruby 2.4.3-p205 tagged as `24`

> ruby -v
ruby 2.4.3p205 (2017-12-14 revision 61247) [i386-mingw32]

> gem install dxopal
Fetching: sourcemap-0.1.1.gem (100%)
Successfully installed sourcemap-0.1.1
Fetching: hike-1.2.3.gem (100%)
Successfully installed hike-1.2.3
Fetching: ast-2.4.0.gem (100%)
Successfully installed ast-2.4.0
Fetching: parser-2.3.3.1.gem (100%)
Successfully installed parser-2.3.3.1
Fetching: opal-0.11.0.gem (100%)
ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ rb_file_s_symlink - (./exe, D:/Ruby/Ruby24/lib/ruby/gems/2.4.0/gems/opal-0.11.0/bin)

Ruby 2.3.3 と同様のエラーが出た。

管理者権限でインストールしないといかんらしい。 :

エラーメッセージでググったら以下の記事に遭遇。

_メモ: Sass をWindowsに入れようとしたらgemで怒られたよ - tetsunosukeのnotebook

管理者権限でコマンドプロンプトを開いて、そこで作業すると改善する場合もあるらしい。試してみた。

Ruby 2.2.6 の場合。
> ruby -v
ruby 2.2.6p396 (2016-11-15 revision 56800) [i386-mingw32]

> gem install dxopal
C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:388:in `symlink': symlink() function is unimplemented on this machine (NotImplementedError)
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:388:in `block (2 levels) in extract_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package/tar_reader.rb:65:in `each'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:365:in `block in extract_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:459:in `block in open_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:456:in `wrap'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:456:in `open_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:364:in `extract_tar_gz'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:345:in `block (2 levels) in extract_files'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package/tar_reader.rb:65:in `each'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:342:in `block in extract_files'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package/file_source.rb:30:in `open'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package/file_source.rb:30:in `with_read_io'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/package.rb:339:in `extract_files'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/installer.rb:772:in `extract_files'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/installer.rb:302:in `install'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/resolver/specification.rb:97:in `install'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/request_set.rb:166:in `block in install'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/request_set.rb:156:in `each'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/request_set.rb:156:in `install'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:205:in `install_gem'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:255:in `block in install_gems'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:251:in `each'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:251:in `install_gems'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/commands/install_command.rb:158:in `execute'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/command.rb:310:in `invoke_with_build_args'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/command_manager.rb:169:in `process_args'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/command_manager.rb:139:in `run'
        from C:/Ruby/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/gem_runner.rb:55:in `run'
        from C:/Ruby/Ruby22/bin/gem:21:in `<main>'
相変わらずダメだった。

Ruby 2.3.3 の場合。
> uru 23
---> now using ruby 2.3.3-p222 tagged as `23`

> ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]

> gem install dxopal
Successfully installed opal-0.11.0
Fetching: dxopal-1.1.0.gem (100%)
Successfully installed dxopal-1.1.0
Parsing documentation for opal-0.11.0
unknown encoding name ""+e)" for lib/opal/cli_runners/node_modules/chrome-remote-interface/chrome-remote-interface.js, skipping
Installing ri documentation for opal-0.11.0
Parsing documentation for dxopal-1.1.0
Installing ri documentation for dxopal-1.1.0
Done installing documentation for opal, dxopal after 132 seconds
2 gems installed
妙なメッセージが出てるけど、一応最後まで通ったらしい。

Ruby 2.4.3 の場合。
> uru 24
---> now using ruby 2.4.3-p205 tagged as `24`

> ruby -v
ruby 2.4.3p205 (2017-12-14 revision 61247) [i386-mingw32]

> gem install dxopal
Successfully installed opal-0.11.0
Fetching: thor-0.19.4.gem (100%)
Successfully installed thor-0.19.4
Fetching: rack-2.0.4.gem (100%)
Successfully installed rack-2.0.4
Fetching: dxopal-1.1.0.gem (100%)
Successfully installed dxopal-1.1.0
Parsing documentation for opal-0.11.0
unknown encoding name ""+e)" for lib/opal/cli_runners/node_modules/chrome-remote-interface/chrome-remote-interface.js, skipping
Installing ri documentation for opal-0.11.0
Parsing documentation for thor-0.19.4
Installing ri documentation for thor-0.19.4
Parsing documentation for rack-2.0.4
Installing ri documentation for rack-2.0.4
Parsing documentation for dxopal-1.1.0
Installing ri documentation for dxopal-1.1.0
Done installing documentation for opal, thor, rack, dxopal after 134 seconds
4 gems installed

つまり…。
  • Windows + Ruby 2.2.x では、DXOpal はインストールできない。
  • Windows + Ruby 2.3.x、Ruby 2.4.x は、管理者権限でコマンドプロンプトを開いてインストール作業をすれば、DXOpal がインストールできないこともない。
という状況らしい。

Linux上ではどうかな。 :

VMware + Ubuntu Linux 16.04 LTS 上で試してみた。

$ sudo apt install ruby

$ ruby -v
ruby 2.3.1p112 (2016-04-26) [x86_64-linux-gnu]

$ gem install dxopal
Fetching: sourcemap-0.1.1.gem (100%)
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /var/lib/gems/2.3.0 directory.

$ sudo gem install dxopal
Fetching: sourcemap-0.1.1.gem (100%)
Successfully installed sourcemap-0.1.1
Fetching: hike-1.2.3.gem (100%)
Successfully installed hike-1.2.3
Fetching: ast-2.4.0.gem (100%)
Successfully installed ast-2.4.0
Fetching: parser-2.3.3.1.gem (100%)
Successfully installed parser-2.3.3.1
Fetching: opal-0.11.0.gem (100%)
Successfully installed opal-0.11.0
Fetching: thor-0.19.4.gem (100%)
Successfully installed thor-0.19.4
Fetching: rack-2.0.4.gem (100%)
Successfully installed rack-2.0.4
Fetching: dxopal-1.1.0.gem (100%)
Successfully installed dxopal-1.1.0
Parsing documentation for sourcemap-0.1.1
Installing ri documentation for sourcemap-0.1.1
Parsing documentation for hike-1.2.3
Installing ri documentation for hike-1.2.3
Parsing documentation for ast-2.4.0
Installing ri documentation for ast-2.4.0
Parsing documentation for parser-2.3.3.1
Installing ri documentation for parser-2.3.3.1
Parsing documentation for opal-0.11.0
unknown encoding name ""+e)" for lib/opal/cli_runners/node_modules/chrome-remote-interface/chrome-remote-interface.js, skipping
Installing ri documentation for opal-0.11.0
Parsing documentation for thor-0.19.4
Installing ri documentation for thor-0.19.4
Parsing documentation for rack-2.0.4
Installing ri documentation for rack-2.0.4
Parsing documentation for dxopal-1.1.0
Installing ri documentation for dxopal-1.1.0
Done installing documentation for sourcemap, hike, ast, parser, opal, thor, rack, dxopal after 93 seconds
8 gems installed

こちらも、管理者権限(sudo 〜)で作業すればインストールできるっぽい。

DXOpalを試用。 :

管理者権限のコマンドプロンプトを閉じて、通常のコマンドプロンプトを開いてから、DXOpal を試用。

> pik list
  187: ruby 1.8.7 (2010-12-23 patchlevel 330) [i386-mswin32]
  187: ruby 1.8.7 (2013-06-27 patchlevel 374) [i386-mingw32]
  193: ruby 1.9.3p551 (2014-11-13) [i386-mingw32]
  200: ruby 2.0.0p648 (2015-12-16) [i386-mingw32]
  219: ruby 2.1.9p490 (2016-03-30 revision 54437) [i386-mingw32]
  220: ruby 2.2.0p0 (2014-12-25 revision 49005) [i386-mswin32_100]
* 226: ruby 2.2.6p396 (2016-11-15 revision 56800) [i386-mingw32]
  233: ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]
  243: ruby 2.4.3p205 (2017-12-14 revision 61247) [i386-mingw32]

> pik 233

> ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]

> mkdir dxopal_test01
> cd dxopal_test01

> dxopal init
DXOpal v1.1.0
Wrote index.html
Wrote main.rb
Wrote dxopal.min.js

> dxopal server
DXOpal v1.1.0
Starting DXOpal Server
(Open http://localhost:7521/index.html in the browser)
---
[2018-02-14 19:48:56] INFO  WEBrick 1.3.1
[2018-02-14 19:48:56] INFO  ruby 2.3.3 (2016-11-21) [i386-mingw32]
[2018-02-14 19:48:56] INFO  WEBrick::HTTPServer#start: pid=10272 port=7521

_http://localhost:7521/index.html をFirefoxで開いたら、「Hello!」の文字と画面が出た。動いてるっぽい。

#2 [dxruby][ruby] DXOpalで画像のアニメーション

DXOpal で画像のアニメーションってどうやればいいのかなと悩んだけど。 _Image#slice_tiles_DXOpalでも実装されてる ので、それを使えばいいらしい。とメモ。

一応サンプルも書いてみた。

_Image#slice_tiles demo

ソースが表示されてるあたりは、 _dxopal/examples at master - yhara/dxopal を参考にさせてもらいました。Webページ内でエディタが使えるようになる、 _Ace というJavaScriptライブラリがあるのですな…。勉強になった…。

2018/02/15(木) [n年前の日記]

#1 [dxruby] DXOpalのWindow.draw_scaleについて動作確認

_Module: DXOpal::Window - Documentation を眺めてたら、拡大縮小描画が可能になる、Window.draw_scale() があることに気づいて、喜びつつ動作確認。以前試した時は、拡大縮小描画はサポートされてなかった記憶があるわけで。

ということで、こんな感じに。

_DXOpal Window.draw_scale()の動作確認

ちゃんと拡大縮小描画ができてる。素晴らしい。

ということは、こういうこともできるかな…。

_DXOpal Sprite.scaleの動作確認

一応できたけど…ちょっとハマった。最初、なんだか妙な位置に描画されてしまって。

DXRuby には、 _Sprite#offset_sync があって、true にすると、拡大縮小回転の中心位置を原点として扱ってくれる。

_mieki256's diary - DXRubyのSpriteのアタリ範囲について

その感覚でソースを書いてしまったものだから、妙な位置に表示されてしまったという…。

DXOpal はそのあたり未実装っぽいので、自分で表示位置を補正してやらないといけない。と言っても、DXRuby もデフォルトでは offset_sync が false だし、DXRuby 1.4.1 から追加された機能なのでアレだけど。

#2 [anime] 「Re:ゼロから始める異世界生活」最終回を視聴

録画したまま見れてなかったけど、ようやく視聴。

面白かった…。これは話題になるわけだなあ。

ただ、原作既読組のつぶやきによると、アニメ版のラストの直後に、かなり衝撃的なたった一言の台詞が本来ならあったそうで。いや、ホントかどうかは分からんけど、たしかにその台詞が納得できる伏線も張ってあったし…。コレがもし、例えばコードギアスのスタッフさん達の手によるアニメだったら、その台詞は絶対入れてたよなー、間違いなく入れてたなー、などと想像したりもするのだけど。このアニメ版スタッフは、あえてその台詞を入れなかったのだなと…。一期の制作で疲労困憊して、「もう続きは作りたくねえ…」「続きを作れないならこの台詞は入れるべきじゃねえ。無責任だ」とでも判断したのか、それとも、あからさまに続きがあります的な見せ方は好みじゃない監督さんやPがたまたま揃ったのか…。それとも原作者の意向なのか…。何にせよ個人的には、その台詞を入れないところに、何か強い意志・ポリシーがありそうな気もしたわけで。

何にせよ、面白かったです。以前も書いたけど、ゲーム的な設定を取り込んで、更に昇華させてるあたりが素晴らしい。

2018/02/16(金) [n年前の日記]

#1 [dxruby] DXRubyのWindow.draw_tile()を再勉強中

DXOpalでタイルマップのBG描画をしてみたいなと思ったのだけど、DXOpal には Window.draw_tile() が無くて。似たような処理を書かないとダメかなと、DXRuby を使って処理を書いて試しているところ。

一応書けたのだけど、DXOpal に持っていったら、これがなかなか厳しい。マップデータを .rb の形に変換して、それを読み込んで使うようにしてみたのだけど、実際に画面が描画されるまで数分待たされる…。Google Chrome なら数分待てば画面が出てくるけれど、Firefoxに至っては、「このスクリプトは応答が無いけど、どうする? 停止させる?」と尋ねてくる始末。どうも変数の初期化で時間がかかってるようだなと…。Rubyソースの形で大量のデータをずらずらと書くのはマズいらしい…。

そもそも、マップデータは Tiled からエクスポートした json を読み込んで .rb に変換してるわけで。であれば、わざわざ .rb の形に変換などせずに、最初から json を読み込んで使えばいいのではないか。以下の記事によると、Opal では jsonライブラリが用意されているようでもあるし。

_Opalの標準添付ライブラリ - Qiita

などと思いついたものの、これまた DXOpal で動かすと、json の読み込みでエラーが出ているようで。Ruby + DXRuby ならスンナリ読み込めるし、parse もできてるのだけどな…。何がいかんのやら…。

2018/02/17() [n年前の日記]

#1 [dxruby] DXOpalでタイルマップBGを描画

_DXOpal で、どうにかタイルマップBGを描画することができた。

_DXOpal fake draw_tile test

マップデータは、 _Tiled マップエディタ 1.0.3 で作成して、json形式でエクスポートして用意した。

Rubyソース内にマップデータをずらずらと書いた場合は、初期化でめちゃくちゃ時間がかかったけど、jsonを読む形にしたら圧倒的に速く初期化が終わるようになった。

しかし…。予想はしていたけど、めちゃくちゃ描画が遅い。

640x480のウインドウサイズで、16x16ドットのタイルチップを使ったBGを、4枚表示してる状態だけど…。DXRuby なら 60FPS で動くけれど、DXOpal では10FPSも出ない。ちなみに自分の環境は、CPU : Core i5-2500 (3.3GHz、4コア)、ビデオカード : NVIDIA GeForce GTX 750 Ti。

考えてみたら、空白部分は描画してないとはいえ、最多では ((640 / 16) + 1) * ((480 / 16) + 1) * 4 = 5084個もタイルチップを描画するのだから、そりゃ遅いよな…。しかし、試しにBGを2枚に減らしてみても、それでも遅くて。タイルチップのサイズを16x16にしてるあたりで、どうしても枚数・個数が増えてしまうわけで…。

以下、ハマった点をメモ。

外部ファイルの読み込みができない。 :

DXRuby上ではスンナリ動いたのに、DXOpalではエラーが出て首を捻ってたけど。どうやら、DXOpal は外部テキストファイルを簡単に読み込めないようで。

例えば、ローカルで動かしてる Ruby上なら、以下のような形でテキストファイルが読み込めるけど。
text = File.open("data.txt") {|f| f.read }

DXOpal は、できない。考えてみれば、ブラウザ + JavaScript で動かしているのだから、サーバ上のファイルは読み込めても、HDDに入ってるローカルファイルを読み込めちゃったらマズいよなと。

なので、以下のような書き方をして、外部テキストファイルを読み込んでみたり。

_DXOpal file read test

  url = 'data.txt'
  req = Native(`new XMLHttpRequest()`)
  req.overrideMimeType("text/plain")
  req.open("GET", url, false)
  req.send
  text_data = req.responseText

何をしているかというと…。Native() を使ってJavaScriptの関数を直接呼んでどうにかしてる、という…。 _dxopal/dxopal.rb の require_remote() を参考にして、たぶんこうかな、と。JavaScript、全然分かんないけど…。

加えて、以下の記事が大変参考になりました。ありがたや。

_OpalでJavaScriptのAPIラッパーを作る - Qiita
_OpalのNativeはどのように実装されているのか - Qiita

「%x{ 〜 } って何だろう?」と首を捻ってたけど、その中に JavaScript を直接書けるのですな…。

jsonのparseができない。 :

Opal は jsonライブラリも用意されてるらしいので、外部テキストファイルが読み込めたら後は楽勝だろう、と思ったら、「JSONが初期化できねえ」と怒られ続けて。

結局、以下のような書き方に。

_DXOpal json parse test

  url = 'data.json'
  req = Native(`new XMLHttpRequest()`)
  req.overrideMimeType("text/plain")
  req.open("GET", url, false)
  req.send
  text_data = req.responseText
  data = Native(`JSON.parse(text_data)`)

これまた、Native() を使って JavaScriptの JSON.parse() を直接呼び出しているという…。いいのかコレで。まあ、動いてるから、いいか…。

DXRuby版。 :

せっかくだから、一応、DXRuby版もメモ。まあ、DXRuby の場合、Window.draw_tile() を使えばタイルマップBG描画はできてしまうのだけど。

_disp_map_load_json.rb
# Tiledからエクスポートしたjsonを読み込んでDXRubyで描画する

# require 'dxopal'
# include DXOpal

require 'dxruby'
require 'json'

# Image.register(:bgchip, 'images/bg_attari.png')

# DXOpal
def json_to_hash_dxopal(url)
  req = Native(`new XMLHttpRequest()`)
  req.overrideMimeType("text/plain")
  req.open("GET", url, false)
  req.send
  text_data = req.responseText
  return Native(`JSON.parse(text_data)`)
end

# DXRuby
def json_to_hash_dxruby(url)
  json_text = File.open(url) {|f| f.read }
  return JSON.load(json_text)
end

def get_map_data_from_json(json_file)
  # res = json_to_hash_dxopal(json_file)
  res = json_to_hash_dxruby(json_file)

  d = {}
  d[:tilewidth] = res["tilewidth"]
  d[:tileheight] = res["tileheight"]
  d[:width] = res["width"]
  d[:height] = res["height"]

  layers = {}
  res["layers"].each do |layer|
    name = layer["name"]
    w = layer["width"]
    h = layer["height"]
    org_data = layer["data"]
    layers[name] = Array.new(h){ Array.new(w) }
    h.times do |y|
      w.times do |x|
        code = org_data[y * w + x] - 1
        layers[name][y][x] = (code < 0)? nil : code
      end
    end
  end
  d[:layers] = layers

  return d
end

def draw_tile(x, y, map_array, imgs, start_x, start_y, x_cnt, y_cnt)
  ofs_x = x
  ofs_y = y
  tile_w = imgs[0].width
  tile_h = imgs[0].height
  bg_h = map_array.length
  bg_w = map_array[0].length
  start_x = start_x % (tile_w * bg_w)
  start_y = start_y % (tile_h * bg_h)
  x_mod = (start_x % tile_w).to_i
  y_mod = (start_y % tile_h).to_i
  x_index = (start_x / tile_w).to_i
  y_index = (start_y / tile_h).to_i
  y_cnt.times do |y|
    x_cnt.times do |x|
      ix = (x_index + x).to_i % bg_w
      iy = (y_index + y).to_i % bg_h
      code = map_array[iy][ix]
      next if code.nil?
      px = ofs_x + (x * tile_w) - x_mod
      py = ofs_y + (y * tile_h) - y_mod
      Window.draw(px, py, imgs[code])
    end
  end
end

def game_main(img)
  imgs = img.slice_tiles(img.width / 16, img.height / 16)

  # mapdata = get_map_data_from_json("mapdata/bg_atari_test.json")
  mapdata = get_map_data_from_json("bg_atari_test.json")
  x_cnt = Window.width / mapdata[:tilewidth] + 1
  y_cnt = Window.height / mapdata[:tileheight] + 1
  bg_x, bg_y = 0, 0
  ofs_x, ofs_y = 0, 0

  Window.bgcolor = [32, 64, 128]

  Window.loop do
    break if Input.keyPush?(K_ESCAPE)

    if false
      a = 8
      bg_x -= a if Input.keyDown?(K_LEFT)
      bg_x += a if Input.keyDown?(K_RIGHT)
      bg_y -= a if Input.keyDown?(K_UP)
      bg_y += a if Input.keyDown?(K_DOWN)
    else
      bg_x += 3
      bg_y += 1
    end

    layer_names = ["layer3", "layer2", "layer1", "layer0"]
    spd = 0.25
    layer_names.each do |name|
      x = bg_x * spd
      y = bg_y * spd
      map_data = mapdata[:layers][name]

      # Window.draw_tile(ofs_x, ofs_y, map_data, imgs, x, y, x_cnt, y_cnt)
      draw_tile(ofs_x, ofs_y, map_data, imgs, x, y, x_cnt, y_cnt)

      spd += 0.25
    end

    Window.draw_font(2, 2, "#{Window.real_fps} FPS", Font.default)
    Window.draw_font(2, 32, "bg x,y = #{bg_x}, #{bg_y}", Font.default)
  end
end

# Window.load_resources do
img = Image.load("bg_attari.png")
# img = Image[:bgchip]
game_main(img)
# end

Tiled データ(.png / .tmx)と、エクスポートした json は、zipにして以下に置いときます。License : CC0 / Public Domain ってことで。

_bg_atari_test.zip

2018/02/18() [n年前の日記]

#1 [dxruby] DXOpalでタイルマップBG描画その2

昨日、DXOpalで試したタイルマップBGの描画は、処理が重くて10FPSも出なかったのだけど。16x16ドットのタイルチップじゃなくて、64x64ドットのタイルチップを使ったらどうなるかなと疑問が湧いたので試してみたり。

_ DXOpal fake draw_tile 3 (chip : 64x64 ver.)

手元の環境では、60FPSが出てくれた。

ということで、タイルチップ1枚あたりのサイズを大きくして、描画枚数・描画個数を減らせば、まだどうにかなるっぽい。もっとも、非力なPC + ブラウザ上では、どんな結果になるのか分からんけど…。

利用・作成した Tiled のマップデータは以下。License : CC0 / Public Domain ってことで。

_scifi_bg.tmx
_scifi_bg_chip.png
_scifi_bg.json

ちなみに、背景色を変更することで、BG内の一部が点滅表示してるように見せかける処理も入れてみたり。

色指定時に与える数値の範囲について。 :

背景色の、Window.bgcolor = [R, G, B} を指定した際に気づいたのだけど、実数を与える場合と、整数を与える場合で、範囲が変わるようだなと。
  • R, G, B が実数なら、与える範囲は 0.0 - 1.0
  • R, G, B が整数なら、与える範囲は 0 - 255

ちなみに Ruby の場合、数値が入った変数.to_i とすれば整数に変換できる…はず。
    bgcol = 255 * (Math.sin(count * Math::PI / 180.0)).abs  # 実数
    Window.bgcolor = [bgcol.to_i, 0, 0]  # 整数に変換して背景色を指定

#2 [nitijyou] 日記をアップロード

2018/02/01から日記をアップロードしてなかったので、少しずつアップロード。

2018/02/19(月) [n年前の日記]

#1 [dxruby] DXOpalでタイルマップBG描画その3

DXOpal で、1チップ 64x64 ドットのタイルマップBGを描画した場合は 60FPSが出たのだけど。32x32ドットのタイルチップならどうなるのか気になったので試したり。

ちなみに、 _以前作成したlove2d用のサンプル のマップデータが、1チップ 32x32ドットだったので、ソレを使用。

_DXOpal fake draw_tile (1 chip : 32x32 ver.)

640x480のウインドウサイズ、1チップ 32x32ドット、レイヤーは2枚の状態だけど。なんだかビミョーな結果になった。ちなみに OSは Windows10 x64。

browserCPU usage (%)60FPS
Firefox ESR 52.6.0 x6422 - 27failure
Google Chrome 64.0.3282.167 x6413 - 18success
Microsoft Edge 41.16299.248.013 - 19success
Vivaldi 1.14.1077.50 x8613 - 18success

Firefox ESR だけは、CPUを1コア使い切ってしまって、60FPSが出ない。タスクマネージャで確認すると、4コアCPU上でCPU使用率が25%を超えてるから、おそらく1コアを使い切ってる。

つまり、Firefox を使うと、1チップが 32x32ドットのタイルマップBGは、手元の環境でも処理が重過ぎて、60FPSで描画できない模様。

1チップ 64x64ドットにすれば改善するけど、それはそれで、ちょっと大き過ぎるのだよなあ。48x48 なら、どうなるのだろう…。

Tiledのエクスポートしたjsonについて。 :

昨日までは、Tiled上で、タイルレイヤーのみを使うマップデータを作成して使っていたけど。love2d のサンプルで使ったマップデータはオブジェクトレイヤーも含んでいたので、そのまま読み込むとエラーが出て、ちょっとハマった。

各レイヤーは、「"type" : "tilelayer"」といった具合に、そのレイヤーの種類を示す情報も持っているので、レイヤー群を順々に調べていく時に、タイルレイヤー以外は見ないようにしておく必要がある。とメモ。
  res["layers"].each do |layer|

    next if layer["type"] != "tilelayer"
    # ...
もちろん、実際のゲーム制作では、敵セットテーブルや地形アタリの指定等をするために、えてしてオブジェクトレイヤー情報も使うことになるだろうけど…。

#2 [anime][neta] スペースオペラ版「鬼平」ってどうだろう

BS JAPANで、アニメ版「鬼平」が放送されてるので見ているのだけど。非常に興味深いアニメだなと…。

自分、時代劇は見るのがちょっとツラくてアレな人なのだけど。そんな時代劇もアニメになればフツーに面白く感じられるものだなと、毎回感心しながら視聴していたりして。

まず、テンポが良い。時代劇は、通常なら1時間枠で放送されるけど、アニメ版は30分番組のせいか、内容が凝縮されていてテンポが速く、見ていて飽きないなと。

そういえば、自分、サンダーバードオリジナル版を見てると途中で眠くなってくるけど、リメイク版サンダーバードは面白く見れたわけで。アレも30分番組になったことで、テンポが速くなってたよなと。アニメ版「鬼平」も、それと近い状態になっている気がする。

また、実写と比べて、アニメ特有の見せ方ができるあたりも好印象。例えば、剣を振った時に残像を透過光で見せたり、走る時もアニメならではのあり得ない速度で走れたり等、色々とイメージ優先のカッコイイ見せ方ができるわけで。

これがもし、人間の役者に全力疾走させたとしたら、なんだかドタバタしてる感じしか伝わらず、「俊足」とは言えない感じがしてくるし。殺陣のシーンも、実写は型が出来てしまっているから、あまり魅力的に感じないわけで。

更に、基本的には人情話になっている点もイイなと。結構真面目な気持ちで、「いい話だなあ」とつぶやけるわけで…。

などと考えてるうちに、ふと、時代劇をスペースオペラにしたら海外でもウケないだろうかと妄想を。

ライトセーバーをブンブン振り回して宇宙の治安を守る、オニ・ヘイ。とか。「ピーププープピー(旦那、大変だ大変だ)」と駆け込んでくるR2-D2モドキ。とか。ダメか…。

基本的に一話完結だから、視聴者も途中参加がしやすいだろうし。人情云々は海外でもイケると思うんだけどな…。

タイトルは変えてほしいよなと。 :

しかし、仮に時代劇を原作として、海外向けに制作するとしても、タイトルは変えてほしいよなと。だって、海外に向けて「ONI」と言っても意味が分からんだろうし。

例えば、中国アニメの「一人之下」も、日本人はタイトルを見て「? どういう意味よ?」となってしまうわけで。同様に「ONI」も、英語圏の人が見たら「What? I don't understand.」になるのではないかと。であれば、そこは意訳をせねばなるまい…。

日本における、「アイツはまるで鬼だ」という言い方は、英語圏ではどういう言い方になるんだろう。悪魔のようだ、みたいな言い方になるのだろうか。だとしたら、デビルなんとか、みたいなタイトルに…? 本編内の犯罪者からはデビルと呼ばれてるけど、視聴者にとってはエンジェルにしか見えないおっさんキャラ。みたいな。

「長谷川平蔵」という名前も、アメリカ人っぽく変えないと…。「平蔵」に相当する英語圏の名前って、何になるんだろう…。おそらくは、珍しい名前ではなく、よく見かける名前、なのではないかなあ。

でもまあ、キャラだけを見たら、アメコミキャラで既に居そうだよな。そういうの。

2018/02/20(火) [n年前の日記]

#1 [dxruby] DXOpalでタイルマップBG描画その4

DXOpalを使って、タイルマップBGを描画する実験をしているわけだけど。32x32ドットの時は Firefox ESR 上で60FPSを出せなかったけど、少しサイズを大きくして、48x48 にしたらどうなるだろうかと疑問が湧いたので試してみたり。

_DXOpal fake draw_tile (1chip: 48x48 ver.)

640x480ドットのウインドウサイズ、レイヤーを3枚描画してる状態。カーソルキーの入力で、任意の方向にスクロールできるようにしてある。

Firefox ESR上では…。ちょっと危ないけど、なんとか60FPS出てる…ように見えなくもない…かな…。ただ、CPU使用率は20%前後をウロウロしてるので、もう少し何かしらの処理を追加したら、すぐに処理落ちしそうな予感もあるのだけれど。

ちなみに、 Google Chrome で動かすと、CPU使用率は13%前後。

Tiled のデータも置いときます。License : CC0 / Public Domain ってことで。

_atari_test_48x48_chip.png
_atari_test_48x48.tmx
_atari_test_48x48.json

余談。 :

jsonファイルを読み込んで、DXRuby の Window.draw_tile() で使える形に変換するあたりは、クラスにして別ファイルに分けてみたり。

また、アレコレ動作確認する際に、サイズの違うタイルマップデータをファイルコピーして作業するのが面倒になってきたので、全部のマップデータを置いといて、スクリプト実行時に数値を指定すれば利用するマップデータも変えられるようにしてみたり。

マップデータは、以下で一覧が見れる…だろうか…。全部、License : CC0 / Public Domain ってことで。

_mapdata/

#2 [dxruby][ruby] RubyスクリプトがOpal上で動いてるかどうかを判別する方法ってあるのかな

今現在、DXRuby と DXOpal の両方で、最低限の修正で動くようなスクリプトソースを書いているつもりではあるのだけれど。そのRubyスクリプトソースが、Opal(DXOpal)上で動いているのか、ローカル(DXRuby)で動いてるかを判別する方法があれば、一々ソースを修正して動かさなくても済みそうだなと思えてきたわけで。

しかし、そんな方法はあるのだろうか…。

require 'opal' がされてるかどうかを判別できればいいのかな? でも、どうやって判別すればいいのだろう。もしかして、名前が定義されているかどうかを調べればいいのだろうか。

ググってみたものの、検索キーワードがマズいのか、それらしい情報には遭遇せず。Ruby で、「既に require 'hoge' されてるか調べる」ってのは、どうやるんだろうなあ…。

2018/03/01追記。 :

コメント欄でDXOpal作者様から判別方法を教えていただけました。ありがとうございます。助かります。

if RUBY_ENGINE == "opal"
  # DXOpal
else
  # DXRuby
end
または、
if RUBY_ENGINE == "ruby"
  # DXRuby
else
  # DXOpal
end
こんな感じかしら。

動作確認してみたけれど、ちゃんと動いてる模様。一々ファイルを修正しなくても動作確認ができるので、かなり楽になりそう。ありがたや…。

_constant Object::RUBY_ENGINE (Ruby 2.5.0)
RUBY_ENGINE -> String
Ruby処理系実装の種類を表す文字列。

constant Object::RUBY_ENGINE (Ruby 2.5.0) より

こんな定数があったのか…。勉強になった…。

この記事へのツッコミ

Re: RubyスクリプトがOpal上で動いてるかどうかを判別する方法ってあるのかな by yhara    2018/02/22 18:19
RUBY_ENGINE == "opal" でいけますね (CRubyだと"ruby"になります)。

#3 [javascript] ACEエディタを複数並べるあたりで悩んだり

JavaScriptで書かれた ACEエディタというものがあると先日知ってちょこちょこ使い始めているのだけど、複数のソースを並べて表示させる方法が分からなくて悩んだり。

今のところ、以下のような書き方をしちゃってるけど…。これでいいのだろうか…。本当に合ってるのか…? もっと上手い書き方があるのでは…?
  <h2>Source code</h2>

  <h3><a href="main.rb">main.rb</a></h3>
  <div id="editor1" class="editor"></div>

  <h3><a href="dxrbmapjson.rb">dxrbmapjson.rb</a></h3>
  <div id="editor2" class="editor"></div>

  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.3.1/ace.js" charset="utf-8"></script>

  <script>
    var file_list = [{
        id: "editor1",
        filename: "main.rb"
      },
      {
        id: "editor2",
        filename: "dxrbmapjson.rb"
      }
    ];
    var editors = (file_list).map(function(file_info) {
      var id = file_info["id"];
      var filename = file_info["filename"];
      var editor = new ace.edit(id);
      // editor.setTheme("ace/theme/chrome");
      editor.getSession().setMode("ace/mode/ruby");
      // editor.setFontSize(16);
      $.get(filename, function(rb) {
        editor.setValue(rb, -1); // -1: set cursor to document start
      });
      return editor;
    });
  </script>

2018/02/21(水) [n年前の日記]

#1 [dxruby][ruby] BGアタリ処理を書いてるところ

せっかく DXOpal でタイルマップBG描画ができたのだから、地形とのアタリ判定もしてみたいところだなと。もっとも、只の四角が敷き詰められてるBGなら、アタリ判定も楽だけど、先日作成したタイルマップは、坂も用意してる地形だったりするから、それに対応した処理を書かないといけない。

ということで、昔 DXRuby用に書いたスクリプトソースを探してきて修正しているところ。

しかし、以前書いたソレを眺めてるうちに、ちょっと修正したくなってきて。

以前は、実行するたびにタイルチップ画像を一つ一つスキャンして、アタリ判定用データを作っていたけれど。考えてみたら毎回起動時にやることでもないよなと。事前に何かのツールを通してアタリ判定用データを別途作って、それを読み込んで処理するほうが妥当だろう…。そのようにしておけば、アタリ判定処理自体は、DXRuby以外の何かしらでも使えるようになるだろうし。

などと思えてきたので、それ用のツールスクリプトを書き始めてしまったり。とりあえず json でアタリ判定用データを出力する方向で…。

#2 [ruby] Rubyで使える画像処理ライブラリは無いのだろうか

DXRuby を利用して、画像を読み込んでスキャンするスクリプトを書いているところなのだけど。昨今の状況を鑑みるに、DXRuby でその手の処理を書くのはどうなんだろうと思えてきたりもして。

現状の DXRuby には、以下の問題があって…。 なので、ツールの類に使うのはどうなんだろうと。そこは環境を選ばない何かを使ったほうが良くないか…。

しかし、Rubyで使える画像処理ライブラリが思いつかない。これが Python なら PIL (Pillow) を入れれば済んでしまうのだけど。

一般的には _RMagick だろうけど、Windows上でのインストールは鬼門で、ImageMagick のバージョンを決め打ちしないとインストールできなかったりするから避けたいなと。

_mini_magick は…。Windows上でインストールできるのかな…。

png画像だけを扱うことにすれば、 _chunky_png を使う手もあるか…。使い方がちょっと分からんけど。いや。 _昔ちょっとだけさわったことがあるな…。 試しにコレで処理してみよう…。

#3 [dxruby][ruby] Rubyはどうなってしまうのだろう

思考メモ。

個人的には、Ruby 2.4 以降に対応したDXRubyが公開されないあたりで、Rubyの今後をちょっと心配していたりもして。…DXRubyの今後じゃなくて、Rubyの今後。

ここ数ヶ月、DXRuby作者様が困っておられるわけで。

_mirichiさんのツイート: "ところでDXRubyは現在VCでビルドしたやつがRubyInstaller2の...
ところでDXRubyは現在VCでビルドしたやつがRubyInstaller2のRubyで使えなくて困っている状態なんだけども、MSYS2でビルドするとダイナミックリンクになってD3DX(標準でWindowsに入ってない)の配布が問題になるんよね。つくづく困った。

mirichiさんのツイート より


困りましたな…。Rubyで使える2Dゲームライブラリは、Rubyのバージョンアップから次々に振り落とされて、軒並み壊滅状態だけど、とうとうDXRubyまで…なのだろうか…。 *1

LinuxやMacに比べれば、おそらくは圧倒的にユーザ数が多いのであろうWindowsユーザに対し、「Rubyでゲームも作れるよ」とオススメしつつとりあえずちょびっとでもRubyを触ってもらうキッカケになる、という点で、DXRuby の存在は結構大きいのではないのかなと個人的には想像していて。逆に、今後 DXRuby が比較的新しい Ruby では使えないことになると、WindowsユーザをRubyへと誘導できる入口が一つ消滅してしまうから、Rubyコミュニティへの新人の流入数が減り、結果、一部のお爺さん達しか使わない言語になっちゃう…可能性だってあるかもしれないよなと危惧したりもするわけで。

昔、 _Ruby作者様がHSPをdisってた ことがあるけれど。当時のHSPで出来ていたことの、ある程度の部分は、Ruby + DXRuby でも出来るようになったから、「わざわざHSPを使わなくてもいいよ!」「それRubyでできるよ!」と言えるぐらいに状況は改善したと言えるわけで。しかし、ここにきて、また昔に ―― 「どうしてHSPなんか使うの?」「は? だってコレRubyでできないじゃん」と言われちゃう時代に逆戻りなのだろうか…。Ruby作者様がプログラムコンテストの類に呼ばれてみたらまたしてもHSP製のアプリがずらりと並んでいてゲンナリする状況に戻ってしまうのだろうか。みたいな。

てなことを考えてしまったりもするので、個人的には DXOpal に期待しているところがあったりするのでした。「それブラウザ + Ruby + DXOpal でできるよ!」と言える状況が実現したら、結構改善するところがあるのだろうなと。何より、ブラウザ上でRubyで書いた何かしらが動くと言うのは大変魅力的なわけで。enchant.js あたりと似たようなプレゼンが出来て、見る側にとっては負担が減るわけだから。ローカルに一々DLしてRubyをインストールして動作確認しなくても、ブラウザで該当ページを開くだけで結果が見れると言うのは大きい…。

でもまあ、Ruby + Gosu を使って誘導する手もあるのかな…。

更に、Ruby に拘らなければ、Lua + love2d を使うとか、そもそもその手のゲームを作るなら JavaScript で、という選択肢も…。要は、プログラミングって面白いよと分かってもらえるなら、何を使ってもいいわけだし。とはいえ、DXRuby のシンプルさと機能性のバランスって、群を抜いてるように思えるわけで。

そもそも、各言語への誘導を促すための何か、プログラミング自体に親しむ何か、ゲームを作るための何か、それぞれの正解は違う、かもしれないのかな。うーん。

まあ、思考メモです。
*1: 少し解説すると、Windows版 Ruby は _RubyInstaller for Windows がメジャー?なのだけど。Ruby 2.4 から MSYS2 を使ってビルドするように変更されたので、色々問題が。そもそも RubyInstaller も、おそらくは元々の作者さんが、「俺はもう Ruby なんて使ってないんだよね。だけどビルドが通るように修正するだけでも時間取られるんだわ。こんなんやってられませんわ」 _みたいなこと になって一度は見捨てられて、後を引き継いだ方が MSYS2 を使って、という流れだから Windows 上で動く Ruby 2.4 が公開されてるだけでもありがたいという…。

#4 [nitijyou] 電動自転車の前輪タイヤとサドルを交換

親父さんが自転車屋さんまで持っていって交換してくれた。詳細はGRPでメモ。

2018/02/22(木) [n年前の日記]

#1 [dxruby] DXOpalで地形アタリ処理ができた

DXOpal上で、地形アタリ処理(地形衝突判定、コリジョン処理)ができたような気がする。

_DXOpal tilemap collision

ここまでできれば、後はプレイヤーキャラの移動処理等を入れていけば、一見それらしくなるはず。

やってることは…。
どういう形で補正用データを持つかは、昔書き残した日記が参考になりそうなので発掘してメモ。異様に読みづらいけど…。

_mieki256's diary - とりあえずBGマップを表示するべく作業中
_mieki256's diary - 地形アタリの実験中
_mieki256's diary - DXRubyでtmxファイルを使ってBG表示

今後は以下を再現してみる予定。

_mieki256's diary - DXRubyで地形アタリを取りながらプレイヤーキャラの移動
_mieki256's diary - DXRubyで地形アタリを取りながらプレイヤーキャラの移動その2
_mieki256's diary - DXRubyで地形アタリを取りながらプレイヤーキャラの移動その3ひとまず完結編

さておき。DXOpalについて、また少し分かってきたことをメモ。

K_LSHIFTやK_LCONTROLが無い。 :

最初、Shiftキー + カーソルキーの処理を書いたら、DXOpal に、「K_LSHIFT? そんな名前は知らねえ」と言われてしまって。どうやら DXOpal は、ShiftキーやCtrlキーが押されたかどうかを調べられないようにしてあるみたいだなと。

_dxopal/key_codes.rb at master - yhara/dxopal

おそらくは上記のソースが、キーの定義部分だろうけど。わざわざ K_LSHIFT や K_LCONTROL をコメントアウトして殺してあるようで。何か不具合でもあるのだろう…。

描画時のZ値が正しく反映されないときがあるかもしれない。 :

処理をした順に上書き描画していく、という素直な(?)書き方なら問題は出ないようだけど。描画時にZ値を指定することで、手前に描画するか奥に描画するかを変更しようとすると、稀に正しく描画されないときがあるようで。

しかし、発生条件が分からない。正しく描画できてる箇所もあれば、奥に隠れちゃう箇所もあって…。

何にせよ、処理した順に奥から手前へと描かれるのだ、てな前提で書いといたほうが良さそうかも。

ちなみに、DXRuby はz値が小さいほうが奥に描画される仕様のはず。

_3.1 Windowモジュール
_DXRuby Sprite#z=

#2 [nitijyou] ネズミ対策で困っていたり

ここ数日、どんなネズミ対策をするかで、家族が喧々諤々状態で。というのも、妹の車のエンジンのコードがネズミにかじられて、エンジンがかからなくなる事件が発生したからで。今までも、壁の中を走り回ってうるさかったり、犬の餌を盗んで食べたりしていたけれど、さすがに車を壊すところまで来ると、もはや放置しておくわけにもいかず。しかし、どんな対策をすればよいのやら。とりあえず、昨日ホーマックで、金網タイプのネズミ捕りを購入してきたのだけど…。詳細はGRPでメモ。

ちなみに、妹が餌として干し芋を使ったら1時間も経たずに以下略。

ペットボトルやバケツでも作れるらしい。 :

ネズミ捕りを自作できるかどうかが気になってググってみたら、ペットボトルやバケツで作る事例が動画で紹介されていて。なんだか工作意欲がちょっとムクムクと。ダンボールで作れないかな。いや。紙製では齧られて脱走されてしまうか。

喧々諤々。 :

うっかり書いてしまったけど、喧々諤々って誤用なのですな…。

_喧々諤々とは - 日本語表現辞典 Weblio辞書
「喧々囂々(けんけんごうごう)」と「侃々諤々(かんかんがくがく)」という別々の言葉が混ざった誤った表現。実際に使われる場合には、「多くの人が集まってうるさく議論する」といった意味で使われることが多い。

喧々諤々とは - 日本語表現辞典 Weblio辞書 より


恥ずかしながら知らなかった。

2018/02/23(金) [n年前の日記]

#1 [windows] Windows10のフォトでB4印刷をするのはどうしたらいいのだろう

親父さんは、Canon PIXUS PRO-100S という、A3対応のプリンタを持っているのだけど。「B4印刷ができないんだが」と相談が。

Windows10 のフォトで画像を開いて、右上のプリンタのアイコンをクリックすれば印刷設定が出てくるけれど、そこでプリンタ(Canon PRO-100S)を選んで用紙をB4にしても、「別のプリンター設定と競合するため、JIS B4は変更されました」とメッセージが表示されて違う用紙サイズが勝手に選ばれてしまう。

仕方なく、IrfanView で画像を開いて印刷してもらったけど…。IrfanView なら、ファイル → 印刷 → プリンタの設定、で、用紙その他を設定するウインドウが開くので B4 を選べる。

そもそも Canon PIXUS PRO-100S は、「標準印刷」「写真印刷」等の、大別した設定項目を選ぶことが可能で。しかし、「写真印刷」が選ばれていると、A4、A3等は選べるものの、B4、B5等は選ぶことができなくなる。「標準印刷」を選べば、B4等を選べるようになるけれど…。Windows10 のフォトには、該当画面を出すためのボタンやリンクが無い模様。

となると…。 こんな感じで選ばないといけない。どう考えても馬鹿げている…。

エクスプローラ上で右クリックしても印刷できるっぽい。 :

興味深い記事に遭遇。

_アプリフォトで印刷する場合のプリンタープロパティの表示方法 - マイクロソフト コミュニティ
_Windows 10でWindowsの印刷機能を使用して写真や画像を印刷する方法 - 121ware.com Q&A番号 018567

エクスプローラ上で画像を右クリック → 印刷、を選ぶと、Windows10のフォトと違って、プリンターのプロパティを呼び出せる別のアプリが表示されるらしい。

ペイントでも印刷できるかもしれない。 :

ペイント(最新のペイント3Dではなくて、昔のペイント)で画像を開くと、印刷を選んだ際にプリンターの詳細設定が開ける模様。ここからでも用紙サイズを指定できそうな気配。

Windows10のフォトを使わないのが一番楽かも。 :

色々ググってみたけれど、どうやらWindows10のフォトから印刷しようとした場合、フチなし・フチアリについても不具合が出る事例があるようで。

_フォトアプリで写真を印刷すると全面印刷ができません。 - マイクロソフト コミュニティ

IrfnView や XnView も試してみたけど、そちらなら最低限でも用紙サイズの選択はできるし…。印刷時はWindows10のフォトを使わないのが一番楽、かもしれない。

余談。Adobe Photoshop Express からも印刷できるのかなとインストールしてみたら、そもそも印刷機能が無かった。基本機能は無料で使えます、系のアプリだから仕方ないわな…。

2018/02/24() [n年前の日記]

#1 [dxruby] DXOpalのz値指定描画について

DXOpalを触った際に、z値を指定して描画したら前後関係がおかしくなった、ような気がしたのだけど本当にそうなるのか動作確認をしてみたり。

DXRubyで動作確認。 :

まず、DXRuby で動作確認。右下から左上に向かって、z値を、256 → 0 に減らしつつ描画。

_main.rb

dxruby_screenshot.png

DXOpalで動作確認。 :

次に、DXOpal で動作確認。

_DXOpal z order

Google Chrome 上での結果。

dxopal_ss_chrome.png

Firefox ESR 上での結果。

dxopal_ss_firefox.png


やはり気のせいではなかったらしい。しかも、Google Chrome と Firefox ESR で試したら、異なる結果画面になった…。

つまり、DXOpal でz値を指定しつつ描画しても、前後関係は不定になる模様。

少し調べてみた。 :

もしかして z値は無視しているのかなと思ったけれど、 _dxopal/window.rb at master - yhara/dxopal を眺めた感じでは、キューをソートしてるように見える。変だな…。何故こんな動作に…。

どうやら、描画要求をキューに登録する際、現在のキューの個数、つまり登録した順番も記録しておくことで、後に同じz値の描画要求があった時は登録順とも比較してソートする、という処理をしようとしてるっぽい。

ということは、登録順の数値の範囲と重ならない大きなz値、もしくは小さなz値を指定してやれば問題を回避できるのかな。と思ったけれど、Firefox上では予想通りの結果になったものの、Google Chrome上では相変わらず前後が不定な状態になった。なんでや…。

ん? そもそも、まずはz値同士で比較して、という形になってないような気がしてきた。
irb(main):026:0> a = [[5, 0], [4, 1], [3, 2], [2, 3], [1, 4]]
=> [[5, 0], [4, 1], [3, 2], [2, 3], [1, 4]]

irb(main):027:0> a.sort{ |a,b| a[0] == b[0] ? a[1] <=> b[1] : a[0] <=> a[1] }
=> [[1, 4], [2, 3], [3, 2], [5, 0], [4, 1]]

irb(main):028:0> a.sort{ |a,b| a[0] == b[0] ? a[1] <=> b[1] : a[0] <=> b[0] }
=> [[1, 4], [2, 3], [3, 2], [4, 1], [5, 0]]
もしかして、こうじゃないかな…。たぶん…。

2018/02/25() [n年前の日記]

#1 [dxruby] 地形アタリ処理を書いてたり

地形とのアタリを取る最低限のメソッドは動いたので、プレイヤーキャラを動かしつつアタリを取る処理を書いているのだけど。空中床というかジャンプで乗れる床の処理で妙な挙動になってアレコレ修正中。空中床が単独で配置されてる場合は問題無いのだけど、一般的な床や壁と隣接して配置されてると、そちらの床や壁の補正値が働いてしまう。空中床に関しては、横方向の補正はスキップするようにしないとダメだなと…。

DXOpalはSingletonモジュールが無いっぽい。 :

グローバルワーク相当を作ろうとして require 'singleton' や include singleton を書いたらエラーが。そのあたりは用意されてないっぽいなと。

以下を参考にして、違う書き方をした。

_Rubyデザインパターン 9日目 : Singleton - Qiita

2018/02/26(月) [n年前の日記]

#1 [dxruby] DXOpalで地形アタリ処理をしながらプレイヤーキャラを移動

DXOpal上で、プレイヤーキャラを動かしつつ地形アタリ処理をするあたりが動いてくれた。

_DXOpal tilemap collision 2
今のところ、妙な補正がかかって大変なことになってしまう場所も、わざとマップ上に残してある。どういう処理をすればバグを回避できるのかは今後の課題。

まあ、そういったバグが出るような危ない地形は作らない、という策もアリだけど…。例えば、敵ボスキャラにプレイヤーが乗れるとして、プレイヤーが乗った状態で敵ボスキャラが移動したりジャンプしたら、たまたまそういう危ない地形が発生してしまった、てな場面もあったりするので、対処できるならしておいたほうがいいわけだけど。

#2 [ruby] FXRubyを少し触ってる

FXRuby は、Ruby を使ってGUIアプリが作れるライブラリ。Fox toolkit なるGUIライブラリを Ruby から利用できるようにしたもの、らしい。

_larskanis/fxruby: FXRuby is an extension module for Ruby that provides an interface to the FOX GUI toolkit.
_fxruby | RubyGems.org | your community gem host
_File: README - Documentation for fxruby (1.6.39)

ちょっとGUIツールを作りたい気もしてきたので、少し触ってみようかと。

インストール。 :

Windows10 x64 + Ruby 2.2.6 p396 mingw32版、もしくは Ruby 2.3.3 p222 mingw32版の場合、以下でインストールができる。
gem install fxruby
動作に必要なバイナリもインストールしてくれる…らしい。たぶん。

#3 [anime] 「宇宙よりも遠い場所」を視聴

BS11で放送されている、「宇宙よりも遠い場所」を視聴。南極観測基地を目指す女子高生4人の姿を描くTVアニメ。

いよいよ南極観測船での旅が始まる回、なのだけど。船内の細かい描写に感心。これはもしかして、地上版プラネテスなのでは…。どこまで調べて、どこから想像なのか分からんのだけど、めちゃくちゃ調べて描かれているように感じる…。女子高生が南極に、というあまりにも大きな大きな嘘を堂々と描くために、細かい事実を大量に積み重ねている、そんな印象が。そういう姿勢で作るという、そのこと自体に、個人的には好感が持てるなと。

2018/02/27(火) [n年前の日記]

#1 [ruby] FXRubyを勉強中

RubyでGUIアプリが作れる、FXRubyというライブラリについて勉強中。環境は、Window10 x64 + Ruby 2.2.6 p396 mingw32 + fxruby 1.6.39 x86-mingw32。

全然関係ないけど、FXRuby の公式サイトが消滅してるような…?

ハローワールド。 :

まずは、Hello World。

_hellofxruby.rb
require "fox16"
include Fox

class MyHello < FXMainWindow

  def initialize(app, title = "Hello World FXRuby")
    # main is window class
    mw = super(app, title, :width => 320, :height => 240)

    # create layout
    pack = FXPacker.new(mw)

    # create label
    lbl = FXLabel.new(pack, "Hello World !")

    # create button
    btn = FXButton.new(pack, "Click !")

    # set button push event
    btn.connect(SEL_COMMAND) do |sender, sel, data|
      # show message box
      msg = FXMessageBox.new(btn, "Message", "Hello World in FXRuby", :opts => MBOX_OK)
      msg.execute
    end
  end

  def create
    super
    show(PLACEMENT_SCREEN)
  end
end

if __FILE__ == $0
  FXApp.new do |app|
    mw = MyHello.new(app)
    app.create
    app.run
  end
end

実行すると以下のようなウインドウが開く。

fxruby_ss01.png

ボタンをクリックするとダイアログが表示される。

fxruby_ss02.png

少し解説。 :

FXRuby を使うときは、最初のあたりに、以下の行を書く。
require "fox16"
include Fox

FXMainWindow というクラスが、おそらくはメインウインドウを担当するクラスなのだろう…。継承して、自分用のクラスを作成して、それを使うのが一般的っぽい。
class MyMainWindow < FXMainWindow

  def initialize(app, title = "Hello World FXRuby")
    mw = super(app, title, :width => 320, :height => 240)

    # 部品を生成したりイベントを設定したり色々初期化
  end

  def create
    super
    show(PLACEMENT_SCREEN)
  end
end

クラスを作ったら、以下のようにして呼び出す…のかな。
FXApp.new do |app|
  mw = MyMainWindow.new(app)
  app.create
  app.run
end

メインウインドウに登録できる部品は色々ある。例えば、以下のような感じ。
  • FXLabel ... ラベル。文字列を表示できる
  • FXButton ... ボタン
  • FXTextField ... テキストフィールド。入力欄。
_File: README - Documentation for fxruby (1.6.39) の左の一覧を眺めると、色んな種類があるようで。

ただ、各部品をメインウインドウにそのまま登録していくと、縦にずらずら並んでいってしまう。部品のレイアウトには FXPacker を使うらしい…が、それについては後述。

ボタンを押したら何か処理をさせたい、てな場合は、以下のように書けば設定できる模様。
    btn = FXButton.new(pack, "Click !")

    btn.connect(SEL_COMMAND) do |sender, sel, data|
      # show message box
      msg = FXMessageBox.new(btn, "Message", "Hello World in FXRuby", :opts => MBOX_OK)
      msg.execute
    end
まだ意味は分かってないけど、とにかくこう書いとけば動くらしい…。ちなみに、上記の例では、ボタンを押すとメッセージボックスが表示される。

少し複雑なレイアウトをしてみる。 :

各部品を、横方向に並べたり等、それなりにレイアウトしたい。

部品のレイアウトには FXPacker、FXHorizontalFrame、FXVerticalFrame を使う。
  1. まずは FXPacker をメインウインドウに登録。
  2. その FXPacker に、FXHorizontalFrame (部品を横並びにしてくれる) や FXVerticalFrame (部品を縦並びにしてくれる) 等のフレームを登録。
  3. それらフレームに、各部品を登録。

ということで、試してみた。

_fileselect_sample.rb
require "fox16"
include Fox

class MyMainWindow < FXMainWindow

  def initialize(app, title = "Generate Tilemap collision data")
    # main is window class
    # mw = super(app, title, :width => 480, :height => 360)
    mw = super(app, title)

    # create layout
    # pack = FXPacker.new(mw, :opts => LAYOUT_FILL)
    pack = FXPacker.new(mw)

    @frms = []
    tbls = [
      { :label => "Source Tiled JSON", :type => 0, :len => 50 },
      { :label => "Source PNG Image", :type => 0, :len => 50 },
      { :label => "Collision layer name", :type => 1, :len => 20 },
      { :label => "layer name (overwrite)", :type => 1, :len => 20 },
      { :label => "Null code", :type => 1, :len => 5 },
      { :label => "Output JSON", :type => 0, :len => 50 },
    ]

    tbls.each_with_index do |dt, i|
      s = dt[:label]
      kind = dt[:type]
      l = dt[:len]

      # create frame
      frm = FXHorizontalFrame.new(
        pack,
        # :opts => LAYOUT_SIDE_LEFT|LAYOUT_SIDE_TOP|LAYOUT_FIX_WIDTH,
        #:padLeft=>0,:padRight=>0,:padTop=>0,:padBottom=>0,
        # :width=>300
      )

      # create label
      FXLabel.new(frm, s)

      # create textfield
      tf = FXTextField.new(frm, l)

      case kind
      when 0
        # create button
        btn = FXButton.new(frm, "...")

        # set button event
        btn.connect(SEL_COMMAND) do |sender, sel, data|
          # show File dialog
          dialog = FXFileDialog.new(self, "Select file.")
          dialog.patternList = [
            "All Files (*)",
            "JSON (*.json)",
            "PNG Image (*.png)",
          ]
          dialog.selectMode = SELECTFILE_ANY
          if dialog.execute != 0
            tf.text = dialog.filename
          end
        end

        @frms.push( { :type => kind, :textfield => tf, :button => btn } )

      when 1
        @frms.push( {:type => kind, :textfield => tf } )
      end
    end

    @frms[2][:textfield].text = "layer0"
    @frms[4][:textfield].text = "0"

    frm = FXHorizontalFrame.new(
      pack,
      :opts => LAYOUT_SIDE_RIGHT|LAYOUT_SIDE_TOP,
      :width => 300,
    )
    sx, sy = 32, 8
    btn = FXButton.new(frm, "Check",
                       :padLeft => sx, :padRight => sx,
                       :padTop => sy, :padBottom => sy)

    btn.connect(SEL_COMMAND) do |sender, sel, data|
      # dump input string
      jsonfile = @frms[0][:textfield].text
      pngfile = @frms[1][:textfield].text
      layername = @frms[2][:textfield].text
      layername_s = @frms[3][:textfield].text
      nullcode = @frms[4][:textfield].text.to_i
      outfile = @frms[5][:textfield]
      s = [
        "json file : #{jsonfile}",
        "png file : #{pngfile}",
        "layer name : #{layername}",
        "layer name sub : #{layername_s}",
        "null code : #{nullcode}",
        "output file : #{outfile}",
      ].join("\n")
      msgBox = FXMessageBox.new(btn, "Result", s, :opts => MBOX_OK)
      msgBox.execute
    end
  end

  def create
    super
    show(PLACEMENT_SCREEN)
  end
end

if __FILE__ == $0
  FXApp.new do |app|
    mw = MyMainWindow.new(app)
    app.create
    # mw.show(PLACEMENT_SCREEN)
    app.run
  end
end

fxruby_ss03.png

それらしくレイアウトできた。

ファイル選択ダイアログについて。 :

上記ソースは、ボタンを押すと、ファイル選択ダイアログボックスを表示するようになっている。呼び出してる部分は以下。
          # show File dialog
          dialog = FXFileDialog.new(self, "Select file.")
          dialog.patternList = [
            "All Files (*)",
            "JSON (*.json)",
            "PNG Image (*.png)",
          ]
          dialog.selectMode = SELECTFILE_ANY
          if dialog.execute != 0
            tf.text = dialog.filename
          end

FXFileDialog がソレ。拡張子のリストを作成して .patternList に設定したり、選択モードを .selectMode に設定したりしている。

dialog.execute を呼ぶとダイアログが表示されて、選択されたファイルの数が返ってくるのだろう…。0が返ってきたら、何も選択していないか、キャンセルされた、ということではないかと。

.selectMode には、 _Class: Fox::FXFileSelector からすると、以下が指定できる模様。
  • SELECTFILE_ANY ... 1ファイルを選択。もしくはファイル名を指定。ファイルセーブ時に使える。
  • SELECTFILE_EXISTING ... 既に存在する1ファイルを選択。ファイルロード時に使える。
  • SELECTFILE_MULTIPLE ... 既に存在する複数ファイルを選択。
  • SELECTFILE_MULTIPLE_ALL ... 既に存在する複数ファイル、または複数ディレクトリを選択。
  • SELECTFILE_DIRECTORY ... 既に存在するディレクトリを選択。

余談。FXRuby のファイル選択ダイアログを使うと、以下のようなダイアログが表示されるのだけど。

fxruby_ss04.png

普段見ているダイアログとは、見た目がちょっと違う。

FXRuby が使っている FOX Toolkit は、OSのネイティブのGUI部品やダイアログを使わずに、それぞれを独自実装しているらしいので、こういった部分で違いが出てくるのだろう…。逆に考えると、Windows でも Linux でも似たような見た目になってくれる…はず。

ドラッグアンドドロップはどうやるのだろう。 :

エクスプローラ等でファイルを選択して、FXRuby で表示したウインドウにドラッグアンドドロップ(Drag and drop, DND, D&D)することでファイルのパスを取得する、といった処理をしたい。しかし、そんなことできるのだろうか…。*NIX上ではできるけど、Windows上ではできないよ、という話を以前見かけたけれど…。

以下で紹介されてるサンプルを、Windows上で動かしてみた。

_Drag and Drop in Windows with Explorer - Ruby

残念ながら、D&Dしてもマウスカーソルは×マークのままだった。

コレ、Linux上なら動くのかな…? どうなんだろう…?

Ubuntu16.04上でFXRubyのインストールと動作確認。 :

FXRuby を使ったソースが、VMware + Ubuntu 16.04 LTS上でも動作するのか確認してみたい。

Ubuntu上での FXRuby インストール手順を調べたが、パッケージをいくつかインストール後、FOX Toolkit の現行版をDL・ビルドして、最後に sudo gem instal fxruby をしないといかんらしい。

gem install fxruby だけで動いてしまうWindows版と比べると、導入が面倒なのだな…。

必要になるらしいパッケージを apt でインストール。
sudo apt install g++
sudo apt install libfox-1.6-dev lxrandr libxext-dev libgl1-mesa-dev libglademm-2.4-dev freeglut3-dev libglew1.5-dev

FOX Toolkit の現行版をDL・ビルド・インストール。
mkdir ~/package
cd ~/package
wget ftp://ftp.fox-toolkit.org/pub/fox-1.6.56.tar.gz
tar xvzf fox-1.6.56.tar.gz
cd fox-1.6.56
./configure
make
sudo make install

Rubyをインストール。sudo apt install ruby だけでは済まなくて、ruby-full をインストールしないといけない。ruby-full を入れると、Rubyのライブラリをビルドできるようになる模様。
sudo apt install ruby-full
sudo gem install fxruby --no-ti --no-rdoc

fxruby がビルドされた。ちなみに、何故かドキュメントの生成で異様に時間がかかったので、--no-ri --no-rdoc をつけてドキュメントの生成はスキップさせた。

irb を起動して、require 'fox16' と打ってエラーが出なければ、インストールはできている。

さておき、前述の、 _FXRubyを使ったドラッグアンドドロップのサンプル を、Ubuntu 16.04上で動かしてみたところ、ファイラーからファイルをD&Dすることでファイル群のパスが取得できた。

つまり、*NIX + FXRuby ならドラッグアンドドロップが働くけど、Windows上では働かない模様。不便だ…。

参考ページ。 :

#2 [ruby] Ruby-GNOME2を試用

Window + FXRuby ではファイルのドラッグアンドドロップが働かないと分かったので、別のGUIライブラリならどうかなと。例えば Ruby/GTK2 だか Ruby-GNOME2 ならどうだろうと。

このライブラリ、正式名称が分からんのだけど…。公式サイトでは「Ruby-GNOME2」と書いてあるから、それが正しいのだろうか?

_Ruby-GNOME2 Project Website - Ruby-GNOME2 Project Website

インストール。 :

Windows10 x64 + Ruby 2.3.3 p222 mingw32版でインストールしてみた。

gem install gtk2
> gem install gtk2
Fetching: pkg-config-1.2.9.gem (100%)
Successfully installed pkg-config-1.2.9
Fetching: native-package-installer-1.0.6.gem (100%)
Successfully installed native-package-installer-1.0.6
Fetching: cairo-1.15.11-x86-mingw32.gem (100%)
Successfully installed cairo-1.15.11-x86-mingw32
Fetching: glib2-3.2.1-x86-mingw32.gem (100%)
Successfully installed glib2-3.2.1-x86-mingw32
Fetching: atk-3.2.1-x86-mingw32.gem (100%)
Successfully installed atk-3.2.1-x86-mingw32
Fetching: cairo-gobject-3.2.1-x86-mingw32.gem (100%)
Successfully installed cairo-gobject-3.2.1-x86-mingw32
Fetching: gobject-introspection-3.2.1-x86-mingw32.gem (100%)
Successfully installed gobject-introspection-3.2.1-x86-mingw32
Fetching: pango-3.2.1-x86-mingw32.gem (100%)
Successfully installed pango-3.2.1-x86-mingw32
Fetching: gio2-3.2.1-x86-mingw32.gem (100%)
Successfully installed gio2-3.2.1-x86-mingw32
Fetching: gdk_pixbuf2-3.2.1-x86-mingw32.gem (100%)
Successfully installed gdk_pixbuf2-3.2.1-x86-mingw32
Fetching: gtk2-3.2.1-x86-mingw32.gem (100%)
Successfully installed gtk2-3.2.1-x86-mingw32
Parsing documentation for pkg-config-1.2.9
Installing ri documentation for pkg-config-1.2.9
Parsing documentation for native-package-installer-1.0.6
Installing ri documentation for native-package-installer-1.0.6
Parsing documentation for cairo-1.15.11-x86-mingw32
Installing ri documentation for cairo-1.15.11-x86-mingw32
Parsing documentation for glib2-3.2.1-x86-mingw32
Installing ri documentation for glib2-3.2.1-x86-mingw32
Parsing documentation for atk-3.2.1-x86-mingw32
Installing ri documentation for atk-3.2.1-x86-mingw32
Parsing documentation for cairo-gobject-3.2.1-x86-mingw32
Installing ri documentation for cairo-gobject-3.2.1-x86-mingw32
Parsing documentation for gobject-introspection-3.2.1-x86-mingw32
Installing ri documentation for gobject-introspection-3.2.1-x86-mingw32
Parsing documentation for pango-3.2.1-x86-mingw32
Installing ri documentation for pango-3.2.1-x86-mingw32
Parsing documentation for gio2-3.2.1-x86-mingw32
Installing ri documentation for gio2-3.2.1-x86-mingw32
Parsing documentation for gdk_pixbuf2-3.2.1-x86-mingw32
Installing ri documentation for gdk_pixbuf2-3.2.1-x86-mingw32
Parsing documentation for gtk2-3.2.1-x86-mingw32
Installing ri documentation for gtk2-3.2.1-x86-mingw32
Done installing documentation for pkg-config, native-package-installer, cairo, glib2, atk, cairo-gobject, gobject-introspection, pango, gio2, gdk_pixbuf2, gtk2 after 11 seconds
11 gems installed
gtk2 3.2.1 x86-mingw32 がインストールされた。

動作には、以下も必要らしい。自動でインストールしてくれる。
  • pkg-config
  • native-package-installer
  • cairo
  • glib2
  • atk
  • cairo-gobject
  • gobject-introspection
  • pango
  • gio2
  • gdk_pixbuf2

ファイルのドラッグアンドドロップ。 :

以下の記事で、ドラッグアンドドロップを使った事例が紹介されてる。

_Ruby Window Drop: いち雑記

ソースをコピペして、Windows10 x64 + Ruby 2.3.3 p222 mingw32 上で動作確認。エクスプローラから、ウインドウにD&Dしたところ…ファイルのパスが表示された。素晴らしい。

つまり、Ruby-GNOME2 なら、Windows上でもファイルのD&Dでファイルパスを取得できるようだなと。

FXRuby と比べると、ウインドウが表示されるまで結構待たされる印象を受けたけど。しかし、その分、高機能、ということになるのだろう…。たぶん。

2018/02/28(水) [n年前の日記]

#1 [ruby] Ruby-GNOME2をもう少し勉強中

Ruby-GNOME2 (Ruby/GTK2?)について、もうちょっと勉強中。環境は Windows10 x64 + Ruby 2.2.6 p396 mingw32 + gtk2 3.2.1 x86-mingw32。

とりあえず、以下ができるところまで試したり。
_table_layout_sample.rb
require 'gtk2'
require 'uri'

class MainWindow < Gtk::Window

  def initialize
    super("Table layout sample")
    set_default_size(640, 260)

    # set MainWindow spacing
    self.border_width = 10

    # set close button
    signal_connect("destroy") { Gtk.main_quit }

    tb = Gtk::Table.new(3, 7, false)

    tbls = [
      {:name => "jsonfile", :label => "Source Tiled JSON", :type => 0 },
      {:name => "pngfile", :label => "Source PNG Image", :type => 0 },
      {:name => "outfile", :label => "Output JSON", :type => 0 },
      {:name => "layername", :label => "Collision layer name", :type => 1 },
      {:name => "layername_s", :label => "Layer name (optional)", :type => 1 },
      {:name => "nullcode", :label => "Null code", :type => 1 },
    ]

    @entrys = {}
    tbls.each_with_index do |dt, i|
      lb = Gtk::Label.new(dt[:label])
      tb.attach(lb, 0, 1, i, i + 1, Gtk::SHRINK, Gtk::SHRINK, 6, 6)

      tf = Gtk::Entry.new

      case dt[:type]
      when 0
        tb.attach(tf, 1, 2, i, i + 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK, 0, 6)

        # file drop setting
        Gtk::Drag.dest_set(
          tf,
          Gtk::Drag::DEST_DEFAULT_MOTION |
          Gtk::Drag::DEST_DEFAULT_HIGHLIGHT |
          Gtk::Drag::DEST_DEFAULT_DROP,
          [["text/uri-list", Gtk::Drag::TARGET_OTHER_APP, 12345]],
          Gdk::DragContext::ACTION_COPY | Gdk::DragContext::ACTION_MOVE
        )

        tf.signal_connect("drag-data-received") do |w, ct, x, y, data, info, tm|
          data.uris.each { |uri|
            tf.text = URI.decode(uri).gsub(/^file\:\/\/\//, "")
          }
        end

        btn = Gtk::Button.new("...")
        btn.signal_connect("clicked") {
          # file select dialog
          dlg = Gtk::FileChooserDialog.new(
            "File select", self,
            # Gtk::FileChooser::ACTION_OPEN,
            Gtk::FileChooser::ACTION_SAVE,
            nil,
            [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
            [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT]
          )

          dlg.run do |res|
            tf.text = dlg.filename if res == Gtk::Dialog::RESPONSE_ACCEPT
          end

          dlg.destroy
        }

        tb.attach(btn, 2, 3, i, i + 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2)

      when 1
        tb.attach(tf, 1, 2, i, i + 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK, 0, 6)

      end
      @entrys[dt[:name]] = tf
    end

    btn = Gtk::Button.new("Convert")
    tb.attach_defaults(btn, 0, 3, 6, 7)

    btn.signal_connect("clicked") {
      jsonfile = @entrys["jsonfile"].text
      pngfile = @entrys["pngfile"].text
      outfile = @entrys["outfile"].text
      layername = @entrys["layername"].text
      layername_s = @entrys["layername_s"].text
      nullcode = @entrys["nullcode"].text.to_i

      s = [
        "json file : #{jsonfile}",
        "png image : #{pngfile}",
        "output json : #{outfile}",
        "layer name : #{layername}",
        "layer name sub : #{layername_s}",
        "null code : #{nullcode}",
      ].join("\n")

      # display message dialog
      dlg = Gtk::MessageDialog.new(
        self,
        Gtk::Dialog::DESTROY_WITH_PARENT,
        Gtk::MessageDialog::INFO,
        Gtk::MessageDialog::BUTTONS_CLOSE,
        s
      )
      dlg.run
      dlg.destroy
    }

    add(tb)

    @entrys["layername"].text = "layer0"
    @entrys["nullcode"].text = "0"

    show_all
  end
end

if $0 == __FILE__
  w = MainWindow.new
  Gtk.main
end

以下のようなウインドウが表示される。

ruby-gnome2_ss01.png

エクスプローラからのD&Dもできてる。

ruby-gnome2_ss02.gif

ここまで動けば、コマンドラインツールをGUIで使えるようにする、ラッパーの類も書けそうな予感。

参考ページ。 :


以上、28 日分です。

過去ログ表示

Prev - 2018/02 - Next
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project