enchant.jsで円と四角形を簡単に書けるようにしておく

ゲーム作ってるとけっこう円や四角形を使いたい、またはとりあえず円か四角形か表示させて開発を進めたいと思ったりすることないですか?(‘ω’)ノ

わたしは画像書くのが面倒なんで手抜きするために円や四角形をサクッと書けるクラスを作りました(*´ω`)面倒くさがりはプログラマーの資質だと思います(ウソ)

というわけで私はこんな感じにクラスを作って用意してあります(‘ω’)ノ

説明

円も四角形もどちらもすぐ表示出来るようにSpriteを継承して作ります。引数で幅と高さ、そして形を塗りつぶす色を指定します。

まぁあとはサーフェスとかコンテキストとか書いてる通りにすれば出来ます(^^;)←説明する気なし

 

円と四角形が掛けるだけのクラスですがけっこう使い道があります。

たとえば私のこのゲームでは

自機がホップするときに出る炎?みたいなものを作るのに使ってますし、こっちでは

見てわかる通り爆発に使ってます。

まぁ要は使いようってことですわ(*´ω`)

 

あと、どうやら複雑な図形もけっこう書けるらしいので興味のある方は調べてみてください(‘ω’)ノ

ゲームの進行状況などをローカルストレージに保存しよう

やっぱりゲームにはセーブ機能が欲しいよなぁ(´Д`)

という願いを叶えてくれるのがローカルストレージというブラウザが持っている機能です。このローカルストレージという機能がどういったものかっていうのはさっぱりわからんが、使えると大変便利な機能です。

例えばパズルゲームの進行状況を保存したり(何面までクリアしたか)とか、ハイスコアを記録させたりとか簡単にできます。

まぁローカルストレージの詳しい話はよそのサイトでしてもらうとして(^^;)、私はこんな感じに作りました(‘ω’)ノ

適当な説明

Storageというクラスを作ってストレージを操作する処理を作っています。

各メソッド名そのままの機能です(^^;)

基本的にセーブとロードができればいいんですが、開発してるときにはデータを消したりする必要もあるのでデリートも出来るようにしてあります。

クラスを生成するときに引数にローカルストレージの名前を指定します。この名前でローカルストレージが読み書きされます。

dataはゲーム内容を保存するオブジェクトです。プログラム内ではここに好きなデータを保存します。ハイスコアを保存したいならhiscoreというプロパティを作って値を保存します。

JSON.○○○というのはローカルストレージがJSON形式で保存するためらしく、そのための変換処理を行う命令のようです。

 

サクッと簡単な説明でしたが、実際ローカルストレージはすごい簡単に使えます(*´ω`)ただしゲームの進行状況をどういう風に保存するかは自分で考えないといけないのでそっちが問題ですね(‘ω’)ノ

enchant.jsのLabelをちょっぴり使いやすくする

enchant.jsのLabelがフォントサイズを変更したりするだけなのにフォント名も一緒に書かないといけないのが面倒なのでちょっと変えてみました(‘ω’)ノ

説明

Labelを継承してクラスを作っています。基本的にフォントサイズとフォントの種類を別々に設定できる以外は普通のLabelです(^^;)

引数のsizeはフォントサイズ、fontはフォント名です。指定したい場合に入力してください。引数がない場合はデフォルトの値が設定されます。

面倒臭がりな方はゲームで一番使うフォントサイズとフォントの種類を最初から設定しておきましょう(*´ω`)

enchant.jsのロード画面を好きなように改造する

enchant.jsのゲームを起動すると一番最初に表示される画面。

このバーが満たされていくことでロード状況を教えてくれるわけですが、何もない画面にこれだとなんか寂しいので改造してみましょう。

ちなみにこれはオリジナルゲーム.comさんの記事を読んだのがきっかけです。

この記事ではloadSceneを作ってgameオブジェクトのloadingSceneに入れているんですが、それならenchant.jsの中身のloadingSceneを直接いじってやろうじゃねぇか!!となった、ということです(*´ω`)

loadingSceneの中身

enchant.js内のloadingSceneの中身がこちら。

なんとこの部分はjavascriptそのものではなく我々が慣れ親しんだenchant.jsのスタイルで書かれています!!これなら改造し放題!!(・∀・)

と、行きたいところですが、ここでは画像や音楽は使えません。だってロード前だから。読み込み状況を知らせてくれる画面だから。。(´;ω;`)

と、諦める必要はなくて、画像を出したいならここで必要な画像だけ先に読み込んでしまえばOKってことです。まぁその方法はオリジナルゲーム.comさんの記事を読んでくださいな(‘ω’)ノ

ちなみに私はこんな感じに作りました。

ラベルを追加して読み込み状況のバーの太さを変えました。barwidth、barHeight、borderあたりの値を変えてやれば簡単にできますよ(‘ω’)ノ

enchant.jsの不安定なフレーム処理を改造する

enchant.jsではFPS(1秒間に画面を更新処理する回数)を好きなように設定できるようになっているのですが、これがどうも安定していないというのがずっと気になっていました。

パズルゲームなどを作っている段階では気にならなかったんですが、シューティングゲームを30FPSで作ってみるとどうも弾の動きが早くなったり遅くなったりしている。

気になりだしたら凄く気になるので改造を試みてみました。

requestAnimationFrame()が更新している

javascriptの知識のまったくない素人がenchant.jsの中身を読んでも全く理解できません(;´・ω・)

が、時間をかけてそれっぽいところをついに探し当てrequestAnimationFrame()という関数が画面の更新処理をしているということを突き止めました( `ー´)ノ

で、更新処理をしているであろう所を読んでみるとなんか変なんですよ。

requestAnimationFrame()が更新処理をしてくれるはずだけどsetTimeout()も使っています。

多分これはrequestAnimationFrame()に対応していないブラウザに対応させるためにあるんだろうと思うんですが(ちゃんとわかっていない)、たぶんいらないんじゃね?(・∀・)

ってことでばっさりカット。

しかし、これだと60FPSになります(requestAnimationFrame()は60FPSで更新処理する)。なのでこの_requestNextFrame が呼ばれたときに好みのFPSになるように調整して必要な時だけ処理するようにします。

たとえば30FPSにしたい場合2回に1回処理するようにすれば処理が半分になり30FPSになります。

で、それを書く場所が _requestNextFrameのちょっとしたにあります。

なんか上でバッサリカットしたらここに_requestNextFrame()が来るようになりました。そしてその下にFPSを調整する処理を書きます(30FPSにしたいなら2回に1回処理するように書く)。変数を使ってゲームによって変更できるようにしておいた方が良いです(自分で考えてね(^_-)-☆)

あとついでにrequestAnimationFrameで検索すると以下のようなところがあります。

たぶんこれはrequestAnimationFrameに対応していないブラウザのための処置だと思うんですが、これ無しで動くのでこいつもバッサリカットしてやりましょう(・∀・)

まとめ

細かい説明はありませんが(説明できないんだよ(;^ω^))こんな感じで修正するとFPSが安定するようになりました。気になる方は試してみてください(改造は自己責任で!ちゃんとバックアップとっとけよ!)

読めるenchant.jsを手に入れよう

enchant.jsは初心者でも簡単にゲームが作れるゲームエンジンです。なので必要最低限の処理は用意してくれているのですが、プログラミングが上達してくると物足りなさや変更したい部分などが出てきます。

ありがたいことにenchant.jsはMITライセンスというライセンスで公開されていて(詳しいことは知らん)、ソースコード内の著作権表示を削除しなければ「ソースコードの改変」「再配布」を自由に行っていいようです。

enchant.jsのライセンス

なのでプログラミング技術が上がってきたら少しずつenchant.jsの改造に着手しましょう。そしていつの日か自作ゲームエンジンを開発してやりましょう!(・∀・)

読めるenchant.jsを手に入れる

enchant.jsダウンロード

上のリンクからenchant.jsをダウンロードするとenchant.min.jsというファイルが入っていて、もちろんこれがenchant.jsなんですけど、これは改行やスペースなどが消されていて読むことができません(´;ω;`)

で、どこかから読めるenchant.jsを入手しないといけないんですが一体どこで手に入れられるのかわからなくてしばらく困っていたんですけど、見つけたんですよ!(・∀・)

enchant.js 0.8.3用プロジェクトテンプレート

jsdo.itはweb上でhtml・css・javascriptの開発が行えるサイトのようで(使ったことないから詳しいことは分からない(^^;))いろんなプログラムが公開されています。なのでenchant.jsを使ったプログラムも公開されていて、なんと!enchant.jsも読める形でアップされています!ヤッター!

ということでここからダウンロードするかコピペしてenchant.jsを手に入れましょう!(私の場合ダウンロードしようとしたらセキュリティーソフトが警告を出したのでコピペしました)

初心者には厳しい現実・・・

で、じっくり読んでみようと思って中身を見てみるとこれが全く理解できない(;´Д`)

当然と言えば当然なんだけど、enchant.jsはゲーム開発初心者でもゲーム制作を楽しめるようにしてくれているゲームエンジンです。つまりプロがプロフェッショナルな技術を駆使して書いてあるプログラムなのでちょっと齧った程度の素人プログラマーが読めるわけはないのです(´;ω;`)

と、諦めるのは早いわけで(;´∀`)

時間をかければ出来るようになるわけで、少しずつ挑戦していきましょう(‘ω’)ノ

enchant.jsのクラスの処理で困ったこと

enchantjs講座

enchant.jsのクラスで私が遭遇した困ったこととその解決策を書いておきます。

thisがダブるとき

クラスを使うと色々な変数をクラスオブジェクトのプロパティとして追加して使うことになるわけですが、たまにイベントリスナを使いたいときに困ったりすることがあります。

と書いたときにplayer.addEventListner内でthis.aaa()メソッドを呼び出した場合、thisはplayerオブジェクトという風に判断されてうまく動いてくれません。こっちはMainGameSceneを指すthisのつもりなのに言うことを聞いてくれません。

一体どうすりゃいいのよ?としばらく悩んで放置していたんですが解決方法は実は簡単でした(´Д`)

変数を作ってやってそれにこのクラスオブジェクトのアドレスを渡してやれば処理できるってわけです。

簡単なことだけど気づかなかった(;´Д`)

クラス内の変数のスコープ

クラス内で宣言した変数は当然ローカル変数になります。それは分かるんだけど同じクラス内でも別のメソッドになるとローカル変数は使えない。

クラスのthis.○○みたいにプロパティにしてしまえば問題ないんだけどシーンのようなたくさん変数を扱う場合すべてをプロパティにするのは入力の字数も多くなるし読みにくくなるしやりたくない。

しかし、実際これはシーンのようなたくさん変数を扱うクラスでない限り問題にならないようで、しかもシーンだと基本的にonenterframeくらいしか使わないのでonenterframeを独立したメソッドとして書かず、

イベントとして処理することで解決しました。

本当は分けて書きたかったんだけど仕方ないね(´・ω・`)

onenterframeは継承しないとない

どうやらonenterframeはSprite、Group、Sceneのどれかを継承してクラスを作らないとフレーム毎に作動してくれません。

そんなに大した問題じゃないけど、どうしてもonenterframeを使いたいってときは継承して作りましょう

なんでもsceneに直接addChildするのは良くない【enchant.js】

今回もちょっとした小技の紹介。大したことじゃないけど知っておくと便利かも。

enchant.jsでは画像はsceneにaddChildすることで表示されます。だけど最初から全部sceneにaddChildしていくと画面全体にエフェクトをかけて演出したいときに困ることがあります。

たとえば画面を揺らす演出をしたいときに画面内に表示されている得点などまで一緒に揺れるのはちょっとおかしくない?それも演出の内なら良いけどそうじゃないなら一緒に揺れると困るわけです。

で、どうするかというとGroupで分けます。ゲームのキャラクターなどを表示するGroupと得点などの情報を表示するGroupって感じに分けて作って振り分けてaddChildします。

例えばこんな感じにしてます。

ゲーム用にscreenというGroupを作ってゲーム部分はそこにaddChildします。keypadはGroupを継承して作ったバーチャルパッドのグループです。ボタンなどはこのkeypadにaddChildされています。

このように作っておくとscreenを動かしたり拡大縮小したりしてもkeypadは完全に別の存在になっているので影響を受けません。

 

大したことじゃないけど、あとから気づいて修正するのは面倒臭いので最初から分けて作っておくのが良いと思います(‘ω’)ノ

enchant.jsで右クリックを使いたい

enchatnt.jsではマウスの右クリックはサポートされていないようです。右でも左でもクリックは同じ扱いで処理されます。そして右クリックするとブラウザのメニューが表示されてしまいます。

でも右クリックが使いたい!!

ゲームで使うつもりだったのに出来ないのは困る!!ってことで方法を探しました。

javascriptで書いてみる

enchant.jsでサポートされていないならjavascript直で処理を書くしかない。ってことで検索して出てきたのがこちら

これでメニューの表示をキャンセルし、右クリックに処理を割り当てることが可能になります。

ただし!enchant.jsとは関連がないのでいろいろ困ることが出てきます。

問題1:eventの位置が違う

enchant.jsのtouchstartは設定したゲーム画面内の位置をeventで渡してくれますがjavascriptのmousedownで書くと当然enchant.js内の位置ではないです。ブラウザ内での位置になります。

なので右クリックかどうかの判定だけはmousedownで判断するが、位置に関してはenchant.jsのtouchstartで拾うということになります。

問題2:スマホに対応していない

当然と言えば当然なんだけどenchant.jsはスマホでもPCでも動くようにしてくれているゲームエンジンです。それを使わずjavascriptのmousedownを使うとスマホでは対応してくれません(マウスの処理だもんね)。なのでPCとスマホで処理を変える必要が出てきます。

ということでスマホかPCかを判別しなくちゃいけません。で、やり方を検索して出てきたのがこちら

まとめ

は?プログラムは?

って思われている方もいるかもしれませんがそれは自分でやってください(^^;)実はこれ、けっこう無理くりな感じになってキレイなプログラムにならないんですよ。なのでそんなプログラム見せたくないので自分で作ってください(^^;)

てかenchant.jsの必要な部分を改造する方法が分かればいいんですが今のところそこまでの知識がないので仕方ないです。いつか方法がわかればその時改めてばっちりなプログラムとともに紹介したいと思います(^^;)

enchant.jsでの画面タッチ処理のいろいろ

enchantjs講座

画面のタッチ処理について自分がやってみて気づいたことを紹介します。

画像無しのスプライトを使う

例えば画面全体のどこかを押すことで何か処理をさせるならシーンにイベントリスナを設定します。

じゃあ画面の右半分にタッチする場合と左半分にタッチする場合で処理を変えたい場合はどうすればいいのかな?

と思ったときに試してみたのが画像を設定しないスプライト。画像は設定していないので当然画面には何も表示されていないけど設定した大きさと場所にスプライトは存在しているようです。なのでイベントリスナを設定してやるとちゃんと反応してくれます。

タッチに当たり判定をつけて処理する

例えばタッチで触ったものに何かしらの処理をさせたいとき、普通はスプライトにイベントリスナを設置して処理すると思うんですが、これだと画像が重なった時に上になっている方のイベントが処理されます。

例えばそれが画像が小さくてスプライト的にはそこにあるけど見た目は何もない部分なんてときに、その余白部分の下に別の画像があって、プレイヤー的にはそっち押したつもりなんて状態の時に正しく処理できない(説明が難しい)。

上の画像で言うと重なってる部分では上になってる方のイベントリスナが発火します。もしプレイヤーが下の方を押したつもりだったらおかしなことになってしまいます。

というか余白部分でも反応してしまうのでそれをどうにかしたい(最初からそう言えば分かりやすかったんだな(^^;))。

で、どうしたもんかな?と考えた結果、スプライトのイベントリスナでは処理をせず、タッチした場所とキャラとの当たり判定を取るようにしました。

通常のシューティングゲームなどと同様にキャラの当たり判定を設定し、画面にタッチするたびにその場所とキャラとの当たり判定をとればOKです。

で、このとき上になってるキャラから当たり判定を取っていけば重なっていても問題なく処理できます。