Я не знаю, как работает оператор присваивания [обработка]

Я пишу программу, имитирующую змею, и значения каждой части змеи хранятся в массиве. Чтобы смоделировать физику змеи, мне нужно назначить последующий раздел предыдущему, и здесь я столкнулся с проблемой.

int bar;
int foo;

void setup() {}

void draw() {
  foo = bar;
  bar = mouseX;
  println(foo);
  println(bar);
}

В этом примере, не должен ли foo выводить предыдущую позицию мыши? Bar назначается mouseX после того, как foo назначается bar. Делает ли оператор присваивания так, что если присваиваемая переменная изменяется, присваиваемая переменная изменяется вместе с ней? Это очень расстраивает, и я думаю, что решение должно быть простым. Как присвоить одну переменную другой, не принимая во внимание будущие изменения в переменной, на которую ссылаются?

РЕДАКТИРОВАТЬ: Вот пример симулятора змеи, который должен работать, но не работает по той же причине, все сегменты в конце каждого цикла for одинаковы:

int segments = int(random(3, 10));
float springing[] = new float[segments];
float damping[] = new float[segments];
PVector accel[] = new PVector[segments];
PVector[] joints = new PVector[segments];
PVector[] delta = new PVector[segments];
PVector food = new PVector(0,0,0);

void setup() {
  size(500, 500);
  stroke(255);
  for(int n = 0; n < joints.length; n++) {
    if (n == 0) joints[0] = new PVector(random(width), random(height));
    else joints[n] = joints[0];
    delta[n] = new PVector(0,0,0);
    accel[n] = new PVector(0,0,0);
    springing[n] = .05*(.07*(n+1)); 
    damping[n] = .95-(.02*n);
  }
}

void draw() {
  background(0);
  food.x =  mouseX;
  food.y = mouseY;
  for(int n = 0; n < segments; n++) {
    if (n == 0) {
     delta[0] = PVector.sub(food, joints[0]); 
     joints[0].add(delta[0]);
    }
    else {
     delta[n] = PVector.sub(joints[n-1], joints[n]);
     delta[n].mult(springing[n]);
     accel[n].add(delta[n]);
     joints[n].add(accel[n]);
    }
    point(joints[n].x, joints[n].y);
    accel[n].mult(damping[n]);
  }
}

person Miles    schedule 16.01.2011    source источник


Ответы (2)


В вашем примере foo и bar являются примитивными типами, поэтому результаты должны соответствовать вашим ожиданиям. Однако если бы это были ссылки, то то, что вы написали, было бы неполным. В таком случае конструктор поможет вам сохранить старое значение переменной.

Пробовали ли вы проверить значение bar при входе в метод рисования и посмотреть, что это на самом деле до и после присваивания?

person Amir Afghani    schedule 16.01.2011
comment
На самом деле это не имеет смысла, бар одинаков до и после присваивания. Я подумал, что это может быть функция мыши, поэтому я попробовал ее со случайным целым числом, и произошло то же самое. И foo, и bar печатают одно и то же число. - person Miles; 16.01.2011
comment
Когда я назначаю bar для mouseX - person Miles; 16.01.2011

Цикл draw() запускается много раз в секунду. Как только он запускается снова, foo перезаписывается значением bar, которое имеет позицию мыши x из предыдущего выполнения draw(). Я думаю, вы сможете увидеть это более четко, если измените операторы println на:

println("foo: " + foo + " bar: " + bar);

Затем, если вы запустите свой скетч, перемещая мышь, вы увидите такие записи, как:

foo: 76 bar: 84
foo: 84 bar: 91
foo: 91 bar: 97
foo: 97 bar: 97

Как и ожидалось, каждый раз, когда выполняется draw(), foo принимает значение, которое было у bar (т. е. mouseX) во время последнего выполнения draw(), потому что ваш цикл draw() продолжает устанавливать foo в текущее значение bar.

person Robert Stewart    schedule 16.01.2011
comment
Это имеет смысл. Однако я все еще не могу заставить свой змеиный код работать должным образом. Я обновил вопрос и включил код. Спасибо. - person Miles; 16.01.2011
comment
Проблема в настройке(). Для первого соединения вы создаете новый PVector со случайным положением. Затем вы устанавливаете остальные элементы в один и тот же объект PVector. Итак, теперь каждый элемент массива указывает на один и тот же объект. Когда вы меняете сочленения[0] в draw(), изменяются все сочленения, поскольку все они являются одним и тем же объектом. Вместо этого вам нужно создать независимые объекты. - person Robert Stewart; 18.01.2011
comment
Вы можете изменить свой код setup() на что-то вроде следующего, предполагая, что вы хотите, чтобы все они были инициализированы одной и той же координатой x-y: float x = random(width); поплавок у = случайный (высота); for(int n = 0; n ‹joints.length; n++) {joints[n] = new PVector(x, y); - person Robert Stewart; 18.01.2011