大家快来玩转盘抽奖游戏(走在网页游戏开发的路上(七))

.  抽奖流程

其实我们的Flash只是一个显示作用,要转到哪个位置(中哪个奖品)是后台来完成的。而且每个奖品的概率是不同的,不是等概率的,我想没有转盘抽奖游戏是等概率的。从玩家点击“抽奖”开始到结束,与后台的交互如下:

转盘抽奖的大致流程是这样的:

F  玩家点击Flash中的“抽奖”按钮;

F  Flash调用web页面中的Javascript函数,告诉它玩家开始抽奖了。当然Flash调用JS的时候是带了参数的,比如是谁在抽奖等详细信息; web页面中的JavaScript函数,通知后台(可以是C++、Python、PHP、Java、C#等等)玩家开始抽奖了。这里也是带了参数的!

F  后台返回结果,JavaScript函数通过调用Flash提供的接口,告诉抽奖结果;

F  Flash拿到结果之后,就开始转到,最终转到指定位置。抽奖介绍!

JavaScript在flash和后台之间充当着桥梁的作用。Flash仅作展示的作用,概率和抽奖结果由后台控制。

2.  AS3和JavaScript之间通信

ExternalInterface 类是外部 PI,在ActionScript和Flash Player的容器之间实现直接通讯的应用程序编程接口,例如:含有JavaScript的HTML页。推荐对所有JavaScript与ActionScript之间的通信使用ExternalInterface。

在HTML页中使用JavaScript,可以调用Flash Player中的ActionScript函数。ActionScript函数可以返回一个值,JavaScript会立即接收它作为该调用的返回值,反之亦然。此功能替代了较旧的fscommand()方法。

利用ActionScript,可以在HTML页上执行以下操作:

F  调用任何JavaScript 函数。

F  传递任意数量、具有任意名称的参数。

F  传递各种数据类型(Boolean、Number、String 等等)。

F  接收来自JavaScript 函数的返回值。

通过在HTML页上使用JavaScript,可以:

F  调用ActionScript函数。

F  使用标准的函数调用表示法传递参数。

F  将值返回给JavaScript函数。

2.1.    ExternalInterface.available属性

ExternalInterface.available属性指示当前的Flash Player是否位于提供外部接口的容器中。如果外部接口可用,则此属性为true;否则,为false。在使用ExternalInterface类中的任何其它功能之前,应始终进行检查以确保当前容器支持外部接口通信,如下所示:

if (ExternalInterface.available)

{

    // 在此执行 ExternalInterface 方法调用。

}

注意ExternalInterface.available属性报告当前容器是否为支持ExternalInterface连接的容器类型。它不会报告当前浏览器中是否启用了JavaScript。

通过使用ExternalInterface.objectID属性,您可以确定Flash Player实例的唯一标识符(具体来说,是指Internet Explorer中object标签的id属性,或者是指使用NPRuntime接口的浏览器中embed标签的name 属性)。这个唯一的ID代表浏览器中的当前SWF文档,并可用于对SWF文档进行引用,例如:在容器HTML页中调用JavaScript函数时进行引用。当Flash Player容器不是Web浏览器时,此属性为null。

2.2.    从ActionScript中调用外部代码

ExternalInterface.call()方法执行容器应用程序中的代码。它至少需要一个参数,即包含容器应用程序中要调用函数的名称的字符串。传递给ExternalInterface.call()方法的其它任何参数均作为函数调用的参数传递给容器。

//调用外部函数"addNumbers"

//传递两个参数并将该函数的结果

//赋给变量"result"

var param1:uint = 3;

var param2:uint = 7;

var result:uint = ExternalInterface.call("addNumbers", param1, param2);

如果容器为HTML页,此方法将调用具有指定名称的JavaScript函数,必须在包含HTML页中的script元素中定义该函数。JavaScript函数的返回值被传递回ActionScript。

<script language="JavaScript">

    //加上两个数字,然后将结果发送回ActionScript

    function addNumbers(num1, num2)

    {

        return (num1 + num2);

    }

</script>

如果容器为其它的ActiveX容器,此方法将导致Flash PlayerActiveX 控件调度它的FlashCall事件。Flash Player将指定的函数名及所有参数序列化为一个XML字符串。容器可以在事件对象的request属性中访问该信息,并用它来确定如何执行它自己的代码。为了将值返回ActionScript,容器代码调用ActiveX对象的SetReturnValue()方法,并将结果(序列化为一个XML字符串)作为该方法的参数进行传递。

无论容器为Web浏览器还是为其它ActiveX容器,只要调用失败或容器方法没有指定返回值,都将返回null。如果包含环境属于调用代码无权访问的安全沙箱,ExternalInterface.call()方法将引发SecurityError 异常。可以通过在包含环境中为allowScriptAccess设置合适的值来解决此问题。例如,要在HTML页中更改allowScriptAccess 的值,请编辑object和embed标签中的相应属性。

2.3.    从容器中调用ActionScript代码

容器只能调用函数中的ActionScript代码,而不能调用任何其它ActionScript代码。要从容器应用程序调用ActionScript函数,必须执行两项操作:向ExternalInterface类注册函数,然后从容器的代码调用它。

首先,必须注册ActionScript函数,指示其应能够为容器所用。使用ExternalInterface.addCallback()方法,如下所示:

function callMe(name:String):String

{

    return "busy signal";

}

ExternalInterface.addCallback("myFunction", callMe);

addCallback()方法采用两个参数。第一个参数为String类型的函数名,容器将籍此名称得知要调用的函数。第二个参数为容器调用定义的函数名时要执行的实际ActionScript函数。由于这些名称是截然不同的,因此可以指定将由容器使用的函数名,即使实际的ActionScript 函数具有不同的名称。这在函数名未知的情况下特别有用,例如:指定了匿名函数或需要在运行时确定要调用的函数。

一旦向ExternalInterface类注册了ActionScript函数,容器就可以实际调用该函数。完成该操作的具体方法依容器的类型而定。例如,在Web浏览器的JavaScript代码中,使用已注册的函数名调用ActionScript函数,就像它是Flash Player浏览器对象的方法(即,一个表示object或embed标签的JavaScript对象的方法)。也就是说,将传递参数并返回结果,就如同调用本地函数一样。

<script language="JavaScript">

    // callResult gets the value "busy signal"

    var callResult = flashObject.myFunction("my name");

</script>

...

<object id="flashObject"...>

    ...

    <embed name="flashObject".../>

</object>

或者,在运行于计算机应用程序中的SWF文件中调用ActionScript函数时,必须将已注册的函数名及所有参数序列化为一个XML格式的字符串。然后,将该XML字符串作为一个参数来调用ActiveX控件的CallFunction()方法,以实际执行该调用。

不管是哪种情况,ActionScript函数的返回值都被传递回容器代码,当调用方为浏览器中的JavaScript代码时直接作为值返回,而当调用方为ActiveX容器时则会序列化为XML格式字符串。

3.  转盘旋转原理与实现

转盘旋转的设计和实现才是本文的重点,与服务器的交互将不再介绍,而且与服务器的交互也不止通过JavaScript的方法,还可以通过cgi的方式。接下来的内容,假设已经经历了Flash(AS3)àJavaScript(cgi等)à后台à JavaScript(cgi等),即Flash已经告诉后台玩家已经开始了抽奖,并且后台返回了结果——中奖物品(指针停止位置)。我们要做的工作就是,让指针旋转起来,并最终停留在指定位置。

3.1.    数学知识

这里可以说是用上了高中的数学知识了,指针从一个位置旋转到另一个位置,相当箭头的顶点绕着中心做圆周运动,运动过程中顶点的坐标变化公式如下:

F  x += radius * sin ᶱ

F  y += radius * cos ᶱ

其中radius为半径(即指针长度)、ᶱ为指针旋转的角度。

我们要做的就是不断的改变旋转角度,直到达到指定的位置,将旋转位置连续起来达到运动的效果(使用Event.ENTER_FRAME或TimerEvent.TIMER,参见走在网页游戏开发的路上(六))。

3.2.    指针运动

以开始给出的转盘为例,转盘中有8个物品,指针角度为0时指向物品1,角度为45时指向物品2…,以360/8=45为间隔。现在假设指针其实为值为物品1,中奖结果为物品5,即指针要旋转180度。为了设计动画效果,我们监听Event.ENTER_FRAME事件,每帧使指针旋转一个小角度,比如5,直到角度为180度停止,这样就可以达到旋转的效果。

那我们现在是每帧根据上面的公式,改变指针顶点的位置吗?不是,在ActionScript中,显示对象有个rotation属性,顾名思义旋转角度的意思。这样每帧改变这个属性值就可以,在Event.ENTER_FRAME事件处理函数中,使指针的rotation += 45,直到rotation等于180。(rotation的取值范围是:(-180, 180])

说明:如果是一个小球绕着某个点,做圆周运动,改变rotation属性显然是不行的,这时必须得通过上面介绍的公式改变小球的x、y坐标达到运动的效果,这也是介绍上面公式的原因。

似乎这样做已经满足了基本要求,但是为了让用户感觉更真实,往往会要求指针至少转几圈,不会在一圈之内就到达指定位置停止了。那么这时指针的指针需要旋转度数:旋转圈数 * 360 + (指针当前位置与指定位置的偏差值)。

3.3.    缓动效果

很显然,上面实现的动画效果比较生硬,需要加入缓动效果。现实实际效果也是如此,高速转到的指针不可能突然停止,其中有个减速的效果,当速度减到0时,指针才会停止。这其实也好办,我们在Event.ENTER_FRAME事件处理函数中,调整指针rotation的增加值从大到小变动,直到这个增量为0停止,这里我就不实现了。下面我要介绍一个非常有用的缓动效果库——TweenMax,如果做flash webgame开发的话,肯定会用用到这个库。

3.3.1TweenMax库简介

TweenMax库包含了很多缓动效果,它是建立在TweenLite核心类及TweenFilterLite基础之上(它们同样包含了一些缓动效果)。但是TweenMax新增功能:

F  进行贝塞尔缓动

F  连续的缓动(序列化的缓动)

F  对对象数组中的对象进行同意的缓动使用allTo()或allFrom()

F  缓动中的暂停/继续功能,使用pause()和resume()方法,或“paused”属性

F  跳转至缓动的任何时段,使用“progress”属性。输入一个0~1之间的数值

F  对16进制的颜色进行缓动,使用hexColors属性

F  获取缓动效果的实例数组,该数组中包括了加在一个指定目标对象上的所有的缓动效果的实例,TweenMax.getTweensOf(mc);如果该mc应用了多个缓动效果,则返回一个数组,数组中是不同的缓动效果的实例

F  获取TweenMax、TweenLite和TweenFilterLite的实例数组,使用静态函数getAllTweens()

F  终止所有的缓动

F  暂停/继续全部的缓动

3.3.2常用方法

l  构造函数:public function TweenMax(target:Object, duration:Number, vars:Object)

l  target:目标对象,即需要缓动效果的对象,我们的例子中就是转盘的指针

l  duration:持续的时间(单位:秒);

l  vars:包含想要缓动的的属性值,缓动的常用属性包括

n  alpha:Number:目标对象在缓动结束时的alpha

n  delay:Number:延迟缓动

n  ease:Function:缓动函数

n  easeParames:Array:缓动函数中的参数

n  autoAlpha:Number:用来代替alpha属性,可获得一些附加小伙,实现透明度缓动效果

n  volume:Number:改变MovieClip或者SoundChannel的音量,将缓动结束时的音量值调整为指定的值

n  tint:Number:改变可显示对象的色调/颜色

n  frame:Number:将MovieClip缓动到指定的帧频

n  bezier:Array:Bezier缓动,允许你以非线醒的方式进行缓动

n  bezierThrough:Array:贝赛尔曲线要经过的位置点

n  orientToBezier:Array:使MovieClip自动调整自身的方向,使之符合贝塞尔路径[x,y,rotation,ang](rotation:旋转属性,ang:旋转的度数

n  hexColors:Object:缓动指定对象中相应颜色属性的值(TweenMax.to(my_obj,{hexColors:{mycolor:0Xff0000}}))

n  onStart:Function:在缓动开始时想要执行的某个函数

n  onStartParams:Array:缓动开始时要执行函数的参数

n  onUpdate:Function:缓动过程中,每次更新属性值时,要执行的函数

n  onUpdateParams:Array:同上

n  onComplete:Function:缓动结束时要执行的函数

n  onCompleteParams:Array:同上

n  renderOnStart:Boolean:阻止缓动的渲染效果直到缓动真正开始

n  overwrite:Boolean:缓动效果是否可以被覆盖

n  blurFilter:Object:应用模糊滤镜,需要传递一个具有下列属性的对象作为参数:blurX(横向的模糊度),blurY(纵向的模糊度),quality(品质,默认值为2)

n  glowFilter:Object:应用发光滤镜,需要传递一个带有以下属性的对象:alpha,blurX,blurY,color,strength(强度),quality,inner(内侧发光),knockout(挖空)

n  colorMatrixFilter:Object:应用颜色矩阵滤镜,需要传递一个带有以下属性的对象:colorize(色调),amount(总量),contrast(对比度),brightness(亮度),saturation(饱和度),hue(色相),threshold(阀值),relative(相关性),matrix(颜色矩阵)

n  dropShadowFilter:Object:应用阴影滤镜,需要传递一个带有以下属性的对象:alpha,angle(角度),blurX,blurY,color,distance(距离),strength,quality

n  bevelFilter:Object:应用斜角滤镜,需要传递一个带有以下属性的对象:angle,blurX,blurY,distance,hightlightAlpha(高亮区的透明度),highlightColor(高亮区的颜色),shadowAlpha(阴影区的透明度),shadowColor(阴影区的颜色),strength(强度),quality

n  progress:Number:缓动进程0~1

n  paused:Boolean:是否停止缓动

l  函数:allTo(targets:Array, duration:Number, vars:Object):Array

返回的是一个数组保存了创建的所有TweenMax Object。

l  函数:allFrom(targets:Array, duration:Number, vars:Object):Array

跟allTo一样,只是定义的是运动对象的初始状态,运动到当前状态。

l  函数:complete(skipRender:Boolean = false, suppressEvents:Boolean = false):void

强制TweenMax到最后结束部分。如果第一个参数设为true,则不会渲染,TweenMax将停在调用那一刻。如果第二个参数设为true则不会触发onCompelte,onUpdate等事件。

l  函数:delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array = null, useFrames:Boolean = false):TweenMax

延迟执行函数

l  函数:getTweensOf(target:Object):Array

返回运动物体正在运行的的TweenMax Object

l  函数:isTweening(target:Object):Boolean

判断是否正在缓动

l  函数:updateTo(vars:Object, resetDuration:Boolean = false):void

可以在运行中新增或改变原有的属性变化值。第二个参数设为false时将不重播缓动,而继续缓动到新的值;设为true将中断并重播缓动。

4.  最终代码实现

前面介绍了转盘的原理和TweenMax库,下面看最终实现的代码。不废话,上关键代码:

package  
{
    import flash.display.Sprite;
    import com.greensock.TweenMax;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.utils.getDefinitionByName;
    /**
     * ...
     * @author ...
     */
    public class DialUI extends Sprite 
    {
        private var _tween:TweenMax;
        private var _view:*;
    
        //物品个数;
        private var _count:int = 8;
        //角度;
        private var _angle:Number = 360/_count;
        //最少旋转圈数;
        private var _rotateNum:int = 2;
        
        public function DialUI() 
        {
            initView();
        }
        
        private function initView():void
        {
            var cls:Class = getDefinitionByName("Dial") as Class;
            if (cls != null)
            {                
                _view = new cls();
                _view.pointer.rotation = 0;
                _view.btnStart.addEventListener(MouseEvent.CLICK, onClickHandler);                
                addChild(_view);
                
                _tween = new TweenMax(_view.pointer, 2, {onComplete: onCompleteHandler});
            }
        }
        
        private function onClickHandler(evt:MouseEvent):void
        {
            _view.btnStart.mouseEnabled = false;
            var temp:uint = Math.floor(8 * Math.random());
            trace(temp);
            var rt = _angle * temp + (360 * _rotateNum);
            _tween.updateTo({rotation: rt}, true)
        }
        
        private function onCompleteHandler():void
        {
            _view.btnStart.mouseEnabled = true;
        }
    }
 
}

 

完整代码下载

写在最后

不知直觉,写到这么晚了,效率啊!最后大概浏览了一下,还是有很多传达的东西没有表现出来,只有大家意会了。声明:本文是我在公司半个月前所做东西
的总结,但并不涉及泄漏公司机密。感觉heaton导师的指导!要休息了,明天还要上班,不然明天要挂了。如果大家觉得还不错,就请推荐。

时间: 2024-10-19 00:02:54

大家快来玩转盘抽奖游戏(走在网页游戏开发的路上(七))的相关文章

走在网页游戏开发的路上(四)

AS3之类 0.  前言 类:面向对象的基础,类是对象的抽象表示形式,类用来存储有关对象可保存的数据类型及对象可表现的行为的信息. 类的定义: [dynamic] [public | internal] [final] class className [ extends superClass ] [ implements interfaceName[, interfaceName... ] ] {     // 此处是类定义 } 在ActionScript 3.0中,可使用以下四个属性之一来修饰

H5游戏能否复制网页游戏

在2014年临近终点的时候,H5因一波游戏的热潮备受关注,跃跃欲试者有之.淡然看衰者也不少.总体来说,前者要远多于后者,不少人在与人沟通的时候,都将手机端的手游和H5游戏将PC端的端游与页游进行类比,由此H5游戏复制页游辉煌的言论很容易因类比思维获得业内人士的心理认同. 细细回想一番,这种类比的方法确实很能说服别人,类似的端与无端.迄今为止颇为相似的发展轨迹以及H5开发上的延续性,都在佐证H5游戏会成为移动互联网时代的页游.按照定义来讲,H5是一系列制作网页互动效果的技术集合.简单来说,它能在移

聚合用户 网页游戏门户成网页游戏发展助推器

中介交易 SEO诊断 淘宝客 云主机 技术大厅 从2008年下半年到2009年,在传统经济受金融危机重创之时,互联网经济却进入了一个创新不断,稳步增长的时代.特别是游戏行业,整体呈现出一种逆势上扬的趋势.各种以"游戏"为主题的投资案例层出不穷.不断有新的投资者介入游戏行业,也不断有新的游戏推出.巨人网络即将推出新网游"绿色征途",湖南卫视将进军游戏领域推网页游戏的消息也说明了游戏市场是一块众人争尝的"大蛋糕".09年的游戏市场,是WEBGAME.

走在网页游戏开发的路上(一)

起步 --此系列谨记录我步入页游开发队伍的历程. 0.写在前面 相信有很多和我一样的人,曾多次问google.问baidu.问各大论坛--如何开发游戏?开发游戏如何入门?由于游戏开发本身其复杂.庞大.涉及东西比较多,始终不得其道,最终激情无情的被时间这把杀猪刀给磨灭.之后又一次激情澎湃,又一次不了了之-- 本人喜欢玩游戏,也有幸在研究生毕业能够加入腾讯QQ游戏开发部门,本系列将记录如何步入网页游戏开发的历程.此系列,至少是目前阶段,主要关注如何使用ActionScript 3.0开发网页游戏(本

走在网页游戏开发的路上(三)

AS3之函数 0.  前言 函数:完成某个目标任务的代码块,它是代码重用的最小单位. 函数是可在ActionScript中调用的基本代码单位.ActionScript中用户定义的函数和内置函数都由Function对象来表示,该对象是Function类的实例. 类的方法与Function对象略有不同.与普通函数对象不同,方法和与其关联的类对象紧密关联.因此,方法或属性具有在同一类的所有实例中共享的定义.可以从实例提取方法并将其处理为"绑定"方法(保留与原始实例的链接).对于绑定方法,th

走在网页游戏开发的路上(九)

游戏中的背景音乐和声效 0.  前言 不管是大型客户端游戏还是轻量级的网页游戏,游戏中背景音乐和声效是必不可少的.好的背景音乐.声效会给游戏增色,本文不从策划/设计等角度去考虑,只从程序实现上面讲在网页游戏开发中如何去实现背景音乐.声效.背景音乐和声效有以下几个要求: ü  背景音乐与声效是分开的,可以独立设置开关 ü  背景音乐一般循环播放一直存在 ü  声效点击才触发,这种声音任何时候只播放一个,如果两个瞬间点击多个按钮,只播放最后一个声音 为了使背景音乐和声效分开,可以使用不同的声道来播放

网页游戏何去何从 分析网页游戏现状和未来

中介交易 SEO诊断 淘宝客 云主机 技术大厅 临近春节,关熙的心里却充满了挫折感.他是北京一所重点大学计算机系的研究生,在2008年10月,他和三个同学自己掏了点钱又向亲友借贷,攒了18万元开发了一款"猜谜"的网页游戏,但就在前几天,由于资金问题这款游戏刚刚失去了开始运营的机会. 现在,有关熙这样遭遇的网页游戏开发小组太多了."我甚至见过一个人开发网页游戏的."一位业内人士透露,但是现在很多开发小组都已经退出了. 事实上,就在这些开发者决定进入这个行业的时候--2

SNS游戏占到网页游戏九成

本报北京6月8日讯(记者赵明) 中国互联网络信息中心(CNNIC)发布的<2010年中国网页游戏调查报告>显示,随着我国互联网用户不断增加,国内网页游戏用户总数量也在激增,截至今年4月,达到1.05亿.其中,SNS(社交类)网页游戏的用户数量已达到了9209万,占网页游戏总规模的87.7%. 这首先要得益于SNS近两年的风生水起.在人人网等网站上,每天都有用户在线上与好友"交换食材".互相"采摘"."雇佣打工".用户一方面在游戏中娱乐

网页游戏赚钱方法 网页游戏怎么网页游戏

引发你的问题的其实是另外三个原因: 1.中国网络业流量过剩,且转化为收入的选择余地有限,除了游戏和电商,基本没了.所以游戏广告多. 2.网页游戏适合这种广告联盟推广方式.不像 MMORPG,客户端几个 G,必须地推.网页游戏一个链接就点开了.所以广告形态匹配. 3.行业初期,大家抢地盘,很多公司不惜血本建广告联盟. 所以网页游戏的网赚就不要做了,几乎是不能够满足我们的.所以我们建议大家做淘宝客或学习seo,只要你有执行力的话,那么你可以达到一个月4000也会没有问题的. 那款网页游戏赚钱 网页游