Konva .to с координатами "Dynami c" - PullRequest
1 голос
/ 26 мая 2020

Я создаю небольшую игру, используя Konva .

Вы управляете одним юнитом, который может перемещаться по карте, и "камера" панорамируется на него. Я добился этого эффекта, центрировав экран по координатам x, y устройства, а затем нарисовав все остальное относительно этого:

class GameWorld {

  public entities = new Map();
  public width = window.innerWidth;
  public height = window.innerHeight;
  public center = {
    x: 0,
    y: 0
  };

  tick(world: any) {
    world.forEach((entity: any) => {
      ...
      if (entity.id === user.id) {
        // this is the user's unit
        this.center.x = entity.x;
        this.center.y = entity.y;
      }
      ...
      let dx = this.dx(entity.x);
      let dy = this.dy(entity.y);

      entity.shape.position({ x: dx, y: dy });
      ...
    });

    this.layer.draw();
  }

  dx(x: number) {
    return x - this.center.x + this.width / 2;
  }

  dy(y: number) {
    return y - this.center.y + this.height / 2;
  }

}

В настоящее время у меня проблемы с простыми брызгами крови. эффект, который работает путем создания 5 "больших" красных кругов и 15 маленьких кругов, разбросанных в случайных направлениях и расстояниях вокруг умирающего юнита (не игрока) с разной скоростью.

let bloodDot = (x: number, y: number, size: number) => {
  let dx = this.dx(x);
  let dy = this.dy(y);

  let dot = new Konva.Circle({
    x: dx,
    y: dy,
    radius: size,
    fill: 'red',
  });
  this.layer.add(dot);

  let dir = Math.random() * Math.PI * 2;
  let dis = Math.random() * size * 5;

  dot.to({
    x: dx + Math.cos(dir) * dis,
    y: dy + Math.sin(dir) * dis,
    duration: Math.random() * 3,
    easing: Konva.Easings.StrongEaseOut,
    onFinish: () => dot.destroy()
  });
}

for (let lg = 0; lg < 5; lg++) {
  for (let sm = 0; sm < 3; sm++) {
    bloodDot(entity.x, entity.y, entity.size / 6);
  }
  bloodDot(entity.x, entity.y, entity.size / 3);
}
* 1010 метод .to(). Все работает хорошо, если игрок неподвижен, но если игрок движется и, следовательно, все остальное, включая кровь, должно двигаться относительно них, x и y, используемые в .to, остаются теми, которые были на время создания точек крови, и кажется, что кровь следует за игроком или, скорее, застряла на одном и том же месте на экране, в то время как все остальное относительно движется.

Как я могу динамически изменять свойства (координаты) анимации движения, пока Konva все еще выполняет анимацию?

1 Ответ

1 голос
/ 26 мая 2020

Ну, это не прямой ответ на заданный вопрос, но это решение проблемы, так что вот оно.

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

let bloodDot = (size: number) => {
  let dot = new Konva.Circle({
    x: 0,
    y: 0,
    radius: size,
    fill: 'red',
  });

  let dir = Math.random() * Math.PI * 2;
  let dis = Math.random() * size * 5;

  g.add(dot);

  dot.to({
    x: Math.cos(dir) * dis,
    y: Math.sin(dir) * dis,
    duration: Math.random() * 3,
    easing: Konva.Easings.StrongEaseOut,
    onFinish: () => dot.destroy()
  });
}

let g = new Konva.Group({
  x: this.dx(entity.x),
  y: this.dy(entity.y)
});
this.layer.add(g);

for (let lg = 0; lg < 5; lg++) {
  for (let sm = 0; sm < 3; sm++) {
    bloodDot(entity.size / 6);
  }
  bloodDot(entity.size / 3);
}

setTimeout(() => g.destroy(), 3000);
...