项目地址:
https://github.com/vitaviva/ugame
整个游戏视图可以分成三层:
- camera(相机):处理相机的preview以及人脸识别
- background(后景):处理障碍物相关逻辑
- foreground(前景):处理潜艇相关
开发中会涉及以下技术的使用,没有高精尖、都是大路货:
- 相机:使用Camera2完成相机的预览和人脸识别
- 自定义View:定义并控制障碍物和潜艇
- 属性动画:控制障碍物和潜艇的移动及各种动效
少啰嗦,先看东西!下面介绍各部分代码的实现。
首先定义障碍物基类,主要负责是将bitmap资源绘制到指定区域。由于障碍物从屏幕右侧定时刷新时的高度随机,所以其绘制区域的需要动态设置
障碍物分为上方和下方两种,由于使用了同一张资源,所以绘制时要区别对待,因此定义了两个子类:和
下方障碍物的资源旋转180度后绘制
接下来创建后景的容器,容器用来定时地创建、并移动障碍物。
通过列表管理当前所有的障碍物,中,将障碍物分别布局到屏幕上方和下方
提供两个方法和,控制游戏的开始和结束:
- 游戏结束时,要求所有障碍物停止移动。
- 游戏开始后会通过,定时刷新障碍物
刷新障碍物
障碍物的刷新经历三个步骤:
- 创建:上下两个为一组创建障碍物
- 添加:将对象添加到,同时将添加到容器
- 移动:通过属性动画从右侧移动到左侧,并在移出屏幕后删除
创建障碍物时会为其设置随机高度,随机不能太过,要以前一个障碍物为基础进行适当调整,保证随机的同时兼具连贯性
定会潜艇类,创建自定义View,并提供方法移动到指定坐标
自定义View中完成以下几个事情
- 通过两个资源定时切换,实现探照灯闪烁的效果
- 通过让移动过程更加顺滑
- 通过一个,让潜艇在移动时可以调转角度,更加灵动
- 通过成员持有潜艇对象,并对其进行控制
- 实现根据人脸识别的回调,移动潜艇到指定位置
- 游戏开始时,创建潜艇并做开场动画
开场动画
游戏开始时,将潜艇通过动画移动到起始位置,即y轴的二分之一处
相机部分主要有和组成。提供给Camera承载preview;工具类主要完成以下功能:
- 开启相机:通过代开摄像头
- 摄像头切换:切换前后置摄像头,
- 预览:获取Camera提供的可预览尺寸,并适配显示
- 人脸识别:检测人脸位置,进行上的坐标变换
适配PreviewSize
相机硬件提供的可预览尺寸与屏幕实际尺寸(即TextureView尺寸)可能不一致,所以需要在相机初始化时,选取最合适的PreviewSize,避免上发生画面拉伸等异常
选取preview尺寸的原则与TextureView的长宽比尽量一致,且面积尽量接近。
用来进行人脸的Matrix初始化,后文介绍
人脸识别
为相机预览,创建一个对象,会话通过返回,通过参数可以让其中包括人脸识别的相关信息
通过对人脸信息进行矩阵变化,确定人脸坐标以使其准确应用到。
最后,在UI线程将包含人脸坐标的通过回调传出:
FaceDetectMatrix
是在获取之后创建的
三大视图层组装完毕,最后需要一个总控类,对游戏进行逻辑控制
主要完成以下工作:
- 控制游戏的开启/停止
- 计算游戏的当前得分
- 检测潜艇的碰撞
- 对外(或者等)提供游戏状态监听的接口
初始化
游戏开始时进行相机的初始化,创建类并建立回调到
游戏状态
定义,对外提供状态的监听。目前支持三种状态
- Start:游戏开始
- Over:游戏结束
- Score:游戏得分
可以在、的时候,更新状态
计算得分
游戏启动时通过开始计算得分并通过上报。
目前的规则设置很简单,存活时间即游戏得分
检测碰撞
根据潜艇和障碍物当前位置,计算是否发生了碰撞,发生碰撞则GameOver
Activity的工作简单:
- 权限申请:动态申请Camera权限
- 监听游戏状态:创建,并监听状态