自作ゲームエンジンに挑戦③「画像を表示する」

やっぱただの四角だと見た目につまらない。ゲームらしい画像を使わなけりゃ面白くないですよね。ってことで今回は画像を表示させてみます。

で、まず画像を用意していただきたいんですが、プレイヤー、敵、弾の3つ作成してください。大きさはプレイヤー、敵が64×64、弾が16×16です。それらをimagesフォルダに入れてください。

前回のサンプルの画像を入れ替えたのがこちらです→サンプル

では作ってきましょう(・∀・)

画像の読み込み

まずは使う画像をASSETSオブジェクトにまとめて入れておきます。それぞれの画像の名前とファイルの場所を入れます。ASSETSという言い方は最近のトレンドらしいんですが、まぁ使うデータのことみたいです。

で、画像の読み込みなんですが、まず画像を扱うにはImageオブジェクトを作成してそこに画像を読み込んで使います。

基本、上記のような感じで書きます。onloadメソッドは画像の読み込みが完了したら発生するイベントです。大きな画像だったりすると読み込むのに時間がかかったりするので必要な処理は読み込みが終わってからする必要があります。

ただ、ゲームだとたくさん画像を扱うので全部読み込んだかどうかの確認が必要です。

で、Coreクラスに以下のような処理をつけました。引数のdataはASSETSです。画像はすべてCoreクラスのassetsオブジェクトに読み込みます。

画像の枚数をカウントしておいて、読み込みの完了した数が画像の枚数と同じになればCoreクラスのonloadメソッドを実行します。

で、それを追加したCoreクラスがこんな感じです

画像の読み込み完了後

画像の読み込みが完了したらゲームプログラムが動き始めるようにします。

core.onloadメソッドに読み込み完了後の処理を記述します。ここで初めてrequestAnimationFrameを使います。この後は自動で更新処理が行われるようになります。

画像を描画する

もっとも大事な画像を描画する部分を忘れてましたね(^^;)

Charaクラスのレンダーメソッドに画像を描画するdrawImageメソッドを記述します。

キャラクターはすべてこのCharaクラスを継承しているのでこの一か所変更するだけでOKです。

これで画像を使ったゲームになります。

まとめ

ただの四角から画像に変わっただけでものすごく進化した気がしますね( *´艸`)

なんだかゲームエンジン作るのなんて簡単なんじゃないか?って錯覚してしまいそうですが、まぁそんなのは今だけの話ですよ。。

じゃ(‘ω’)ノ

自作ゲームエンジンに挑戦②「さっそくゲーム作ってみる」

とりあえず画面の更新処理さえできてしまえばゲームは出来るはずです。

ってことで作ってみたのがこちらです → サンプルプログラム

かなり簡素ではありますが一応シューティングゲームのようなものになってます。まぁ弾は1発しか撃てないし敵も1匹ずつしか出てきませんが敵と弾の当たり判定をつけてあるのでちゃんとゲームになってますよね(*´ω`)

プログラムはこんな感じでやってみました。

プログラムの説明

なんかjavascriptでもclassが使えるようになったということで練習がてら使ってみました(‘◇’)ゞ

キャラクターの部分はCharaというクラスから継承して少し楽してますね。また、ゲームの基幹的な部分もひとまとめにしてみました。

ゲームにするためには操作が必要なのでmousedown,  mouseup, mousemoveを使って操作できるようにしました。ただ、これはマウスでの操作にしか反応してくれません。スマホなどのタッチでの操作はまた別なんですよね(´Д`)どっちもOKな入力イベントないのかなぁ。。

あと、関係ないけど、画面に表示されているキャラは四角なのに当たり判定は円っていうね。うん、円の当たり判定の方が書く量が少ないからこっちにしたんですよ。へへへ(´∀`)

 

て、ことで更新処理さえあればゲームは作れるってことが証明されましたね(´∀`)

ゲームエンジン作成は気が遠くなりそうですがいきなり完璧なゲームエンジンを作らなくてもゲームは出来るので少しずつ頑張ってやっていきたいと思います。では(‘ω’)ノ

自作ゲームエンジンに挑戦①「画面の更新処理」

私は今までenchant.jsというゲームエンジンを使ってゲームを作ってきたんですけれども、そろそろjavascriptのcanvasをちゃんと理解したほうがいいのではないかと思ったので勉強を始めました。

そんなわけで私の勉強がてら記事を書いていこうかと思います。一応目標はゲームエンジン作成ですが、そのレベルのものは出来ないと思いますが、それなりにゲームらしいものが出来るようにはしたいと思っています。

canvasとは?

Canvasとは、ブラウザ上に図を描くために策定された仕様なんだそうです。図を描いたり線を描いたりすることは得意なようですが、ゲームを作ることは得意ではないみたいです。

なので私たちがゲームを作るにはゲーム用のプログラムを自分で作るか、もしくはゲームエンジンを使ったりしないと作れません。もどかしいですね。

とりあえずやってみる

まぁ、とりあえずやってみましょう(‘ω’)ノ

まずはHTMLファイルを準備。

canvasタグがcanvasです。idもとりあえずcanvasにしときましょう。背景色はゲームらしく黒にしておきます。

ここで一つ要注意なのがcanvasのサイズの指定の仕方です。

canvasのサイズはcssでもjavascriptでも指定できるようになっているんですが、cssの方は表示エリアの指定になっていて、javascriptの方は解像度みたいな扱いになっています。

つまり表示エリアが300×300になっていて解像度が600×600になっていると300×300に収まるように縮小されます。これだとOKなんですが縦横の比率が違うように指定しますと変に伸びたり縮んだりしてしまいます。なので基本的にはcssでは幅だけ指定するのが良いと思います。

簡単なフレーム更新プログラム

まずは簡単なフレーム更新プログラムを作ってみました。

sampleプログラム

今回このなかで大事なのはrequestAnimationFrameというメソッドです。これはおよそ60FPSになるような一定の間隔で引数に渡した関数を呼び出してくれるようです。

ただし、requestAnimationFrameは一回こっきりしか働いてくれないようで、ずっと更新処理をし続けるには毎回requestAnimationFrameを呼ぶ必要があるようです。

画面が更新されていても何も表示されていなければわからないので四角形を表示させて移動させてみました。DVDプレーヤーのアレみたいなやつを作ってみました。角に行ったら盛り上がってください(外国で流行っているらしいです)。

まとめ

とりあえず画面の更新処理が出来るようになったのでもうゲームは作れます。ゲームエンジンを作ろうと思うと先はものすごく長いですが、作りたいものに対して必要なものは何か?ってことがわかれば最低限のプログラムでゲームが作れるはずなので段階的に頑張っていきたいと思ってます。では(‘ω’)ノ

参考にした記事

JavaScriptでフルスクラッチゲーム開発しよう 第1回 準備編

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を使いたいってときは継承して作りましょう