吾知网

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 8018|回复: 1
打印 上一主题 下一主题

AS3.0 2D游戏人物影子实现思路

[复制链接]
跳转到指定楼层
楼主
发表于 2016-10-27 15:47:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
近期偶然看到一个2D网页RPG游戏,不像以前那些游戏一样只是使用一张黑色渐变的位图做为人物的影子,而是采用了位图渲染的方式来渲染人物影子(效果如上图),感觉效果很不错,于是也动手写写。
       我的思路很简单,就是每帧都克隆一份人物位图(当然考虑效率问题,这里可以根据需要和效果来更改),然后使用Graphics.drawTriangles的方式进行位图的拉伸,做出的效果还行,效率也还好,总之过得去,呵呵。。。

        以下是简单的代码:

    package com.game.engine.gameobject.entity.base
{
import com.game.GlobalConst;

import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Rectangle;


public class EntityShadow extends Sprite{
  public  static const DIRECTION_RIGHT:int =  1;
  public  static const DIRECTION_LEFT :int = -1;

  private var vertices  :Vector.<Number>;
  private var indices   :Vector.<int>;
  private var uvtData   :Vector.<Number> ;
  private var bmpd      :BitmapData;
  private var bodySprite:Shape;
  private var direction :int;
  private var delay     :int;
  private var matrix    :Matrix
  
  public function EntityShadow(direction:int = DIRECTION_LEFT){
   this.direction     = direction;
   this.bodySprite    = new Shape();
   this.vertices      = new Vector.<Number>();
   this.indices       = new Vector.<int>();
   this.uvtData       = new Vector.<Number>();
   this.matrix        = new Matrix();
   
   this.mouseChildren = false;
   this.mouseEnabled  = false;
   
   this.indices.push(0, 3, 4);
   this.indices.push(0, 1, 4);
   this.indices.push(1, 4, 5);
   this.indices.push(1, 2, 5);
   
   this.uvtData.push(1, -1);
   this.uvtData.push(0, -1);
   this.uvtData.push(0, 1);
   this.uvtData.push(1, -1);
   this.uvtData.push(1, -1);
   this.uvtData.push(1, 1);
  }
  public   function render(oMovieClips:Array):void{
   if(delay <= 0){ //提升效率,两帧渲染一次
        this.delay = 2;
        this.dispose();

        //OMovieClip 是自己封装的一位图序列帧播放器

        //这里的数组包括的是人物、武器、翅膀位图
      for each(var omc:OMovieClip in oMovieClips){
               if(omc.bitmapData != null){
                   matrix.b =  0;
                   matrix.c =  0;
                   matrix.d =  1;
                   matrix.tx=  omc.x;
                   matrix.ty=  omc.y;
                  if(!omc.isMirro){ //位图是使用了镜像
                      matrix.a =  1;
                      bodySprite.graphics.beginBitmapFill(omc.bitmapData,matrix);
                      bodySprite.graphics.drawRect(omc.x,omc.y,omc.bitmapData.width,omc.bitmapData.height);
                      bodySprite.graphics.endFill();
              }else{
                 matrix.a = -1;
                 bodySprite.graphics.beginBitmapFill(omc.bitmapData,matrix);
                 bodySprite.graphics.drawRect(omc.x-omc.bitmapData.width,omc.y,
                                                                omc.bitmapData.width,omc.bitmapData.height);
                 bodySprite.graphics.endFill();
           }
        }
     }

    //上面是把一个人物包含所有位图(人物、武器、翅膀)画成一个Shape,方便下面位图拉伸
     this.update(bodySprite);
    }else{
         this.delay--;
    }
  }

//进行位图拉伸
  private  function update(display:DisplayObject):void{
   var rect:Rectangle  = display.getRect(display);
   if(rect.width > 0 && rect.height > 0){
           var tempH:Number    = rect.height;

            //把Shape转换成BitmapData
            this.bmpd = new BitmapData(rect.width,rect.height,true,0xFFFFFF);
            this.bmpd.lock();
            this.bmpd.draw(display,new Matrix(1,0,0,.95,-rect.x,-rect.y));

            //将合成的位图添加一个半透明的黑色滤镜,new ColorMatrixFilter([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,.5,0]);
            this.bmpd.applyFilter(this.bmpd,bmpd.rect,GlobalConst.ZERO_POINT,
                                             GlobalConst.ALPHA_BLACK_COLORMATRIXFILTER);
            this.bmpd.unlock();
      

          //下面就是进行位图拉伸,可以自己查看相对应的api文档

   
          //这里在这120×120的位图上定义了6个点
            this.vertices.splice(0,vertices.length);

            this.vertices.push(0,0);
            this.vertices.push(tempH*this.direction,0); //这里如果是 vertices.push(0, 60);则左边不扭曲
            this.vertices.push(0, rect.height);
            this.vertices.push(rect.width, 0);
            this.vertices.push(rect.width+tempH*this.direction,0); //这里如果是 vertices.push(120, 60);则右边不扭曲
            this.vertices.push(rect.width,rect.height);
   
            this.graphics.beginBitmapFill(bmpd,null,false);
            this.graphics.drawTriangles(vertices,indices,uvtData);
            this.graphics.endFill();
            this.x = rect.x;
            this.y = rect.y;
      }
  }

  /**销毁,位图不用时需要从内存销毁**/
  public   function dispose():void{
        this.graphics.clear();
        this.bodySprite.graphics.clear();
        if(this.bmpd != null)  this.bmpd.dispose();
  }
}
}


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|吾知网 ( 粤ICP备13013563号-1 )

GMT+8, 2024-12-23 00:32 , Processed in 1.093750 second(s), 9 queries , Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表