В последнее время я стал безнадежно зависимым от 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, установите его свойство quiet
быть true
, и связать его и его цель ползучести. После того, как у ползунки есть задача, ей будет предложено запустить ее, пока она не станет недействительной (код не включен выше). Ползучесть отлично выполняет задачу, но она все еще записывает все на консоль.
Я думал бы, что в harvester.js, когда я установил taskHarvest.quiet = true;
, поведение, импортированное из Task.js, увидело бы this.quiet
как true
. Однако кажется, что это не так. В roleHarvester
, работает console.log(creep.task.quiet)
возвращает true
, но в Task
, работает console.log(this.quiet)
, когда ползучесть выполняет назначенное задание, дает false
.
Я могу добавить quiet
в конструктор как необязательный параметр, но это запутанно, и я хочу знать, почему то, что я делаю, не работает.
Когда вы проверяете значение 'this.quiet', вы на 100% уверены, что' this' верен? Я не вижу ничего явно неправильного или неверного понимания вашего наследства. Установка 'taskHarvest.quiet = true;' должна работать нормально. – jfriend00
@ jfriend00 в Task.js, 'this' должен ссылаться на' Task', а в task_harvest.js 'this' должен ссылаться на' taskHarvest', который не определяет 'this.quiet', поэтому он должен ссылаться на унаследованная переменная Task.js. Затем, когда я создаю экземпляр 'taskHarvest' и устанавливаю его' instance.quiet = true', он, похоже, не меняет унаследованное значение из 'Task'. Если я делаю 'console.log (экземпляр.quiet) ', он возвращает' true', но если я добрался до 'Task' и сделаю' console.log (this.quiet) ', он вернет' false'. –
Я не спрашивал вас, что это должно быть. Я спросил, что это на самом деле. Здесь есть только две возможности. Что-то еще устанавливает '.quiet' обратно в' false' или вы не смотрите на один и тот же объект через некоторое время. Вы должны выяснить, кто из них. Вы не показываете достаточно своего кода, чтобы мы следили за жизнью объекта и всем, что могло случиться с ним. Например, я понятия не имею, что делает 'creep.assign()'. Это может быть копирование объекта, установка некоторых свойств на нем и т. Д. – jfriend00