ニコ生ゲームを作ろうと思ったらすぐ作ろう その3

第3回は表示を追加していきます。残弾表示標的となるタイルを追加します。

■目次

【改造内容】

  • 残弾表示を作る (画像を追加する)
  • 残弾表示を更新する (常に処理する)
  • 残弾を補充する (条件の例外について)
  • タイルを作る (四角を追加する)
  • タイルを並べる (四角を並べる)

 


 

【改造内容】 残弾表示を作る (画像を追加する)

 

前回は残弾の数値を追加しましたが、現状だと今何発残っているのかわかりません。
表示を追加しましょう。

数字でもいいんですが画像でやってみます。

 

弾を発射したときに画像を表示する呪文がサンプルゲームにすでにあります。
こちらをコピーしていきましょう。

  // プレイヤーが発射する弾を生成します

var shot = new g.Sprite({
  scene: scene,
  src: shotImageAsset,
  width: shotImageAsset.width,
  height: shotImageAsset.height
});
// 弾の初期座標を、プレイヤーの少し右に設定します
shot.x = player.x + player.width;
shot.y = player.y;


この弾は var shot という呪文で、飛んでいく画像に「shot」の名前をつけています。
残弾表示の弾の名前が、飛んでいく弾と同じ名前だと具合が悪いので、残弾表示の方は「shot1」にしましょう。

ついでに初期座標も左上にします。

var shot1 = new g.Sprite({
  scene: scene,
  src: shotImageAsset,
  width: shotImageAsset.width,
  height: shotImageAsset.height
});

shot1.x = 40;
shot1.y = 80;


これで良さそうですが、残念ながら2つの落とし穴があります。以下の2つを追加します。

shot1.modified();
scene.append(shot1);

 

1行目の shot1.modified(); はshot.1に加えた変更を反映させるものです。
shot1.xとshot1.yの値を40と80に指定したのでそれを反映させるために必要です。

2行目の scene.append(shot1); はsceneにshot1を加えるものです。
これがないとそもそも表示されません。sceneはゲームのことだと思っててください。

 

これらをどこに追加するのか。loadの中である必要があります。

しかし、 scene.onPointDownCapture.add(function () { の中はタッチしたときしか処理されないので、その外になるように直前に入れてみましょう

 

さて、1つだけでは3つの残弾は表現できません。

さきほどの呪文の「shot1」を「shot2」「shot3」としたものも追加しましょう。

同じ場所に重ねると見えないので、縦のy座標のところは数字を 160、240 と変えます。

var shot1 = new g.Sprite({
  scene: scene,
  src: shotImageAsset,
  width: shotImageAsset.width,
  height: shotImageAsset.height
});
shot1.x = 40;
shot1.y = 80;
shot1.modified();
scene.append(shot1);

var shot2 = new g.Sprite({
  scene: scene,
  src: shotImageAsset,
  width: shotImageAsset.width,
  height: shotImageAsset.height
});
shot2.x = 40;
shot2.y = 160;
shot2.modified();
scene.append(shot2);

var shot3 = new g.Sprite({
  scene: scene,
  src: shotImageAsset,
  width: shotImageAsset.width,
  height: shotImageAsset.height
});
shot3.x = 40;
shot3.y = 240;
shot3.modified();
scene.append(shot3);

 

ここで起動テストをしてみましょう。すでに起動していた場合は、ブラウザを更新するだけで良いです。

左上に弾が3つ並んでいるでしょうか。


  

【改造内容】 残弾表示を更新する (常に処理する)

では実際の残弾数 bullet と表示の状態を一致させます。

左端のshot1は残弾が1より小さければ表示を消します。
表示を消すのには不透明度 opacityを0に変えます。

if (bullet < 1) {
  shot1.opacity = 0;
}
shot1.modified();

これも shot2 と shot3 の分をコピペして、条件をそれぞれ bullet < 2 bullet < 3 とします。opacity と modified のところもshot2 shot3に変えましょう。

 

そしてこれらを追加するところは、先ほどと同じ loadの中であるだけではだめです。loadの直下はゲームの開始時に1度実行されるだけなので、ゲーム中の変化は反映されません。

 

前々回のセクション分けで「(9)常に更新する処理」 と書いてある場所に追加します。ちょうどtimeLabelという残り時間表示の更新が書かれているところがあるので、その後に追加しましょう。

var updateHandler = function () {
  if (time <= 0) {
    // RPGアツマール環境であればランキングを表示します
    if (param.isAtsumaru) {
      var boardId_1 = 1;
      window.RPGAtsumaru.experimental.scoreboards.setRecord(boardId_1, g.game.vars.gameState.score).then(function () {
        window.RPGAtsumaru.experimental.scoreboards.display(boardId_1);
      });
    }
    scene.onUpdate.remove(updateHandler); // カウントダウンを止めるためにこのイベントハンドラを削除します
  }
  // カウントダウン処理
  time -= 1 / g.game.fps;
  timeLabel.text = "TIME: " + Math.ceil(time);
  timeLabel.invalidate();
  if (bullet < 1) {
    shot1.opacity = 0;
  }
  shot1.modified();
  if (bullet < 2) {
    shot2.opacity = 0;
  }
  shot2.modified();
  if (bullet < 3) {
    shot3.opacity = 0;
  }
  shot3.modified();
};
scene.onUpdate.add(updateHandler);


sandboxを更新してみましょう。射撃ごとに残弾表示が消えていったでしょうか。



【改造内容】 残弾を補充する (条件の例外処理について)

弾が3つでなくなってしまうので物足りないですね。

画面内から弾がなくなったら一つ弾を補充するようにしましょう。

画面をタッチしたときの処理 scene.onPointDownCapture.add(function () {の中に、画面内から弾がなくなるときの処理があります。

  if (shot.x > g.game.width)
  shot.destroy();

shotが画面の右端よりも右に行った場合shotを破壊する、という処理になっています。


ここのifには { } のカッコがありません。
ifはカッコがない場合、後ろの処理を一つだけ処理します。今回は残弾を復活させる処理を追加するので、下のようにカッコも追加しましょう。

if (shot.x > g.game.width) {
  shot.destroy();
  bullet = bullet + 1;
}

これでテスト起動してみると弾は補充されるはずですが、残弾表示は減ったままです。
残弾表示は弾が減ったときに透明にしましたが、増えたときのことは決めていませんでした。


残弾表示のshot1はbulletが1より小さいときは透明ですが、それ以外は不透明であるべきです。この「それ以外は」という処理を追加する場合は次のようにします。

if (bullet < 1) {
  shot1.opacity = 0;
} else {
  shot1.opacity = 1;
}
shot1.modified();

ifのカッコに続けてelseと入力し、またカッコで処理を記載します。
shot2とshot3も同じようにします。

テスト起動してみましょう。弾が画面外に行くと同時に残弾表示が増えるはずです。




【改造内容】 タイルを配置する (四角の配置)

現状は射撃するだけなので、標的を用意します。
標的用の画像を用意してもいいのですが、単純な四角形を配置してみます。これは標準で用意されているので、うまく使えばかなり楽ができます。

var tile = new g.FilledRect({
  scene: scene, cssColor: "royalblue", parent: scene,
  x: g.game.width-100, y: g.game.height/2,
  width: 80, height: 80, opacity: 1,
});

は、cssColor: "royalblue" というように色の名前で指定しています。下のサイトのような色見本があるサイトを見て名前を指定するのが楽です。

"rgb(0,100,200)" や "#0066bb" のような数字で指定することもできます。

 

また、これまで使っていないパラメーター parent: scene, を追加しました。

これはこの四角をどこに配置するか指定するものです。

「どこ」の候補は色々あるのですが、今はゲーム本体であるsceneに置きます。

これだと scene.append(tile); を後で記載する必要がなくなります。

 

tileの呪文もloadの直下に配置してください。右側に青い四角が配置されたでしょうか。


  


【改造内容】 タイルを並べる (四角を並べる)

これを縦に7個並べたいと思います。残弾表示のように呪文を複数コピペしてもいいのですが、数が多くなってくると記載がどんどん長くなって見づらくなってきます。

同じような処理は以下のような繰り返し処理を使います。

for (var i = 0; i < 処理回数; i++) {
  処理内容
}

処理回数に7、処理内容にさきほどの四角配置処理を入れるのですが、縦に並べて配置するには少しづつ位置を変える必要があります。

ここで i という値を使います。これは最初の繰り返しでは0で、処理ごとに数値が1増えるようになっています。これを使って縦の位置が90ずつずれるようにします。

for (var i = 0; i < 7; i++) {
  var tile = new g.FilledRect({
    scene: scene, cssColor: "royalblue", parent: scene,
    x: g.game.width-100, y: 90 * i,
    width: 90, height: 90, opacity: 1,
  });
}

更新してみると四角がくっついてしまって、中心もずれていますね。




四角を少し小さくしつつ全体的に下に動かします。

for (var i = 0; i < 7; i++) {
  var tile = new g.FilledRect({
    scene: scene, cssColor: "royalblue", parent: scene,
    x: g.game.width-100, y: 90 * i + 47,
    width: 86, height: 86, opacity: 1,
  });
}

これできれいに縦に並んだはずです。

  


しかしまだスペースがあるので、手前にも配置してしまいましょう。
横の位置をずらした列を用意するのに、また繰り返し処理を使います。

for (var j = 0; j < 12; j++) {
  for (var i = 0; i < 7; i++) {
    var tile = new g.FilledRect({
      scene: scene, cssColor: "royalblue", parent: scene,
      x: g.game.width-100 - 90 * j, y: 90 * i + 47,
      width: 86, height: 86, opacity: 1,
    });
  }
}

今度は j をつかって i とかぶらないようにし、xの値を90ずつずらしています。

タイルが敷き詰められたでしょうか。

  

 



終了

第3回は以上で終了です。お疲れさまです。

最終コードはこちらです。

次はゲームの要素を増やすため、様々な判定を追加していきます。