前回の演習で書いた魔法のポーションのコードに戻りましょう。 プレイヤーが回復ポーションを飲んだら回復コードを実行し、ダメージ ポーションを飲んだらダメージ コードを実行する必要があります。
まずコードを書いてみる
-
ポーションの種類に関する質問に答える必要がありそうなため、種類を記録する新しい文字列変数
PotionType
を作成します。var PotionType: string = "heal"
-
これで、変数
PotionType
が別の文字列と等しいかどうかをチェックできるようになりました。PotionType
が"heal"
と等しいかどうかをチェックすると、答えはイエスになるため、回復コードが実行されます。if (PotionType = "heal"): set PlayerHealth = PlayerHealth + PotionHealAmount
-
次に、ダメージ コードに対しても同じような if 式を記述します。
if (PotionType = "damage"): set PlayerHealth = PlayerHealth - PotionDamageAmount
でも待ってください。 回復コードには問題があります。
ここでは、プレイヤーがポーションで体力値を上げ続けることを止めるものは何もありません。これを制限するのは良い考えです。ここで
if
を使います。 -
まず、
float
型の新しい定数を宣言します。MaxHealth
という名前を付け、100.0
に設定します。MaxHealth: float = 100.0
プレイヤーが回復ポーションを飲んだときに、
PlayerHealth
の値がMaxHealth
の値を超えるようであれば、PlayerHealth
をMaxHealth
に設定する必要があります。# プレイヤーが回復ポーションを飲んだ場合に実行されるコード。 # 回復された場合にプレイヤーの体力値が MaxHealth を超えなければ、 # 全量を回復させます。 if (PotionType = "heal" and (PlayerHealth + PotionHealAmount) < MaxHealth): set PlayerHealth = PlayerHealth + PotionHealAmount else: set PlayerHealth = MaxHealth
上記のコードには、
PotionType
が"heal"
と等しいかどうかと、PlayerHealth + PotionAmount
がMaxHealth
より小さいかどうかをチェックするためのand
があるのがわかります。PlayerHealth
をPotionHealAmount
だけ増やすには、この両方の条件を満たしている必要があります。このコードを読んでも、PlayerHealth が MaxHealth を超えないようにするためのコードだということがわからない場合もあります。そこで、コード コメントが役に立ちます。実際のコードの上にある 3 行のコメントに注目してください。
-
ダメージ コードは動作しますが、
if
...else if
...else
を使用することで改善できます。プレイヤーがダメージ ポーションを飲んで PlayerHealth が0.0
以下になる場合、代わりに PlayerHealth を1.0
に設定したいと思います。PlayerHealth
がすでに1.0
であれば、それを0.0
に設定します。こうすることで、プレイヤーをあまりにひどい目に遭わせることなく、ポーションが有害であると伝えることができます。# プレイヤーがダメージ ポーションを飲んだ場合に実行されるコード。 # 体力値が MinHealth より大きいが PotionDamageAmount より小さければ、プレイヤーを倒しません。 # 体力値がすでに MinHealth 以下であれば、プレイヤーを倒します。 if (PotionType = "damage" and PlayerHealth > PotionDamageAmount): set PlayerHealth = PlayerHealth - PotionDamageAmount else if (PlayerHealth > MinHealth): # 体力値が小さければ、プレイヤーにもう一度チャンスを与えます。 set PlayerHealth = 1.0 else: set PlayerHealth = 0.0
... バグを見つける
この演習のすべてのコードと、テスト用に追加した Print()
関数呼び出しを以下に示しています。このコードを実行してみてください。Print()
呼び出しは、自由に変更して構いません。PotionType
変数が "heal"
に初期化されているため、回復コードだけが実行されることが想定されます。
しかし、待ってください、バグがあります。
以下のコードを実行し、バグを見つけてください。
MaxHealth: float = 100.0
MinHealth: float = 1.0
var PotionType: string = "heal"
# プレイヤーが回復ポーションを飲んだ場合に実行されるコード。
# 回復された場合にプレイヤーの体力値が MaxHealth を超えなければ、
# 全量を回復させます。
if (PotionType = "heal" and (PlayerHealth + PotionHealAmount) < MaxHealth):
set PlayerHealth = PlayerHealth + PotionHealAmount
Print ("Full heal")
else:
# そうでなければ、PlayerHealth を MaxHealth に設定します。
set PlayerHealth = MaxHealth
Print("PlayerHealth too high for full heal")
# プレイヤーがダメージ ポーションを飲んだ場合に実行されるコード。
# 体力値が MinHealth より大きいが PotionDamageAmount より小さければ、プレイヤーを倒しません。
# 体力値がすでに MinHealth 以下であれば、プレイヤーを倒します。
if (PotionType = "damage" and PlayerHealth > PotionDamageAmount):
set PlayerHealth = PlayerHealth - PotionDamageAmount
Print("Full damage")
else if (PlayerHealth > MinHealth):
# 体力値が小さければ、プレイヤーにもう一度チャンスを与えます。
set PlayerHealth = 1.0
Print("PlayerHealth set to 1.0")
else:
# プレイヤーを倒します。
set PlayerHealth = 0.0
Print("Player eliminated!")
PotionType
が「heal」に設定されていれば、回復コードだけが実行されるはずです。しかし、ダメージのコードにある if
... else if
... if
式がまだ実行されています。つまり、PlayerHealth
が MinHealth
より大きい場合、PlayerHealth
は 1.0
に設定されるということです。これは望ましい動作ではありませんが、if
式の中に他のチェックをネスティングして、PotionType
だけをチェックすることで修正できます。
# プレイヤーが回復ポーションを飲んだ場合に実行されるコード。
# 回復された場合にプレイヤーの体力値が MaxHealth を超えなければ、
# 全量を回復させます。
if (PotionType = "heal"):
if ((PlayerHealth + PotionHealAmount) < MaxHealth):
set PlayerHealth = PlayerHealth + PotionHealAmount
Print ("Full heal")
else:
# set PlayerHealth the MaxHealth
set PlayerHealth = MaxHealth
Print("PlayerHealth too high for full heal")
# プレイヤーがダメージ ポーションを飲んだ場合に実行されるコード。
# 体力値が MinHealth より大きいが PotionDamageAmount より小さければ、プレイヤーを倒しません。
# 体力値がすでに MinHealth 以下であれば、プレイヤーを倒します。
if (PotionType = "damage"):
if ((PlayerHealth > PotionDamageAmount)):
set PlayerHealth = PlayerHealth - PotionDamageAmount
Print("Full damage")
else if (PlayerHealth > MinHealth):
# 体力値が小さければ、プレイヤーにもう一度チャンスを与えます。
set PlayerHealth = 1.0
Print("PlayerHealth set to 1.0")
else:
# Eliminate player
set PlayerHealth = 0.0
Print("Player eliminated!")
これで、if
式の内の一つの下でインデントされた、PotionType
をチェックするコード ブロックだけが実行されるようになりました。PotionType
を "damage"
に設定したケースでも、このコードを試してみます。
ふう! コードの変更がかなり多くありましたが、できましたね。
一休みして、ポー…水を飲んで、次のレッスンの準備ができたら、また来てください。
完全なスクリプト
using { /Fortnite.com/Devices}
using { /Verse.org/Simulation}
hello_world_device := class(creative_device):
# 実行中のゲームで仕掛けが開始されたときに実行します
OnBegin<override>()<suspends> : void =
MaxHealth : float = 100.0
MinHealth : float = 1.0
var PotionType: string = "heal"
set PlayerHealth = 80.0
# プレイヤーが回復ポーションを飲んだ場合に実行されるコード。
# 回復された場合にプレイヤーの体力値が MaxHealth を超えなければ、
# 全量を回復させます。
if (PotionType = "heal"):
if ((PlayerHealth + PotionHealAmount) < MaxHealth):
set PlayerHealth = PlayerHealth + PotionHealAmount
Print ("Full heal")
else:
# そうでなければ、PlayerHealth を MaxHealth に設定します。
set PlayerHealth = MaxHealth
Print("PlayerHealth too high for full heal")
# プレイヤーがダメージ ポーションを飲んだ場合に実行されるコード。
# 体力値が MinHealth より大きいが PotionDamageAmount より小さければ、プレイヤーを倒しません。
# 体力値がすでに MinHealth 以下であれば、プレイヤーを倒します。
if (PotionType = "damage"):
if ((PlayerHealth > PotionDamageAmount)):
set PlayerHealth = PlayerHealth - PotionDamageAmount
Print("Full damage")
else if (PlayerHealth > MinHealth):
# 体力値が小さければ、プレイヤーにもう一度チャンスを与えます。
set PlayerHealth = 1.0
Print("PlayerHealth set to 1.0")
else:
set PlayerHealth = 0.0
Print("Player eliminated!")
Print("PlayerHealth now {PlayerHealth}")