本連載について
- プログラミング初心者がスーパーマリオ的なゲームを作成するのに情報をまとめたものです
- 不明点や不備あれば、ばしばしコメントいただきたいです!!!より良いものにしたいので!
- 一番最初の連載はこちらから確認お願いします!
 ▼ゲームイメージ
  
 
▼目次
[1章 準備する](https://qiita.com/hockeyarchitecture/items/139c27ff4806eaf2367f)
[2章 簡単なページ作ってみる](https://qiita.com/hockeyarchitecture/items/76e0e90c1883d91b3e87)
[3章 画像を動かしてみる](https://qiita.com/hockeyarchitecture/items/c526e2345cb512109e18)
[4章 落ちちゃダメ!!](https://qiita.com/hockeyarchitecture/items/bea44d14aa16aa7f916e)
本章の概要
- 本章では主人公の画像を表示して、キーボードの入力に応じて動かすとこまでいきます
- ゲームっぽくジャンプしたり、落ちたり敵にぶつかってゲームオーバーになったりはこの後やります
- 本章の内容は大きく4ステップです
- その1 〜画像を表示できるよの巻〜
- その2 〜画像が動くよの巻〜
- その3 〜キーボードの入力が検知できるよの巻〜
- その4 〜画像を動かせるよの巻〜
 
- 各ステップごとに実際のソースをQiita上に記載しています
 
- 上記と同じくソースの実態を保存しているgitのリポジトリも記載しています
 リンクにアクセスして実際のソースをダウンロードすることができます
 ぜひダウンロードして動かしながら試してみてください!
その1 〜画像を表示できるよの巻〜
ゴール
- 特定の画像をcanvas要素のエリアに表示すること
- マリオのゲーム作るにはマリオを画面に表示することは必要ですからね!
前提
- 大枠の流れとしては、 canvas要素に対してどこにどんな画像を表示するかを指定します
- 
canvas要素に対して画像の指定する際はdrawImageの関数を使用します
- 画像を表示する場合、主に 画像ファイルのパス指定するまたは画像をエンコードして文字列としたものを記載するの2択がありますが今回は前者を採用します
やること
- 画像ファイルを作成し、配置します ([参考]ドッド絵を作成する)
- 
index.jsでindex.htmlで定義したcanvas要素を取得するように修正します
- 
Image要素を作成し、canvas要素に対して追加(draw)するように修正します
- フォルダ階層は以下ようにしています
 
└┬─ src    ┬─ index.html
 │         └─ index.js
 └─ images ── character-01 ── base.png
▼ソース
// canvas要素の取得
const canvas = document.getElementById("maincanvas");
const ctx = canvas.getContext("2d");
// ロード時に画面描画の処理が実行されるようにする
window.addEventListener("load", update);
// 画面を更新する関数を定義 (繰り返しここの処理が実行される)
function update() {
  // 画面全体をクリア
  ctx.clearRect(0, 0, 640, 480);
  // 主人公の画像を表示
  var image = new Image();
  image.src = "../images/character-01/base.png";
  ctx.drawImage(image, 0, 0, 32, 32);
  // 再描画
  window.requestAnimationFrame(update);
}
※ 実際のソースコードは こちら からダウンロードできます
▼CodePenのサンプル
See the Pen mario-game-tutorial-01-03-01 by taku7777777 (@taku7777777) on CodePen.
説明
- 
document.getElementById("maincanvas")でcanvas要素を取得しています
 maincanvasはindex.htmlでcanvas要素のidとして指定しているものです
 index.js内からindex.htmlに記載している要素を取得することができます
- 
canvas.getContext("2d")で取得したcanvas要素からさらに二次元の情報(今回描画したい対象の情報)を取得します
 ここまでは定型文のようなものなので、深く突っ込まず「へぇーこうゆうふうに記載すればいいんだ」くらいでOKです!
- 
ctx.clearRect(0, 0, 640, 480)でcanvas要素の描画対象をクリアしている
 これをしないと、この後に実施する画像表示の処理が重複して、意図せず複数の画像が表示されかねないので注意です
- 
var image = new Image()で新しく画像要素を作成し、image.src = "../images/character-01/base.png"で画像要素の画像情報を定義しています
- 
ctx.drawImage(image, 0, 0, 32, 32)ではどの画像要素をどこにどのような大きさで表示するかを定義しています
 今回の例では、"../images/character-01/base.png"の画像をx座標が0(一番左から右に0ピクセル移動したとこ)、y座標が0(一番上から下に0ピクセル移動したとこ)に横幅32ピクセル、縦幅32ピクセルで画像を表示するということになります
 例えばctx.drawImage(image, 100, 200, 10, 20)の場合x座標が100(一番左から右に100ピクセル移動したとこ)、y座標が200(一番上から下に200ピクセル移動したとこ)に横幅10ピクセル、縦幅20ピクセルで画像を表示するということになります
 
その2 〜画像が動くよの巻〜
ゴール
- 表示した画像が横に少しづつ動くようにします!(超簡単なアニメーション!?)
やること
- 「その1 〜画像を表示できるよの巻〜」で対応した drawImageの画像表示位置を少しづつ変えます
- 最初は一番左に画像を表示し、一定の速度で右に移動するようにします
▼ソース
// canvas要素の取得
const canvas = document.getElementById("maincanvas");
const ctx = canvas.getContext("2d");
// ロード時に画面描画の処理が実行されるようにする
window.addEventListener("load", update);
// 主人公の初期座標を定義
var x = 0;
// 画面を更新する関数を定義 (繰り返しここの処理が実行される)
function update() {
  // 画面全体をクリア
  ctx.clearRect(0, 0, 640, 480);
  // 座標を更新する
  x = x + 1;
  // 主人公の画像を表示
  var image = new Image();
  image.src = "../images/character-01/base.png";
  ctx.drawImage(image, x, 0, 32, 32);
  // 再描画
  window.requestAnimationFrame(update);
}
※ 実際のソースコードは こちら からダウンロードできます
▼CodePenのサンプル (右下の"return"をクリックして、リフレッシュしてから確認してみてください)
See the Pen mario-game-tutorial-01-03-02 by taku7777777 (@taku7777777) on CodePen.
説明
- x座標を変数化し(x)、update処理が実施されるごとに1増えるようにしています
その3 〜キーボードの入力が検知できるよの巻〜
ゴール
- キーボードで上下右左が押されたことを検知できるようにします
- これができると入力に応じていろんなことをできるようになります!
やること
- 以下のソースをコピペ
 (これも定型文みたいなものなので細かいとこは気にしなくて大丈夫ですー)
// キーボードの入力状態を記録する配列の定義
var input_key_buffer = new Array();
// キーボードの入力イベントをトリガーに配列のフラグ値を更新させる
window.addEventListener("keydown", handleKeydown);
function handleKeydown(e) {
  console.log("key down : " + e.keyCode);
  input_key_buffer[e.keyCode] = true;
  if (e.keyCode === 37) {
    alert("左が押されたよ");
  } else if (e.keyCode === 38) {
    alert("上が押されたよ");
  } else if (e.keyCode === 39) {
    alert("右が押されたよ");
  } else if (e.keyCode === 40) {
    alert("下が押されたよ");
  }
}
window.addEventListener("keyup", handleKeyup);
function handleKeyup(e) {
  console.log("key up : " + e.keyCode);
  input_key_buffer[e.keyCode] = false;
  if (e.keyCode === 37) {
    alert("左がはなされたよ");
  } else if (e.keyCode === 38) {
    alert("上がはなされたよ");
  } else if (e.keyCode === 39) {
    alert("右がはなされたよ");
  } else if (e.keyCode === 40) {
    alert("下がはなされたよ");
  }
}
※ 実際のソースコードは こちら からダウンロードできます
説明
- 
window.addEventListener("keydown", XXXXX)キーボードが押された際にXXXXXの関数を実行するよって定義することができます
- 
window.addEventListener("keyup", XXXXX)キーボードが押された状態からはなされた際にXXXXXの関数を実行するよって定義することができます
- 
handleKeydownhandleKeyupでキーボーが押された際/はなされた際に実行される関数を定義しています
 引数(e)の部分でキーボードが押された/はなされたイベント情報をもらい、なんのキーが入力されたかをe.keyCodeで取得することができます
- 
alertのとこの分岐は処理を確認するためのおまけ、本当は不要なコードになります
その4 〜画像を動かせるよの巻〜
ゴール
- その2、その3を組み合わせて上下左右のボタンを押した方向に画像が動くようにします
- ちょっとゲームっぽくなってくるのではないでしょうか?
やること
- 画像のx座標、y座標を変数化します
- キーボードの入力状態に応じてx座標、y座標を更新します
▼ソース
// キーボードの入力状態を記録する配列の定義
var input_key_buffer = new Array();
// キーボードの入力イベントをトリガーに配列のフラグ値を更新させる
window.addEventListener("keydown", handleKeydown);
function handleKeydown(e) {
  console.log("key down : " + e.keyCode);
  input_key_buffer[e.keyCode] = true;
}
window.addEventListener("keyup", handleKeyup);
function handleKeyup(e) {
  console.log("key up : " + e.keyCode);
  input_key_buffer[e.keyCode] = false;
}
// canvas要素の取得
const canvas = document.getElementById("maincanvas");
const ctx = canvas.getContext("2d");
// 画像を表示するの座標の定義 & 初期化
var x = 0;
var y = 0;
// ロード時に画面描画の処理が実行されるようにする
window.addEventListener("load", update);
// 画面を更新する関数を定義 (繰り返しここの処理が実行される)
function update() {
  // 画面全体をクリア
  ctx.clearRect(0, 0, 640, 480);
  // 入力値の確認と反映
  if (input_key_buffer[37]) {
    // 左が押されていればx座標を1減らす
    x = x - 1;
  }
  if (input_key_buffer[38]) {
    // 上が押されていればy座標を1減らす
    y = y - 1;
  }
  if (input_key_buffer[39]) {
    // 右が押されていればx座標を1増やす
    x = x + 1;
  }
  if (input_key_buffer[40]) {
    // 下が押されていればy座標を1増やす
    y = y + 1;
  }
  // 主人公の画像を表示
  var image = new Image();
  image.src = "../images/character-01/base.png";
  ctx.drawImage(image, x, y, 32, 32);
  // 再描画
  window.requestAnimationFrame(update);
}
※ 実際のソースコードは こちら からダウンロードできます
▼CodePenのサンプル
See the Pen mario-game-tutorial-01-03-04 by taku7777777 (@taku7777777) on CodePen.
説明
- 
input_key_bufferにkeyCodeごとにおされているか(true)、押されていないか(false)を保持しているので、update処理を実行する際に押されているキーに応じて座標を更新します
終わりに
お疲れまです!!!
ゲームっぽさが出てきましたね!
次に進みましょう!!!
4章へすすむ!!!