ラベル Web の投稿を表示しています。 すべての投稿を表示
ラベル Web の投稿を表示しています。 すべての投稿を表示

2020年4月4日土曜日

[Enchant.js]スマホで全画面表示した際、Viewportのサイズに画面を合わせる方法


Enchant.jsで沼にはまったところがあったので、ここにメモしておきます。



Enchant.jsをはじめとして、HTML5ベースに作ったWebアプリをスマホとかで全画面表示(ネイティブアプリっぽく表示)するとき、 metaタグでviewportとかの設定をすると思います。





ただ、このときに、ゲーム画面が全体にフィットしないという問題が起こりました。
スマホの解像度に合わせて作ったにも関わらず...




結構これで悩んだのですが、いろいろ試したり調べたりするうちに、「viewportで表示した際、innerHeightを取得すると、最初の一回 目はアドレスバーを考慮した数値が出てくる」ということがわかりました。


viewportでの表示の時と、普通のブラウザの時の表示で何が異なるかというと、主にアドレスバーの有無です。



ブラウザで表示した際のinnerHeightが500だったとします。
viewportで表示すると、アドレスバーがない分これより値が大きくなりそうですが、一回目の表示の際は500となることがわかりました。

で、その状態でリロードすると、innerHeightの値が500より大きい、すなわち、アドレスバーが消えた状態の高さが取得できました。




実際には、最初に読み込んでからしばらく時間が経ってからinnerHeightを取得すれば、正しい高さが取得できるようでしたので、次のような コードを実装すればこの問題は解決できると思われます。



var game = new Core(540, 930);

var CenterMove = function (core) {
    var scale = Math.min(window.innerWidth / core.width, window.innerHeight / core.height);
    core.scale = scale;

    var stage = document.getElementById('enchant-stage');
    stage.style.position = 'absolute';
    stage.style.top = (window.innerHeight - (core.height * core.scale)) / 2 + 'px';
    stage.style.left = (window.innerWidth - (core.width * core.scale)) / 2 + 'px';
    core._pageX = (window.innerWidth - (core.width * core.scale)) / 2;
    core._pageY = (window.innerHeight - (core.height * core.scale)) / 2;
};

setTimeout(function () {
    CenterMove(game);
}, 55);
  


最初にgameオブジェクトを作成します。


正しい高さを取得するため55ms後にCenterMove関数を呼び出します。



ここでは、縦、横においてそれぞれ、拡大縮小率を計算し値が小さいものを選んで、それをgameオブジェクトのスケールとします。



その後は、画面を中央に表示しています。




以上です。


2020年2月24日月曜日

[Unity]ゲームを作ったらunityroomで公開してみよう ~WebGLで手軽にブラウザで~


はい、こんにちは。
@CortanMathです。




今回は、「unityroom」について書きたいと思います。


「unityroom」って何かといいますと、UnityでWebGL向けに書き出したゲームを公開できるサービスになります。





通常、Unityで作成したゲームを公開しようと思ったら、Apple StoreやGoogle Playに申請したり、自分のサイトとかでexeを配布したり、サーバーを契約してWebGL出力のものをアップデートしたり、

などといった手段があります。


しかし、いずれもお金がかかったり、手間がかかったりして大変です。





そこで、便利なのがこの「unityroom」です。





Twitterアカウントさえあれば簡単に登録でき、無料でゲームを公開することができます。





それに加えて、ゲームの評価機能、コメント機能などもあったりして、プレイヤーやほかのクリエイターと交流できる点も魅力的ですね。






Twitterアカウント自体簡単に取得できますから、いまTwitterアカウントを持っていない方でも手軽に始められます。





では、やってみましょう。

簡単に大まかな流れを書いておきます。

とはいっても、登録後は画面の設定項目に従うだけなので、あまり詳しくは書きません。




unityroomを使ってみる



まずは、unityroomに登録します。



こちらがそのサイトです。

https://unityroom.com/


登録ボタンを開くと、こんな感じの画面になると思います。



そうしたらTwitterでログインをクリックします。

アプリ認証しておいてください。





するとプロフィールの設定画面になります。



基本的には、Twitterに登録してあるプロフィールが表示されます。


変更したい部分は、ここで変更しておいてください。






プロフィールの登録が終わったら、早速ゲームを登録していきます。



あらかじめUnityの方から、WebGLで出力しておいてください。



出力方法ではないですけど、出力時の注意点についてはこちらに書きましたので、よければご覧ください。

[Unity]WebGL で出力する際の注意点 ~テキストが表示されない、画面サイズが合わないなど~




ゲームを登録するというボタンをクリックすると、このような画面が開きます。



タイトルや紹介文などを入力してください。



ゲームidというのは、そのゲームのURLに使われます。





設定が終わったら、その都度保存しておきましょう。



ゲームのアイコン画像などを設定します。





あとは左下にある、各設定項目を設定していってください。
画面の通りにやればすぐ終わると思います。



いろいろ設定がありますけど、基本設定と、WebGL設定、WebGLアップロードをやってお けば基本大丈夫です。




一通り終わったら、下の方にある公開設定から、自分の好きなものを選んでください。

多くの人に見てもらいたければ、一般公開にしておきましょう。







以上です。

おそらく簡単にゲームの公開ができたと思います。




自分がゲームをアップロードするだけでなく、他人のゲームをプレイするのも面白いですし、参考にもなると思いますので、積極的に使っていきましょう。



ちなみに僕が最初に作った作品は下の脱出ゲームになります。

https://unityroom.com/games/escape_from_storageroom





ということでこの記事を終わります。




ではさようなら。
またお会いしましょう。

もしよければ、LINEスタンプの方もよろしくお願いします。


https://line.me/S/sticker/7072968

無言で何かを伝えよう とする白男くん - LINE スタンプ | LINE STORE

白男くんが何もしゃべらずに、何か大事なことを伝えようとするスタンプです。


お そらくいつでも使えるLINEスタンプ集


[Unity]WebGLで出力する際の注意点 ~テキストが表示されない、画面サイズが合わないなど~


はい、こんにちは。
@CortanMathです。



この間、UnityでWebGL出力しようと思って、いくつかつまずいた点があったのでここに記録しておきます。

同じ症状で悩んでいる方のお役に立てれば、幸いです。






具体的に困った点は主に2つあります。


まず、「Unity上では動作していたのに、WebGLに持って行った際、日本語のテキストが表示されなかった」ということ。


そして、もう一つは、「WebGLとしてブラウザで動かしたとき、画面サイズの調節がうまくいかなかった」ということ。

画面のUIが崩れたり、あるいは、画面サイズが大きすぎて、スクロールしないと見れない状態に陥ったりしていました。




では、実際にそれぞれの解決策を見ていきましょう。



WebGLで日本語フォントが表示されない



まずは、テキストが表示されないという問題です。



Unityでは、テキストボックスを作成した際、標準で「Arial」というフォントを使用しています。

エディタ上で動かしている分にはこれで問題なく動くのですが、WebGLに書き出すと日本語が表示されなくなってしまいます。




これを防ぐためには、日本語対応のフォントを使うようにしましょう。


調べると無料のフォントもたくさんあります。



僕はこの「源流明朝」という無料のフォントを使用させていただきました。

https://github.com/ButTaiwan/genryu-font



ただ、著作権には気をつけてください。

2次作品に使用した場合、配布物に同梱してはいけないフォントなどもあります。



「配布可能か」、「商用利用はできるのか」、などのライセンスは良く確認しておいてください。


ちなみに先ほど僕が紹介したフォントは、「フォントを使用した制作物を有償・無償を問わず自由 に公開・配布」可能と書いてありました。




フォントが用意できたら、テキストボックスのフォントを変更します。

非常に簡単です。



TextコンポーネントのFontというところに、ダウントードしたttfファイルを設定して やるだけです。




フォントの変更はいつでもできますが、早めに済ませておいた方が良いでしょう。


同じフォントサイズに設定していても、フォントの種類によって微妙に大きさが異なったりします。



場合によっては、フォントを変えたことにより、後から微調整が必要になることもあります。
(実際、僕がそうでした。)




画面サイズがうまく合わない



続きまして、画面サイズの問題です。


最初にも書きましたが、WebGLで出力すると(WebGLに限った話ではないかもしれませんが)画面のUIが崩れたり、あるいは、画面サイズが大き すぎて、スクロールしないと見れないことがあります。




それぞれ解決していきましょう。


まず、uGUIの方です。


Canvasを選択し、「Canvas Scaler」という項目を見てください。



UI Scale Modeを「Scale With Screen Size」というのにしてください。

これにより、UIはスクリーンサイズに合わせてレイアウトを維持してくれます。



そして、その下の部分で、基本となる画面の解像度を設定してきましょう。
僕は、Unityにおける「Srandalone」のサイズにしています。




この部分をしっかり設定しないと、画面全体が表示されず、一部だけ拡大されて表示されるということが起こる可能性があります。


Screen Match Modeは「Expand」にしました。




これで、UIのレイアウトが崩れたり、画面の一部だけが表示される、なんてことは起こらなくなると思います。




そうしたら次に、ブラウザのサイズにゲーム画面サイズを合わせるということをやっていきましょう。




こちらも簡単です。
ある無料アセットを導入し、ビルド時のテンプレートにそれを選択すればいいのです。


まず、Asset Store で、「responsive」と検索しましょう。



そうしましたら、この「Responsive WebGL Template」というのをダウンロード、インポートし、プロジェクトに導入してください。




ビルドセッティングから「Player Settings」を開きます。



WebGLテンプレートで、先ほどインポートした「Responsive」を選択します。




これで、一通りの設定が終わりました。


後は、WebGLで出力するだけです。

ブラウザのサイズを変更すると、縦横比を保ったまま、ゲーム画面のサイズも変わります。




お疲れさまでした。




ではさようなら。
またお会いしましょう。

もしよければ、LINEスタンプの方もよろしくお願いします。


https://line.me/S/sticker/7072968

無言で何かを伝えよう とする白男くん - LINE スタンプ | LINE STORE

白男くんが何もしゃべらずに、何か大事なことを伝えようとするスタンプです。


お そらくいつでも使えるLINEスタンプ集


2020年1月10日金曜日

[Enchant.js]Granim.jsを利用してマ〇オの無敵状態(スターの状態)みたいな虹色グラデーションをつくる


はい、こんにちは。
@CortanMathです。


少し遅れましたが、あけましておめでとうございます。



僕は今年(去年?)年賀状代わりにこんなものを作りました。
Enchant.jsを使用した横スクロールゲームになっています。





一応こちらにリンク張っておきます。

http://kumakuma.life.coocan.jp/ShiraoAkeome/

上のはバージョン1になります。



で、こっちがバージョン2。

http://kumakuma.life.coocan.jp/ShiraoAkeome2/

何が違うがおわかりいただけたでしょうか。




答えは無敵状態機能です。

以前のバージョンでは、1倍速⇒2倍速⇒8倍速という感じにスクロールスピードを上げ、難易度を高めていたのですが、さすがに8倍速は無理がありまし た。

ということで、いのししを5回倒すと永遠に無敵状態に入るようなアップデートを行いました。
(ゲームとしての仕様に問題があることに関してはアップデートされませんでした。)


実際に完成したものがこんな感じになっています。
無敵状態は動画の後半の方です。



でこれをつくるにあたって課題となったのが、マ〇オの無敵状態みたいにキラキラ光らせる処理で す。



無敵状態なったとき敵に当たったらその敵を倒すという処理は、フラグの変数を使用すれば割と簡単に実現できます。


ただ、この無敵状態を表すため、プレイヤーを虹色にするという処理に悩みました。




いろいろ調べた結果、Granim.jsというライブラリを使用することに決めました。



Granim.jsについて



今回使用するGranim.jsというのは、いろいろな色のグラデーションをアニメーションさ せることのできるJavaScriptライブラリです。



公式サイトにデモやソースコードが載っているので、そちらを見た方が理解がはやいと思います。



公式サイト:
https://sarcadass.github.io/granim.js/index.html


デモページ:
https://sarcadass.github.io/granim.js/examples.html



見てるだけでも、結構面白いです。



使い方は簡単で、以下のページからGranim.js本体をダウンロードし、HTMLファイルから読み込むだけです。

https://github.com/sarcadass/granim.js/releases


解凍したうちの「dist」フォルダ内に「granim.js」「granim.min.js」があると思います。


どちらか一方(どちらでもよい。minは圧縮されたファイルになっていて少し容量が少ない。)をコピーして使う感じですね。


公式サイトにサンプルコードがいろいろ載っているので、迷うことはあまりないと思います。


現在(この記事執筆時)の最新バージョンはv2.0.0です。


実際に無敵状態にする



では実際にやってみましょう。


まずは、Enchant.jsとGranim.jsをHTMLから読み込みます。


<script type="text/javascript" src="./js/lib/enchant.min.js"></script>
<script type="text/javascript" src="./js/lib/granim.min.js"></script>


今回はどちらも、minとなっている方(軽量化タイプ)を選びました。

ファイルのパスは各自のフォルダ構造に合わせて設定してください。



次にJavaScriptの方を書いていきます。

Enchant.jsを使用しますので、詳しい全体のコードの書き方などは、Enchant.jsのサイトを参考にしてください。

今回は無敵処理部分のみ載せておきます。



ちょっと長いです。


    //無敵状態画像
    var player_surface = new Surface(360, 180);

    var tmpCanvas = document.createElement('canvas');
    tmpCanvas.width = 360;
    tmpCanvas.height = 180;

    document.body.appendChild(tmpCanvas);
    tmpCanvas.style.visibility = 'hidden';

    var granimInstance = new Granim({
        element: tmpCanvas,
        direction: 'left-right',
        opacity: [1, 1],
        states: {
            "default-state": {
                gradients: [
                    ['#EB3349', '#F45C43'],
                    ['#FF8008', '#FFC837'],
                    ['#4CB8C4', '#3CD3AD'],
                    ['#24C6DC', '#514A9D'],
                    ['#FF512F', '#DD2476'],
                    ['#DA22FF', '#9733EE']
                ],
                transitionSpeed: 100
            }
        }
    });

    var mask = new Image();
    mask.src = './img/player.png';

    var invincibleDraw = function () {
        player_surface.context.globalCompositeOperation = 'source-over';
        player_surface.context.drawImage(tmpCanvas, 0, 0);
        player_surface.context.globalCompositeOperation = 'destination-in';
        player_surface.context.drawImage(mask, 0, 0);
    };

    mask.onload = function () {
        invincibleDraw();
    };


    var player = new Sprite(120, 180);
    player.image = game.assets['./img/player.png'];
    player.y = 120;
    main.addChild(player);


まず前提として、プレイヤーの画像はこんな感じになっていて、アニメーション用に3パターンが あります。
これらは、360×180の1つの画像にまとまっていまして、一つのパターンあたり120×180のサイズになっています。



上に乗せたコードは、メインシーン読み込み時に一度だけ実行されるものです。

player_surfaceというのは、無敵状態の画像を入れておく Surface(Canvasをラップしたもの)です。



大まかな流れとしては、

player_surfaceに無敵用のキラキラ画像を生成しておく。

通常時はplayerのスプライトの画像として、直接元の画像ファイルを指定しておく。

無敵状態に入った場合、playerのスプライトの画像を、player_surfaceに切り替える。


という感じですね。


スプライト自体は、120×180にし、サーフェイスの方はアニメーションの切り替えのため360×180にしてあります。

また、フレームの切り替えは、ここには載せていませんが、onenterframeの部分に書いてあります。




で、ここからが今回の本題となります。

どうやって、虹色画像を生成するかです。



Granim.jsではキャンバスを指定し、そこに虹色のグラデーションを生成することができます。

ということで今回は、360×180の一時的なキャンバスを生成し、bodyに追加後(追加しないと正しく動作しませんでした。)、非表示にしていま す。

あくまで、プレイヤーの全体の画像と同じサイズの虹色グラデーションを作り、画面上では見えないようにしているだけです。

ちなみに、このグラデーションは勝手にアニメーションされます。



granimInstanceというのが、実際にグラデーションを生成している部分ですね。



elementに描画するキャンバスを指定しています。


本来はCSSセレクタで指定するようです。
なので、一時的なキャンバスにidを設定し、element部分に「#id名」と指定してみましたが、うまく動きませんでした。


なぜか、キャンバスの変数を指定したら動きました。



Granim.jsの詳しい使い方は、公式サイトのAPIのところを見てください。



次に進みます。



先ほど作った虹色グラデーション画像を元のプレイヤー画像でマスクし、player_surfaceに描画します。



要するに、虹色グラデーション画像のうち、キャラ画像の形の部分だけが残る画像が生成されるわけです。



ただ、これだけだと、グラデーションがアニメーションされないので、invincibleDraw関数は毎フレーム事に呼び出します。



後は、無敵状態を表すフラグを変数で用意しておき、無敵の条件が揃ったらそれをtrueにする。

それをもとに、スプライトの画像をplayer_surfaceに切り替えたり、敵を倒す処理を書いたりすればよいわけです。





Granim.jsは別に無敵処理とかじゃなくても面白く使えると思うので、ぜひ試してみてください。




ではさようなら。
またお会いしましょう。

もしよければ、LINEスタンプの方もよろしくお願いします。


https://line.me/S/sticker/7072968

無言で何かを伝えよう とする白男くん - LINE スタンプ | LINE STORE

白男くんが何もしゃべらずに、何か大事なことを伝えようとするスタンプです。


お そらくいつでも使えるLINEスタンプ集


2019年10月20日日曜日

YouTubeの動画をダウンロードするならブラウザの拡張機能「YouTube Video Downloader」がおすすめ!音声ファイルMP3への変換も可


みなさん、こんにちは。
‎@CortanMathです。


最近、YouTubeが急成長していますよね。


ということで、今回はYouTube動画をMP4などの動画ファイル、MP3などの音声ファイルとしてダウンロードする方法をご紹介します。


もちろん、違法にならないように使用してください。
いかにも違法アップロードされた動画などをダウンロードすることは犯罪になります。



YouTubeをダウンロードする方法と言ってもいろいろあるのですが、今回は中でも手軽な「拡張機能を使用するやり方」をお勧めします。



拡張機能と言えば、Chromeの拡張機能が有名ですね。



で、今回使用する拡張機能は「YouTube Video Downloader」というものです。
YouTube動画のダウンロードに特化した拡張機能で、MP3に変換ダウンロードもできます。


対応ブラウザは、以下のようになっています。



  • Chrome
  • Chromium
  • Firefox
  • Opera
  • Vivaldi
  • UCBrowser
  • Comodo Dragon
  • SRWare
  • Slimjet


主要ブラウザはだいたい対応してますね。


では、実際にやってみましょう。



拡張機能のダウンロード・インストール



拡張機能「YouTube Video Downloader」のダウンロードは以下のURL先から行えます。

https://addoncrop.com/youtube_video_downloader/


すると右側のサイトバーにこのようなものが表示されていると思いますので、ここからダウンロー ドできます。



僕はこの時、Edgeブラウザで開いてしまったので、「Edgeのバージョンは手に入らない」つまり、「Edgeには対応していない」といわれてしま いました。


そういう時は、下の「Download For Other Browser」から指定したブラウザ版の拡張機能がダウンロードできます。


もちろんそこで選んだブラウザにしか使えませんが、ダウンロードはどのブラウザでもできます。




ダウントードできたら、実際にブラウザにインストールしてみましょう。
今回僕は、Chrome版をダウンロードしたので、Chromeで操作していきます。




ブラウザのメニューから、「拡張機能」を選択します。



そうしたら、「デベロッパーモード」をオンにしましょう。
これをオンにしないと、Store以外からの拡張機能はインストールできません。




「パッケージ化されていない拡張機能を読み込む」をクリックし、先ほどダウントードしたファイルを選びます。

インストールが完了したという画面が出れば、成功です。



では、実際に使ってみましょう。


「YouTube Video Downloader」を使用する



まず、拡張機能を入れたブラウザでYouTubeを開き、ダウンロードする動画のページを出し ます。
僕は、自分の動画のページを開きました。
(DominoでMIDIの打ち込みしてみた系のやつですね。)



高評価ボタンの左にある「…」ボタンから、メニューが出せるので、ここから好きな設定でダウンロードできます。
「Convert to MP3」を選択すれば、MP3(音声ファイル)としてダウンロードできます。


最後に


以上です。


拡張機能なだけあって、手軽で便利ですが、1つデメリットを上げるとすればこれですね。


デベロッパーモードをオンにしたがために、ブラウザ起動時、毎回これが出てきます。

「デベロッパーモードの拡張機能を無効にする
デベロッパーモードで実行される拡張機能はパソコンにダメージを与える恐れがあります。...」


ただ、デベロッパーモードをオフにすると、この拡張機能が使用できません。


消し方も調べたのですが、なんかいい感じの解決策が見つかりませんでした。



我慢するしかないですね。


では、これで終わります。
また次回お会いしましょう。
さようなら。


2019年8月25日日曜日

メインアドレスでも捨てアドでも便利なYahooメールの紹介!<超簡単に取れるフリーメールアドレス>


こんにちは。


ネットを使っていると、メールアドレスが必要になることがよくあると思いますが、皆さんは、メールアドレスとして何を使用していますか。



僕はメインのアドレスとして、gmailを使用しています。

主要な場合はこのアドレスを使えばいいのですが、場合によってはこの本アドレスを使用したくない場合などもありますよね。

例えば、ちょっとしたWebでの登録にメールアドレスが必要な時、あるいは、Web上で知り合った人などと連絡を取らなければならない場合などです。



こう場合に、メインのアドレスを使用するのは、リスクが高いです。



ということで、メインとは別に、サブのフリーメールアドレスを取っていこうとなるわけです。



フリーのメールアドレスと言えば、gmailやyahoo mail、outlookなどが思い浮かびます。

調べたところ、そんな中でもYahooメールは特に登録が簡単で、サブメールアドレスに適してそうなので、今回は、こちらをご紹介します。


もちろん、Yahooメールはサブメールアドレスだけでなく、メインのメールアドレスとしてでもおすすめです。


新規メールアドレス取得方法



まずは、こちらのページにアクセスします。

https://mail.yahoo.co.jp/promo/


おそらく上の画像のような画面が出てくると思いますので、「今すぐメールアドレスを作る」をクリックします。


すると以下のような、登録画面が開きます。



ここに必要な情報を入力し、登録を完了させます。

とはいえ、入力する情報はかなり最低限です。
他のメールサービスと比べると、入力内容がかなり少ないように思えます。


以前のYahooメールは、既存のメールアドレス無しで新規にメールアドレスの作成ができたようですが、現在はできなくなっています。

すでに持っているgmailなどのフリーメールアドレス、または、キャリアメールアドレスなどを入力する必要があるようです。

メールアドレス取得にメールアドレスが必要だなんて変な話ですが、本人確認のためなので仕方がないでしょう。


どうでしょうか。
メールアドレスの取得はできたでしょうか。
簡単だったと思います。


Yahooメールもgmail上でまとめて管理するのがおすすめ



無事、Yahooメールでサブメアドを用意したわけですが、もし、さらにサブメアドを作って いったりしたら、管理が大変ですよね。

ちなみに、Yahooメールは1人のアカウント所有数が決まっていないようなので、いくらでも作れます。



ということで、今回はgmailで管理する方法をお勧めします。

理由としては、gmailはほとんどの人が使用しているだろうということ、また、gmailの アプリは使いやすいというのもあります。


Yahooメールをgmailで扱うようになると次にようになります。

  • Yahooメールに届いたメールをgmailのアドレスに転送し、gamilで受信
  • gmailからgmailのサーバーを経由し、Yahooメールのアドレスでメールを転 送


メールの受信方法ですが、上に書いた方法(Yahooメールに届いたものを、gmailの方に 転送する方法)とは別に、Yahooで受信したものをgmailアプリから見に行くという方法もあります。

ただし、こちらは、メールの受信が遅れる(すなわち、リアルタイムに受信できない)、通知が来ないなどの問題がありましたので、あまりお勧めはしませ ん。



今回は、おすすめの方法でご紹介します。


メールの受信

まず、ブラウザでYahooメールにアクセスし、「メールの設定」から「IMAP/POP /SMTPアクセスとメール転送」という項目を開きます。



「ほかのメールアドレスにメールを自動転送する」を選択し、転送先メールアドレスにgmail のアドレスを入力します。


これで、Yahooメールに届いたメールは、gmailのアドレスに届きます。


gmailで通知設定をしていれば、同様にリアルタイムで通知が来ます。


なお、届いたメールがgmail宛てなのかYahooメール当てなのかは、見ればわかるようになっているので、ご安心ください。


ちなみにメールの実体は、Yahooのサーバーではなく、gmailのサーバーに残ります。


メールの送信

続いてメールの送信です。
gmailアプリからYahooのメールアドレスを使って送信できるようにしたいですよね。



幸いgmailには、他のメールアドレスを追加する機能が備わっていますので、それを使用します。


しかし、その前に、ここで使用するgmailのgoogleアカウントは2段階認証になっている必要があります。
もし、2段階認証にしてなければ、設定してください。
ついでにセキュリティが上がるので、おすすめです。


まず、gmailの設定画面を開きます。

「アカウントとインポート」というところを開き、「名前:」という欄にある「他のメールアドレ スを追加」をクリックします。


出てきた画面に従って入力してください。


SMTPの設定では次のように入力してください。
既存の設定では、Yahooの情報が入力されていると思いますが、先ほどメール受信の設定でYahooのSMTPサーバーは無効になってしまったので 使用できません。


  • SMTPサーバー: smtp.gmail.com
  • ポート: 587 (465でも可能)
  • ユーザー名: Gmailのユーザー名(gmailアドレスのうち、@より手前の部分)
  • パスワード: Gmailの2段階認証で取得したパスワード(後術)
  • SSL or TLS: ポートによって出る推奨に合わせる(587ならTLS、465ならSSL)


パスワードですが、googleにログインしたブラウザで以下のurlを開き、「アプリパス ワード」を生成してください。
そこで生成されたものを、上のパスワードのところに入力します。

https://myaccount.google.com/security


以上です。

これで、gmailでYahooのメールも管理することができるようになりました。


これで、快適なメールライフをお過ごしください。
では、さようなら。
また、お会いしましょう。


[Enchant.js]テトリスもどきをつくってみたかった...~落ちて2つに破壊する~


こんにちは。

皆さん、「Enchant.js」ってご存知ですか?


「Enchant.js」とは


Enchant.jsとは、ゲームやアプリを簡単に作れるJavaScriptのライブラリで す。
HTML5+JavaScript+CSSのWebアプリを作る際に使えます。


オープンソース(MITライセン ス)なので、無料で使え、また、商用利用などもできます。


Webアプリなので、サーバーにアップロードしておけば、PCだけでなくiPhone・Androidなどのスマホでもアプリを実行できます。

Webアプリの状態でも全画面表示にしてアプリっぽくしたり、あるいはPWAにしてオフライン対応にすることもできます。
もしくは、Apache Cordovaでネイティブアプリにもできます。


要するにマルチプラットフォームなわけです。



こちらの公式サイトからダウンロードできます。

http://enchantjs.com/ja/


Enchant.js本体だけでなく、ゲームに使える画像素材やプラグインなども入っています。


テ■リスをつくりたかったのに...


今回は、このEnchant.jsを使って、テ■リスもどきをつくっていこうと思います。

あくまでも流れを紹介するだけなので、詳しいことは省きます。
チュートリアルではないので、ご了承ください。


ファイルなどの準備

まずは、ファイルなどの準備をしていきます。



最初に用意するのは、HTMLファイルと、JavaScriptファイルですね。


フォルダ構成はこんな感じです。



次に画像の作成を行いました。

ゲーム自体に使う画像と、アイコンにする画像の2つを用意しました。
フリーの画像編集ソフト「GIMP」を用いて作成しております。



ゲームに使う方の画像は、色違いでひとマスずつ作成し、プログラムの方で各プロックを作成する ようにしました。

また、アイコンの方は、スマホ(Android or iPhone)でホーム画面に追加したときに表示されるアプリアイコン画像です。


続きまして、HTMLの中身を用意します。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8" />
    <title>T□TRIS</title>

    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <link rel="apple-touch-icon" href="./img/icon.png">

    <script type="text/javascript" src="./js/lib/enchant.min.js"></script>
    <script type="text/javascript" src="./js/main.js"></script>

    <style>
        body {
            padding: 0;
            margin: 0;
            background: #000000;
        }
    </style>
</head>

<body>

</body>

</html>


こんな感じです。

メインのJavaScriptファイル及びEnchant.jsの読み込み、アイコンの設定、 スマホでホーム画面に追加したときの全画面設定などを行っております。


メインのJavaScriptを書いていく

ゲームを動作させるメインのプログラムをJavaScriptで書いていきます。

実装させる基本的な処理はこちらです。

  • スタート画面作成
  • 枠組みの表示
  • 各ブロック生成
  • テ■リス落下
  • 移動、回転処理
  • 着地処理
  • 一列揃ったら消す
  • スコアを付ける

では、早速書いていきましょう。


スタート画面の作成は、特に難しいことはないですね。

シーンを2つ作って、一つをスタート画面、もう一方をゲームメイン画面とします。
最初はスタートのシーンを表示して、それをタッチするとメイン画面に切り替えるようにしてあります。



枠組みは、Enchant.jsのマップ機能を使用して作成しました。
最初に用意した画像のうち、茶色のマスを使用しています。



次に、ブロックの生成ですね。


最初に、このような画像を用意したと思います。

一番左のマスは、先ほど枠組みとして使用しましたから、テ■リスのブロック生成には、残りの4 色を用います。


作るブロックの形は、以下の5種類です。
色は気にしないでください。
形ごとに4色分のブロックを作りますので、合計20種のブロックができます。(本家だと形ごとに色が決まってたりしましたっけ?そのへんあやふやです みません。)



形の種類の数が本家と違うと思いますが、著作権の問題のためです。
そのまま同じにはできないわけです。


ではこの部分のソースコードです。

var tetris_map = [
                [
                    [1, 1, 1, 1]
                ],
                [
                    [1, 1],
                    [1, 1]
                ],
                [
                    [0, 1, 0],
                    [1, 1, 1]
                ],
                [
                    [1, 0, 0],
                    [1, 1, 1]
                ],
                [
                    [1, 1, 0],
                    [0, 1, 1]
                ]
            ];

            var tetris_surface = new Array();


            for (var i = 0; i <= 3; i++) {
                for (var j = 0; j <= 4; j++) {

                    var tmp_surface = new Surface(tetris_map[j][0].length * 32, tetris_map[j].length * 32);

                    for (var k = 0; k < tetris_map[j].length; k++) {
                        for (var l = 0; l < tetris_map[j][k].length; l++) {

                            if (tetris_map[j][k][l] == 1) {
                                tmp_surface.draw(game.assets['./img/tetris.png'], (i + 1) * 32, 0, 32, 32, l * 32, k * 32, 32, 32);
                            }

                        }
                    }

                    tetris_surface.push(tmp_surface);

                }
            }


Surfaceというのは、Canvasをラップしたもので、Enchant.js上で Canvasを使用するのに使います
Spriteのimageに代入することで、画像として表示できます。


ここでは、あらかじめ配列にブロックの形を用意しておいて、4重ループで、それに応じて20のブロックを生成し、tetris_surfaceという 配列にプッシュしています。


次に行きます。

テトリスの落下は、特に難しいことはないですね。
ただy座標を足していくだけです。

個人的にはなめらかに動いてほしくないので、毎フレームちょっとずつ動かすのではなく、何フ レームかごとに1マス分足しています。

この何フレームかごとというのは、if分と変数を使って処理しています。


では次にいきましょう。


次は移動回転処理ですね。

これが地味に難しかったです。


まず操作方法ですが、PCとスマホのどちらでも動くようにしたいので、キー操作とタッチ操作の両方を実装します。


<PCの場合>
・方向キーの左右で移動
・方向キーの上で右回転、「/」キーで左回転
・方向キーの下で加速落下


<スマホの場合>

・画面のタップで移動
(左半分をタップすれば左、右半分なら右)


・左から右へドラッグで、右回転
右から左へドラッグで、左回転


・上から下へドラッグで、加速落下



操作の部分はそこまで難しくないです。
が、問題は実際の回転の部分なのです。


正方形のブロックは回転の中心がちょうどいいところにくるので大丈夫なのですが、そのほかのブロックは回転の中心が微妙なところにくるので、回転した 瞬間、枠組みの配列に対して、ズレが生じるのです。


ということで、回転後に計算した分のずれを、x軸、y軸に足して、調節することにしました。


tetrisという変数は、メインの動かしているスプライトです。

tetris_wとtetris_hは、それぞれ現在のブロックの幅と高さが入る変数です。
単純にtetris.widthとtetris.heightでは、回転した後も値が変わらず、現在表示されている状態での幅や高さにならないので、 わざわざこのような変数を用意して、回転に応じて値を調節しています。

tetris_center_xは、スプライトの中心のx座標です。
回転処理をしているうちにだんだん右に移動していったり、左にいったりなどということが起こってしまったので、この変数を使用して、それを防止してい ます。

これらの変数はあらかじめ宣言し、落下するブロックを生成した段階で、値を代入しています。


ソースコードを見てもらった方が早いですね。


var change_wh = function () {
    var tmp = tetris_w;
    tetris_w = tetris_h;
    tetris_h = tmp;
};

var tetris_left_rote = function () {
    tetris.rotation -= 90;
    change_wh();
    tetris.x = Math.floor((tetris.x + (tetris.width - tetris_w) / 2 - 4) / 32) * 32 + 4 - (tetris.width - tetris_w) / 2;
    tetris.y = Math.round((tetris.y + (tetris.height - tetris_h) / 2 - 80) / 32) * 32 + 80 - (tetris.height - tetris_h) / 2;

    if (tetris_center_x - 32 >= tetris.x + tetris.width / 2) {
        tetris.x += 32;
        tetris_center_x = tetris.x + tetris.width / 2
    }

    if (tetris.x + ((tetris.width - tetris_w) / 2) < 36) {
        tetris.x = 36 - (tetris.width - tetris_w) / 2;
    }
    if (tetris.x + tetris.width - ((tetris.width - tetris_w) / 2) > 324) {
        tetris.x = 324 - (tetris.width - ((tetris.width - tetris_w) / 2));
    }
};
var tetris_right_rote = function () {
    tetris.rotation += 90;
    change_wh();
    tetris.x = Math.ceil((tetris.x + (tetris.width - tetris_w) / 2 - 4) / 32) * 32 + 4 - (tetris.width - tetris_w) / 2;
    tetris.y = Math.round((tetris.y + (tetris.height - tetris_h) / 2 - 80) / 32) * 32 + 80 - (tetris.height - tetris_h) / 2;

    if (tetris_center_x + 32 <= tetris.x + tetris.width / 2) {
        tetris.x -= 32;
        tetris_center_x = tetris.x + tetris.width / 2
    }

    if (tetris.x + ((tetris.width - tetris_w) / 2) < 36) {
        tetris.x = 36 - (tetris.width - tetris_w) / 2;
    }
    if (tetris.x + tetris.width - ((tetris.width - tetris_w) / 2) > 324) {
        tetris.x = 324 - (tetris.width - ((tetris.width - tetris_w) / 2));
    }
};


回転した後に左右の枠をはみ出た際の処理も書いています。

移動でも同様な感じでズレの判定をしています。



では、次に行きましょう。

次は着地処理及び、消去処理ですが、ここで問題発生です。

ここら辺の書き方がよくわからなかった。
僕には少し早かったみたいです。


ということで、この部分の処理をやめて、違う処理を入れました。

落下し、着地した瞬間、こんな感じにします。



地面についた瞬間、2つに破壊されるんですね。



しょうもな...


ということで、やっていきましょう。


テ■リスを2つに破壊する



では、どうやって先ほどのように割るのかというと、JavaScriptでCanvasのピク セル操作を行うことで、破壊されたように見せます。


CanvasのコンテキストのgetImageDataで指定した範囲のピクセルデータを取得し、putImageDataで逆に書き出します。


実際に、プログラムを見てもらいましょう。

var mod = function (i, j) {
    return (i % j) < 0 ? (i % j) + 0 + (j < 0 ? -j : j) : (i % j + 0);
};

var destroy = function (s) {

    var speed = s;

    tetris.visible = false;

    var destroy_imagedata = tetris.image.context.getImageData(0, 0, tetris.width, tetris.height);

    var destroy_surface_left = new Surface(tetris.width, tetris.height);
    var destroy_surface_right = new Surface(tetris.width, tetris.height);

    var destroy_left = new Sprite(tetris.width, tetris.height);
    var destroy_right = new Sprite(tetris.width, tetris.height);


    main.addChild(destroy_left);
    main.addChild(destroy_right);



    destroy_left.x = tetris.x;
    destroy_left.y = tetris.y;
    destroy_left.rotation = tetris.rotation;
    destroy_right.x = tetris.x;
    destroy_right.y = tetris.y;
    destroy_right.rotation = tetris.rotation;


    switch (mod(tetris.rotation / 90, 4)) {
        case 0:
            for (var h = 0; h < tetris.height; h++) {
                var r = Math.floor(Math.random() * 20) - 9;

                for (var w = 0; w < tetris.width; w++) {

                    if (w == (tetris.width / 2) + r - 1) {
                        destroy_surface_left.context.putImageData(destroy_imagedata, 0, 0, 0, h, w + 1, 1);
                    }
                    if (w == tetris.width - 1) {
                        destroy_surface_right.context.putImageData(destroy_imagedata, 0, 0, (tetris.width / 2) + r, h, tetris.width - ((tetris.width / 2) + r), 1);
                    }
                }
            }
            break;
        case 1:
            for (var w = 0; w < tetris.width; w++) {
                var r = Math.floor(Math.random() * 20) - 9;

                for (var h = 0; h < tetris.height; h++) {

                    if (h == (tetris.height / 2) + r - 1) {
                        destroy_surface_right.context.putImageData(destroy_imagedata, 0, 0, w, 0, 1, h + 1);
                    }
                    if (h == tetris.height - 1) {
                        destroy_surface_left.context.putImageData(destroy_imagedata, 0, 0, w, (tetris.height / 2) + r, 1, tetris.height - ((tetris.height / 2) + r));
                    }

                }

            }
            break;
        case 2:
            for (var h = 0; h < tetris.height; h++) {
                var r = Math.floor(Math.random() * 20) - 9;

                for (var w = 0; w < tetris.width; w++) {

                    if (w == (tetris.width / 2) + r - 1) {
                        destroy_surface_right.context.putImageData(destroy_imagedata, 0, 0, 0, h, w + 1, 1);
                    }
                    if (w == tetris.width - 1) {
                        destroy_surface_left.context.putImageData(destroy_imagedata, 0, 0, (tetris.width / 2) + r, h, tetris.width - ((tetris.width / 2) + r), 1);
                    }
                }
            }
            break;
        case 3:
            for (var w = 0; w < tetris.width; w++) {
                var r = Math.floor(Math.random() * 20) - 9;

                for (var h = 0; h < tetris.height; h++) {

                    if (h == (tetris.height / 2) + r - 1) {
                        destroy_surface_left.context.putImageData(destroy_imagedata, 0, 0, w, 0, 1, h + 1);
                    }
                    if (h == tetris.height - 1) {
                        destroy_surface_right.context.putImageData(destroy_imagedata, 0, 0, w, (tetris.height / 2) + r, 1, tetris.height - ((tetris.height / 2) + r));
                    }

                }

            }
            break;

    }



    destroy_left.image = destroy_surface_left;
    destroy_right.image = destroy_surface_right;


    destroy_left.tl.rotateBy(-270, speed);
    destroy_right.tl.rotateBy(270, speed)
    destroy_left.tl.and();
    destroy_right.tl.and();
    destroy_left.tl.moveBy(-200, 300, speed);
    destroy_right.tl.moveBy(200, 300, speed);

    destroy_right.tl.then(function () {
        main.removeChild(destroy_left);
        main.removeChild(destroy_right);

        createTetris();
        frame_cnt = 0;
        frame_max = 30;
        touch_down = false;

        down_fg = true;
    });

};


まず、破壊された後、左側に落ちるスプライトと、右側に落ちるスプライトの2つを用意します。


ブロックの回転具合によって、分割する箇所が異なるので、そこのところを場合分けで書いていきます。



いよいよピクセル処理の出番です。


Enchant.jsのSurfaceの方にも、getPixelとsetPixelというピクセル処理の機能が備わっているのですが、こちらは、1 ピクセルごとに処理するため、動作がかなり重いです。


なので、今回はラップされていないもともとの「getImageData」と「putImageData」を使用します。



回転による場合分けをした後、2重ループを使い、ブロックの幅をランダムな長さにしながら、左右のスプライトに分けています。



分けた後は、もとのメインスプライトを非表示にし、2つのスプライトをうまく動かして、落下させます。

落下スピードに応じて、破壊後の動きにも変化をつけています。


破壊処理は以上ですね。


スコアは適当につけています。


かなり、はしょったわかりにくい説明だったと思います。
ソースコードもこれだけではよくわからないでしょう。


ということで、ソースコードの全体は、こちらから見れます。

http://kumakuma.life.coocan.jp/DestroyTetris/js/main.js


完成



プレイ動画(?)みたいなのは、この動画の後半にあります。


また、こちらのURLから遊ぶ(?)ことができます。

http://kumakuma.life.coocan.jp/DestroyTetris/


スマホで開いて、ホーム画面に追加するとアプリっぽくなります。
オフラインには対応してませんが。


では、これで終わります。
Enchant.js面白いので、ぜひ触ってみてください。


人気の記事