ここまでのバックナンバーは下記の記事を参照してください。
- 【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
プロパティを用いることも重要ですね。