私は最近、絶望的にScreepsに夢中になってしまい、タスクベースの実装を行うためにいくつかのコードをリファクタリングしました。タスクとは、「歩くまで歩いた後、フルキャパシティーになるまで収穫する」のようなもので、ES6スタイルのクラスとして書かれた単一の基本タスクテンプレートに基づいています。クリープには、関連タスクファイルをロードして新しいタスクインスタンスを返すラッパー(tasks.js)を使用してタスクを割り当てることができます。サブクラスインスタンスの変数を変更する
今日私はJavascriptの継承モデルを完全に理解していないと思う奇妙なバグが発生しました。以下関連するコードである:
Task.js:(ベース・タスク・クラス)
class Task {
constructor(taskName) {
// Parameters for the task
this.name = taskName; // name of task
this.quiet = false; // suppress console logging if true
this.creep = [creep assigned to this task]
this.target = [thing task operates on, e.g. "repair this wall"]
...
}
...
// Execute this task each tick. Returns nothing unless work is done.
step() {
...
if (creep.pos.inRangeTo(target, this.targetRange)) {
var workResult = this.work();
console.log(this.quiet) // < returns false, should be true?
if (workResult != OK && this.quiet == false) {
creep.log("Error: " + workResult); // < is printed when run
}
return workResult;
} [else move to target]
}
...
// Task to perform when at the target
work() {
// overwrite this in child class
}
}
module.exports = Task;
task_harvest.js:(収穫タスク)
var Task = require('Task');
class taskHarvest extends Task {
constructor() {
super('harvest');
// no mention of this.quiet here
}
...
work() {
console.log("harvest:" + this.quiet);
return this.creep.harvest(this.target);
}
}
module.exports = taskHarvest;
tasks.js:生成する(ラッパー新しいタスクインスタンス関数呼び出しを経由して)
module.exports = function (taskName) {
var TaskClass = require('task_' + taskName); // all tasks follow this naming pattern
var taskInstance = new TaskClass;
return taskInstance;
};
harvester.js:(収穫クリープのための行動モデル)
var tasks = require('tasks');
var roleHarvester = {
...
harvest: function (creep) {
var target = Game.getObjectById(creep.memory.assignment);
var taskHarvest = tasks('harvest');
taskHarvest.quiet = true; // < this task shouldn't print anything
creep.assign(taskHarvest, target); // assigns to creep.task
return OK;
},
...
run: function (creep) { // executed every tick
// execute the task
creep.task.step();
},
...
}
私は元から採取するクリープを割り当てると、私はtask_harvest.jsから新しいタスクを作成し、true
こと、およびクリープに、その標的に結合するために、そのquiet
プロパティを設定します。クリープにタスクが設定されると、クリープが無効になるまで実行されるよう指示されます(コードは上記に含まれていません)。クリープはタスクをうまく実行しますが、それでもすべてをコンソールに記録します。
harvester.jsでtaskHarvest.quiet = true;
と設定すると、Task.jsからインポートされた動作はthis.quiet
としてtrue
と表示されます。しかし、それはそうではないように思われる。 では、console.log(creep.task.quiet)
を実行するとtrue
が返されますが、には、が実行され、割り当てられたタスクを実行しているときにはfalse
となります。
オプションのパラメータとしてquiet
をコンストラクタに追加することはできますが、それは複雑で、私が何をしているのかが分かりません。
'this.quiet'の値をチェックしているときに' this'が正しいことを100%確信していますか?明らかに間違ったことやあなたの相続について誤解されたことはありません。 'taskHarvest.quiet = true; 'を設定するとうまくいくはずです。 – jfriend00
@ jfriend00はTask.jsで 'this'は' Task'を参照し、task_harvest.jsでは 'this'は' this.quiet'を定義していない 'taskHarvest'を参照する必要があります。 Task.js変数を継承します。それから 'taskHarvest'のインスタンスを作成し、' instance.quiet = true'を設定すると、継承された値を 'Task'から変更しているようには見えません。私が 'console.log(インスタンス。'true'を返しますが、' Task'に行って 'console.log(this.quiet)'を実行すると 'false'を返します。 –
私はそれが "すべき"ことをあなたに尋ねなかった。私はそれが実際に何だったか尋ねました。ここには2つの可能性しかありません。何か他のものが '.quiet'を' false'に戻しているか、後で同じオブジェクトを見ていません。あなたはそれがどれであるか把握しなければなりません。あなたは、オブジェクトの生涯とそれに起こり得るすべてのことに私たちが従うために十分なコードを表示しません。例えば、私は 'creep.assign()'が何をしているのか分かりません。 – jfriend00