非传统的控制方式

在游戏中使用不同的控制机制有助于触及更广泛的受众。实现移动和桌面端控制是推荐的,也是必须的,而游戏手柄控制则能带来额外的体验。但想象一下更进一步——在本文中,我们将探索各种非传统的网页游戏控制方式,有些比其他的更加非传统。

电视遥控器

在电视屏幕上玩游戏不一定非要通过游戏主机。现在已经有适用于桌面电脑的 Gamepad API,我们可以模仿这种体验,但还可以做得更多。现代智能电视可以处理 HTML 游戏,因为它们内置了浏览器,可用作游戏平台。智能电视通常附带遥控器,如果你知道怎么做,就可以用它来控制你的游戏。

《Captain Rogers: Battle at Andromeda》最早的演示版经过调整,可以在巨大的电视上运行。有趣的是,第一款《Captain Rogers》游戏(《Asteroid Belt of Sirius》)是为运行 Firefox OS 的低端、小屏幕、廉价智能手机优化的,所以你可以看到三年带来的变化——你可以在我们的 为 Firefox OS TV 构建游戏 Hacks 文章中阅读完整的故事。

Panasonic TV remote controls for the game Captain Rogers: Battle at Andromeda.

事实证明,使用电视遥控器控制游戏非常容易,因为控制器触发的事件会模拟传统的键盘按键。Captain Rogers 已经实现了键盘控制。

js
this.cursors = this.input.keyboard.createCursorKeys();
// …
if (this.cursors.right.isDown) {
  // move player right
}

它可以开箱即用。光标是键盘上的四个方向箭头键,它们的键码与遥控器上的箭头键完全相同。如何知道其他遥控器按键的键码?你可以通过在控制台中打印输出来检查它们。

js
window.addEventListener("keydown", (event) => {
  console.log(event.keyCode);
});

遥控器上的每个按键按下都会在控制台中显示其键码。如果你使用的是运行 Firefox OS 的松下电视,也可以参考下面的这个便捷的备忘单。

Remote control key codes for Panasonic TV.

你可以添加在状态之间切换、开始新游戏、控制飞船并摧毁目标、暂停和重新开始游戏。所有这些只需要检查按键即可。

js
window.addEventListener("keydown", (event) => {
  switch (event.keyCode) {
    case 8: {
      // Pause the game
      break;
    }
    case 588: {
      // Detonate bomb
      break;
    }
    // …
  }
});

你可以通过观看 此视频 来了解它的实际运行情况。

Leap Motion

你是否曾想过只用双手来控制游戏?这借助 Leap Motion(一款沉浸式游戏和应用控制器)来实现是可能的。

Leap Motion 因其与 VR 头显出色的集成而越来越受欢迎——在 Oculus Rift 上展示 Rainbow Membrane,并连接 Leap Motion,被全球会议上参观演示展位的 JavaScript 开发者评为最佳 WebVR 体验之一。

除了非常适合虚拟界面之外,它还可以用于休闲的 2D 游戏体验。仅凭双手完成所有操作会非常困难,但对于简单的 Captain Roger 游戏玩法——操纵飞船和射击——是完全可行的。

要让 Leap Motion 在你的电脑上工作,你必须先按照 docs.ultraleap.com 上的步骤进行安装。当所有安装完成并且控制器已连接到你的电脑后,我们就可以继续在我们的 小演示 中实现支持了。首先,我们添加一个指向 https://js.leapmotion.com/leap-0.6.4.min.jsurl<script> 标签,并在关闭 </body> 标签之前添加 <div id="output"></div> 来输出诊断信息。

我们的代码需要一些辅助变量才能工作——一个用于计算弧度转角度,两个用于存储手部相对于控制器倾斜的水平和垂直角度,一个用于该倾斜的阈值,还有一个用于手部抓握状态。我们接下来将这些行添加到键盘和鼠标所有事件监听器的后面,但在 draw 方法之前。

js
const toDegrees = 1 / (Math.PI / 180);
let horizontalDegree = 0;
let verticalDegree = 0;
const degreeThreshold = 30;
let grabStrength = 0;

紧接着,我们使用 Leap 的 loop 方法在每一帧获取 hand 变量中的信息。

js
Leap.loop({
  hand(hand) {
    horizontalDegree = Math.round(hand.roll() * toDegrees);
    verticalDegree = Math.round(hand.pitch() * toDegrees);
    grabStrength = hand.grabStrength;
    output.innerText = `Leap Motion:
  roll: ${horizontalDegree}°
  pitch: ${verticalDegree}°
  strength: ${grabStrength}
`;
  },
});

上面的代码正在计算并赋值我们将要使用的 horizontalDegreeverticalDegreegrabStrength 值,并将它们输出到 HTML 中,以便我们可以看到实际值。当这些变量更新后,我们就可以在 draw() 函数中使用它们来移动飞船。

js
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // …

  if (horizontalDegree > degreeThreshold) {
    playerX -= 5;
  } else if (horizontalDegree < -degreeThreshold) {
    playerX += 5;
  }
  if (verticalDegree > degreeThreshold) {
    playerY += 5;
  } else if (verticalDegree < -degreeThreshold) {
    playerY -= 5;
  }
  if (grabStrength === 1) {
    alert("BOOM!");
  }

  ctx.drawImage(img, playerX, playerY);
  requestAnimationFrame(draw);
}

如果 horizontalDegree 值大于我们的 degreeThreshold(在此例中为 30),则飞船在每一帧向左移动 5 像素。如果其值低于阈值的负值,则飞船向右移动。上下移动的工作方式相同。最后一个值是 grabStrength,它是一个介于 0 和 1 之间的浮点数——当达到 1(握紧拳头)时,我们暂时显示一个警报(在完整游戏中,这可以被替换为射击逻辑)。

Leap Motion controller support in the game, with visible output for roll, pitch and strength.

就这些了——你用 JavaScript 实现一个可用的 Leap Motion 示例所需的一切都在这里了。你可以探索 hand 的属性,并在你的游戏内部实现任何你喜欢的行为。

多普勒效应

有一篇非常有趣的文章 利用多普勒效应进行运动感应,它将挥手与使用麦克风结合起来。这次是关于检测声波反射物体并返回到麦克风。

Doppler effect as a way to control the scroll of an article on a laptop using hand gesture.

如果反射声的频率与原始频率不同,那么我们就可以检测到该物体的运动。这样,我们就可以仅使用内置麦克风来检测手部运动了!

这可以通过 Daniel Rapp 创建的 小型库 来实现——这可以简单地计算两个频率之间的差值。

js
doppler.init((bandwidth) => {
  const diff = bandwidth.left - bandwidth.right;
});

diff 将是手部初始位置和最终位置之间的差值。

这种方法无法提供像游戏手柄或 Leap Motion 那样的完全灵活性,但它绝对是一种有趣、非传统的替代方案。你可以用它来免提滚动页面,或者玩特雷门琴,但如果实现得当,它也足以使飞船在屏幕上上下移动。

Makey Makey

如果你想玩得更疯狂,可以使用 Makey Makey,这是一个可以将任何东西变成控制器的板子——它就是将现实世界中的导电物体连接到电脑上,并将它们用作触摸界面。

Controlling a banana piano using Makey Makey.

观看 香蕉钢琴视频,并务必访问 快速入门指南 以获取所有所需信息。

甚至还有一个 Cylon.js 支持的 Makey Button 功能,灵感来自 Makey Makey 板,所以你可以使用流行的 Cylon 机器人框架来尝试 Arduino 或 Raspberry Pi。连接这些板子并使用它们可能看起来是这样的。

js
const Cylon = require("cylon");

Cylon.robot({
  connections: {
    arduino: { adaptor: "firmata", port: "/dev/ttyACM0" },
  },
  devices: {
    makey: { driver: "makey-button", pin: 2 },
  },
  work(my) {
    my.makey.on("push", () => {
      console.log("Button pushed!");
    });
  },
}).start();

正如描述所说:这个 GPIO 驱动程序允许你将一个 10 MΩ 的电阻连接到 Arduino 或 Raspberry Pi 的一个数字引脚上,用香蕉、黏土或可绘制电路来控制你的机器人。

总结

我希望你喜欢这些实验——如果你有其他可能引起他人兴趣的实验,请随时在此处添加它们的详细信息。

请记住:制作游戏要开心!