Rumah > hujung hadapan web > Tutorial H5 > [HTML5游戏开发]挑战横版ACT(一):开天地黄忠初登场

[HTML5游戏开发]挑战横版ACT(一):开天地黄忠初登场

黄舟
Lepaskan: 2017-03-01 16:14:59
asal
1899 orang telah melayarinya

鄙人虽然不是专职的游戏开发者,但是自己也尝试着开发过各种各样类型的游戏,不过横版类游戏还没有尝试过,本次就使用lufylegend引擎来挑战一下横版ACT类游戏的开发,

大家可以到

http://lufylegend.com/lufylegend

下载lufylegend引擎的最新版本,

由于鄙人也是第一次开发此类游戏,所以有不妥的地方,欢迎大家回帖探讨和指正。

该系列文章目录(更新中)

(一):开天地黄忠初登场

http://www.php.cn/html5-tutorial-354344.html

(二):秀身手勇猛如当年

http://www.php.cn/html5-tutorial-354345.html

(三):遇红颜英雄亦多情

http://www.php.cn/html5-tutorial-354347.html

首先,素材问题,苦寻半个月,一直没找到满意的素材,不得已求助于黄忠黄老将军,黄老将军跟我说自从被马忠那个孙子暗算之后,已经有几百年没上战场了,一听说要上战场,立刻兴奋的不得了,直接就跳着《江南style》来了首《好汉歌》,那架势真有像是从梁山泊穿越而来的李逵,唱完后抄起家伙吼了声:“Go”,我也不敢怠慢,赶紧拿起电脑,准备起来。本次估且先拿黄老将军来挡一下,如果哪位朋友有好的素材,希望能提供一下,好让一把年纪的黄老将军休息一下。






由于黄老将军过于兴奋,只顾着一个劲儿的向前冲,所以只有向右的动作,没有向左的动作,为此我不得不使用lufylegend引擎中的LAnimation对象,因为LAnimation对象可以使用图片的镜像,来显示与上面的图片相反的动作。

考虑到战场上有各种各样的士兵武将,但是他们都属于人,有一些共通的属性,况且黄老将军过于兴奋,为了便于管理和操作,本次开发依然以OOP思想为基础(黄老将军听了后自言自语道,哦哦屁?),先来建一个人物的父类Character


1

2

3

function Character(dataList,coordinateList,locationList,speed){

    base(this,LSprite,[]);

};

Salin selepas log masuk

来看看这四个参数:

dataList:举个例子,看上面黄老将军的图片,有很多组动作,每组动作为一张图片,参数dataList就是这几组图片

coordinateList:LAnimation对象需要根据坐标来顺序显示图片,以形成动画,这个即使要传入LAnimation对象的坐标数组

locationList:考虑到人物的每个动作的图片的大小都不一样,位置也不一样,这个数组用来调整相对应动作组图片的显示位置

speed:方便控制人物动作在时间轴上每帧的频率

下面是Character类的完整构造器


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

function Character(dataList,coordinateList,locationList,speed){

    base(this,LSprite,[]);

    var self = this;

    //初始化

    //动作

    self.action = ACTION.STAND;

    //方向

    self.direction = DIRECTION.RIGHT;

    //保存参数

    self.coordinateList = coordinateList;

    self.locationList = locationList;

    self.dataList = dataList;

    self.speed = speed==null?1:speed;

    //保存初始化动作的图片

    self.data = dataList[ACTION.STAND];

    self.speedIndex = 0;

    //利用LAnimation对象来显示连贯的动作

    self.anime = new LAnimation(self,self.data,self.coordinateList[0]);

    self.anime.setAction(0);

    self.anime.x = -self.data.width*0.5;

    self.anime.y = -self.data.height;

};

Salin selepas log masuk

其中ACTION变量和DIRECTION变量为别如下


1

2

3

4

//动作

var ACTION = {STAND:0,MOVE:1,RUN:2,JUMP:3,ATTACK:4};

//方向

var DIRECTION = {RIGHT:"right",LEFT:"left"};

Salin selepas log masuk


下面详细介绍下LAnimation类,LAnimation类是通过顺序或倒序播放一组图片来形成动画,它的官方解释如下

LAnimation类 LAnimation(layer,data,list)


■作用:

实现简单动画的播放,原理是将一张大的图片,按照保存有坐标的二维数组保存的坐标来逐个显示。

■参数:

layer:LSprite显示层
data:LBitmapData对象
list:装有坐标的二维数组


上面的三个参数中,layer是一个LSprite对象,data是一个LBitmapData对象,这些都比较好理解,第三个参数list是一个二维数组,它的格式如下


1

2

3

4

5

[

[{x:0,y:0},{x:0,y:0},{x:0,y:0}],

[{x:0,y:0},{x:0,y:0},{x:0,y:0}],

[{x:0,y:0},{x:0,y:0},{x:0,y:0}]

]

Salin selepas log masuk

LAnimation对象的setAction函数,有四个参数,分别为

1

2

3

4

5

6

LAnimation.setAction(rowIndex,colIndex,mode,isMirror)

参数:

rowIndex:播放动画的行号

colIndex:播放动画的列号

mode:(1,0,-1)分别代表(正序播放,静止,倒序播放)

isMirror:Boolean型,当设定为true的时候,图片显示为水平翻转后的镜像

Salin selepas log masuk

当然,光有一个构造器是不行的,因为LAnimation对象是通过调用onframe函数来实现播放的,所以给Character类添加一个函数,如下


1

2

3

4

5

6

7

8

Character.prototype.onframe = function (){

    var self = this;

    //人物动作速度控制

    if(self.speedIndex++ < self.speed)return;

    self.speedIndex = 0;

    //人物动画播放

    self.anime.onframe();

};

Salin selepas log masuk

如此一来,只要不断的调用Character的实例的onframe函数,就能实现动态播放了。


黄老将军可能对比不感兴趣,此时已经在一旁打起了呼噜,我必须加快速度了......

考虑到战场上敌方和我方会有不同处理,建立一个继承自Character类的子类,如下


1

2

3

function Player(datalist,coordinateList,locationList,speed){

    base(this,Character,[datalist,coordinateList,locationList,speed]);

};

Salin selepas log masuk

因为想要实例化这个类,需要三个参数,我再新建一个对象来获取这三个参数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

var CharacterList = {

    huangzhong:function(){

        //图片数据

        var dataList = new Array();

        dataList.push(new LBitmapData(imglist["player_stand"],0,0,106,77));

        dataList.push(new LBitmapData(imglist["player_move"],0,0,115,85));

        dataList.push(new LBitmapData(imglist["player_run"],0,0,125,87));

        dataList.push(new LBitmapData(imglist["player_jump"],0,0,131,212));

        dataList.push(new LBitmapData(imglist["player_attack"],0,0,242,143));

        //图片分割数据

        var coordinateList = new Array();

        coordinateList.push(LGlobal.pideCoordinate(1272,77,1,12));

        coordinateList.push(LGlobal.pideCoordinate(920,85,1,8));

        coordinateList.push(LGlobal.pideCoordinate(750,87,1,6));

        coordinateList.push(LGlobal.pideCoordinate(786,212,1,6));

        var attackList = LGlobal.pideCoordinate(484,143,1,2);

        coordinateList.push([[attackList[0][0],attackList[0][1],attackList[0][1],attackList[0][1]]]);

        //图片位置数据

        var locationList = new Array();

        locationList.push({x:0,y:0});

        locationList.push({x:0,y:0});

        locationList.push({x:0,y:0});

        locationList.push({x:0,y:0});

        locationList.push({x:20,y:20});

        return [dataList,coordinateList,locationList];

    }

}

Salin selepas log masuk

所以我们要得到黄老将军的参数的话,就直接CharacterList.huangzhong()就可以了。

这时候,耳旁突然一声大吼,用什么拼音,要用English,怎么的也得叫Mr.Huang或者Huang Sir吧,由于英语太差,所以我假装没听到,继续写代码......
下面,开始就马上开始游戏初始化的工作。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

//初始化层

baseLayer = new LSprite();

addChild(baseLayer);

     

//背景层

backLayer = new LSprite();

backLayer.graphics.drawRect(1,"#000",[0,0,LGlobal.width,LGlobal.height],true,"#000");

baseLayer.addChild(backLayer);

     

//人物层

charaLayer = new LSprite();

baseLayer.addChild(charaLayer);

addHero();

 

//添加贞事件

baseLayer.addEventListener(LEvent.ENTER_FRAME,onframe);

Salin selepas log masuk

暂时没有准备背景图片,所以就画了一个黑色矩形当做背景了,下面看addHero函数和onframe函数

1

2

3

4

5

6

7

8

9

10

11

12

13

function addHero(){

    var heroData = CharacterList.huangzhong();

    hero = new Player(heroData[0],heroData[1],heroData[2]);

    hero.x = 200;

    hero.y = 200;

    charaLayer.addChild(hero);

}

function onframe(){

    var key = null;

    for(key in charaLayer.childList){

        charaLayer.childList[key].onframe();

    }

}

Salin selepas log masuk

运行代码,得到效果如下


话说,黄老将军正在呼呼地睡大觉,突然被我弄进了游戏里,并且四种漆黑一片,立刻就想到跑,但是由于我没有添加动作变换代码,它只能傻傻的站在那里,脑子里各种问号,为了不欺负人家,我必须赶紧写下去。

游戏中,有走,跑,跳,攻击等各种动作,咱们就用键盘的wsad来控制上下左右,j控制攻击,k控制跳,首先要添加键盘事件


1

2

3

//添加键盘事件

LEvent.addEventListener(LGlobal.window,LKeyboardEvent.KEY_DOWN,onkeydown);

LEvent.addEventListener(LGlobal.window,LKeyboardEvent.KEY_UP,onkeyup);

Salin selepas log masuk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

function onkeydown(e){

    if(keylock)return;

    switch(e.keyCode){

        case KEY.LEFT:

            hero.setAction(ACTION.MOVE,DIRECTION.LEFT);

            break;

        case KEY.RIGHT:

            hero.setAction(ACTION.MOVE,DIRECTION.RIGHT);

            break;

        case KEY.UP:

            hero.setAction(ACTION.MOVE,hero.direction);

            break;

        case KEY.DOWN:

            hero.setAction(ACTION.MOVE,hero.direction);

            break;

        case KEY.ATTACK:

            keylock = true;

            hero.setAction(ACTION.ATTACK,hero.direction);

            break;

        case KEY.JUMP:

            keylock = true;

            hero.setAction(ACTION.JUMP,hero.direction);

            break;

    }

}

function onkeyup(e){

    if(hero.action == ACTION.MOVE || hero.action == ACTION.RUN)hero.setAction(ACTION.STAND,hero.direction);

    keylock = false;

}

Salin selepas log masuk

hero是Player对象的一个实例,既然调用了Player对象的setAction函数,那就必须给Player对象添加这个函数,不过我依然将函数添加到它的父类Character里面

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

/**

 * 动作变换

 * @param action 动作

 * @param direction 方向

 */

Character.prototype.setAction = function (action,direction){

    var self = this;

    //动作和方向都没有改变,则不做变换

    if(self.action == action && self.direction == direction)return;

    //重新设定保存在LAnimation对象中的图片和坐标数组

    self.data = self.dataList[action];

    self.anime.bitmap.bitmapData = self.data;

    self.anime.bitmap.bitmapData.setCoordinate(0,0);

    self.anime.imageArray = self.coordinateList[action];

    self.action = action;

    self.direction = direction;

    //如果方向向左则必须使用镜像

    self.anime.setAction(0,0,null,self.direction == DIRECTION.LEFT);

    //调整位置

    self.setLocation();

    //如果被添加了事件,则将事件移除

    self.anime.removeEventListener(LEvent.COMPLETE,self.overAction);

    //除了走和跑,其他动作要保持连贯性,在一个动作结束之前,不能再次变换,所以添加动画播放结束事件,来控制keylock的值

    if(self.action != ACTION.MOVE && self.action != ACTION.RUN){

        self.anime.addEventListener(LEvent.COMPLETE,self.overAction);

    }

};

Character.prototype.setLocation = function (){

    var self = this;

    self.anime.x = self.locationList[self.action].x*(self.direction == DIRECTION.LEFT ? -1 : 1)-self.data.width*0.5;

    self.anime.y = self.locationList[self.action].y-self.data.height;

};

Character.prototype.overAction = function (anime){

    var self = anime.parent;

    self.anime.removeEventListener(LEvent.COMPLETE,self.overAction);

    self.setAction(ACTION.STAND,self.direction);

    keylock = false;

};

Salin selepas log masuk

也许是黄老将军太久没有上战场了,现在已经开始活蹦乱跳了


测试连接

http://lufy.netne.net/lufylegend-js/act/index.html



黄老将军虽然无比兴奋,但是很快就发现了不对劲儿,因为无论走,跳,向左,向右,他只能在同一个地方折腾,急得他满头大汗,于是我在他回头看我之前,我就先闪人了,身后传来黄老将军的一声怒吼:“我X”。

本次丫丫就到这里了,要想知道黄老将军在战场上究竟做了什么,请听下回分析。

本次源码下载

http://fsanguo.comoj.com/download.php?i=act01.rar

 以上就是[HTML5游戏开发]挑战横版ACT(一):开天地黄忠初登场的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Label berkaitan:
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan