【问题标题】:How to add a bounce compression animation to a ball in P5?如何在 P5 中为球添加反弹压缩动画?
【发布时间】:2019-04-25 17:16:22
【问题描述】:

我用 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();
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"&gt;&lt;/script&gt;

【问题讨论】:

  • 球运动得越快,压缩得越厉害吗?
  • 在现实世界中应该是这样的,但是一旦设置了机制,就很容易调整。我只需要基本的动画代码,稍后我会调整它。

标签: javascript canvas processing p5.js


【解决方案1】:

一个非常简单的解决方案是动态增加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();
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"&gt;&lt;/script&gt;

【讨论】:

  • 这很棒。感谢您提供如此充实的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-28
  • 2021-11-27
  • 2018-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多