字节摄像头小游戏开发教程

背景

字节小游戏:字节小游戏是基于字节跳动全产品矩阵开发,不需用户进行下载,点开即玩的全新游戏类型。相较 APP,小游戏有着开发周期短、开发成本低等特性,能够让开发者更简单的参与到开发过程中。实现快速上线,快速变现。

摄像头游戏:一种全新的游戏形式。玩家通过摄像头采集到的图像信息,控制游戏中的行为。抖音中的《眼睛眨眨》、《潜水艇大挑战》就是摄像头游戏的一个成功例子。

如果你已经有了小游戏开发的相关基础,那么如何进行摄像头游戏的开发呢?本文将使用字节跳动创意游戏前端团队开发的摄像头sdk,简单介绍一下如何快速从零开发一款字节平台的摄像头游戏。

介绍

摄像头 SDK是允许开发者接入摄像头互动类场景游戏的 API 集合。SDK 本身是基于字节小游戏运行环境的,主要提供了人脸识别、手势识别、摄像头UI显示等调试能力,降低开发者接入成本。


快速上手

举个例子:下面我们将使用cocos creator来开发一款仿抖音《潜水艇大作战》的摄像头小游戏。玩家通过鼻子控制潜水艇躲过障碍,躲过的障碍越多,分数越高,最终赢得游戏。默认大家已经完成了cocos creator的基础教程学习,本文章中将不会过多介绍Cocos Creator的开发方法,如果还没有Cocos Creator的开发经验建议先学习官方教程。

  • 摄像头游戏的完整工程地址:https://github.com/congyd/camera-video

项目创建

第一步是安装Cocos Creator的编辑器,我们从官网上下载CocosDashboard用来创建Cocos Creator工程

下载完成安装后,我们登陆CocosDashboard,进入编辑器的侧边栏,这里我们使用下载的v2.4.2版本,此版本开始支持打包成字节小游戏,打包后可以直接在字节跳动开发者工具上运行。

安装完成后我们在项目侧边栏中选择新建一个Creator项目。

这里我们注意选择的版本和创建的项目类型,此次项目我们采用TypeScript开发,所以初始默认选择TypeScript项目,然后创建打开项目。

这样我们就得到了一个新建的Cocos Creator工程。

摄像头SDK安装

我们现已将摄像头SDK发布到npm上,使用过NodeJS的同学一定对npm并不陌生,如果没有使用过NodeJS也可查看官网并安装。

进入项目文件夹根目录使用npm安装摄像头sdk、安装cocos引擎适配包,依次执行下方命令

npm install @byted-creative/camera @byted-creative/camera-face
npm install @byted-creative/camera-cocos-layer

我们在Script文件夹中创建一个脚本main

双击打开Main脚本,引入摄像头SDK包

import camera, { CameraCapacity } from '@byted-creative/camera';
import face, { FaceEvent, FaceInfo } from '@byted-creative/camera-face';
import { CameraCocosLayer } from "@byted-creative/camera-cocos-layer";

创建函数initCamera在start生命周期调用,初始化摄像头能力,并开启人脸检测能力。

async start () {
  await this.initCamera();
  // this.startGame();
}

// 初始化
private async initCamera() {
  this._layer = new CameraCocosLayer({ root: this.cameraNode });
  // 初始化摄像头
  camera.init({
    layerAdapter: this._layer,
    capacity: [CameraCapacity.Face],
  });
  try {
    await camera.start();
    // 设置美颜
    camera.setBeauty({ 
      whiten: 1, 
      smoothen: 1,
      enlargeEye: 1, 
      slimFace: 1,
    });
    face.init({interval: 30});
    face.startDetect();
    // face.debugEnable(FaceDebug.Box);
    // face.debugEnable(FaceDebug.Face);
  } catch (err) {
    console.log('camera start fail', err);
  }
}

将此脚本挂载在主场景的Canvas节点上

此时预览游戏,屏幕中会展现出摄像头拍摄下来的画面(默认为前置摄像头)。

添加场景元素

接下来,将潜水艇和柱子拖到场景中

针对潜水艇,注册人脸检测事件,当事件触发时,将潜水艇的纵坐标改为人脸鼻子的纵坐标。

 face.on(FaceEvent.onFaceInfos, this.onFaceInfos, this);
private onFaceInfos(faceInfos: FaceInfo[]){
  if(faceInfos.length === 0){
    return;
  }

  const faceInfo = faceInfos[0];
  this.ship.setPosition(this.ship.position.x, faceInfo.nose[13].y);
}

针对柱子,开始游戏时需要初始化柱子位置,柱子的x坐标间距是相同的,但是柱子的y坐标可以是随机的,上下起伏。

 this.colunms[0].setPosition(115,0);
 this.colunms[1].setPosition(653,0);
 this.colunms.forEach(element => {
   this.resetColunmPosition(element);
 });
private resetColunmPosition(node: cc.Node){
  const r = Math.random() * 360 - 180;
  node.setPosition(node.position.x, r);    
}

在界面中,我们可以感受到潜水艇是从左到右游动,我们通过控制柱子从右向左移动也可以达到相同的效果。在update生命周期函数中,我们可以定时改变柱子的位置,视觉上看起来缓慢向左移动。代码量比较大,简化成文字,具体代码内容可以查看代码仓库

update(dt){ 
    ...
  // 控制柱子从右向左移动
  // 1.当柱子位置小于潜水艇,得分加一
  // 2.当柱子脱离界面,重置柱子位置
}

在检测到潜水艇与柱子发生碰撞之后,游戏结束

this.ship.on('onCollision', this.onCollision, this);
onCollision(){
  console.log('onCollision');
  this.stopGame();
}

最后将用户开始时需要初始化的内容封装成startGame

private startGame(){
  // 关闭弹窗
  this.dialog.active = false;  
  // 重置得分
  this.score = 0;
  
  face.on(FaceEvent.onFaceInfos, this.onFaceInfos, this);
    
  this.colunms[0].setPosition(115,0);
  this.colunms[1].setPosition(653,0);
  this.colunms.forEach(element => {
    this.resetColunmPosition(element);
  });
  // 触发碰撞结束游戏
  this.ship.on('onCollision', this.onCollision, this);
  // 开始标记,柱子开始移动
  this._startFlag = true;
}

结束游戏时,需要清空开始游戏时的监听事件

private stopGame(){
  // 取消face监听事件
  face.off(FaceEvent.onFaceInfos, this.onFaceInfos, this);
  // 取消潜水艇碰撞监听事件
  this.ship.off('onCollision', this.onCollision, this);
  // 关闭标记,柱子不随时间移动
  this._startFlag = false;
  // 打开弹窗
  this.dialog.active = true;   
}

完成游戏核心逻辑之后,我们将游戏构建成字节跳动小游戏

下载字节跳动开发者工具,将构建完成的工程导入到字节跳动开发者工具中,使用真机预览。打开头条或者抖音客户端,扫描二维码,就可以看到我们开发好的摄像头游戏啦!

原文链接:,转发请注明来源!