近期偶然看到一个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();
}
}
}
|