かならずお読みください注意事項

Web Toy 2

その次 どうするか

Webのおもちゃ

ナイスショット

0 はじめに

むかしむかしまだ私も若くこの仕事を始めて間もない頃のことです。当時の東京都補装具研究所の市川洌さんには大変お世話になり、いろいろと教えていただきました。そのひとつがこれでした。

「こどもさんを相手にするときはネタをたくさん準備しておかないといけないよ。なにしろすぐに飽きるし、そうなるとやる気もみるみるなくなりついには機嫌まで悪くなる。こうなったらもう手がつけられなくなるよ。もしかしたら散々な目に遭うかもしれないよ。だから気を付けてね」

このアドバイスにもかかわらず、その後このような散々な目に何度か遭遇しました。実にお恥ずかしい話です。

そのかいあって、いまではいろいろなことを考えながらものを作るようになりました。今回は前回ご紹介したWebToy1について説明し、続いてその次にできることについてお話したいと思います。

1 WebToy1

前回紹介したwbToy1は、次のようなファイルの集まりです。現在皆さんに提供しているものはこれにPWAオフラインWebアプリ機能のための変更が加わりますが、ここでは理解しやすくするためにその部分は省略しました。しかしオンラインWebアプリとして使うにはこれだけでできます。

├─js
│ ├─lib
│ │ ├─plugins
│ │ │ ├─nineleep.enchant.js
│ │ │ └─ui.enchent.js
│ │ ├──box2d.enchant.js
│ │ ├──Box2dWeb-2.1.a.3.js
│ │ └──enchant.js
│ └─main.js
├─snd
│ └─jump.mp3
└─index.html

ここで、jsフォルダ内のlibフォルダ内のファイルは、enchant.jsのサイト https://github.com/wise9/enchant.js/ からダウンロードできます。当方では特に手を入れずオリジナルのままで使用しています。またsndフォルダ内のjump.mp3はクリックした際の効果音です。これも参考にしたサンプルから頂いたものです。

つまりWebToy1のために作製したのは、index.htmlとmain.jsだけです。

まず、index.htmlをみてみましょう。


<!DOCTYPE html>
<html>
    <head>
        
        
        
         
        
        Web-Toy-1
        
        
        
        
        
    </head>
    <body>
    </body>
</html>

Webページを開くときに最初に読み込むのが、index.htmlです。中を見るとheadタグ以外ほとんどありません。まずutf-8への対応に続きブラウザへの対応、タイトルの指定のあと、enchant関連のライブラリを順次読み込んでいきます。そして最後に次に説明するmain.jsを読み込みます。これらはmain.jsを動かすための役割をしています。ですから改造するときでも、書き換えるのはtitleタグだけでそのほかは特にそのままで変更する必要はないでしょう。

続いてmain.jsは次のようになっています。ここに動きのすべてが書いてあります。

enchant();
window.onload = function() {
        var game = new Core(320, 320);
        game.fps = 24;
        game.preload('./snd/jump.mp3');
        game.onload = function() {
                //物理エンジンの宣言
                var world = new PhysicsWorld(0, 9.8);//重力加速度 下方向に9.8m/s2

                //床の作成
                var floor = new PhyBoxSprite(320, 16, enchant.box2d.STATIC_SPRITE, 0, 1.0, 0, false);//密度0摩擦1反発0
                floor.backgroundColor = "#aaa";
                floor.position = {
                        x: 160,
                        y: 312
                }
                game.rootScene.addChild(floor);

                //右壁の作成
                var rwall = new PhyBoxSprite(16, 320, enchant.box2d.STATIC_SPRITE, 0, 1.0, 0, false);
                rwall.backgroundColor = "#aaa";
                rwall.position = {
                        x: 312,
                        y: 160
                }
                game.rootScene.addChild(rwall);

                //左壁の作成
                var lwall = new PhyBoxSprite(16, 320, enchant.box2d.STATIC_SPRITE, 0, 1.0, 0, false);
                lwall.backgroundColor = "#aaa";
                lwall.position = {
                        x: 8,
                        y: 160
                }
                game.rootScene.addChild(lwall);

                //天井の作成
                var top = new PhyBoxSprite(320, 16, enchant.box2d.STATIC_SPRITE, 0, 1.0, 0, false);
                top.backgroundColor = "#aaa";
                top.position = {
                        x: 160,
                        y: 8
                }
                game.rootScene.addChild(top);

                //点の作成
                var dot = new PhyBoxSprite(2, 2, enchant.box2d.STATIC_SPRITE, 0, 1.0, 0, false);
                dot.backgroundColor = "#aaa";
                dot.position = {
                        x: 160,
                        y: 160
                }
                game.rootScene.addChild(dot);

                //四角形の作成
                var count1 = 0;
                var addBox = function(){
                var box = new PhyBoxSprite(32, 32, enchant.box2d.DYNAMIC_SPRITE, 1.0, 0.5, 0.5, true);//密度1摩擦0.5反発0.3
                box.backgroundColor = "red";
                box.position = {
                        x: 80,
                        y: 50
                }
                game.rootScene.addChild(box);

                game.rootScene.addEventListener(Event.TOUCH_START, function(e) {
		  game.assets['./snd/jump.mp3'].clone().play(); //クリックすると音

                  if (count1 == 0){
                    Impx = 50;
                  } else if (count1 == 1){
                    Impx = -50;
                  } else {
                   Impx = 0;
                   count1 = -1;
                  }
                   Impy = -50; 
                 box.applyImpulse(new b2Vec2(Impx, Impy));
                 count1++;

                });
                }
                  addBox();

                //物理エンジン処理
                game.rootScene.onenterframe = function() {
                        world.step(game.fps);
                }
        }

        game.start();
}

1行目は、enchat.jsを使用する宣言です。
2行目以下のすべてが、起動した際の処理を示します。
3行目は、320ドット四方の空間(名前はgameです)の宣言です。
4行目は、フレームレート(動画のコマ数)毎秒24コマの指定です。
5行目は、効果音ファイルの事前読み込み。
6行目以下が読み込み終了時の処理です。つまり上の行のファイル読み込み終了を待ちます
8行目は物理エンジンの宣言です。この例では、x方向にゼロ、yプラス方向に9.8m/s2の加速度(地球の重力加速度ですね)を設定しています。ちなみに座標系は原点が左上角で右がxプラス、下がyプラスです。
11行目で床を作ります。320ドットx16ドットの静的(STATIC)画像、密度0、摩擦1.0、反発0、色はカラーコードでaaa、中心座標が(160,312)で18行目で画面に表示します
同じ要領で、左右の壁、天井、中央の点、を作ります。これらは静的ですので同じ場所にとどまります。
55-64行で赤い正方形を作る関数を記載しています。ただしここで作っているのは、動的な(DYNAMIC)画像です。これは動的ですので、画面に出現後、重力によって落下します。
66-81行でクリックした際に、効果音を鳴らし、赤い正方形に三種類の力を順次加えて飛び跳ねさせています。
83行で赤い正方形をひとつ発生させています。この行を3つ重ねるとホントに3つ出て来ます。
86行で物理エンジン処理を動作させています。
91行で、全体を動かし始めています。

このように、赤い正方形が落下したり、飛び跳ねたり跳ね返ったり回転したりはいちいち書き込んでいません、一切は物理エンジンが取り仕切っています。このため100行以下でこのように複雑な動きを作ることができます。

原理も理屈もわからない魔法のようなものでは創意工夫の余地がありません。また『魔法使いの弟子』のような騒動も起きます。しかしこのように仕組みが理解できるといろいろな工夫ができるようになります。次はそのような事例について紹介します。

2 飽きちゃった場合には

多分一番多いのはこのような場合つまり飽きちゃったです。

飽きること自体は学習の結果ですから特に悪いことでもありません。しかし飽きたまま過ごして時間や資源を無駄遣いすべきではありませんので少し手を加えてみましょう。

たとえばバスケットボールのようなゴールを追加し中央の点を外してみましょう。(このページのトップ画像参照)

オリジナルの46行から53行を削除し、かわりに次のコードを挿入します。

            //ゴールの作成
                var goall = new PhyBoxSprite(100, 4, enchant.box2d.STATIC_SPRITE, 0, 1.0, 0, false);
                goall.backgroundColor = "#aaa";
                goall.position = {
                        x: 125,
                        y: 160
                }
                goall.angle = 75;
                game.rootScene.addChild(goall);
                var goalr = new PhyBoxSprite(100, 4, enchant.box2d.STATIC_SPRITE, 0, 1.0, 0, false);
                goalr.backgroundColor = "#aaa";
                goalr.position = {
                        x: 195,
                        y: 160
                }
                goalr.angle = -75;
                game.rootScene.addChild(goalr);

壁や天井の作り方と同じです。goall.angle = 75;で傾き角度を設定しているところは注目しましょう。

画面に棒を二本追加しただけですが、これでずいぶん違ってきます。お試しください。

WebToy2

できる操作は相変わらずクリックだけですが、ゴールが追加されおもちゃとしての性格がずいぶん変わりました。ポンポンはねるのを眺めるだけだったのが目標(ゴール)ができました。理解のハードルがやや(もしくはかなり)上がっています。

床に落ちる前に次のクリックができるとゴールに入る可能性が上がるようです。ですのでたくさんのクリックが苦手なひとはここでも苦労するでしょう。これは一種の身体能力の『バリア』ですがこのおかげで面白くもなります。ゴールの寸法や位置や角度を変えると、バリアの大きさも面白さも変わります。簡単すぎて飽きちゃった場合も難しすぎて泣きそうな場合もこれで何とかできます。しかもかなり細かく微調整できます。

しかしあそんでいるうちにコツやノウハウを自分でみつけて、それを友達に教えてあげるなんてのもいいですね。だからおもちゃの世界にはおとなはあまり口出ししない方がいいのかもしれません。

あとはこの文をお読みのあなたのアイデアと簡単なプログラミング次第で可能性が広がります。

既製品のゲームはかなりむつかしいです。そして高価です。もともとそうでないと人気がでない世界の商品なのですから仕方がありません。とくに不自由のあるこどもさんの場合、難易度をうまく合わせてあげると、ながくとりくめるかもしれません。

3 うまくいかない場合には

飽きちゃう人もいる一方で、うまくいかない人もいるかもしれません。

スイッチを押して赤い正方形がポンポンはねているのに、ほかのおこさんとはちょっと様子が違う。なんとなくぼんやりして、動きに対する反応があまり見られない。もしかしたらその人は周囲の人とは違う見え方をしているのかもしれません。

モニターを顔の正面で見ているでしょうか。左右に傾いたり、上目や下目使いになっていないでしょうか。モニターに近すぎたり離れすぎたりしていませんか。また両目でしっかり見ているでしょうか。疲れやすくないですか。

おとなで脳卒中などの病気のあと、うまく見えなくなるひとがいます。視野が狭くなったり、視力が急に落ちたり、左右どちらか視力が落ちたりすることもあります。病気がきっかけで急に悪くなるのでご本人も周囲も気がつきます。しかし白内障のようにゆっくりすすむ病気では気がつかないことが多いです。またこどもさんのようによく見えた経験が少ないとこれもまた気がつかないことがおおくなります。またご家族にしても昔から変わらないとおっしゃるかもしれません。

またすばやい動きを見るのが苦手なこともあります。世界一流の卓球試合では猛烈なスピードでうちあいます。目がついていける観客は熱狂しますが、ついていけない観客は呆然とするばかりです。WebToy1もポンポコくるくる動きます。そこがおもしろいところなのですが、もし目がついていかないと卓球と同じでおもしろくありません。もしかしたらひどく疲れるかもしれません。見えると見えないのあいだには、がんばれば見えるというのがあります。がんばれば見えるということは、疲れると見えないということです。そのひとにとってはつらいできごとですから、手助け、場合によっては『合理的配慮』ともいいますが、これが必要になります。

さてそこで、月に行くことにしましょう。月の重力加速度は1.622m/s2で地球の約1/6です。ついでにクリックではねる力も1/6にしましょう。月に行くのは簡単ではありませんが月のように赤い正方形を動かすのは簡単です。具体的には、オリジナルの8行と66-82行を以下のように変更します。具体的には、重力加速度を、9.8から1.622に、はねる力を、50から8、-50から-8に変更しています。ところであなたの目は細かい文字が見えますか?

     //物理エンジンの宣言
           var world = new PhysicsWorld(0, 1.622);//月の重力加速度 下方向に1.622m/s2
                game.rootScene.addEventListener(Event.TOUCH_START, function(e) {
          game.assets['./snd/jump.mp3'].clone().play(); //クリックすると音
 
                  if (count1 == 0){
                    Impx = 8;
                  } else if (count1 == 1){
                    Impx = -8;
                  } else {
                   Impx = 0;
                   count1 = -1;
                  }
                   Impy = -8; 
                 box.applyImpulse(new b2Vec2(Impx, Impy));
                 count1++;
 
                });

こちらもお試しください。ときどきおられるのです。自分では試していないのにおこさんにはやらせるおとなの方が。これは反対ですね。こどもに隠れて(つまりないしょのふりをして)おとなが楽しそうに遊んでいるとこどもの興味関心はあふれ出してきます。この方法もお試しください。

WebToy3

速さ以外の外見はすべて同じです。なにも知らせずにこちらをためしたらなにか違いがわかるかもしれません。見え方が変わったからでしょうか?もしかしたらどちらも見えるけれど、ゆっくりのほうも好きになるかもしれません。なにしろおもちゃですから好き嫌いのことまではわかりません。

まあどちらにせよ、楽しく毎日遊んでくれれば、クリック操作やスイッチ操作が上手になると期待できます。まあこの際、ご本人が訓練しているなどと自覚する必要はありません。

4 おわりに

おもちゃには対応年齢というジャンルわけがあります。0歳児むけ、1,2才むけ、3-6才児むけ、小学校低学年、中学年、高学年、中学高校、おとな、おおむねこのくらいでしょうか。

しかし不自由を持つこどもたちの場合は、この階段はもっと細かく準備しなくてはいけません。いくらか難しくても何とかするゆとりの部分がやや少ないからです。池の飛び石を普通よりもたくさん細かく配置して、うまく渡れないひとのために通路を用意するのと同じ理屈です。

今回は、とび石をたくさん準備する方法について考えてみました。もっといろいろ試してみたい方のために今回はお土産を用意しました。

WebToy1お試し版一式
WebToy2お試し版一式
WebToy3お試し版一式

前回と今回ご紹介した3種類のWebToyのおためし版です。ダウンロードしたあと展開して(win10では、右クリック>すべて展開)index.htmlをダブルクリックで動き始めます。(このような操作はパソコンでできます。タブレットやスマホではできません)main.jsをメモ帳などで書き換えて保存すれば、動きが変更できます。どうぞお試しください。ちなみに火星の重力加速度は、3.711m/s2です。

さてさて話は変わります。プログラミングの話をすると、よくこんな言葉を耳にします。

「私はプロではない」

それはわかります。ではその仕事を誰かプロに任せたギャラは誰が払うのでしょうか?プロはただで仕事をしません。だからプロなんです。プロに仕事を任せるにはお金が必要なのです。ではお金のない人はどうすればいいのですか?あきらめますか?泣き寝入りしますか?

私の職場から国際協力機構の仕事に参加する人もいます。関係する本など読むと、飲み水に困っているひとを助けるときには、井戸の掘り方を学んでもらうそうです。この場合、水さえ出てきて自立できればプロである必要はないのです。その都度援助しているといつまでも自立できないこともよくあるそうです。

また手料理、日曜大工、家庭菜園、草野球などアマチュアでも必要とする人のためには役に立てます。シェフでも、建築家でも、農業経営者でも、プロ野球選手でもいいですがそうである必要はありません。

そもそも、『いまはできない』ひとから『できる』を見つけようとしているのですから、共に進むひとびともいたほうがいいと思いますが、いかがでしょうか。

さて、次回はさらに手直しを加え発展させていく予定です。どうぞお楽しみに。

関連する記事

参考URL


2020/06/26 公開

研究企画課リハ工学科にもどる ←もくじはこちらです