[連載]スーパーマリオ的なゲームをjavascriptで作ってみる 初級編 〜2章〜 簡単なページ作ってみる

## 本連載について
- プログラミング初心者がスーパーマリオ的なゲームを作成するのに情報をまとめたものです
- 不明点や不備あれば、ばしばしコメントいただきたいです！！！より良いものにしたいので！
- 一番最初の連載は[こちら](https://qiita.com/hockeyarchitecture/items/139c27ff4806eaf2367f)から確認お願いします！<br/>
▼ゲームイメージ<br/>
![ゲームイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499206/949bb1ad-7109-1c70-b116-36ef83df3aa9.gif)<br/>
<br/>
▼目次<br/>
[1章 準備する](https://qiita.com/hockeyarchitecture/items/139c27ff4806eaf2367f)<br/>
[2章 簡単なページ作ってみる](https://qiita.com/hockeyarchitecture/items/76e0e90c1883d91b3e87)<br/>
[3章 画像を動かしてみる](https://qiita.com/hockeyarchitecture/items/c526e2345cb512109e18)<br/>
[4章 落ちちゃダメ！！](https://qiita.com/hockeyarchitecture/items/bea44d14aa16aa7f916e)<br/>

## 概要
- とりあえず簡単なページ作ってみる
- キャラ画像の表示したり、入力キーに応じて表示内容変えるとかはこの後
- 以下3ステップ
  - その１ 〜html作ってページ開いてみるよの巻〜
  - その２ 〜jsも組み込んでみるよの巻〜
  - その３ 〜フレーム処理を組み込むよの巻〜

## 補足事項
- 各ステップごとに実際のソースをQiita上に記載しています。コピペしてファイル作れば動かして確認できるはずです。
- 上記と同じくソースの実態を保存しているgitのリポジトリも記載しています。<br/>
リンクにアクセスして実際のソースをダウンロードすることができます。<br/>
ぜひダウンロードして動かしながら試してみてください！

## その１ 〜html作ってページ開いてみるよの巻〜
### ゴール
- ゲームを動かす大元のwebページを作って、Chromeなどのブラウで開けることを確認する

### 前提
- 主にwebページは以下の要素から成り立ちます
    - `html` : 何を表示するか (どんな文字や画像を表示するかなど)
    - `css` : どう表示するか (太文字や文字色や位置、背景をどうするかなど)
    - `js` : どのように動かすか (クリックした際やフォーカスした際にどうするかなど)<br/>
    ※ 詳細は省きますが、気になる方は後でググってみてください。(あとで参考リンク貼る予定) 
- ここでは上記の内の主に`html`と`css`部分を1ファイルにまとめて作成します
- 実際には`js`の部分がゲームの動きを決める要となります

### やること
- 以下記載のソースコードをコピってメモ帳やテキストエディタなどに貼り付けてファイル名を `index.html` で保存する
- 作成したファイル `index.html` をChromeなどのwebブラウザで開く
- 中央にグレーのエリアが表示されていることを確認する<br/>
※ コピーだと不要な書式情報が付与されてペーストされ適切に動かない場合があります。<br/>
  　その場合は、以下のいづれかの方法を試してみてください<br/>
  　　・ コピペしないで直接入力をする<br/>
  　　・ リンクからダウンロードしてからファイル開いて修正する

▼ソースコード

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>スーパーマリオ</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      canvas {
        background: #eee;
        display: block;
        margin: 0 auto;
      }
    </style>
  </head>
  <body>
    <canvas id="maincanvas" width="960" height="640">
    <script>
      // JavaScriptのコードがここに入ります
    </script>
  </body>
</html>
```

※ 実際のソースコードは [こちら](https://github.com/taku7777777/mario-game-tutorial-01-02-01) からダウンロードできます

codepenでの確認は以下から
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="taku7777777" data-slug-hash="dyPVBgG" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="mario-game-tutorial-01-02-01">
  <span>See the Pen <a href="https://codepen.io/taku7777777/pen/dyPVBgG">
  mario-game-tutorial-01-02-01</a> by taku7777777 (<a href="https://codepen.io/taku7777777">@taku7777777</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


### 説明
- ソースの構成は以下
  - `<head>〜</head>` の中の `<meta>` : いろんな情報を指定することができる部分、ここでは文字コードを指定しています
  - `<head>〜</head>` の中の `<title>` : タブに表示されるタイトルを指定する部分
  - `<head>〜</head>` の中の `<style>` : 背景色などのcssにあたる部分
  - `<body>〜</body>` : 実際にwebページに表示する内容を定義する部分
  - `<body>〜</body>` の中の `<canvas>` の部分が実際にキャラクターなどを画面を表示する要素を記載
  - `<body>〜</body>` の中の `<script>` : 動き担当のjsを記載する
- アレンジどころ
  - `<title>スーパーマリオ</title>` の `スーパーマリオ` の部分を `俺様のゲーム` などに変えるとタブに表示されるタイトルが変わる
  - `background: #eee` の `eee` の部分を `1E90FF` などに変えると背景色が変わる [色の参考](http://www.netyasun.com/home/color.html)
  - `<canvas id="maincanvas" width="960" height="640"></canvas>` の `960` の部分を変えるとエリアの横幅が変わる
  - `<canvas id="maincanvas" width="960" height="640"></canvas>` の `640` の部分を変えるとエリアの縦幅が変わる


## その2 〜jsも組み込んでみるよの巻〜
### ゴール
- `js` のファイルを追加して `js` ファイルに記載した内容が実行されることを確認する

### 前提
- 実現方法はいくつかありますが、今回は `htmlファイル(index.html)` と `jsのファイル(index.js)` の2ファイルの構成で進めていきます

### やること
- `index.html` があるのと同じ階層に `index.js` を作成する
- `index.html` に `<script src="./index.js"></script>` を追加する
- `index.js` の中身を以下に記載している内容をコピペする
- `index.html` をChromeなどのwebブラウザで開く
- 画面上に `start js alert` が記載された簡易ダイアログが表示されることを確認する
- (Chromeの場合) ディベロッパー・ツールのコンソールに `start js console` が記録されることを確認する (確認方法は[こちら](https://www.buildinsider.net/web/chromedevtools/01))

▼ソースコード

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>スーパーマリオ</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      canvas {
        background: #eee;
        display: block;
        margin: 0 auto;
      }
    </style>
  </head>
  <body>
    <canvas id="maincanvas" width="960" height="640"></canvas>
    <script src="./index.js"></script>
  </body>
</html>
```
```javascript:index.js
// js の処理が開始されたことを確認するためのもの
alert(`start js alert`);
console.log(`start js console`);
```

※ 実際のソースコードは [こちら](https://github.com/taku7777777/mario-game-tutorial-01-02-02) からダウンロードできます


### 説明
- `<script src="./index.js"></script>` は同階層の `index.js` を参照するよって宣言
- ソースが実行される流れとしては以下
  - `index.html` が読み込まれる
  - `index.html` に記載の `<script src="./index.js"></script>` を確認
  - `index.js` が読み込まれる
- `index.html` に `index.js` を参照するよって宣言を記載してあげないと `index.js` を作っても読み込まれません


- `alert(XXXXX)` で `XXXXX` の内容が画面上に簡易ダイアログで表示されます
- `console.log(XXXXX)` で `XXXXX` の内容がディベロッパー・ツールのコンソールにログが表示されます
- `alert` と `console.log` は意図通りに動いているか、変数に何が入っているかなどを簡易確認したい場合などに使えます
サンプルソースは以下記載の内容で
  - `come in if branch` が表示され、記載のif文の分岐に入ることが確認できる
  - `test is 2` が表示され、`test` の変数に `2` が入っていることが確認できる

```javascript:index.js
var test = 1;
if(test === 1){
  alert('come in if branch');
  console.log('come in if branch');
  test++;
}

alert('test is ' + test);
console.log('test is ' + test);
```

## その３ 〜フレーム処理を組み込むよの巻〜
### ゴール
- スーパーマリオに必須のフレーム処理ができる
- マリオやクリボーを動かすために、一定間隔ごとに画面を更新できるようにする

### 前提
- リアルタイムにキャラクターや敵を動かしていく必要がある
- 一定時間ごとに描画する必要があり、アニメーションのフレーム処理に使われるメソッドを用いて実現する
- 右ボタン押されてたら右に少しづつ動き、ジャンプ中だったら次第に勢い失って落下していくことを実現するために必要
- 右ボタン押されてたら0.1秒後には◯◯だけ右に動いていて、ジャンプ中だったら0.1秒後には速度が△△まで落ちてて、地面から□□のとこにいるみたいな
- これを実現するためには一定間隔で次の状態はどうなっているかを決める処理を実行する必要がある

### やること
- `index.js` を以下に修正する
- `start js alert` の簡易ダイアログまたはコンソールが表示されることを確認する
- `start update alert, cnt = 1` の簡易ダイアログまたはコンソールが表示されることを確認する
- `start update alert, cnt = 2` の簡易ダイアログまたはコンソールが表示されることを確認する
- `start update alert, cnt = 3` の簡易ダイアログまたはコンソールが表示されることを確認する

```javascript:index.js
// js の処理が開始されたことを確認するためのもの
alert("start js alert");
console.log("start js console");

// ロード時に処理が実行されるようにする
window.addEventListener("load", update);

// update処理が実行された回数を記録するためのもの
var cnt = 1;

// ロード時に実行する関数の定義
function update() {
  // update 関数の処理が実行されたことを確認するためのもの
  alert("start update alert, cnt = " + cnt);
  console.log("start update alert, cnt = " + cnt);

  // 回数を1つ増やす
  cnt = cnt + 1;

  // 繰り返し処理を実行するよの定義
  window.requestAnimationFrame(update);
}
```

### 説明
- `window.addEventListener("load", XXXXXX)`<br/>
   `XXXXX` で指定した`関数`を、ページロードのタイミングで実行するよっ登録することができる
- `function XXXXX(...) {....}`<br/>
  `XXXXX` という名前の `関数` を定義することができる<br/>
  引数を `(...)` の部分で定義し、処理内容を `{....}` の部分で定義する<br/>
   ここでは関数の書き方の詳細は省略します
- `window.requestAnimationFrame(XXXXX)`<br/>
  `XXXXX` で指定した `関数` を一定間隔後に実行する
- 処理の流れとしては以下
    - `index.js` が読み込まれる(上から順に)
    - `alert("start js alert")` が実行される
    - `console.log("start js console")` が実行される
    - `window.addEventListener("load", update)` が実行され、loadをトリガーにupdate処理を実行するよってことが登録される (このタイミングでは処理が実行されない)
    - `cnt` の `変数` が1で指定される
    - `update` の `関数` が定義される (このタイミングでは処理が実行されない)
    - `index.js` が読み込みが完了する
    - `load` が実行される
    - 初めて `update` 処理が実行される
    - `alert("start update alert, cnt = " + cnt)` が実行され `start update alert, cnt = 1` が表示される
    - console.logもそんな感じ
    - `cnt` が2になる
    - `window.requestAnimationFrame(update)` が実行され一定間隔後(基本1/60秒後)にupdate処理を実行するよってことが登録される (このタイミングでは処理が実行されない)
    - 一定間隔が経過する
    - 2回目の `update` 処理が実行される
    - `alert("start update alert, cnt = " + cnt)` が実行され `start update alert, cnt = 2` が表示される
    - console.logもそんな感じ
    - `cnt` が3になる
    - `window.requestAnimationFrame(update)` が実行され一定間隔後(基本1/60秒後)にupdate処理を実行するよってことが登録される (このタイミングでは処理が実行されない)
    - 3回目の `update` 処理が実行される
    - ... 以下同様
- 基本的にはソースの上から順に実行される
- ただし記載の処理がそのタイミングで実行されるものと、実行されないものがあるので注意
- 関数の定義や、特定のタイミングで指定の処理の実行を登録することなどは処理内容がその場で実行されるわけではないことに注意
- 実行タイミングがわかりづらい場合などはconsole.logなどを仕込んで処理順序を確認してみると良いです<br/>
サンプルソースは以下記載の内容で
  - update関数の中身は最後に繰り返し実行されることが確認できる
  - update関数の中身以外は上から順に実行されていることが確認できる

▼サンプルソース

```javascript:index.js
// js の処理が開始されたことを確認するためのもの
alert("start js alert");
console.log("start js console");

// ロード時に処理が実行されるようにする
console.log("start define addEventListener");
window.addEventListener("load", update);
console.log("end define addEventListener");

// update処理が実行された回数を記録するためのもの
console.log("start define cnt");
var cnt = 1;
console.log("end define cnt");

// ロード時に実行する関数の定義
console.log("start define update");
function update() {
  console.log("start update function, cnt = " + cnt);

  // 回数を1つ増やす
  cnt = cnt + 1;

  // 繰り返し処理を実行するよの定義
  window.requestAnimationFrame(update);
  console.log("end update function, cnt = " + cnt);
}
console.log("end define update");
```

実際のソースコードは [こちら](https://github.com/taku7777777/mario-game-tutorial-01-02-04) からダウンロードできます


▼出力結果

```
start js console
start define addEventListener
end define addEventListener
start define cnt
end define cnt
start define update
end define update
start update function, cnt = 1
end update function, cnt = 2
start update function, cnt = 2
end update function, cnt = 3
update function, cnt = 3
end update function, cnt = 4
start update function, cnt = 4
end update function, cnt = 5
...
```

## 終わり
お疲れまです！！！<br/>
次に進みましょう！！！<br/>
[3章へすすむ!!!](https://qiita.com/hockeyarchitecture/items/c526e2345cb512109e18)
<br/><br/><br/>