小萝莉的游乐园

本文将详细介绍如何利用HTML5的开源框架lufylegend来进行游戏的开发。

一、lufylegend库件简介

  • 一个HTML5开源框架
  • 利用JavaScript和ActionScript相似性,用仿ActionScript3.0的语法对HTML5 Canvas的API进行了封装
  • 支持多种常用环境,手机浏览器与PC浏览器自动切换事件

1.1 工作原理

lufylegend库件封装了Canvas绘图的所有API,它利用JavaScript的setInterval函数,对Canvas画板进行周期性重绘。每次重绘时,首先要使用clearRect对Canvas画板进行清空整个画板,再调用需要重绘的各个API函数,这样可以达到重新绘制所有图形的目的。

lufylegend库件初始化时,会根据浏览器来判断需要加载的是mouse事件还是touch事件。再利用lufylegend库件加载点击事件的时候,只是将被加载的事件加入了框架预先准备的数组中,当点击事件发生的时候才会调用这个数组里的事件。

1.2 库件使用流程

  1. http://lufylegend.com/lufylegend下载库件最新版。

压缩包内包含lufylegend-x.x.x.js和lufylegend-x.x.x.min.js两个完整版本,还有lufylegend-x.x.x.simple.js和lufylegend-x.x.x.simple.min.js两个缩减版本,***.min是去除了回车和空格的压缩版本。

simple缩减版本与完整版本的区别在于,将LBox2d,LQuadTree,LTransitionManager,LoadingSample1,LoadingSample2,LoadingSample3,LoadingSample4,LoadingSample5等几个类与引擎的常用部分分离,缩减了引擎的体积。如果用到了被分离的部分的功能的话,可以进行手动加载。

  1. 在html中将库件引入。

  2. 调用LInit函数,初始化库件。

示例代码:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8" />
    <script type="text/javascript" src="../lufylegend-1.7.6.min.js"></script> 
</head>
<body>
<div id="mylegend">loading...</div>
<script type="text/javascript">
init(50,"mylegend",500,350,main);
function main(){  
    alert("lufylegend start");  
}
</script>
</body>
</html>

二、图片的加载与显示

步骤:

  1. 使用Lloader类加载图片数据
  2. 将读取完的图片数据保存到LbitmapData中
  3. 利用Lbitmap将图片显示到画板上

2.1 图片显示举例

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8" />
    <script type="text/javascript" src="../lufylegend-1.7.6.min.js"></script> 
</head>
<body>
<div id="mylegend">loading...</div>
<script type="text/javascript">
var loader;  
init(50,"mylegend",500,350,main);

function main(){  
    /*给Image添加一个onload事件*/
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("face.jpg","bitmapData");  
}  

function loadBitmapdata(event){  
    /*图片读取完调用loadBitmapdata函数,新建一个LBitmapData对象。此时的loader.content就是一个Image*/
    /*LbitmapData是lufylend库件的一个类,用来保存和读取Image对象,如果要将图片显示到Canvas画板上,则需要用到Lbitmap*/
    var bitmapdata = new LBitmapData(loader.content); 

    /*LBitmap的功能是将Image对象显示到Canvas画板上*/
    var bitmap = new LBitmap(bitmapdata);  
    addChild(bitmap);  
} 
</script>
</body>
</html>

给Image添加一个onload事件的代码:
loader = new LLoader();
loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);
loader.load(“face.jpg”,”bitmapData”);

等价于:

var image = new Image();
image.onload = function(){
};

上面的代码可以看出图片显示主要用到LBitmapData和LBitmap两个对象。

2.2 LBitmapData对象

LBitmapData(image,x,y,width,height)

参数针对可视范围,若后面四个参数缺省,则显示整张图片

<script type="text/javascript">
var loader;  
init(50,"mylegend",500,350,main);

function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("face.jpg","bitmapData");  
}  
function loadBitmapdata(event){  
    var bitmapdata = new LBitmapData(loader.content,50,50,150,150);  
    var bitmap = new LBitmap(bitmapdata);  
    addChild(bitmap);  
} 
</script>

2.3 LBitmap对象

功能:

  1. 将图片显示到Canvas画板上

  2. 控制图片的各种属性,坐标(x,y)、透明度(rotate)、旋转(rotate)、缩放(scaleX、scaleY)等

    /设置图片旋转与透明度/

三、层的概念

如果把不同的图形放到不同层,我么就能觉得这些图像在游戏画面里出现的顺序。

lufylegend.js库件为Canvas实现了层的概念,就是LSprite对象。

创建LSprite对象,并把layer层添加到画板:

var layer = new LSprite();
addChild(layer);

把layer层添加到画板,然后将bitmap添加到layer层:

var layer = new LSprite();
addChild(layer);
layer.addChild(bitmap);

LSprite对象也和LBitmap对象一样,有坐标(x,y)、透明度(rotate)、旋转(rotate)、缩放(scaleX、scaleY)等属性,不过它控制的是整个层的属性。

/*使用LSprite对象的旋转属性*/

<script type="text/javascript">
var loader;  
init(50,"mylegend",500,350,main);

function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("face.jpg","bitmapData");  
}  
function loadBitmapdata(event){  
    var bitmapdata = new LBitmapData(loader.content);  
    var bitmap = new LBitmap(bitmapdata);  
     //加入层LSprite
    var layer = new LSprite();
    addChild(layer);
    layer.addChild(bitmap);  
    layer.x = 50;
    layer.y = 50;
    layer.rotate = 60;
} 
</script>

四、使用LGraphics对象绘图

LGraphics是lufylegend库件中的一个绘图类,它内置了一些函数以简化绘图。

可以单独属于,也可以与LSprite对象配合使用。

4.1 绘制矩形

使用LGraphics对象中的drawRect函数绘制矩形:

drawRect (thickness,lineColor,pointArray,isfill,color)

<script type="text/javascript">
init(50,"mylegend",500,350,main);
function main(){  
   var graphics = new LGraphics();
   addChild(graphics);
   graphics.drawRect(1,'#000000',[50,50,100,100]);
   graphics.drawRect(1,'#000000',[170,50,100,100],true,'#cccccc');
}  
</script>

4.2 绘制圆

drawArc (thickeness,lineColor,pointArray,isfull,color)

pointArray:圆形参数数组[坐标x,坐标y,半径,起始角度,结束角度,顺时针或逆时针]

<script type="text/javascript">
init(50,"mylegend",500,350,main);
function main(){  
/*建立一个绘图对象,并将其加载到Cavans画板上*/
   var graphics = new LGraphics();
   addChild(graphics);
    /*画一个空心圆*/
   graphics.drawArc(1,'#000000',[60,60,50,0,360*Math.PI/180]);
    /*画一个实心圆*/
   graphics.drawArc(1,'#000000',[180,60,50,0,360*Math.PI/180],true,'#cccccc');
}  
</script>

4.3 绘制任意多边形

drawVertices (thickness,lineColor,vertices,isfill,color)

vertices:顶点数组[[顶点1],[顶点2],[顶点3
]…]

<script type="text/javascript">
init(50,"mylegend",500,350,main);
function main(){  
   var graphics = new LGraphics();
   addChild(graphics);
    /*画一个空心六边形*/
   graphics.drawVertices(1,'#000000',[[50,20],[80,20],[100,50],[80,80],[50,80],[30,50]]);
    /*画一个填充六边形*/
   graphics.drawVertices(1,'#000000',[[150,20],[180,20],[200,50],[180,80],[150,80],[130,50]],true,'#cccccc');
}  
</script>

4.4 使用Canvas原始绘图函数进行绘图

LGraphics对象可以使用Canvas的原始绘图函数进行绘图。

script type="text/javascript">
init(50,"mylegend",500,350,main);
function main(){  
    /*建立一个绘图对象,并将其加载到Canvas画板上*/
    var graphics = new LGraphics();
    addChild(graphics);

    /*调用LGraphics对象中的add函数,传入绘图函数*/
    graphics.add(function(coodx,coody){
        LGlobal.canvas.strokeStyle = "#000000";
        LGlobal.canvas.moveTo(20,20);
        LGlobal.canvas.lineTo(200,200);
        LGlobal.canvas.stroke();
    });
}  
</script>

因为写在fun内部的JavaScript代码都会被运行,所以绘制图形的代码可以写在他的里面。

这里用到的LGlobal.canvas其实就是getContext(“2d”)所返回的对象。

add函数原型:add(fun)

4.5 使用LSprite对象进行绘图

由于每个LSprite对象都包含一个LGraphics对象,所以上面的绘图都可以使用LSprite对象中的graphics来实现,比如4.1中画一个矩形的代码也可以这样写:

<script type="text/javascript">
init(50,"mylegend",500,350,main);
function main(){  
   var layer = new LSprite();
   addChild(layer);

   layer.graphics.drawRect(1,'#000000',[50,50,100,100]);
   layer.graphics.drawRect(1,'#000000',[170,50,100,100],true,'#cccccc');
}  
</script>

4.6 使用LGraphics对象绘制图片

使用LGraphics对象绘制图片,主要是结合LGraphics对象的beginBitmapfull函数来实现的。

4.6.1 绘制一个圆形区域的图片

LGraphics对象的beginBitmapfull函数和drawArc函数结合起来使用

<script type="text/javascript">
var loader;  
init(50,"mylegend",500,350,main);

function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("face.jpg","bitmapData");  
}  
function loadBitmapdata(event){  
    var bitmapdata = new LBitmapData(loader.content);  
    var backLayer = new LSprite();
    addChild(backLayer);
    backLayer.graphics.beginBitmapFill(bitmapdata);
    backLayer.graphics.drawArc(1,"#000",[110,80,50,0,Math.PI*2]);
}
</script>

解析:

利用beginBitmapfull函数将LBitmapData对象存储到LGraphics对象中:

backLayer.graphics.beginBitmapFill(bitmapdata);

利用drawArc函数绘制一个圆形区域。LBitmapData对象会直接将存储在自己内部的BitmapData对象通过这个圆形区域显示出来:

backLayer.graphics.drawArc(1,"#000",[110,80,50,0,Math.PI*2]);
4.6.2 绘制一个矩形区域的图片
<script type="text/javascript">
var loader;  
init(50,"mylegend",500,350,main);

function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("face.jpg","bitmapData");  
}  
function loadBitmapdata(event){  
    var bitmapdata = new LBitmapData(loader.content);  
    var backLayer = new LSprite();
    addChild(backLayer);
    backLayer.graphics.beginBitmapFill(bitmapdata);
    backLayer.graphics.drawRect(1,"#000",[80,50,70,100]);
}
</script>
4.6.3 绘制一个多边形区域的图片

LGraphics对象的beginBitmapfull函数和drawVertices函数结合起来使用

<script type="text/javascript">
var loader;  
init(50,"mylegend",500,350,main);

function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("face.jpg","bitmapData");  
}  
function loadBitmapdata(event){  
    var bitmapdata = new LBitmapData(loader.content);  
    var backLayer = new LSprite();
    addChild(backLayer);
    backLayer.graphics.beginBitmapFill(bitmapdata);
    backLayer.graphics.drawVertices(1,"#000",[[120,50],[100,200],[200,150]]);
}
</script>
4.6.4 绘制一个扭曲的图片

LGraphics对象的beginBitmapfull函数和drawTriangles函数结合起来使用

drawTriangles函数:drawTriangles(vertices,indices,uvtData,thickness,color)

vertices:由数字构成的矢量,其中每一对数字将被视为一个坐标位置(x,y),该参数是必须要有的

indices:由整数或索引构成的矢量,其中每3个索引定义一个三角形,如果indeces参数为null,则每三个顶点定义一个三角形。(三角形定点顺序:左上-右上-左下或右上-左下-右下)

uvtData:用于应用纹理映射的标准坐标构成的矢量。表示定义上面的每个顶点相对于整张图片的比例

thickness:分割玩的三角形边框线宽

color:分割玩的三角形边框颜色

<script type="text/javascript">
var loader;  
init(50,"mylegend",500,350,main);

function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("face.jpg","bitmapData");  
}  
function loadBitmapdata(event){  
    var bitmapdata = new LBitmapData(loader.content);  
    var backLayer = new LSprite();
    backLayer.x=100;
    addChild(backLayer);

    vertices = new Array();
    vertices.push(0, 0);
    vertices.push(0-50, 120);//这里将原坐标的x坐标左移50
    vertices.push(0, 240);
    vertices.push(120, 0);
    vertices.push(120, 120);
    vertices.push(120, 240);
    vertices.push(240, 0);
    vertices.push(240+50, 120);//这里将原坐标的x坐标右移50
    vertices.push(240, 240);

    indices = new Array();
    indices.push(0, 3, 1);
    indices.push(3, 1, 4);
    indices.push(1, 4, 2);
    indices.push(4, 2, 5);
    indices.push(3, 6, 4);
    indices.push(6, 4, 7);
    indices.push(4, 7, 5);
    indices.push(7, 5, 8);

    uvtData = new Array();
    uvtData.push(0, 0);
    uvtData.push(0, 0.5);
    uvtData.push(0, 1);
    uvtData.push(0.5, 0);
    uvtData.push(0.5, 0.5);
    uvtData.push(0.5, 1);
    uvtData.push(1, 0);
    uvtData.push(1, 0.5);
    uvtData.push(1, 1);

    backLayer.graphics.beginBitmapFill(bitmapdata);
    backLayer.graphics.drawTriangles(vertices, indices, uvtData);
}
</script>
4.6.5 实现3d效果

使用drawTriangles函数,示例代码如下

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>3D</title>
        <script type="text/javascript" src="../lufylegend-1.7.6.min.js">
        </script>
        <script type="text/javascript">
            LSystem.screen(0.5);
        </script>
    </head>
    <body>
        <div id="legend">
        </div>
        <script>
            init(50, "legend", 600, 500, main);
            var leftspeed = 0;
            var leftindex = 1;
            var upspeed = 10;
            var upindex = 1;
            var vertices;
            var indices;
            var uvtData;
            var backLayer;
            var bitmapData, earthBitmapData;
            var rows = 24, cols = 24;
            var mi = 0;
            var imgData = [{
                name: "earth",
                path: "earth.jpg"
            }];
            var imglist;
            function main(){
                LLoadManage.load(imgData, null, gameInit);
            }

            function gameInit(result){
                imglist = result;
                earthBitmapData = new LBitmapData(imglist["earth"]);
                //earthBitmapData = new LBitmapData("#ffffff", 0, 0, 500, 300);

                var i, j;
                var r = 100;
                vertices = new Array();
                for (i = 0; i <= cols; i++) {
                    for (j = 0; j <= rows; j++) {
                        var angle = (90 - 180 * j / rows) * Math.PI / 180;
                        var a = Math.sin(angle);
                        if ((90 - 180 * j / rows) % 90 == 0 && (90 - 180 * j / rows) % 180 != 0) 
                            a = (90 - 180 * j / rows) > 0 ? 1 : -1;
                        if ((90 - 180 * j / rows) % 180 == 0) 
                            a = 0;
                        var sy = -r * a;
                        var sa = Math.cos(angle);
                        if ((90 - 180 * j / rows) % 180 == 0) sa = 1;
                        var sr = Math.abs(r * sa);
                        var angle2 = 360 * (i + 1) / cols;
                        var b = Math.cos(angle2 * Math.PI / 180);
                        if (angle2 % 360 == 0) 
                            b = 1;
                        else if (angle2 % 180 == 0) 
                            b = -1;
                        var sx = sr * b;
                        vertices.push(sx, sy);
                    }
                }
                indices = new Array();
                for (i = 0; i < cols; i++) {
                    for (j = 0; j < rows; j++) {
                        indices.push(i * (rows + 1) + j, (i + 1) * (rows + 1) + j, i * (rows + 1) + j + 1);
                        indices.push((i + 1) * (rows + 1) + j, i * (rows + 1) + j + 1, (i + 1) * (rows + 1) + j + 1);
                    }
                }
                uvtData = new Array();
                for (i = 0; i <= cols; i++) {
                    for (j = 0; j <= rows; j++) {
                        uvtData.push(i / cols, j / rows);
                    }
                }
                backLayer = new LSprite();
                backLayer.x = 110;
                backLayer.y = 110;
                addChild(backLayer);
                backLayer.graphics.clear();
                backLayer.graphics.beginBitmapFill(earthBitmapData);
                backLayer.graphics.drawTriangles(vertices, indices, uvtData);

                backLayer.addEventListener(LEvent.ENTER_FRAME, onframe);
            }

            function onframe(){
                if (leftspeed < 10 && leftindex++ > leftspeed) {
                    leftindex = 0;
                    for (i = 0; i <= rows; i++) {
                        uvtData.push(uvtData.shift());
                        uvtData.push(uvtData.shift());
                    }
                }
                if (upspeed < 10 && upindex++ > upspeed) {
                    upindex = 0;
                    for (var i = 1; i < uvtData.length; i += 2) {
                        uvtData[i] += 1 / rows;
                        if (uvtData[i] > 1) 
                            uvtData[i] -= 1;
                    }
                }
            }

            function runspeed(value){
                leftspeed = 10 - value;
            }

            function runmax(value){
                backLayer.scaleX = value / 50;
                backLayer.scaleY = backLayer.scaleX;
            }
        </script>
        <div id="mylegend1" style="position:absolute;top:400px;width:400px;z-index:1;color: #ffffff;background-color:#000000;">
            旋转速度:<input type="number" max="10" min="0" value="10" onchange="runspeed(this.value);"/>
            <br/>
            伸缩:<input type="number" max="100" min="0" value="50" onchange="runmax(this.value);"/>%
        </div>
    </body>
</html>

五、文本

5.1 文本属性

创建的文本框对象不会自动加入可视化对象列表中,只有手动调用addChild()方法添加它才能显示。

<script type="text/javascript">
init(50,"mylegend",500,350,main);
function main(){  
   var layer = new LSprite();
   addChild(layer);
   var field = new LTextField();
   field.text = "Hello World!";
   layer.addChild(field);
}  
</script>

加一些改进:

<script type="text/javascript">
init(50,"mylegend",500,350,main);
function main(){  
   var layer = new LSprite();
   addChild(layer);
   var field = new LTextField();
   field.x = 50;
   field.y = 50;
   field.text = "Hello World!";
   field.size = 25;
   field.color = "#333333";
   field.weight = "bolder";
   layer.addChild(field);
}  
</script>

5.2 输入框

LTextField只要将文本的texttype属性设置为LTextFieldType.INPUT,就可以将文本变成输入框

<script type="text/javascript">
init(50,"mylegend",500,350,main);
function main(){  
   var layer = new LSprite();
   addChild(layer);
   var field = new LTextField();
   field.x = 50;
   field.y = 50;
   field.setType(LTextFieldType.INPUT);
   layer.addChild(field);
}  
</script>

六、事件

6.1 鼠标事件

鼠标事件分为鼠标按下、鼠标弹起和鼠标移动事件

<script type="text/javascript">
init(50,"mylegend",300,300,main);
var field;
function main(){  
   var layer = new LSprite();
   layer.graphics.drawRect(1,'#cccccc',[0,0,300,300],true,'#cccccc');
   addChild(layer);

    /*建立一个文本*/
   field = new LTextField();
   field.text = "Wait Click!";
   layer.addChild(field);
    /*给layer对象加载鼠标按下和鼠标弹起事件侦听*/
   layer.addEventListener(LMouseEvent.MOUSE_DOWN,downshow);
   layer.addEventListener(LMouseEvent.MOUSE_UP,upshow);
}  
/*侦听鼠标按下和弹起事件,当鼠标按下时...*/
function downshow(event){
    field.text = "Mouse Down!";
}
function upshow(event){
    field.text = "Mouse Up!";
}
</script>

注意:手机上用TOUCh_START等代替,但是这个库件会根据运行环境自动转换,所以不用自行切换。

6.2 循环事件

使用LRvent.ENTER_FRAMR来添加侦听循环事件

/*现象:屏幕上文本从开始不断自增*/
<script type="text/javascript">
init(50,"mylegend",300,300,main);
var field;
function main(){  
    var layer = new LSprite();
    layer.graphics.drawRect(1,'#cccccc',[0,0,300,300],true,'#cccccc');
    addChild(layer);

    field = new LTextField();
    field.text = "0";

    layer.addChild(field);
    /*给layer对象加载循环时间侦听*/
    layer.addEventListener(LEvent.ENTER_FRAME,onframe);
}  

/*回调函数*/
function onframe(){
    field.text = parseInt(field.text) + 1;
}
</script>

6.3 键盘事件

使用LKeyboardEvent.KEY_DOWN、LKeyboardEvent.KEY_up、LKeyboardEvent.KEY_PRESS来侦听键盘事件

由于键盘事件需要加载到window上,所以加载的时候与前面讲述的方法会稍微有些变化。

<script type="text/javascript">
init(50,"mylegend",300,300,main);
var field;
function main(){  
    var layer = new LSprite();
    layer.graphics.drawRect(1,'#cccccc',[0,0,300,300],true,'#cccccc');
    addChild(layer);
    field = new LTextField();
    field.text = "Wait Click!";
    layer.addChild(field);
    LEvent.addEventListener(LGlobal.window,LKeyboardEvent.KEY_DOWN,downshow);
    LEvent.addEventListener(LGlobal.window,LKeyboardEvent.KEY_UP,upshow);
}  
function downshow(event){
    field.text = event.keyCode + " Down!";
}
/*键盘按键的值*/
function upshow(event){
    field.text = event.keyCode + " Up!";
}
</script>

这里使用LEvent.addEventListener来加载键盘事件,其中LGlobal.window就是window对象,所以键盘事件就是加载到window对象上的,这样能侦听到整个浏览器窗口。

LEvent.addEventListener(LGlobal.window,LKeyboardEvent.KEY_DOWN,downshow);
LEvent.addEventListener(LGlobal.window,LKeyboardEvent.KEY_UP,upshow);

6.7 按钮

内置LButton类来添加按钮

LButton(DisplayObject_up,DisplayObject_over)

DisplayObject_up:按钮默认up状态,当鼠标不在按钮上,按钮就处于这个状态

DisplayObject_up:鼠标在按钮时的状态

传入按钮的这两个状态对象,可以是LSprite对象,也可以是LBitmap对象

<script type="text/javascript">
init(50,"mylegend",300,300,main);
var loader,bitmapup,bitmapover,field;  

/*读取两种图片,准备接下来当作按钮的两个状态*/
function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadUp);  
    loader.load("up.png","bitmapData");  
}  
function loadUp(event){  
    bitmapup = new LBitmap(new LBitmapData(loader.content));
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadOver);  
    loader.load("over.png","bitmapData");  
}


function loadOver(){  
    bitmapover = new LBitmap(new LBitmapData(loader.content));
    var layer = new LSprite();
    addChild(layer);
    field = new LTextField();
    field.text = "Wait Click!";
    layer.addChild(field);
    /*新建LButton按钮对象,并将bitmapup、bitmapover做为参数传给这个按钮*/
    var testButton = new LButton(bitmapup,bitmapover);
    testButton.y = 50;
    layer.addChild(testButton);

    /*LButton继承自类LSprite,所以由LSprite类的所有属性和方法,这样就可以给按钮添加鼠标点击事件了*/
    testButton.addEventListener(LMouseEvent.MOUSE_DOWN,downshow);
}  
function downshow(event){
    field.text = "testButton Click!";
}
</script>

八、动画

LAnimation(layer,data,list)

layer:LSprite对象
data:LBitmapData对象
list:一个存储坐标的二维数组

动画需要一个坐标的二维数组,也就是小图片的坐标,这里用LGlobal.dividiCooedinate函数来实现:

LGlobal.dividiCooedinate(width,height,row,col)

row:行数
col:列数

<script type="text/javascript">
var loader,anime,layer;  
init(200,"mylegend",500,350,main);
function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("chara.png","bitmapData");  
}  
function loadBitmapdata(event){  

    /*将读取完的Image保持到LBitmapData,显示范围为(0,0,64,64)*/
    var bitmapdata = new LBitmapData(loader.content,0,0,64,64);

    /*建一个保存有坐标位置的二维数组*/  
    var list = LGlobal.divideCoordinate(256,256,4,4);

     //加入层LSprite
    layer = new LSprite();
    addChild(layer);

    /*建一个LAnimation类,并将上面准备好的layer、bitmapdata、list作为参数传入LAnimation对象中*/
    anime = new LAnimation(layer,bitmapdata,list);

    /*给layer层添加循环事件侦听*/
    layer.addEventListener(LEvent.ENTER_FRAME,onframe);
}  

/*循环事件的回调函数调用LAnimation类的onframe函数,来实现动画的顺序循环播放*/
function onframe(){
    anime.onframe();
}
</script>

LAnimation类的onframe函数的功能是将所播放图片的列号加1,如果循环onframe函数,就变成动画了。但是目前只是实现了第一行图片的循环播放,如果实现所有图片的循环播放,则需要用LAnimation类的setAction函数。

setAction(rowIndex,colIndex)

rowIndex:数组行号
colIndex:数组列号

如果只需要改变播放的行号,那么第二个参数可省。

<script type="text/javascript">
var loader,anime,layer;  
init(200,"mylegend",500,350,main);
function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("chara.png","bitmapData");  
}  
function loadBitmapdata(event){  
    var bitmapdata = new LBitmapData(loader.content,0,0,64,64);  
    var list = LGlobal.divideCoordinate(256,256,4,4);
     //加入层LSprite
    layer = new LSprite();
    addChild(layer);
    anime = new LAnimation(layer,bitmapdata,list);
    layer.addEventListener(LEvent.ENTER_FRAME,onframe);
}  
function onframe(){
    /*使用LAnimation类的getAction函数取得anime对象当前所播放动画的行号列好,其返回值为数组类型[行号,列号]*/
    var action = anime.getAction();

    /*利用switch对当前所播放动画的行号进行了区别处理,[0,1,2,3]这4个行号分别代表下、左、右、上4个方向,然后再4个方向上改变坐标值进行相应的移动,并且根据所移动到达的位置来该百年移动的方向*/
    switch(action[0]){
        case 0:
            layer.y += 5;
            if(layer.y >= 200){
                anime.setAction(2);
            }
            break;
        case 1:
            layer.x -= 5;
            if(layer.x <= 0){
                anime.setAction(0);
            }
            break;
        case 2:
            layer.x += 5;
            if(layer.x >= 200){
                anime.setAction(3);
            }
            break;
        case 3:
            layer.y -= 5;
            if(layer.y <= 0){
                anime.setAction(1);
            }
            break;
    }

    /*循环事件的回调函数调用LAnimation类的onframe函数,来实现动画的肾虚循环播放*/
    anime.onframe();
}
</script>

九、致谢

本文内容是我对张路斌老师《HTML5 Canvas 游戏开发实战》第四章的学习总结,感谢张路斌老师,也感谢阅读本文的你给我的鼓励!

作为一个前端小白,如果学习笔记中有错误的地方,还请不吝指点,谢谢!