前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >闪屏还可以这样玩

闪屏还可以这样玩

原创
作者头像
林焕彬
修改2018-07-30 09:37:04
1.2K0
修改2018-07-30 09:37:04
举报
文章被收录于专栏:林焕彬的专栏

前言

对于多数应用来说,在进入APP的时候使用短暂的闪屏广告来吸引用户是很常见的一个场景。但随着这种模式的频繁应用,越来越多的用户会感到审美疲劳,甚至不看就跳过闪屏了。那么,是否有形式比较新颖的闪屏,来改变这个现状呢?下面开始来介绍可互动闪屏。

一.什么是可互动闪屏

可互动闪屏对于传统广告闪屏的区别就是,在之前的基础上,补充了可交互的内容形式,增加了互动性和趣味性,可充分唤起用户的好奇心,从而提升整个广告或者某个模块的点击率。

举个例子:

在手Q游戏中心中,针对FIFA足球世界新游上线之际,我们尝试设计了一个可踢球互动的广告闪屏,引导用户下载游戏,具体如下:

视频内容

这个闪屏上线之后,数据非常可观,点击率是以往传统营销闪屏的3到4倍,进一步提升了游戏的下载转化。

二.关键技术点

这种可互动闪屏的形式,功能上跟目前市面上的H5小游戏很相似,但从技术实现的角度来看,在内容繁多、逻辑复杂的H5页面上增加一个小游戏框架来实现这种闪屏,是不可取的。一方面增加了文件资源大小,另一方面给页面渲染带来了更多的压力。那是不是就没有办法解决了?其实办法是有的,可以借鉴游戏框架的实现方式并进行简化。下面会围栏这个案例开始讲解。

1.设计总体互动框架

通过对多个游戏框架进行对比分析,以及接口文档研究,可以总结出以下处理模块

* 精灵图管理 * 预加载 * 物理引擎 * 动画 * 粒子效果 * 事件输入 * 声音管理 * 设备插件管理 * 基本图形绘制 * 网络模块 * ......

对于互动闪屏来说,并不需要太多的模块,经过对视频中的玩法分析,可以精简为以下模块进行开发,减少工作量。

* 精灵图 * 资源预加载 * 动画 * 事件输入 * 特效处理 * 生命周期

除了分析模块组成,还得设计一下总体流程框架图:

根据框架图,我们对整个互动闪屏的逻辑一目了然,可以开始编码整个互动闪屏的控制逻辑:

经过设计后的代码框架,大小有10kb,初步符合我们对框架简化的要求。

2.游戏元素设计

在这个互动闪屏中,有足球场,守门员,门框,足球,发射按钮,准心等元素。可以先设计一下这些元素的通用类属性和方法,并对其进行派生。

除此之外,闪屏中比较复杂的逻辑就是对足球的状态控制,涉及射击轨迹,守门员的状态变化等。

A.射击轨迹

一条射击轨迹一般会经过两个点,一个发射的起点和结束的终点。起点是固定的,关键点在于结束的终点,其实也就是准心的位置,可以获取准心的位置来确定:

代码语言:javascript
复制
Aim.prototype = {
......
        // 获取准心的位置,以及获胜的概率
        getInfo: function() {
            return {
                x: this.drawX + this.moveX + this.width / 2,
                y: this.drawY + this.height / 2
            }
        },
......
}

由于轨迹有可能是曲线的,可以通过二次贝赛尔曲线公式来计算得出。其中需要知道中间控制点的位置,把参数代入公式中就可以获得每个时间段的位置,把这些位置连起来就是这条曲线了。

代码语言:javascript
复制
//发射了,并还在运动时间内
if (this.isFired && this.t < this.duration) {
    //移动的时候根据时间缩小宽高
    this.width -= this.t * 15;
    this.height -= this.t * 15;
    //最终位置
    this.endpos[0] = this.finalpos[0] - this.width / 2;
    this.endpos[1] = this.finalpos[1] - this.height / 2;
    //发射位置
    this.startpos = [this.drawX, this.drawY];
    //计算控制点位置
    this.cp = [
        (this.startpos[0] + this.endpos[0]) / 2 - (this.startpos[1] - this.endpos[1]) * this.curveness,
        (this.startpos[1] + this.endpos[1]) / 2 - (this.endpos[0] - this.startpos[0]) * this.curveness
    ];
    //通过贝塞尔公式获得每个时间t的位置
    var x = quadraticBezier(this.startpos[0], this.cp[0], this.endpos[0], this.t);
    var y = quadraticBezier(this.startpos[1], this.cp[1], this.endpos[1], this.t);
    //时间t
    this.t += 0.2;
 
    this.drawX = Math.floor(x);
    this.drawY = Math.floor(y);
}

B.守门员状态

守门员有准备状态,守到球,守不到球的情况,可以通过雪碧图的方式,设定守门员的不同状态,并通过控制当前帧来确定守门员的状态。

利用canvas画图的API,恰好可以指定绘制原图片的某个区域大小,满足绘制控制精灵图不同状态的需求 相关代码如下:

代码语言:javascript
复制
Goalkeeper.prototype = {
    update: function() {
        // 预备阶段
        if (this.isReady) {
            this.srcY = this.height * this.curFrame;
            //控制准备状态的帧数
            if (this.curFrame < this.frameNum - 1) {
                this.curFrame++;
            } else {
                this.curFrame = 0;
            }
        } else {
            // 准备扑球,可进球可不进
            if (this.isKeepBall) {
                this.curFrame = 12
            } else {
                this.curFrame = 13
            }
            this.srcY = this.height * this.curFrame;
        }
    },
    draw: function(gamectx) {
        if (this.visible) {
            //绘制守门员
            gamectx.drawImage(SpriteTool.goalkeeperSprite, this.srcX, this.srcY, this.width, this.height, this.drawX, this.drawY, this.width, this.height);
        }
    },
}

C.进球逻辑判断

在用户点击发射按钮后,根据准心的位置可以判定是否进球。若是在球框外,那是肯定进不了的;若是在球框内,那有一定的进球概率。可以设定进球概率为60%,通过设置随机数的方式进行判断,代码如下:

代码语言:javascript
复制
var getRandomPercent = function(probability) {
    var probability = probability * 100 || 1;
    var odds = Math.floor(Math.random() * 100);
    if (probability === 1) { return true };
    if (odds < probability) {
        return true;
    } else {
        return false;
    }
}

确定了进球概率后,接下来就是设定守门员的状态变化了,可以根据球的位置移动,以及终点的位置后确定守门员的状态

代码语言:javascript
复制
//判断是否进球
var info = this.aim.getInfo();
// 球停止了,且被扑中了
if (this.ball.isStop && info.result == false) {

    this.keeper.catchball();
    this.keeper.keepBall(info.x);
    this.ball.hide();
    //球停止了,且进球了
} else if (this.ball.isStop && info.result) {
    this.keeper.catchball();
    this.ball.hide();
    // 进球的时候,球在门框的位置
    if (this.aim.moveX > 0) {
        this.ballstage.drawBallInRight();
    } else {
        this.ballstage.drawBallInLeft();
    }
}
3.特效应用

在互动结束后,可以看到整个闪屏以螺旋扭曲的形式缩小到新游运营位,这种炫酷的形式,其核心是应用了WebGL来动态改变图片的展现形式。 可以想象扭曲一张纸,通过确定了扭曲的中心点,扭曲的角度和扭曲的半径,就可以实现。在WebGL中,是通过这3个变量以及扭曲算法来改变图片的顶点着色器,控制螺旋特效的展现情况。

代码语言:javascript
复制
//控制变量
uniform float radius; //螺旋半径
uniform float angle;  //螺旋角度
uniform vec2 center;  //螺旋中心点
uniform vec2 texSize; //螺旋画布大小
uniform sampler2D texture; //纹理素材
varying vec2 texCoord; //坐标轴

void main() {
   //更新坐标轴xy
    vec2 coord = texCoord * texSize;
    coord -= center;
    float distance = length(coord);
    if (distance < radius) {
        float percent = (radius - distance) / radius;
        float theta = percent * percent * angle;
        float s = sin(theta);
        float c = cos(theta);
        
        coord = vec2(
            coord.x * c - coord.y * s,
            coord.x * s + coord.y * c
        );
    }
    coord += center;
    //改变顶点
    gl_FragColor = texture2D(texture, coord / texSize);
    vec2 clampedCoord = clamp(coord, vec2(0.0), texSize);
    if (coord != clampedCoord) {
        /* fade to transparent if we are outside the image */
        gl_FragColor.a *= max(0.0, 1.0 - length(coord - clampedCoord));
    }
}

这里涉及GLSL的着色器代码,不懂的同学可以阅读其他资料来了解,这里就不赘述了。

三,结尾

整体来说,借鉴其他游戏框架并输出一个简洁有力的微互动框架,一方面可以满足产品方面对互动闪屏的需求,另一方面也会后续的互动闪屏开发奠定了基础,以后面对这样的需求开发就更加省心省力了。文章如有不正确的地方,欢迎指正。

参考文章

http://phaser.io/docs/2.6.2/index https://github.com/hujiulong/blog/issues/1 https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/ http://evanw.github.io/glfx.js/

都看到最下面了,关注一下呗?

关注DeepOcean公众号,不定时给你推荐一些技术分享,内容也许不新但一定是对你有帮助

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一.什么是可互动闪屏
  • 二.关键技术点
    • 1.设计总体互动框架
      • 2.游戏元素设计
        • 3.特效应用
        • 三,结尾
          • 参考文章
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档