10. 四則演算と余り
前のレッスンでは、ダメージ計算で引き算-と割り算/を使いました。このレッスンでは、JavaScriptで使える計算記号について詳しく学びましょう。
演算子
+や-のような計算に使う記号を演算子(えんざんし)と呼びます。
JavaScriptでは、次の演算子が使えます。
| 演算子 | 意味 | 例 | 結果 |
|---|---|---|---|
+ |
足し算 | 10 + 3 |
13 |
- |
引き算 | 10 - 3 |
7 |
* |
掛け算 | 10 * 3 |
30 |
/ |
割り算 | 10 / 4 |
2.5 |
% |
余り | 10 % 3 |
1 |
掛け算は×ではなく*(アスタリスク)を使います。割り算は÷ではなく/(スラッシュ)を使います。これは多くのプログラミング言語で共通の書き方です。
%は余りを求める演算子です。10 % 3は「10を3で割った余り」なので1になります。
複数の演算子を使う
複数の演算子を使った計算もできます。
console.log(10 + 5 - 3);
算数と同じように、掛け算と割り算は足し算と引き算より先に計算されます。
console.log(10 + 5 * 2);
結果は20です。5 * 2が先に計算されて10になり、10 + 10で20になります。
順番を変えたいときは、算数と同じように()を使います。
console.log((10 + 5) * 2);
結果は30です。(10 + 5)が先に計算されて15になり、15 * 2で30になります。
まおうがゆうしゃを攻撃
前のレッスンでは「ゆうしゃ」が「まおう」を攻撃しました。今度は「まおう」が「ゆうしゃ」を攻撃してみましょう。
- 「まおう」の攻撃力: 186
- 「ゆうしゃ」の防御力: 97
ダメージを計算してみましょう。
console.log((186 - 97) / 2);
44.5と表示されます。RPGのダメージ計算では、通常は整数にしたいところです。
小数点以下を切り捨てて整数にするには、Math.floor()を使います。
console.log(Math.floor((186 - 97) / 2));
44と表示されます。Math.floor()は小数点以下を切り捨てる命令です。
レッスン08と同様に、このダメージをメッセージボックスに表示してみましょう。テンプレートリテラルを使います。
<!-- battle.html hidden -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>バトル</title>
<link rel="stylesheet" href="css/battle.css">
<script src="js/battle.js" defer></script>
</head>
<body>
<table id="status">
<tr>
<th>ゆうしゃ</th><th>せんし</th><th>そうりょ</th><th>まほうつかい</th>
</tr>
<tr><td>HP 153</td><td>HP 198</td><td>HP 101</td><td>HP 77</td></tr>
<tr><td>MP 25</td><td>MP 0</td><td>MP 35</td><td>MP 58</td></tr>
</table>
<div id="monster">
<img class="dark-knight" src="img/dark-knight.png">
<img class="dark-lord" src="img/dark-lord.png">
<img class="demon-priest" src="img/demon-priest.png">
</div>
<div id="message">
まおうがあらわれた。
</div>
</body>
</html>
/* battle.css hidden */
body {
background-color: rgb(34, 34, 34);
color: white;
font-family: sans-serif;
}
table#status {
border: solid 2px white;
border-collapse: collapse;
margin: 10px auto 0 auto;
width: 640px;
}
table#status tr:first-child {
border-bottom: solid 1px white;
}
table#status td {
text-align: center;
}
#monster {
text-align: center;
margin-top: 40px;
}
#monster .dark-lord {
width: 400px;
}
#monster .dark-knight {
width: 150px;
}
#monster .demon-priest {
width: 150px;
}
#message {
border: solid 2px white;
border-radius: 4px;
padding: 10px;
width: 720px;
margin: 30px auto;
}
// battle.js
document.getElementById("message").textContent = `ゆうしゃに${Math.floor((186 - 97) / 2)}のダメージ。`;
メッセージボックスに「ゆうしゃに44のダメージ。」と表示されます。
ステータスに反映する
計算結果をステータス表示に反映してみましょう。
まず、「ゆうしゃ」のHPを表示している要素を確認します。HTMLでは、ステータス表の2行目の1列目に「HP 153」と書かれています。
<!-- highlight:6 -->
<table id="status">
<tr>
<th>ゆうしゃ</th><th>せんし</th><th>そうりょ</th><th>まほうつかい</th>
</tr>
<tr>
<td>HP 153</td>
<td>HP 198</td>
<td>HP 101</td>
<td>HP 77</td>
</tr>
<tr><td>MP 25</td><td>MP 0</td><td>MP 35</td><td>MP 58</td></tr>
</table>
どうすればこの要素を指定することができるでしょうか?document.querySelector()を使えば、CSSセレクタを使って要素を指定することができます。
「ゆうしゃ」のHPのセルはCSSセレクタで#status tr:nth-child(2) td:nth-child(1)(#statusの中の2番目のtrの1番目のtd)と書くことができます。最初の子要素を指定するtd:first-childでも書けますが、後で「せんし」や「そうりょ」など他のキャラクターのHPを更新することも考えて、nth-child(1)にしておきます。これなら、数字の部分だけ変えれば他のキャラクターにも対応できます。
// battle.js
document.getElementById("message").textContent = `ゆうしゃに${Math.floor((186 - 97) / 2)}のダメージ。`;
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${153 - Math.floor((186 - 97) / 2)}`;
ゆうしゃのHPが「HP 109」に変わりました。
試してみよう
- 他のキャラクターのHPも変更してみましょう
- 余りの演算子
%を使って、いろいろな計算を試してみましょう - 割り切れないとき、
Math.round()やMath.ceil()を使って、結果がどう変わるか確認してみましょう
これまでの成果
<!-- battle.html folded -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>バトル</title>
<link rel="stylesheet" href="css/battle.css">
<script src="js/battle.js" defer></script>
</head>
<body>
<table id="status">
<tr>
<th>ゆうしゃ</th><th>せんし</th><th>そうりょ</th><th>まほうつかい</th>
</tr>
<tr><td>HP 153</td><td>HP 198</td><td>HP 101</td><td>HP 77</td></tr>
<tr><td>MP 25</td><td>MP 0</td><td>MP 35</td><td>MP 58</td></tr>
</table>
<div id="monster">
<img class="dark-knight" src="img/dark-knight.png">
<img class="dark-lord" src="img/dark-lord.png">
<img class="demon-priest" src="img/demon-priest.png">
</div>
<div id="message">
まおうがあらわれた。
</div>
</body>
</html>
/* battle.css folded */
body {
background-color: rgb(34, 34, 34);
color: white;
font-family: sans-serif;
}
table#status {
border: solid 2px white;
border-collapse: collapse;
margin: 10px auto 0 auto;
width: 640px;
}
table#status tr:first-child {
border-bottom: solid 1px white;
}
table#status td {
text-align: center;
}
#monster {
text-align: center;
margin-top: 40px;
}
#monster .dark-lord {
width: 400px;
}
#monster .dark-knight {
width: 150px;
}
#monster .demon-priest {
width: 150px;
}
#message {
border: solid 2px white;
border-radius: 4px;
padding: 10px;
width: 720px;
margin: 30px auto;
}
// battle.js
document.getElementById("message").textContent = `ゆうしゃに${Math.floor((186 - 97) / 2)}のダメージ。`;
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${153 - Math.floor((186 - 97) / 2)}`;