2D游戏新手引导点光源和类迷雾实现

来源:互联网 发布:湖南拼车软件 编辑:程序博客网 时间:2024/05/18 00:31

一、新手引导需要的遮罩效果

一般做新手引导的时候,会把游戏画面变的半黑,然后需要玩家点击的地方就亮起来。常用的做法是采用遮罩来实现,但是只能实现方形的,不能不规则图形,以及是完全挖空,做不到渐变效果(除非美术直接出整张资源)。表现效果如下:
这里写图片描述
实事上,我们想做把那个透明框做得更自然一点,更好看一点。
也就是类似火把,点光源的效果。比如下面游戏的画面那样:
这里写图片描述
比较效果,肯定是类似点光源酷多了。
既然要这样的效果,那肯定得出我们图像混合大法了。

二、AS3实现的类似点光源效果

  1. 这里是采用一张美术出的具有渐变效果的图片来实现类似点光源的效果的。美术图如下:
    这里写图片描述
    实际上,想要更好的效果,美术可以把这个图片做得更精细一些,这里我把角色阴影来做的。
    如果想要实现点光源的动画效果,那么出多几张这个图片,形成动画效果就可以了。
  2. 实现使用的API
DisplayObject.blendMode属性BlendMode 类中的一个值,用于指定要使用的混合模式。

用到了BlendMode类的两个属性

LAYER : String = "layer"[静态] 强制为该显示对象创建一个透明度组。
ERASE : String = "erase"[静态] 根据显示对象的 Alpha 值擦除背景。

有看过我之前文章的读者,可能会发现这API眼熟,没错,是我上篇Blog一样的实现原理
页游《火影忍者》角色和背景遮挡半透明效果的实现
使用的API和用法一摸一样。
3. 最终实现的效果图:
这里写图片描述
4.代码下载地址
2DAS3游戏地图角色遮罩和点光源
选择里面的PointLightTest.as执行看效果

三、代码实现过程

package{    import flash.display.Bitmap;    import flash.display.BlendMode;    import flash.display.Shape;    import flash.display.Sprite;    import flash.events.Event;    import flash.events.MouseEvent;    /**     * 地图透明角色测试例子     * @author sodaChen     * Date:2017-2-16     */    [SWF(width="1274",height="768")]    public class PointLightTest extends Sprite    {        /** 背景 **/        [Embed(source = "res/alpha/bg.jpg")]        private var bgClass:Class;        /** 透明遮罩背景 **/        [Embed(source = "res/alpha/alphaBg.png")]        private var alphaBgClass:Class;        /** 角色 **/        [Embed(source = "res/alpha/role.png")]        private var roleClass:Class;        /** 角色容器 ,用来存放角色和透明图像的**/        private var roleContainer:Sprite;        /** 角色层,只放角色 **/        private var roleLayer:Sprite;        //点光源图片(这里拿了人物脚底阴影放大来用)        [Embed(source = "res/alpha/shadow.png")]        private var shadowClass:Class;        public function PointLightTest()        {            super();            addEventListener(Event.ADDED_TO_STAGE,onStage);        }        private function onStage(evt:Event):void        {            //添加背景            addChild(new bgClass());            //添加角色容器            roleContainer = new Sprite();            //强制为该显示对象创建一个透明度组            roleContainer.blendMode = BlendMode.LAYER;            addChild(roleContainer);            //创建角色层,其实角色可以不用单独容器,但是必须保证alphaBg在所有角色的最上面            roleLayer = new Sprite();            roleContainer.addChild(roleLayer);            //创建角色并添加到角色容器中            createRole(300,120);            createRole(230,550);            //不会被遮挡的角色            createRole(400,200);            //根据显示对象的 Alpha 值擦除背景.这个透明图像必须在最顶层,确保下面的角色会被擦出            var alphaBg:Bitmap = new alphaBgClass();            alphaBg.blendMode = BlendMode.ERASE;            roleContainer.addChild(alphaBg);            /////////////////////////////文本的正式测试代码啦/////////////////////////////            //新建一个专门做点光源的顶层容器            var topContainer:Sprite = new Sprite();            topContainer.mouseEnabled = false;            //强制为该显示对象创建一个透明度组            topContainer.blendMode = BlendMode.LAYER;            addChild(topContainer);            //创建半透的黑色遮罩            var mask:Shape = new Shape();            //颜色可以选自己喜欢的            mask.graphics.beginFill(0x000000);            mask.graphics.drawRect(0,0,1274,768);            mask.graphics.endFill();            mask.alpha = 0.5;            topContainer.addChild(mask);            //制作点光源,其实就是新手引导里的光亮部分。效果挺酷的。比遮罩那种一个方形的框好看多了            var pointBitmap:Bitmap = new shadowClass();            //根据显示对象的 Alpha 值擦除背景,就是那个半透的黑色遮罩            pointBitmap.blendMode = BlendMode.ERASE;            pointBitmap.x = 290; pointBitmap.y = 70;            pointBitmap.width = 300; pointBitmap.height = 400;            var role:Sprite = new Sprite();            role.addEventListener(MouseEvent.MOUSE_DOWN,onMouse);            role.addEventListener(MouseEvent.MOUSE_UP,onMouse);            role.addChild(pointBitmap);            topContainer.addChild(role);        }        private function createRole(roleX:int,roleY:int):void        {            var role:Sprite = new Sprite();            var roleBitmap:Bitmap = new roleClass();            role.x = roleX;            role.y = roleY;            role.addChild(roleBitmap);            roleLayer.addChild(role);            role.addEventListener(MouseEvent.MOUSE_DOWN,onMouse);            role.addEventListener(MouseEvent.MOUSE_UP,onMouse);        }        private function onMouse(evt:MouseEvent):void        {            var role:Sprite = evt.currentTarget as Sprite;            if(evt.type == MouseEvent.MOUSE_DOWN)                role.startDrag();            else                role.stopDrag();        }    }}
0 0