Как добавить анимацию сжатия отказов в шар в P5? - PullRequest
7 голосов
/ 25 апреля 2019

Моя простая игра, созданная с помощью P5.js, состоит из шара, который падает под действием силы тяжести и отскакивает от земли.Я хотел бы добавить анимацию «сжатия» к мячу, когда он касается земли, чтобы он выглядел более реалистично.

Как я могу сделать это, не делая его странным?

код такой:

function Ball() {
  this.diameter = 50;
  this.v_speed = 0;
  this.gravity = 0.2;
  this.starty = height / 2 - 100;
  this.endy = height - this.diameter / 2;
  this.ypos = this.starty;
  this.xpos = width / 2;

  this.update = function() {

    this.v_speed = this.v_speed + this.gravity;
    this.ypos = this.ypos + this.v_speed;

    if (this.ypos >= this.endy) {
      this.ypos = this.endy;
      this.v_speed *= -1.0; // change direction
      this.v_speed = this.v_speed * 0.9;
      if (Math.abs(this.v_speed) < 0.5) {
        this.ypos = this.starty;
      }
    }
  }

  this.show = function() {
    ellipse(this.xpos, this.ypos, this.diameter);
    fill(255);
  }
}

var ball;

function setup() {
  createCanvas(600, 600);
  ball = new Ball();
}

function draw() {
  background(0);
  ball.update();
  ball.show();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>

1 Ответ

5 голосов
/ 25 апреля 2019

Очень простое решение заключается в динамическом увеличении this.endy на эмпирическое значение, которое зависит от скорости.Максимальное значение должно быть меньше this.diameter/2.В примере я использую this.diameter/3 для максимальной суммы, но вы можете использовать это значение.Если скорость равна 0, то сумма также должна быть равна 0:

endy = this.endy + Math.min(Math.abs(this.v_speed), this.diameter/3);
if (this.ypos >= endy) {
      this.ypos = endy;
      // [...]
}

Это приводит к тому, что мяч немного опускается ниже дна.Используйте это, чтобы «сжать» мяч на ту же сумму:

this.show = function() {
    h = Math.min(this.diameter, (height - this.ypos)*2)
    w = 2 * this.diameter - h;
    ellipse(this.xpos, this.ypos, w, h);
    fill(255);
}

См. Пример, где я применил предложения к коду вопроса:

function Ball() {
  this.diameter = 50;
  this.v_speed = 0;
  this.gravity = 0.2;
  this.starty = height / 2 - 100;
  this.endy = height - this.diameter / 2;
  this.ypos = this.starty;
  this.xpos = width / 2;

  this.update = function() {

    this.v_speed = this.v_speed + this.gravity;
    this.ypos = this.ypos + this.v_speed;

    endy = this.endy + Math.min(Math.abs(this.v_speed), this.diameter/3); 
    if (this.ypos >= endy) {
      this.ypos = endy;
      this.v_speed *= -1.0; // change direction
      this.v_speed = this.v_speed * 0.9;
      if (Math.abs(this.v_speed) < 0.5) {
        this.ypos = this.starty;
      }
    }
  }

  this.show = function() {
    h = Math.min(this.diameter, (height - this.ypos)*2)
    w = 2 * this.diameter - h;
    ellipse(this.xpos, this.ypos, w, h);
    fill(255);
  }
}

var ball;

function setup() {
  createCanvas(600, 600);
  ball = new Ball();
}

function draw() {
  background(0);
  ball.update();
  ball.show();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
...