html5简单游戏编程从零开始

      本文基于lufylegend游戏引擎,所以以下内容全部和此有关,

      lufylegend引擎的下载地址: http://www.lufylegend.com/lufylegend

     既然是使用引擎,首先就要配置引擎的开发环境,lufylegend的使用极其方便,只需将lufylegend-x.x.x.min.js文件引入即可,默认将legend文件夹放入当前文件路径中,如下方所示,

     <!DOCTYPE html>  
    <html lang="en">  
    <head>  
    <meta charset="utf-8" />  
    <title>LTileMap</title>  
    <script type="text/javascript" src="lufylegend.js-lufylegend-1.9.7/lufylegend-1.9.7.min.js"></script>

    此时即可开始使用lufylegend开始我们的游戏之旅

   一、初始化引擎

   加载引擎后,就需要对环境初始化,lufylegend的初始化需要使用引擎中提供的函数init(30,"legend",500,400,main);

  第一个参数为刷新频率,也就是多久对屏幕刷新一次

  第二个参数为需要初始化的html中的div的id,这也是lufylegend的优点之一

  第三个参数为窗口的长

  第四个参数为窗口的宽

  第五个参数为初始化时调用的函数

  二、游戏的图层

既然是游戏,那么图层就必不可少,对于本次游戏来说会分成地图层,也就是载入地图的层次,人物层,也就是载入人物的图层,金币层,也就是载入掉落的金币的图层,游戏结束层,也就是游戏结束时所调用的图层,时间层,也就是载入倒数计时的图层,分数层,查看分数的图层,游戏结束图层,也就是游戏结束时调用的图层

总的来说本次游戏开发会分成地图层,人物图层,金币层,时间层,分数层,游戏结束层这6个图层,所以就需要先定义这6个图层,定义的代码如下

var backLayer,maplayer ,timelayer,playerlayer,moneylayer,pointlayer,gameoverLayer;

定义好之后就需要在main函数中于初始化过程中将图层全部载入,另外需要注意的是图层的顺序,地图层要在最下面,否则会遮住其他图层,而导致其他图层出现显示不出的情况,在lufylegend中是根据图层加入的顺序来决定谁在最下方,也就是先加入的就是最下面的图层,之后以此类推,所以init函数就需要这样定义

function gameinit(result){
        //移除loading
removeChild(loadingLayer);  
   //初始化分数
point=0;
imglist=result
       //加入backlayer背景层
        backLayer = new LSprite(); 
        addChild(backLayer);
      //加入地图层 
       maplayer= new LSprite();
       backLayer.addChild(maplayer);
      //加入timelayer时间层
       timelayer= new LTime(1);
  timelayer.x=340;
timelayer.y=0;
       backLayer.addChild(timelayer);

      //加入人物层
      playerlayer= new LSprite(); 
      backLayer.addChild(playerlayer);
     //加入金币层  
      moneylayer= new LSprite(); 
      backLayer.addChild(moneylayer);
    //加入分数层
      pointLayer= new LSprite(); 
      backLayer.addChild(pointLayer);
//加入游戏结束层
 gameoverLayer = new LSprite();  
      backLayer.addChild(gameoverLayer);
    //初始化游戏
      gamestart();
    } 

其中LSprite为lufylegend所提供的精灵类,此类可以实现载入图片,以及绘制各种图形,具体的参数可以参考API:http://lufylegend.com/api/zh_CN/out/index.html,而LTime则是由自己实现的LTime类作用是为了实现倒计时的运算和显示,具体的函数如下:

function LTime(min){
var s=this;
base(s,LSprite,[]);
s.x=1;
s.y=1;
s.time=min;
leftTime=s.time*60*1000;
time=new LTextField();
time.x=25;
time.y=10
time.size=15;
time.color="#ffD700";
s.onshow();
//s.onframe();
}

LTime为此类的构造函数,可以很清楚地看出此类继承自LSprite类,因此也具有精灵类的所有特性,在此基础上添加了一个用以显示倒计时的文字区域,x,y为文字起始位置的坐标,需要注意的是这里的x,y并不是针对整个游戏的坐标系来说的,而是针对所在类来看,如下图:


构造函数之后就是倒计时的实现了,大致上的实现是用类似UNIX时间戳的形式,需要注意的只有lefttime需要减去的值,正常情况下直接减去真实时间即可,但这样就和游戏的刷新率有冲突,会导致时间的跳动,所以在这里需要按照游戏的刷新率来减去时间,也就是说我们需要减去的时间为游戏的刷新率即init函数中的第一个参数,这样才能在每一次刷新时显示正确且连贯的时间

LTime.prototype.onframe=function(){
//var s=this;
        minutes=Math.floor(leftTime/1000/60);
second=Math.floor(leftTime/1000-60*minutes);
millsecond=Math.floor(leftTime-60*minutes*1000-1000*second);
mill=Math.floor(millsecond/10);
if(second<10){
second="0"+second;
    }
if(mill<10){

mill="0"+mill;
    }
time.text="Time:"+minutes+":"+second+":"+mill;
if(leftTime>0){
   leftTime -= 1000*60/(1000*60/30); 
}else{
return false;
}
    

}

在这之后就可以得到一个漂亮的倒计时显示了



三,绘制游戏

只是载入图层而不向图层中添加东西,获得的只会是一个空白的画面,所以在载入所需的图片和插入图层后就需要绘制游戏的画面,也就是需要向各个精灵类中添加载入的图片和绘制图形,下面就是绘制函数gamestart。

//开始绘制游戏界面
function gamestart(result){
//加入地图
var bitmapData=new LBitmapData(imglist['map']);
var bitmap=new LBitmap(bitmapData);
maplayer.addChild(bitmap);
//加入人物图片
anima=new LCharcter(imglist['cr']);
playerlayer.addChild(anima);
//timelayer.addChild(time);
//加入记分牌
pointtext=new LTextField();
pointtext.x=0;
pointtext.y=360;
pointtext.size=15;
       pointtext.color="#ffD700";
pointLayer.addChild(pointtext);
//加入动画和按键事件监听
backLayer.addEventListener(LEvent.ENTER_FRAME,onframe);
LEvent.addEventListener(LGlobal.window, LKeyboardEvent.KEY_DOWN,move); 
                LEvent.addEventListener(LGlobal.window, LKeyboardEvent.KEY_UP,stop);
}

在这里要说的是LCharcter类,这个类是自己实现的类,是为了实现人物的载入和移动,下面是主要函数的介绍,首先可以看出此类依然继承自LSprite类,接下来需要关注的就是lufylegend引擎提供的Lanimation类,这个类的主要作用是讲类似下图的图片依次载入,从而实现动画效果,在这里在入的图片就是8方向的人物行走图,通过动画类就可以实现人物的行走效果了,关于此类的应用也可以直接参照引擎的API


function LCharcter(imgdata){
var s=this;
base(s,LSprite,[]);
s.x=200;
s.y=100;
s.imgdata=imgdata;
var list=LGlobal.divideCoordinate(640,728,8,8);
bitmapData=new LBitmapData(s.imgdata);
s.width=bitmapData.width/8;
s.height=bitmapData.height/8;
player= new LAnimation(s,bitmapData,list);
        player.setAction(0,1,1,false);
s.addChild(player);
}

下为移动内的实现,需要注意的仅是在第一次按下方向键时才设置帧序列的位置,否则会不断设置序列,导致人物无法正确表现跑步动画,所以在这里使用了4个计数器,来记录按键次数,避免在第二次按下时仍然设置序列位置

LCharcter.prototype.move=function(moveto){
//仅设置一次action避免重复设置导致图形不断重置
  var s=this;
  if(moveto==40){
    if(down==0){
     player.setAction(0,1,1,false);
 down++;
}
 if(s.y<400-bitmapData.height){
       s.y=s.y+speed;
 }
  }else if(moveto==39){
  if(left==0){
     player.setAction(2,1,1,false);
 left++;
}   
 if(s.x<500-bitmapData.width){
       s.x=s.x+speed;
}
  }else if(moveto==38){
   if(up==0){
     player.setAction(3,1,1,false); 
 up++;
}   
  if(s.y>0){
       s.y=s.y-speed;
}
  }else if(moveto==37){
    if(right==0){
     player.setAction(1,1,1,false);
 right++;
}   
   if(s.x>0){
       s.x=s.x-speed;
}   
  }
  s.addEventListener(LEvent.ENTER_FRAME,s.onmove);
}

之后需要注意的就是碰撞检测的函数,函数目的就是为了检测是否与金币碰撞,从而计分的目的,在这里我仅使用了最简单的碰撞检测,也就是长方形的交错检测,长方形检测仅需要判断一下,两个长方形是否有交叠即可,交叠一般可以用4种情况来判断,在上方,在左方,在右方,在下方,下面有4个图可以表示这4中情况的碰撞





上面的图片显示的均是未碰撞的条件,所以反过来说也就是除了上述条件以外全都是发生了碰撞,所以碰撞函数的写法就可以确定了

LCharcter.prototype.CheckContact=function(money){
    var s=this;
//money在右侧
if((s.x>money.x)&&(money.x+money.width<s.x)){
return false;
    //money在左侧
}else if((s.x<money.x)&&(s.x+s.width<money.x)){

return false;
//money在下测
}else if((s.y<money.y)&&(s.y+s.height<money.y)){

return false;
//money在上测
}else if((s.y>money.y)&&(money.y+money.height<s.y)){
return false;
}else{
money.mode="die";
return true;
}
}

到这里基本需要使用的函数定义和画面的组成就介绍完毕了,下面需要考虑的就是游戏的运行

四,游戏的运行

游戏的运行需要基于刷新率来运行,也就是通过这个刷新率来实现游戏的动画效果,所以需要编写基于屏幕刷新事件而运行的函数,因为是基于事件运行的函数,所以就需要添加对屏幕刷新事件的监视器,添加方法:backLayer.addEventListener(LEvent.ENTER_FRAME,onframe);第一个参数为事件名,第二个参数是在事件发生时所调用的函数名,在这里的函数为onframe,可以看出在onframe函数中,需要对几个参数进行刷新,一个是分数,一个是倒计时的刷新,一个是对金币位置和数量的刷新,和对金币精灵死亡后将其移出画面,总共需要做这4个操作,所以onframe函数就需要这样写

function onframe(){

     //刷新分数
     pointtext.text="得分:"+point;   
if(startflag==true){
       var result=timelayer.onframe(); 

    //刷新金币
  addmoney();
       if(result==false){
          playerlayer.die();   
   //backLayer.die(); 
 gameover();
  }
  for(i=0;i<moneylayer.childList.length;i++){
//让金币动起来
moneylayer.childList[i].run();
if(anima.CheckContact(moneylayer.childList[i])==true){
point++;
}
if(moneylayer.childList[i].mode == "die"){ //当金币移出屏幕或是与人物碰撞时……
//移除该成员
moneylayer.removeChild(moneylayer.childList[i]);
totalmoney++;
}
  }
  
}
   }

这样一个简单的游戏就编写出来了,附上游戏画面:


源码地址:http://pan.baidu.com/s/1eQ6cbVO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值