今回はTerrainのチュートリアルを紹介します。Terrainは日本語で地形を意味します。地形とクリープの関係はいったいどのようにプログラムすれば良いのでしょうか。
各チュートリアルは別途記事にしてありますので、他のチュートリアルは下記を参考にしてください。
- Loop and import(ループとインポート)
- Simple move(単純な移動)
- First attack(初めての攻撃)
- Creeps bodies(クリープの各パーツ)
- Store and transfer(エネルギーのストアと転送)
- Terrain(地形)
- Spawn creeps(クリープを生成)
- Harvest energy(エネルギーの採取)
- Construction(工事・建築)
- Final test(最終試験)
Terrain ー地形ー
ゲームには5種類の地形があります。
- 平地
- 自然の不滅の(破壊不可能な)壁
- 構築された破壊可能な壁
- 沼地
- 道路
沼地と道路は、Creeps Weight(クリープウェイト・重量)の概念と連動して機能します。 MOVE
を除くすべてのクリープボディパーツは、それに重量を追加します。空のCARRY
ボディ部分は重量を追加しませんが、クリープがそこ(著者注:CARRY
)にリソースを保持している場合は、重量を追加します。 すべてのMOVE
ボディパーツは、クリープの移動速度を上げます。 MOVE
ボディパーツと他のすべてのボディパーツの数が同じである場合、クリープが平地でeach tick(各ティック:著者注:ティックとはループの周期単位でScreeps :Arenaではこのように1ティック、2ティックと表現する)の移動は可能です。 そうでなければ、それはfatigue
(倦怠感)を覚え、動きのないティックを見逃します(著者注:クリープが動かないティック・周期が発生してしまうことを言っているらしい)。

ちょっと無理やり訳した感が出てしまいましたが、突っ込みあればTwitterでもFacebookでもメールでもいいのでご指摘ください
しかし、同じボディパーツを持つ場合、沼地ではそれははるかにfatigue
(倦怠感)が増し、5ティックごとに1回しか動くことができなくなります。沼地ですべてのティックを動かすには、クリープの体に5倍のMOVE
パーツが必要です。
一方、道路はMOVE
パーツを半分にするため、クリープのパーツの必要性を軽減します。たとえば、クリープに10個の重いボディパーツがある場合、道路上のすべてのティックを移動するために必要なMOVEパーツは5個だけです。

道路は早く動けるよってことでいいのか?サンプルコード見たほうが早い気がしてきた
このチュートリアルステップでは、すべてのクリープを対応する旗に移動するだけです。地形や体によって、速度が異なることに注目してください。
ここでfindClosestByPath
関数を使用できることに注意してください。 あなたが見つける必要があるときに使用すると便利です。(著者注:自ら目視で一番近い敵機や旗を指定するのは不要だということのようです。findClosestByPath
メソッドで一番近い目標を自動で追尾してくれるんですね。)
パスファインディングアルゴリズム(著者注:findClosestByPath
メソッドのアルゴリズム)を使用して最も近い位置にある配列からの敵機・目標オブジェクトは以下のように表します:
var flags = getObjectsByPrototype(Flag);
svar closestFlag = creep.findClosestByPath(flags);
目的:すべてのクリープをフラグに移動します。
サンプルコード
import { getObjectsByPrototype, findClosestByPath } from '/game/utils';
import { Creep, Flag } from '/game/prototypes';
export function loop() {
var creeps = getObjectsByPrototype(Creep).filter(i => i.my);
var flags = getObjectsByPrototype(Flag);
for(var creep of creeps) {
var flag = creep.findClosestByPath(flags);
creep.moveTo(flag);
}
}
まとめ
- 複数の自機を取り出すには
find()
ではなくfilter()
メソッドを使うといいですね filter()
でとった自機たちのそれぞれ最も近い(最短ルート)の旗(フラッグ)を指定するにはcreep.findClosestByPath(flags)
をティックが進むたびに取得できるようにfor…of…で囲ってループしてやる必要がありますね
いやーこの章は、製作者の意図がきちんと汲み取れているのか微妙なところですが、大枠は合っていて、そこまでずれていないとは思います。tickの和訳ですが、おそらく時計のtick tackの音が語源かと思われます。秒刻みで時間が進んでいくイメージですね。ダニではないと思いますwww