ここまでのバックナンバーは下記の記事を参照してください。
- 【PCゲーム】Screeps: Arenaの遊び方(チュートリアル「Loop and import」)を日本語に!和訳して解説!(その1)
- 【PCゲーム】Screeps: Arenaの遊び方(チュートリアル「Simple move」)を日本語に!和訳して解説!(その2)
- 【PCゲーム】Screeps: Arenaの遊び方(チュートリアル「First attack」)を日本語に!和訳して解説!(その3)
それでは、今回はCreeps bodies(機体パーツ)チュートリアルを翻訳してご紹介します。
各チュートリアルは別途記事にしてありますので、他のチュートリアルは下記を参考にしてください。
- Loop and import(ループとインポート)
- Simple move(単純な移動)
- First attack(初めての攻撃)
- Creeps bodies(クリープの各パーツ)
- Store and transfer(エネルギーのストアと転送)
- Terrain(地形)
- Spawn creeps(クリープを生成)
- Harvest energy(エネルギーの採取)
- Construction(工事・建築)
- Final test(最終試験)
Creeps bodies
さまざまなクリープ関数を呼び出すことができますが、すべてのクリープですべての関数を使用できるわけではありません。 クリープが実行できることは、クリープが持つ体の部分によって異なります。 その本体が適切であるかどうかを確認できます。配列では、各要素が特定のタイプの1つの本体部分を表します。
MOVE…クリープの移動を可能にしますATTACK…近接範囲での攻撃を可能にしますRANGED_ATTACK…3タイル離れたターゲットを攻撃できるようにしますHEAL…それ自体または別のクリープを癒すことができますWORK…労働クリープは構造物を構築したり、エネルギーを収穫したりできますCARRY…リソースを運ぶクリープの能力を高めますTOUGH…効果はありません
if(creep.body.some(bodyPart => bodyPart.type == ATTACK)) {
// this creep has ATTACK body parts
}
some()メソッドを知らない人は調べてくださいね。配列の内容の判定に用いるJavaScriptのメソッドです。
ボディパーツごとにクリープのhits(ヒット数)が100増加します。クリープがダメージを受けると、ボディパーツもダメージを受け、パーツのヒットカウンターが0になると機能しなくなります。同じタイプのボディが多いほど強くなります。
さて、このチュートリアルのステップでは、3つの異なるクリープがあります:ATTACK、RANGED_ATTACK、およびHEALパーツを使用します。 相手の行動を調整した場合にのみ、相手を倒すことができます。
これを行うには、前のチュートリアルステップと同じアプローチを使用しますが、体の部分に基づいてアクションを区別します。ダメージディーラーはさまざまな方法(attackとrangedAttack)でダメージを与え、ヒーラーはダメージを受けたクリープをhealメソッドで回復する必要があります。
目的:敵のクリープを倒します。
サンプルコード
import { getObjectsByPrototype } from '/game/utils';
import { Creep } from '/game/prototypes';
import { ERR_NOT_IN_RANGE, ATTACK, RANGED_ATTACK, HEAL } from '/game/constants';
export function loop() {
var myCreeps = getObjectsByPrototype(Creep).filter(creep => creep.my);
var enemyCreep = getObjectsByPrototype(Creep).find(creep => !creep.my);
for(var creep of myCreeps) {
if(creep.body.some(bodyPart => bodyPart.type == ATTACK)) {
if(creep.attack(enemyCreep) == ERR_NOT_IN_RANGE) {
creep.moveTo(enemyCreep);
}
}
if(creep.body.some(bodyPart => bodyPart.type == RANGED_ATTACK)) {
if(creep.rangedAttack(enemyCreep) == ERR_NOT_IN_RANGE) {
creep.moveTo(enemyCreep);
}
}
if(creep.body.some(bodyPart => bodyPart.type == HEAL)) {
var myDamagedCreeps = myCreeps.filter(i => i.hits < i.hitsMax);
if(myDamagedCreeps.length > 0) {
if(creep.heal(myDamagedCreeps[0]) == ERR_NOT_IN_RANGE) {
creep.moveTo(myDamagedCreeps[0]);
}
}
}
}
}まとめ
ATTACK、RANGED_ATTACK、HEALなどのパーツ定数は/game/constantsからimportfor(var creep of myCreeps)のようにfor...of...でループさせて各機体を参照すると良い- パーツの判別には
some()メソッドで判定させると良い。if(creep.body.some(bodyPart => bodyPart.type == ATTACK)) {のように、ATTCK、HEALなどの役割を判別する - ヒーラーは
myCreeps.filter(i => i.hits < i.hitsMax)のようにダメージを受けた機体を選定して、heal()メソッドで回復。サンプルコードを見る限り、隣接していないと回復できない。
creep.bodyが配列オブジェクトになるので、creep.body.some()で配列の存在をチェックするのがポイントでしょうか。some()メソッド内のbodyPart => bodyPart.type == ATTACKの形も覚えておいたほうが良さそうです。
また、ダメージを受けているかどうかにはmyCreeps.filter(i => i.hits < i.hitsMax)にあるように、hitsプロパティ、hitsMaxプロパティを用いることも重要ですね。

