var enemies = [
{
nick: "Bob1",
x: 12,
y: 21
},
{
nick: "Bob2",
x: 20,
y: 21
},
{
nick: "Bob3",
x: 12,
y: 21
}
]
var me = {
x: 19,
y: 20
}
for (var x in enemies) {
var enemy = enemies[x];
if ((Math.abs(me.x - enemy.x) <= 1 && Math.abs(me.y - enemy.y) <= 1)) {
console.info("Enemy In range");
} else {
console.info("Enemies not in range");
}
}Здравствуйте все. У меня есть множество врагов, и я проверяю, находится ли какой-нибудь враг на расстоянии 1 поля от моей позиции x или y. И я хочу войти только один раз, если это так или нет. Как вы теперь видите, он проверяет каждого врага и регистрирует каждого врага. Это не то, что я хочу. Я просто хочу просто проверить, есть ли враги на расстоянии 1 поля от моей позиции x или y или нет, и получить простой ответ да или нет. Я новичок, но если у вас есть подсказка для меня, это было бы здорово!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вместо этого вы можете использовать Array#find для досрочного возврата из цикла, если найден соответствующий элемент.
var enemies = [{
nick: "Bob1",
x: 12,
y: 21
},
{
nick: "Bob2",
x: 20,
y: 21
},
{
nick: "Bob3",
x: 12,
y: 21
}
]
var me = {
x: 19,
y: 20
}
var enemy = enemies.find(enemy => (Math.abs(me.x - enemy.x) <= 1 && Math.abs(me.y - enemy.y) <= 1));
if (typeof enemy !== undefined) {
console.info("Enemy In range");
} else {
console.info("Enemies not in range");
}Имейте логическое значение, например found, которое начинается как false. Когда найдете, установите true и break. Тогда у после цикла есть if (found) ... else .... Это выводит печать из цикла, гарантируя, что вы получите ее только один раз.
Кроме того, вы можете сильно сжать это, используя новый метод some, который внутренне делает в основном то же самое (только быстрее):
let found = enemies.some(enemy => enemyIsClose(enemy, me));
Если вам действительно нужно найти ближайшего врага, find вместо some вернет первого, а filter вернет их всех.
Чтобы ваш код проверял, находится ли поблизости враг, ему нужно будет перебрать все их позиции, этого нет, но если вы хотите только уменьшить количество журналов консоли, вы можете использовать этот код:
var isEnemyFound = true;
for (let x of enemies) {
var enemy = enemies[x];
if ((Math.abs(me.x - enemy.x) <= 1 && Math.abs(me.y - enemy.y) <= 1)) {
console.info("Enemy In range");
break;
} else {
isEnemyFound = false;
}
}
if (!isEnemyFound){
console.info("Enemies not in range");
}
Вы можете просто отфильтровать объект с помощью Array.filter и найти свою коллекцию.
var enemies = [
{
nick: "Bob1",
x: 12,
y: 21
},
{
nick: "Bob2",
x: 20,
y: 21
},
{
nick: "Bob3",
x: 12,
y: 21
}
]
var me = {
x: 19,
y: 20
}
var enemy=enemies.filter(item=>{
return me.x-item.x<=1
})[0];
console.info(enemy);В целом, вот душа получше. Предыдущий я делал на ходу. Попробуйте поиграть с ним и посмотрите, нужно ли оно вам. Я искренне надеюсь, что это так :)
Если вы измените свой (мне - значения) на «13», результат все равно будет тот же, но попробуйте изменить его, например, на «14» и посмотрите, как работает логика. Это перебор, но если вы хотите продвинуть свою игру, это отличное решение, потому что вы можете создавать столько вариаций и возможностей, сколько захотите, на лету, просто позвонив next();, чтобы создать следующее значение. Просто предложение. Удачи!
let enemies = [
{nick: "Bob1", x: 12, y: 21},
{nick: "Bob2", x: 12, y: 21},
{nick: "Bob3", x: 12, y: 21}
];
let me = {
x: 12,
y: 21
}
function* range() {
for (let x in enemies) {
let enemy = enemies[x];
while(Math.abs(me.x - enemy.x) <=1 && Math.abs(me.y - enemy.y) <= 1) {
yield "Enemy is in range";
break; // closes iterator, triggers return
}
yield "Enemy is NOT in range";
break;
}
}
var gen = range(); // Creating a generator
console.info(gen.next().value); // Then we use it to get the next value
.filter(...)[0]даст те же результаты, что и.find(...), только медленнее.