calendar

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
293031    
<< October 2017 >>

categories

archives

JavascriptをActionScript内に隠ぺいして実行

0
    FlashのActionScriptからJavascriptを呼びだして実行する方法です。例えば、URL情報はActionScriptでは取得できませんので、Javascriptを呼びだして取得する必要があります。また、mixiアプリでマイミク情報を取得する場合、Ajaxで取得する必要があるため、やはりJavascriptをActionScriptから実行する必要があります。

    ActionScriptからJavascriptを呼びだして実行する場合flash.external.ExternalInterfaceを使います。(getURLという命令もありますが、こちらは古いので最近のFlashではExternalInterfaceを使うよう、公式ページでは書かれています)


    例えば、URL情報を取得する場合は以下のように記述します。
    ------------------------------------------------------
    var url:String = String(ExternalInterface.call("function() { return window.location.href; }"));
    ------------------------------------------------------


    Javascriptが長いプログラムの場合は、以下のように記述します。
    ------------------------------------------------------
    var jsCode:String = <![CDATA[
    function() {
       return window.location.href;
    }
    ]]>;

    var url:String = String(ExternalInterface.call(jsCode));
    ------------------------------------------------------
    ここでポイントとなるのは、文字列を<![CDATA[ 〜 ]]>;で括るという部分です。こうすることで、長い文字列を "" + "" + ... で繋ぐ必要が無くなるため、格段に保守性が良くなります。更にこの記述方法の良い点は、JavascriptをActionScriptの内部に書く為、コードを隠ぺいできる点です。


    最後にExternalInterfaceを利用する場合の注意点。ExternalInterfaceは、FlashのObjectタグに、id属性を追加し、文字列"external"が入った名前を設定しないと、IEの場合戻り値がnullになってしまします。
    以下は設定例です。
    ---------------------------------------------------------
    <script type="text/javascript">
     AC_FL_RunContent('width','650','height','650','src','aaaaaa','quality','high','movie','aaaaaa', 'id', 'externalswf' );
    </script>

    <noscript>
       <object width="650" height="650" id="externalswf">
       <param name="movie" value="aaaaaa.swf" />
       <param name="quality" value="high" />
       <embed src="aaaaaa.swf" quality="high" type="application/x-shockwave-flash" width="650" height="650"></embed>
       </object>
    </noscript>
    ---------------------------------------------------------
    ※分かりやすくするために、一部記述を省いています。
    AC_FL_RunContentとobjectの2箇所にid属性を追加します。



    hitTestPointの当たり判定漏れ防止策

    0
      前回のエントリーでは、「自弾とザコ敵」の当たり判定は二次元配列上で行う方法がパフォーマンス的には有効であると書きましたが、「自機と敵弾」や、「自弾と障害物」の当たり判定は、やはりhitTestPointを利用する方法がいいと思います(※1)。つまり、当たり判定が「1対多」か「多対多」かで手法を分けます。(背景は背景用のスプライトにすべて追加し、1と数えます)

      ところがこのスプライトでのhitTestPointは、タイミングによって当たり判定がうまくいかない場合があります。以下のデモを見てください。

      デモはこちら

      障害物である壁が配置されているSpriteに対し、弾一つ一つがhitTestPointで当たり判定を行っていますが、弾が速いためタイミングによっては壁を弾がすり抜けてしまいます。もちろん弾のスピードを遅くしたり、壁の厚さを広げれば判定漏れは減りますが、見た目やゲームシステム上そうしたくない場合も多々あります。


      そこで、当たり判定を広げるため、壁のMovieClipの輪郭に沿って、アルファ0%のビットマップを追加します。(輪郭用のレイヤーを別途追加した方が編集しやすいでしょう。)

      これによって、見た目や弾のスピードを変えることなく当たり判定をより正確に行う事が出来るようになります。


      デモはこちら

      ※1:hitTestPointを使った手法とは、ある1つのSprite(例えば背景なら背景全体)に対して、弾の座標(x,y)が当たっているか否かを判別する手法です。

      シューティングゲームの当たり判定を高速化

      0
        ゲームを作る上で大きな課題の一つとして「当たり判定を如何に高速化できるか」というのがあります。今回は当たり判定を配列に置き換えて高速化する、という手法を思い付いたのでやってみました。

        先ずはデモをご覧下さい。

        デモはこちら

        敵は弾が当たると白く光り、5回弾が当たると爆発するようになってます。


        よくある手法として、弾をある1つのスプライトにすべて配置し、敵一つ一つに対して、弾のスプライト(全体)とhitTestする事によって当たっているか、否かを判定する方法があります。この方法は非常に高速に当たり判定を処理できますが、どの弾と当たったか、を判定できないので、当たった球を消せない、という欠点があります。

        では、弾一つ一つと敵一つ一つをそれぞれ当たり判定しようとすると、これは膨大な量の判定を行わなければならなくなり、デモのような沢山の弾・沢山の敵が出現するシステムでは非常に重くなってしまいます。
        単純な例として、敵が100匹、弾が100発画面上にあったら、100×100=10000回の判定が毎回必要になってしまいます。

        そこで、座標を大きなマス目に置き換え、それぞれのマス目内で判定を行います。デモでは背景にマス目がありますが、これが当たり判定を行っている単位です。
        意外とマス目は大きく感じますが、当たり判定にはそれ程違和感がありません。これは弾が速いのと、「敵に弾があたる」という行為自体、判定が広くても潜在的に不満は起こらない為だと思います。(これが自機の当たり判定となると、もっとシビアにやらないと不満が出ます。)

        具体的な判定ロジックとしては、

        ・縦横の二次配列Aを用意(初期化)する。(マス目の数に合わせた配列、デモは15×15)
        ・画面に表示されている敵の座標からマス目座標を算出し(※1)、配列Aに敵(の参照)を当てていく。
        (配列位置が重複した場合も特に気にせす上書きしちゃう)
        ・画面に表示されている弾一つ一つに対し、マス目座標で配列Aに敵がいるか判定(配列A[x][y]!=undefinedかどうか)、いたら当たり処理を行う。

        この方法ですと、配列作成で15回ループ、敵を配列代入で100回ループ、弾当たり判定100回ループ、で215回のループで全ての判定が行えます(しかも実際の当たり判定処理は100回のみ)。マシンスペックによっては215回でも重いでしょうけど、10000回判定と比べると雲泥の差です。

        ※1例えばマス目の大きさが40x30で、敵の座標が(300,100)だったら、マス目座標は、(300/40, 100/30)で、(8,4)といった具合。

        Box2Dの格闘ゲーム

        0
          なんか久々にBox2Dのネットにあるソースとか弄ってみたら、ぐらびっちょんの時のライブラリはバージョンが古かった事が判明!メジャーな更新されたと思われる時期よりも後に作り始めたんだがなあ・・・ぶつかったタイミングで効果音出すとか、やりたくて諦めた事が簡単に出来そうな予感。

          という訳で、例によってデモを改造しつつ、Box2Dで格闘ゲームを作ることにしましたよ。たぶんボクシングになると思われます。

          こんなかんじでテスト中です。


          ちょっと動かした感じで面白そうになる手ごたえが得られたので、今後は更に作りこんでみます。今回のゲームはこんな感じで進捗を晒していこうかなと。ブログの更新滞りすぎなんでw

          Transmover オンラインステージ登録の傾向分析

          0
            Transmover公開してからもうすぐ1カ月ですが、ここらへんでオンラインステージ登録に関する運用面での解析を自分なりにしてみたいと思います。オンラインステージ登録はあまり例を見ない試みで、もちろん自分的にも初めてだったので、当初は実験的な要素として考えてましたが、1カ月経ってある程度の傾向が見えてきたのでざっくばらんにレポートしてみます。

            ・登録者の地域について
            これは海外からの登録が7〜8割で日本より断然多いです。これはプレイ数にも比例しています。オンラインステージは質より量を重要視していたので、外人でも遊べるゲーム(説明とかちゃんと読まなくても感覚的に遊び方がわかるゲーム)にしたことで狙い通りの成果が得られたと思います。あと個人的な印象では、日本人は体裁など気にして遠慮しがちなのに対し、外人は比較的こういうものに対して実験的に参加していく傾向があるのかなと感じています。

            ・登録ユーザについて
            まんべんなくいろんな人が登録するのではなく、同じ人が連続的に投稿する傾向があります。登録されるステージの内容も人によって特徴が似ているので内容が片寄ります。これも事前から予測されていたんですが、あえて人や難易度で検索できる仕組みは入れませんでした。(どの程度の偏りが出るかが予測できなかった&正直作るのが面倒くさかったw)

            ・登録される内容について
            簡単なステージが圧倒的に多いです。「人に遊ばせるステージを登録する」というよりは、「自分でステージを作って登録する事自体が遊び」と捉えている人が多い事がわかります。恐らく登録した内容についての反響・レスポンスが分からないシステムに原因があると思われますが、気軽に登録できる、正に「登録する遊び」と考えればこれでもいいのかなと。あとは日本人はトリッキーな仕掛けを頭を使って考えるのに対し、外人はシンプルで単純なものを作る傾向があるようなので、ユーザの比率に従った結果こうなったのも大きいのかもしれません。

            ・その他
            オンラインステージによってゲーム自体の寿命?はもちろん伸びますが、どちらかというとコアな一部のユーザが繰り返し遊んでくれている様な感じがします。ゲーム自体、万人受けするというよりはマニアックなものですし。ただ、システム自体の自由度は自分が予想していたよりも高くて、自分自身未だに「こんな方法があったのか!」とか思わされることがあり、この辺は、オンラインステージ登録機能と上手くマッチして相乗効果が得られたと思います。



            これ以外にも見えてない傾向が色々あるようですが切りがないのでこの辺で。

            boss追加と当たり判定クラスの追加

            0
              ボスを追加。

              デモはこちら

              あとはパフォーマンス改善をいろいろ。
              ・爆発で破片が飛び散るのを中止。
              ・爆発で火花を散らすのを中止。
              ・当たり判定ロジックを各キャラ別に個別に行っていたのをクラスで一本で管理するようにした。

              なんか技術的なネタも特になく・・・ブログの記事的にはつまらない内容だなw
              とにかく間がちょっと空いてしまったので、モチベーション下がらないようにちょっとづつでも何か更新してなんとか完成にこぎつけたいところ。

              地上物追加と影の追加

              0
                地上物と影を追加してみました。
                相変わらず重いですがw

                デモはこちら

                あとはミサイルの挙動も地上に添って動くように変更。これら地上物のオブジェクトを追加するにあたって、調整が必要になったのが地面の高さ。PV3DではZソート(奥手前を正確に描画する仕組み?)がいまいちみたいなんで、地上物の位置が地面の平面と近いと見えなくなったりする不具合が起こるんですね。

                なので、見た目には分かりづらいですが、地面の高さは-800で、地上物の高さは-400位になってます。カメラ位置固定だとこういう裏ワザも使えていいですね。

                PV3Dのレンダリング情報表示クラスを使用する

                0
                  とりあえず今まで作った内容を全て盛り込んだものをこさえてみました。

                  デモはこちら

                  デモ見ると分かる通り、相当重いです。まあアルファだのブレンドだの使いまくってやりたい放題やったからなあw ゲーム作ってる時間って実は半分以上がパフォーマンス調整だったりして、これが地味で時間がかかる作業だったりします。まあプログラムスキルはここで上がって次回作に生かされる訳ですけど。プロなんかは予め決められた容量無いで作る様に設計してるんでしょうけどねえ。

                  で今回、パフォーマンス云々を可視化する手法として、PV3Dに最初から用意されているレンダーステータス表示クラスstatsViewを使用してみました。画面の左上に出てる文字列がそれです。使い方は簡単でクラスをインスタンス化してaddChildするだけ。

                  import org.papervision3d.view.stats.StatsView;

                  var sv:StatsView = new StatsView(renderer);
                  addChild(sv);

                  これだけ。今んとこ気にしてみてるのは
                  FPS
                  Tri(三角ポリゴン数)
                  Sha(シェーディングされたポリゴン数?)
                  Mem(使ってるメモリ数)

                  Triは光とか爆発のMCがほとんどで、Shaは自機とか敵雑魚とか。背景が不必要にTri多くしてたんで、極限までローポリ化しました。あとはブラウザで実行すると使用しているMemが少なくなるのがわかります。ある程度まで増えてって一気に減るからカベージコレクタの制御ってこんな感じかとか。


                  パフォーマンス改善ってブログネタとしても地味だし、今後どうしよっかなあw

                  雲ステージを作ってみた

                  0
                    Photoshopで雲模様を作る事を覚えたんで、雲の中ステージを作ってみました。

                    デモはこちら

                    ついでに、嵐バージョンも↓

                    デモはこちら

                    晴れから次第に嵐に変わっていってボス出現、とかやればオーダインの一面みたいのが作れるかな〜とか思ったんですけど、手間がかかりそうなのでとりあえず保留。嵐のところはPhotoshopで雷作って光らせる、とかもやってみたいけど。

                    技術としては、3DオブジェクトのSpriteの前にMC用のSpriteを配置してアルファ表示しているだけ。全体にアルファがかかるため、実際のゲームにしたらパフォーマンスが落ちるのかも。

                    演出に凝りすぎて、時間かけ過ぎたりパフォーマンスに苦しむのを何度も経験していい加減学習したので、やりたいことがあっても全体を考えてあえてやらないとか、ちょっとやってみて時間かかりそうだなと思ったらそのまま作り続けないで保留にしておく、というのが作品を効率よく仕上げる上で一つ重要な要素なのかなと思われます。

                    背景にGoogle moonの画像を使ってみた

                    0
                      背景にどうしようかなーといろいろテクスチャーを探してて、試しにGoogle moonの画像を使ってみたら、以外とシックリきたんで採用。

                      デモはこちら

                      ついでにGoogle mapのグランドキャニオン周辺版も(遠くの山は月のまんまだけどw)

                      デモはこちら

                      ベクター画像と実写の背景の組み合わせって素材としてなかなか難しいんだけど、今回の組み合わせは「半リアルアニメ的?」な独特な感じが醸し出せて十分満足しております。しかもGoogle Map系(moon、marsとかも)だったらバリエーションも簡単に増やせる。今のところ考えてるのは、月表面、火星表面、グランドキャニオン、海+島、森、エリア51周辺、ナスカ地上絵周辺などなどなど。あとは宇宙ステージと前回のデモのような無機質マテリアルステージとかかな・・。

                      あとConeプリミティブで山(=障害物)とか作ろうかと思ってたんだけど、手間かける割にはかえって不自然なものができあがりそうなのであえて止めました。starPolygonはガッツリ作り込んだ3ステージって感じだったけど、今回のはできるだけ楽に作ってその分ステージを増やすっていう方針で考えてます。

                      << | 2/3PAGES | >>