在我的游戏引擎中添加旋转和缩放 - 第4部分
#javascript #编程 #开源 #gamedev

您好,开发人员! ðð

我回来了一些新闻!我在我们的游戏对象中添加了旋转和图像缩放。这样做有很多方法,这就是我所做的。

在我的previous post中,我尝试在我的引擎Helicity.ai中制作一个蓬松的鸟类游戏,很明显,我们需要轮换和缩放以获得正常可用的体验。

我发现这一事件序列特别有趣,因为 *就像拿起铅笔并将其移至我们要绘制某些东西的地方,旋转页面,然后绘制然后绘制,然后旋转页面并将铅笔带回到达的地方。 *

这是Github

Image description

更改游戏对象的渲染方式

窥视GameObject类。清除画布后,我们正在调用每个帧的“渲染”方法。

// GameObject.js
render() {
  if (this.image.loaded) {
    Renderer.drawImage(
      this.image,
      this.x,
      this.y,
      this.width * this.xscale,
      this.height * this.yscale,
      this.angle,
      this.alpha
    );
  } else {
//No image was provided. Just drawing a black block.
    Renderer.drawBlock(
      "black",
      this.x,
      this.y,
      this.width * this.xscale,
      this.height * this.yscale,
      this.angle,
      this.alpha
    );
  }
}

GameObject现在根据“ Xscale”和“ Yscale”属性进行缩放,并根据“角度”属性旋转。您可以完全控制这些值ð®。

但是这两个功能都会发生什么?让我们看看

现在,让我们去参加渲染器课:

// Renderer.js
drawImage(image, x, y, width, height, angle, alpha) {
  this.context.save();
  this.context.translate(x, y);
  this.context.rotate(-angle);
  this.context.globalAlpha = alpha;
  this.context.drawImage(image, 0, 0, width, height);
  this.context.restore();
}

drawBlock(color, x, y, width, height, angle, alpha) {
  this.context.save();
  this.context.translate(x, y);
  this.context.rotate(-angle);
  this.context.globalAlpha = alpha;
  this.context.fillStyle = color;
  this.context.fillRect(0, 0, width, height);
  this.context.restore();
}

解释事件序列

注意新事物吗?现在,“ drawimage”和“ drawblock”方法包括“角度”和“ alpha”参数。

让我们分解渲染器的绘制和绘制方法中发生的事情。他们都遵循类似的操作顺序。

1。**保存帆布状态**(context.save()):在任何转换之前,我们保存画布的当前状态。保存()方法将当前状态推到堆栈上。这使我们能够应用转换,然后在完成图纸后恢复到原始状态。

  1. 翻译原点(context.translate(x,y)):translate(x,y)函数将我们的画布的(0,0)起源转移到提供的(0,0) x,y)点。这特别有用,因为画布中的旋转始终是围绕当前来源执行的。因此,通过将原点转换为我们要旋转的点(在这种情况下,是图像或块的中心),我们准备了旋转的画布。

  2. 旋转画布(context.rotate(-angle)):既然原点位于图像或块的中心,我们可以旋转画布。旋转(角度)函数通过指定角度(以弧度测量)围绕电流原点旋转画布。我们使用 - 角是因为画布的正旋转是顺时针方向,而通常在2D游戏中,我们将正旋转视为逆时针。

  3. 设置透明度(context.globalalpha = alpha):GlobalAlpha属性用于将透明度应用于我们的图像或块。它可以在0.0(完全透明)和1.0(完全不透明)之间进行值。

  4. 绘制图像或块:通过设置转换,我们现在可以绘制图像或块。对于图像,我们使用绘制图(图像,0,0,宽度,高度)方法,该方法将指定的图像绘制到画布上。对于块,我们使用fillRect(0,0,宽度,高度)方法,在用fillstyle =颜色填充颜色后。

  5. 还原画布状态(context.restore()):完成绘图后,我们使用Restore()方法将画布恢复为原始状态。这弹出了最近从堆栈中保存的状态并将其应用。我们应用的所有转换(翻译,旋转和全局变化)都撤消了,因此它们不会影响画布上的任何进一步的绘制。

这种操作顺序使我们能够控制其位置,大小,旋转和透明度,将图像和块绘制到画布上,从而在如何在画布上显示对象的方式具有很大的灵活性。

结论

因为我们这样做了,我们现在可以使游戏中的鸟旋转以使它看起来像是在下降。
您可以尝试游戏的this variant

//In the update method of the bird
 //change angle of bird to make it look like it is falling. -90 is straight down
    //dont make it indefinitely dependent on velocityY, or else it will keep rotating
    this.angle = Math.min(this.velocityY * 0.05, 90);

但是,有一些新的挑战。

物理

这个可爱的功能不足以处理旋转大声笑。

 //Adjusted for scaling but NOT rotation
  static checkCollision(object1, object2) {
    return (
      object1.x < object2.x + object2.width * object2.xscale &&
      object1.x + object1.width * object1.xscale > object2.x &&
      object1.y < object2.y + object2.height * object2.yscale &&
      object1.y + object1.height * object1.yscale > object2.y
    );
  }

精灵起源

现在,到目前为止,游戏对象的起源,其x或y是图像的左上角。现在很好,但这意味着所有旋转都会发生在这一点上,使看起来像鸟有点奇怪的方式……但是它看起来很正常,大声笑。

如果您喜欢这样并对开发感兴趣,请考虑加入discord server
Helicity.ai团队ð