【问题标题】:Motion effect for standing object站立物体的运动效果
【发布时间】:2021-03-16 18:54:50
【问题描述】:

我试图为站立的物体实现运动效果
例如,我假设我的对象将能够向右或向左移动。
我想让幻觉就像那个物体还在移动一样。即使目前没有移动。 (同时背景可以静止不动......)

'use strict';

const pressedKeys = [];
const canvas = document.querySelector('#game');
const ctx = canvas.getContext('2d');

canvas.width = 300;
canvas.height = 150;

class Player
{
    xPosition = 150;
    yPosition = 50;
    speed = 5;
    isMoving = false;

    update(pressedKeys)
    {
        if (pressedKeys['ArrowLeft']) {
            this.xPosition -= this.speed;
        } else if (pressedKeys['ArrowRight']) {
            this.xPosition += this.speed;
        }
    }

    draw(ctx)
    {
        ctx.fillStyle = '#2976f2';
        ctx.fillRect(this.xPosition, this.yPosition, 30, 30);
    }
}

const player = new Player();

function animate()
{
    window.requestAnimationFrame(animate);
    ctx.clearRect(0, 0, canvas.width, canvas.height)

    if (player.isMoving) {
        player.update(pressedKeys);
    }

    player.draw(ctx);
}

animate();

window.addEventListener('keyup', function (event) {
    delete pressedKeys[event.key];
    player.isMoving = false;
})

window.addEventListener('keydown', function (event) {
    switch (event.key) {
        case 'ArrowLeft':
        case 'ArrowRight':
            pressedKeys[event.key] = true;
            player.isMoving = true;
            break;
    }
})
canvas {
    border: 1px solid blue;
}
<canvas id="game"></canvas>

【问题讨论】:

    标签: javascript html html5-canvas 2d motion-blur


    【解决方案1】:

    通常这种效果是通过不断复制所需对象、将其移动到完全相同的屏幕位置并最终随着时间逐渐淡出来完成的,例如一秒钟内。

    在您的情况下,尽管我们可以稍微简化一下,因为您希望保持“运动模糊”的外观,即使它没有移动。

    所以首先我们需要另一个属性到你的 Player 类oldX。它在运动发生之前保持对象的位置。通过从 x 中减去 oldX,我们可以确定对象是向左还是向右移动 - 因此我们知道将尾随重复项放在哪里。

    如果我们知道方向,我们可以开始使用简单的 for 循环创建副本,例如:

    for (var a = 0; a < 7; a++) {
      ctx.fillRect(this.x - (this.x - this.oldX) / this.speed * a * 2, this.y, 30, 30);
    }
    

    这将创建七个外观相同的正方形 - 所以它看起来还不是很好。原件旁边的副本应该具有几乎相同的颜色,而最后一个应该几乎与背景混合。为此,我们可以使用画布上下文的globalAlpha 属性。值 1 是不透明的,而 0 是完全透明的。

    把它们放在一起:

    const keys = [];
    const canvas = document.getElementById('game');
    const ctx = canvas.getContext('2d');
    
    canvas.width = 300;
    canvas.height = 150;
    
    class Player {
      x = 150;
      y = 50;
      oldX = 150;
      speed = 5;
      moving = false;
    
      update(keys) {
        this.oldX = this.x;
        if (keys['ArrowLeft']) {
          this.x -= this.speed;
        } else if (keys['ArrowRight']) {
          this.x += this.speed;
        }
      }
    
      draw(ctx) {
        ctx.fillStyle = '#2976f2';
        ctx.fillRect(this.x, this.y, 30, 30);
        ctx.save();
        for (var a = 0; a < 7; a++) {
          ctx.globalAlpha = 0.5 - (a / 7) * 0.5;
          ctx.fillRect(this.x - (this.x - this.oldX) / this.speed * a * 2, this.y, 30, 30);
        }
        ctx.restore();
    
      }
    }
    
    const player = new Player();
    
    function animate() {
      window.requestAnimationFrame(animate);
      ctx.clearRect(0, 0, canvas.width, canvas.height)
    
      if (player.moving) {
        player.update(keys);
      }
    
      player.draw(ctx);
    }
    
    animate();
    
    window.addEventListener('keyup', function(event) {
      delete keys[event.key]
      player.moving = false;
    })
    
    window.addEventListener('keydown', function(event) {
      switch (event.key) {
        case 'ArrowLeft':
        case 'ArrowRight':
          keys[event.key] = true;
          player.moving = true;
          break;
      }
    })
    canvas {
      border: 1px solid blue;
    }
    &lt;canvas id="game"&gt;&lt;/canvas&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-27
      • 1970-01-01
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多