2021年11月14日日曜日

javascriptでマリオを作る part1

 


マリオのようなゲームを作りたい


子供のころからずっと思っていました。


ただ、毎日の忙しさを理由に、どんどん先延ばしにしていました。


会社の後輩が、勉強がてら「javascriptの勉強をする」という話を聞き、


この機会を逃したら一生作れないかも!


と思い、後輩に「自分も作ってみる」という宣言をしました。


さあ大変です。


毎日の自分の自由な時間を考えると、、、、午前中 ~1時間 午後1~2時間 と思われます。


週末までにある程度形を作って見せたいので、実質5,6時間で作らないと。


今まで、作ろうとしては挫折した経験が実はあります。


・キャラをどう作るのか、フリーの素材にするのか・自分で作るのか


・言語は何にするのか、ゲーム用のフレームワークを使うのか、どれにするのか


・本を買うのか、ネットで探すか


・サンプル探すか、自分で作るか、サンプルなかなか出てこない、動かない


いろいろな部分で時間がかかり、そして中途半端で終わっていました。


今回はそれを踏まえて、全て決めて、その中で自分にできることを考えていきたいと思います。


今回参考にするのは codecampさんのサイトにある以下のページです。

【JavaScriptを好きになろう】JavaScriptで横スクロールゲームを作ろう(コード付き)


こんな素晴らしいプログラムをソースコードも見せてくれるなんて、、、ただ感謝するのみです。codecampさん、ありがとうございます。


これを使えば、ある程度動くものの中で、マリオ要素を追加・修正すればいいだけのはず。


早速ソースコードをいただきます。


上記ページ内のダウンロードリンクを押すと以下の画面になるので、画面右上の下矢印アイコンをクリックしてファイルを取得します。



落としてきたファイルを解凍すると以下のようなファイルがあると思います。

この中の flappy.html をブラウザで開けばゲームが始まります。




flappy.html を開いていきます。


まずflappybirdというゲームは、飛んでいる鳥を操作して、土管にぶつからないように進むゲームです。


土管にぶつかったり、地面に落ちたらゲームオーバー。


マリオのゲームとルールが異なるので、そこから直していきたいと思います。


まず、「地面に落ちたらゲームオーバー」から見ていきます。


コメントも書いていただいているのでわかりやすいですね。175行目付近です。


この式の中の「&&」は「かつ」。左右の式、どちらもそうなっているか、いればTrue
「||」は「または」、左右の式、どちらかがそうなっているか、いればTrue

「または」で区切ってみます。

①bX + bird.width >= pipe[i].x && bX <= pipe[i].x + pipeNorth.width && (bY <= pipe[i].y + pipeNorth.height
 ||(または)
 ②bY+bird.height >= pipe[i].y+constant)
 ||(または) 
③bY + bird.height >=  cvs.height - fg.height

このうち「pipe」が含まれている条件は、土管とぶつかったときの判定と思われるので、それが入っていない③をザクっと削除してみます。



地面に落ちてもゲームオーバーにはならないのですが、地面からさらに下にもぐってしまいました。


マリオは地上を歩くので、地面についたらそこで着地したいと思います。


まず鳥が下に落ちていく処理はどこにあるのでしょうか。

188行目付近です。



bYは、鳥の画像の左上の座標と思われます。


原点がゲーム画面全体の左上にあって、右にX軸 下にY軸だったかと思うので


bYを増やすことで、Y軸の下に向かうことができます。


地面で止まらせたい、、、


では地面はどの位置なのか、、、、


変数の定義を見直します。


「fg」という変数が地面のようです。「fg.height」という変数もあったので、これが地面の高さかということで、とりあえず「地面のところまでは下がるけど、地面よりも下には下がらない」というかんじで、適当に以下のif文を挟みました。

          if(bY < fg.height){
        	bY += 1;
        }


動かしたら、、、




上のほうで鳥が降りなくなってしまいました。


「fg.height」は、地面の画像の高さ、だったんですね。


ちょうど逆、というか、画面中央で半分に割ったら反対側になるぐらいの位置になってくれれば、、、


ゲーム画面全体の高さや幅も決めているはずです。


もしゲーム画面の縦から、地面の高さを引いた分の値だけ、下向きのY軸で進ませれば、、、


Canvas という領域でheightが「300」になっていました。

こうしたらどうだろう


        if(bY < 300 - fg.height){
        	bY += 1;
        }


どうなるか、、




いなくなってしまいました。


そういえば、鳥の「縦の長さ」のことを考えていませんでした。


        if(bY < 300 - fg.height - bird.height){
        	bY += 1;
        }






出てきた。


これをベースに何とかやっていけそうな予感です。


どこまで参考になるかわかりませんが、今回の修正版をここにアップしました。


よろしければどうぞ。