“是男人就下一百层”h5游戏全网最详细教学、全代码,js操作

博主的话

	这里博主将展示此游戏的html和js部分的代码,主要是对这些代码的讲解,教大家如何编写这样一个简单的
h5小游戏。希望大家在认真看完博主的文章后,不但能编写“是男人就下一百层”,还可以发散思维,编写更多有
趣的小游戏。
	如果想要跑程序的话,还需要css代码和图片资源;在js里面还用到了jq和lufylegend框架,这是开源的,
大家可以到网上下载。

对于要css代码和img资源的,下载地址:
https://download.csdn.net/download/qq_43592352/12368545

游戏展示

看图说话
游戏初始界面:在这里插入图片描述
游戏开始:
在这里插入图片描述

编程工具介绍

1’ Google浏览器。
	我是在Google上跑的游戏,如果大家拿我的文件参照的话,尽量用Google。我做的时候没有考虑兼容性
	,觉得一个小游戏,没必要。
2’VS Code。
	这个没什么要求的,我用的是VS Code,只要可以编html、css、js,什么都可以,个人喜好。
3’JQuery和lufylegend插件。
	简单的说,它们两个也是js文件。只是被封装起来,方便各种功能的调用。
	用的话<script src="js/lufylegend-1.10.1.min.js"></script>
    	  <script src="js/jquery-3.3.1.js"></script>
    直接在相关的文件里引用就可以了。
4’JQuery介绍
	jq简单来说就是对原生js的简化,使js的使用更加方便快捷。
5’lufylegend介绍
	lufylegend是一种游戏开发引擎,它是通过html的canvas标签来操作的。里面有一些方法很好用,但是,
它的排版和监听和js一比实在是太麻烦,于是我就抛弃了lufylegend。我的js代码只用了lufylegend一点点的
游戏动作封装的函数。
	而且,用lufylegend只是身边正好有一本它的书。个人觉得lufylegend不是最好的游戏引擎。大家对游戏
感兴趣的话,不妨去网上找一些更大众的开源引擎。

游戏代码

<html>
        <link rel="stylesheet" type="text/css" href="css/index.css"/>
        <script src="js/lufylegend-1.10.1.min.js"></script>
        <script src="js/jquery-3.3.1.js"></script>
<body>
<div id="container">
    <div id="game">
        <audio id="player" src=""></audio>
        <div id="info">
            <div id="info_life"></div>
            <div id="info_score">
                <div class="info_score_num"><img src="css/img/0.png"></div>
                <div class="info_score_num"><img src="css/img/0.png"></div>
                <div class="info_score_num"><img src="css/img/0.png"></div>
                <div class="info_score_num"><img src="css/img/0.png"></div>
            </div>
        </div>
        <div id="main">
            <div id="menu">
                <div id="menu_title"><text>是男人就下100</text></div>
                <div id="menu_hero">
                    <div id="menu_hero1"><img src="css/img/left.png"/></div>
                    <div id="menu_hero2"></div>
                    <div id="menu_hero3"><img src="css/img/right.png"/></div>
                </div>
                <div id="menu_button">
                    <button id="menu_button1">开始游戏</button><br/>
                    <button id="menu_button2">排行榜</button>
                </div>
            </div>
            <div id="gamemain">
                
                <div id="hero"></div>
                <div id="game_bg2"><img src="css/img/game_bg2.png"></div>
            </div>
            <div id="ranking">
                <text>排行榜</text>
                <div id="rank_table">
                    <dl>
                        <dt>排名</dt>
                        <dd>1</dd>
                        <dd>2</dd>
                        <dd>3</dd>
                        <dd>4</dd>
                        <dd>5</dd>
                    </dl>
                    <dl>
                        <dt>英雄大名</dt>
                        <dd></dd>
                        <dd></dd>
                        <dd></dd>
                        <dd></dd>
                        <dd></dd>
                    </dl>
                    <dl>
                        <dt>层数</dt>
                        <dd></dd>
                        <dd></dd>
                        <dd></dd>
                        <dd></dd>
                        <dd></dd>
                    </dl>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script>
    /**************************便捷函数**************************************/
    function getRandom(min,max){//获取在区间[min.max]内的int数
        var s;
        s=parseInt(Math.random()*max+1);
        while(s<min)
        {
        s=parseInt(Math.random()*max+1);
        }
        return s;
    }
    function onIt(hx,hy,fx,fy){
        if(hx<=fx+60&&hx>=fx-32&&hy>=fy-32&&hy<=fy-31)
            return 1;
        else 
            return 0;
    }
    var shansuoTimes=0;
    function shansuo(){//闪烁3次
        shansuoTimes++;
        $('#hero').fadeTo(200,0.1);
        $('#hero').fadeTo(200,1);
        if(shansuoTimes<=3) 
        setTimeout("shansuo()",400);
        else
            shansuoTimes=0;
      }
      function sleep(ms){//时间延迟函数
          return new Promise(resolve =>setTimeout(resolve,ms))
      }
      async function test() {
        console.log('Hello')
        await sleep(1000)
        console.log('world!')
        }
        test();
    /**************************基础页面操作设置**************************************/
    var hero_href=new Array(),hero_href_key=1;
    for(var i=1;i<=15;i++){
        hero_href[i]="css/hero/"+i+".png";
    }
    //js改变网页页面大小
    document.body.style.zoom=.8;
    //控制menu、gamemain、ranking的显示
    $("#menu_button1").click(function(){
        $("#menu").css('display','none');
        $("#gamemain").css('display','block');
        $("#ranking").css('display','none');
        heroDie();
        init(0,"hero",32,32,main);
        check();
        heroDown();
        myfloor();
        displayScore();
        displayLife();
    })
    $("#menu_button2").click(function(){
        $("#menu").css('display','none');
        $("#gamemain").css('display','none');
        $("#ranking").css('display','block');
    })
    //控制英雄的切换
    $("#menu_hero1 img").click(function(){
        if(hero_href_key>1) hero_href_key--;
        heroDie();
        main();
    })
    $("#menu_hero3 img").click(function(){
        if(hero_href_key<15) hero_href_key++;
        heroDie();
        main();
    })
   //分数显示
    var score_pic=new Array('css/img/0.png','css/img/1.png','css/img/2.png','css/img/3.png','css/img/4.png','css/img/5.png','css/img/6.png','css/img/7.png','css/img/8.png','css/img/9.png',);
    var score=0;
    function displayScore(){
        var s=score;
        var score0=s%10;
        var score1=parseInt(s/10)%10;
        var score2=parseInt(s/100)%10;
        var score3=parseInt(s/1000);
        $(".info_score_num img").eq(3).attr('src',score_pic[score0]);
        $(".info_score_num img").eq(2).attr('src',score_pic[score1]);
        $(".info_score_num img").eq(1).attr('src',score_pic[score2]);
        $(".info_score_num img").eq(0).attr('src',score_pic[score3]);
        setTimeout('displayScore()',50);
    }
    //生命条显示
    var deadflag=false;
    function displayLife(){
        isdie();
        $("#info_life").css('width',nowHP*8+'px');
        if(nowHP<=4&&nowHP>0) $("#info_life").css('background','red');
        if(nowHP==0&&deadflag==false) {playMusic(1);deadflag=true;}
        setTimeout('displayLife()',50);
    }
    function playMusic(i) {
        var player = $("#player")[0];
        if(i==1)
        {
            player.src='css/sound/dead.mp3';
            player.play();
        }
            
        
    }

    /**************************游戏设置**************************************/
    /***lufylegend框架封装英雄类*****/
    var loader,anime,layer;
    init(50,"menu_hero2",32,32,main);
    function main(){
        loader=new LLoader();
        loader.addEventListener(LEvent.COMPLETE,loadBItmapdata);
        loader.load(hero_href[hero_href_key],"bitmapData");
    }
    function loadBItmapdata(event){
        var bitmapdata=new LBitmapData(loader.content,0,0,64,64);
        var list=LGlobal.divideCoordinate(128,128,4,4);
        layer=new LSprite();
        addChild(layer);
        anime=new LAnimation(layer,bitmapdata,list);
        layer.addEventListener(LEvent.ENTER_FRAME,onframe);
    }
    function onframe(){
        $(document).keydown(function(event){
        if(event.which==39){
            anime.setAction(2);
        }
        else if(event.which==37){
            anime.setAction(1);
        }
        });
        $(document).keyup(function(event){
            anime.setAction(0);
        });
        anime.onframe();
    }
    function heroDie(){
        layer.die();
        layer.removeAllChild();
    }
    /***封装游戏背景类*****/
    var bgHeight=0;
    function background(){
        bgHeight+=2;
        $("#gamemain").css('background','url("css/img/gamemain_bg.png") 0px '+bgHeight+'px');
        if(bgHeight>=550) bgHeight=0;//防止bgHeight过大
        setTimeout('background()',50);
    }
    background();
    /*********封装地板****************/
    function floor(){
        var that=this;
        var img=$(new Image());
        var floorx=Math.random()*370;
        var floory=530;
        this.createFloor1=function(){//地板1类
            img.attr({
                'src':'css/img/floor1.png',
                'class':'floor',
                'relative':0,
                'type':1
            });
            img.css({
                'margin-left':floorx+'px',
                'margin-top':floory+'px',
            });
            
            $("#gamemain").append(img);
            this.run();
        }
        this.createFloor2=function(){//地板2类
            img.attr({
                'src':'css/img/floor2.png',
                'class':'floor',
                'relative':10,
                'type':1
            });
            img.css({
                'margin-left':floorx+'px',
                'margin-top':floory+'px',
            });
            
            $("#gamemain").append(img);
            this.run();
        }
        this.createFloor3=function(){//地板3类
            img.attr({
                'src':'css/img/floor3.png',
                'class':'floor',
                'relative':0,
                'type':1
            });
            img.css({
                'margin-left':floorx+'px',
                'margin-top':floory+'px',
            });
            
            $("#gamemain").append(img);
            this.run();
        }
        this.createFloor4=function(){//地板4类 会消失的地板
            img.attr({
                'src':'css/img/floor4in1.png',
                'class':'floor',
                'relative':0,
                'type':2
            });
            img.css({
                'margin-left':floorx+'px',
                'margin-top':floory+'px',
            });
            
            $("#gamemain").append(img);
            this.run();
        }
        this.createFloor5=function(){//地板5类 会滚动的地板
            img.attr({
                'src':'css/img/floor5.gif',
                'id':'floor5',
                'class':'floor',
                'relative':0,
                'type':3
            });
            img.css({
                'margin-left':floorx+'px',
                'margin-top':floory+'px',
            });
            
            $("#gamemain").append(img);
            this.run();
        }
        this.run=function(){
            if(floory>=-20)
            {
                floory-=2;
                img.css('margin-top',floory+'px');
                setTimeout(that.run,20);
            }
            else
            {
                img.css('display','none');
                img.remove();
                score++;
            }
        }
    }
    async function changefloor4($ppp) {//地板4类消失函数
        $ppp.attr('src','css/img/floor4in2.png')
        await sleep(300)
        $ppp.attr("src","css/img/floor4in3.png")
        await sleep(300)
        $ppp.css('display','none');
        $ppp.remove();
        score++;
        ontheFloor=false;heroDown();clearTimeout(up);
        }

    async function floor5Move1(fx){//地板5类左移英雄
        while(position[0]+20>fx){
        $('#hero').css('margin-left',position[0]+'px');
        position[0]-=2;
        await sleep(40);
        }
        ontheFloor=false;heroDown();clearTimeout(up);
    }

function myfloor(){//创建地板
    var ppp=new floor();
    if(getRandom(1,5)==1) ppp.createFloor1();
    else if(getRandom(1,5)==2) ppp.createFloor2();
    else if(getRandom(1,5)==3) ppp.createFloor3();
    else if(getRandom(1,5)==4) ppp.createFloor4();
    else if(getRandom(1,5)==5) ppp.createFloor5();
    setTimeout('myfloor()',500);
}


/*********封装英雄(未封装原因:lufylegend插件已经生成了英雄)****************/
    var position=new Array(0,10);//全局变量,hero的位置坐标
    var maxHP=12,nowHP=12;//全局变量,最大HP,现在HP
    var ontheFloor=false;//全局变量,是否在地板上
    var gspeed=2;//全局变量,英雄下落速度,可随游戏时间增加
    $(document).keydown(function(event){//对英雄移动的键盘操作
            if(event.which==37){
                ((position[0]-3)<0)?position[0]=0:position[0]-=3;
                $("#hero").css('margin-left',position[0]+'px');
            }
            else if(event.which==39){
                ((position[0]+3)>398)?position[0]=398:position[0]+=3;
                $("#hero").css('margin-left',position[0]+'px');
            }

    });
    var down,up,move;
    function heroDown(){//英雄自由下落
        position[1]+=gspeed;
        $("#hero").css('margin-top',position[1]+'px');
        down=setTimeout("heroDown()",20);
    }
    function heroUp(){//英雄随地板上升,此函数与floor类的run函数数值同步
        position[1]-=2;
        $("#hero").css('margin-top',position[1]+'px');
        up=setTimeout("heroUp()",20);
    }
    function isdie(){//对英雄向上触碰、向下掉底直接死亡,设置nowHP=0,然后交给‘生命条显示’函数来做英雄死亡后的事件
        var y=parseInt($("#hero").css('margin-top'));
        if(y>=520||y<=9) nowHP=0;
        
    }
 
/************************对是否落到地板上进行判断、处理****************************/
    var StandX;
    function check(){
        var allfloor=$(".floor");
        var n=allfloor.length;
        for(var i=0;i<=n;i++){
            var fx=parseInt(allfloor.eq(i).css("margin-left"));
            var fy=parseInt(allfloor.eq(i).css("margin-top"));
            var relativey=parseInt(allfloor.eq(i).attr("relative"));//将木板的relative值转化为int型
            var type=parseInt(allfloor.eq(i).attr("type"));//将木板的type值转化为int型
            var hx=position[0],hy=position[1];
            if(onIt(hx,hy,fx,fy)&&(ontheFloor==false))
                {
                    ontheFloor=true;
                    clearTimeout(down);
                    position[1]+=relativey;//每个地板加了一个属性relative,是人物相对于木板的距离,方便带刺木板人物位置摆放
                    if(relativey==10) {nowHP--;shansuo();}
                    if(type==2){
                        changefloor4(allfloor.eq(i));
                    }
                    else if(type==3){
                            floor5Move1(fx);
                    }
                    heroUp();
                    StandX=fx;
                }
            if((hx<StandX-32||hx>StandX+60)&&(ontheFloor==true))
                {ontheFloor=false;heroDown();clearTimeout(up);}

        }
        setTimeout("check()",.5);
    }
    /************************对排行榜相关数据处理****************************/
    /*var fso=new XMLHttpRequest(Scripting.FileSystemObject);
    var f=fso.createtextfile("data.txt",2,true);
    f.writeLine("wo shi di yi hang"); */

    
</script>
</html>

代码讲解

我尽量把讲解的重心放在游戏编程思想和js上面。

首先是html的节点结构。无论是编游戏,还是编网页,编程之前做好html节点的树结构是十分重要的事情。

如图:
在这里插入图片描述
dom结构大概是这样,方便大家搞清关系。

container

这是一个容器div,背景是截图中的那张山水图片。然后我把这个div居中,其他元素都写在container里面。

game

这也是一个容器div,背景如下:
在这里插入图片描述
让game居container的中。

info

这里面会显示生命条和分数。

main

main里面有三个div,这才是核心部分。第一个div是菜单,第二个是游戏主页,第三个是排行榜。

其次是js代码的编写,这是核心。

我们把main的宽高限制在#game(以后的div用#id替代)背景的第三个白色透明框。同样的,#menu,#gamemain,#ranking的宽高也是。

js 第一步 切换div的显示与隐藏

当我们刚开始打开游戏,出现的应该是菜单页面,在点击“开始游戏”“排行榜”之后,会切换到相应的div。即显示相应的div,隐藏其他的div。

//控制menu、gamemain、ranking的显示
    $("#menu_button1").click(function(){
        $("#menu").css('display','none');
        $("#gamemain").css('display','block');
        $("#ranking").css('display','none');
    })
    $("#menu_button2").click(function(){
        $("#menu").css('display','none');
        $("#gamemain").css('display','none');
        $("#ranking").css('display','block');
    })

对相应的按钮点击后,对不同的div进行显示和隐藏。

js 第二步 在菜单页面用lufylegend插件封装英雄

/***lufylegend框架封装英雄类*****/
    var loader,anime,layer;
    init(50,"menu_hero2",32,32,main);
    function main(){
        loader=new LLoader();
        loader.addEventListener(LEvent.COMPLETE,loadBItmapdata);
        loader.load(hero_href[hero_href_key],"bitmapData");
    }
    function loadBItmapdata(event){
        var bitmapdata=new LBitmapData(loader.content,0,0,64,64);
        var list=LGlobal.divideCoordinate(128,128,4,4);
        layer=new LSprite();
        addChild(layer);
        anime=new LAnimation(layer,bitmapdata,list);
        layer.addEventListener(LEvent.ENTER_FRAME,onframe);
    }
    function onframe(){
        $(document).keydown(function(event){
        if(event.which==39){
            anime.setAction(2);
        }
        else if(event.which==37){
            anime.setAction(1);
        }
        });
        $(document).keyup(function(event){
            anime.setAction(0);
        });
        anime.onframe();
    }
    function heroDie(){
        layer.die();
        layer.removeAllChild();
    }

这里值得注意的是:

init(50,"menu_hero2",32,32,main);

此init()方法表示在#menu_hero2为id的div里面建立一个宽高都为32px的canvas标签,整体速度是50ms一次,回调函数是main()。【建议大家去看一下lufylegend的官方API】

在main()函数中有如下代码:

loader.load(hero_href[hero_href_key],"bitmapData");

【划重点!!!】
这里hero_href[hero_href_key]是一个存放我本地英雄图片url的数组。

在main()函数中又调用了loadBItmapdata()函数。loadBItmapdata()函数里有如下代码:

javascriptvar list=LGlobal.divideCoordinate(128,128,4,4);

【划重点!!!】
这是对图片进行分割。长宽都为128px的图片,进行4x4的分割。如下图。这种RPG小游戏的人物图片都是这样的,经过插件封装后会自动循环播放(这里播放速度就和init()函数里面的参数有关啦)。
如果自己用js代码写的话,不一定可以写出来,而且也没有人家的好。
在这里插入图片描述

好了,到这里,lufylegend的使命已经结束了,接下来都是js的功劳了。

js 第三步 在菜单页面实现挑选英雄

带大家理清思路。我们要实现的是#menu、#gamemain、#ranking三部分。现在我们已经把#gamemain、
#ranking的display设置为none了,它们消失了,只有#menu存在,所以我们专心做菜单的业务。

大家回到最上方看一下我菜单的样式,css我就不再说了,很简单的。在英雄两边设置了两个按钮来改变英雄的样式。
这个要怎么实现呢?

var hero_href=new Array(),hero_href_key=1;
    for(var i=1;i<=15;i++){
        hero_href[i]="css/hero/"+i+".png";
    }
     //控制英雄的切换
    $("#menu_hero1 img").click(function(){
        if(hero_href_key>1) hero_href_key--;
        heroDie();
        main();
    })
    $("#menu_hero3 img").click(function(){
        if(hero_href_key<15) hero_href_key++;
        heroDie();
        main();
    })

1’定义一个数组hero_href[]用来存放"css/hero/1.png",“css/hero/2.png”……这样的字符,注意我这里的字符就是我用js访问图片的路径,大家要设置好。
2’定义一个hero_href_key。当点击按钮的时候,hero_href_key会加一或者减一。
3’调用heroDie()函数把页面清空,然后再重新调用main(),但是此时的图片url已经改变,所以英雄会相应改变。

js 第四步 在游戏页面生成英雄

这时候菜单页面已经做完了,我们把#menu的display设为none,#gamemain的display设为block。方便调试,
不然每次都要点击一下“开始游戏”按钮。接下来,我们开始做游戏模块!

同样的,在点击“开始游戏”按钮后,插件会清除画布,并在#hero里面生成英雄。这时,init()的参数速度不能为>0,因为多次调用init,它的速度参数会叠加。

//控制menu、gamemain、ranking的显示
 $("#menu_button1").click(function(){
     $("#menu").css('display','none');
     $("#gamemain").css('display','block');
     $("#ranking").css('display','none');
     heroDie();
     init(0,"hero",32,32,main);
 })

定义全局变量,position[0]为英雄的x,position[1]为英雄的y;
监听键盘的左键和右键控制英雄左右移动,并且不可以移出#gamemain之外。

var position=new Array(0,10);//全局变量,hero的位置坐标
$(document).keydown(function(event){//对英雄移动的键盘操作
         if(event.which==37){
             ((position[0]-3)<0)?position[0]=0:position[0]-=3;
             $("#hero").css('margin-left',position[0]+'px');
         }
         else if(event.which==39){
             ((position[0]+3)>398)?position[0]=398:position[0]+=3;
             $("#hero").css('margin-left',position[0]+'px');
         }

 });

js 第五步 在游戏页面制作滚动的背景

/***封装游戏背景类*****/
 var bgHeight=0;
 function background(){
     bgHeight+=2;
     $("#gamemain").css('background','url("css/img/gamemain_bg.png") 0px '+bgHeight+'px');
     if(bgHeight>=550) bgHeight=0;//防止bgHeight过大
     setTimeout('background()',50);
 }
 background();

这里的技巧主要在css的background上,大家不妨去查一下background的参数。首先,我设置background是可以repeat的(没写默认可以),然后再定义y方向上的偏移量。最后每50ms执行一次其y上的偏移量加2。【值得注意的是,虽然背景图片是一张,但是拼接起来要看不出来分界线才行,要不然滚动也没意义】

js 第六步 在游戏页面添加地板!

/*********封装地板****************/
 function floor(){
     var that=this;
     var img=$(new Image());
     var floorx=Math.random()*370;
     var floory=530;
     this.createFloor1=function(){//地板1类
         img.attr({
             'src':'css/img/floor1.png',
             'class':'floor',
             'relative':0,
             'type':1
         });
         img.css({
             'margin-left':floorx+'px',
             'margin-top':floory+'px',
         });
         
         $("#gamemain").append(img);
         this.run();
     }
     this.createFloor2=function(){//地板2类
         img.attr({
             'src':'css/img/floor2.png',
             'class':'floor',
             'relative':10,
             'type':1
         });
         img.css({
             'margin-left':floorx+'px',
             'margin-top':floory+'px',
         });
         
         $("#gamemain").append(img);
         this.run();
     }
     this.createFloor3=function(){//地板3类
         img.attr({
             'src':'css/img/floor3.png',
             'class':'floor',
             'relative':0,
             'type':1
         });
         img.css({
             'margin-left':floorx+'px',
             'margin-top':floory+'px',
         });
         
         $("#gamemain").append(img);
         this.run();
     }
     this.createFloor4=function(){//地板4类 会消失的地板
         img.attr({
             'src':'css/img/floor4in1.png',
             'class':'floor',
             'relative':0,
             'type':2
         });
         img.css({
             'margin-left':floorx+'px',
             'margin-top':floory+'px',
         });
         
         $("#gamemain").append(img);
         this.run();
     }
     this.createFloor5=function(){//地板5类 会滚动的地板
         img.attr({
             'src':'css/img/floor5.gif',
             'id':'floor5',
             'class':'floor',
             'relative':0,
             'type':3
         });
         img.css({
             'margin-left':floorx+'px',
             'margin-top':floory+'px',
         });
         
         $("#gamemain").append(img);
         this.run();
     }
     this.run=function(){
         if(floory>=-20)
         {
             floory-=2;
             img.css('margin-top',floory+'px');
             setTimeout(that.run,20);
         }
         else
         {
             img.css('display','none');
             img.remove();
             score++;
         }
     }
 }

首先,我们来封装个地板类。我们把地板的x坐标设为随机,y坐标固定在底部。
然后,不同的createfloor函数,它们的url不同(即图片的样式,是地板还是尖刺还是弹簧……),relative不同(针对尖刺地板,假设图片高是20px,对于一般木板,英雄可以直接站上去,但是带刺的木板,英雄要踩刺,得再往下站一些,所以定义relative相当于木板和英雄的相对距离),type不同(不同类型木板,英雄站上去之后有不同的函数去执行)。
最后,我们让每一个createfloor函数都去执行run函数,来控制木板上升,当木板上升到最上方时,把木板删去,分数+1。

function myfloor(){//创建地板
    var ppp=new floor();
    if(getRandom(1,5)==1) ppp.createFloor1();
    else if(getRandom(1,5)==2) ppp.createFloor2();
    else if(getRandom(1,5)==3) ppp.createFloor3();
    else if(getRandom(1,5)==4) ppp.createFloor4();
    else if(getRandom(1,5)==5) ppp.createFloor5();
    setTimeout('myfloor()',500);
}

每隔0.5秒随机创建五种木板里的一种出来。

js 第七步 定义英雄上升、下降、死亡函数

首先这里面的数值不是随便设置的,不然没有游戏体验的。
封装出英雄上升,下降,死亡函数。
在踩到地板时上升;脚下没有地板时下降,碰到上方的刺或者掉落判断死亡。

var down,up,move;
   function heroDown(){//英雄自由下落
       position[1]+=gspeed;
       $("#hero").css('margin-top',position[1]+'px');
       down=setTimeout("heroDown()",20);
   }
   function heroUp(){//英雄随地板上升,此函数与floor类的run函数数值同步
       position[1]-=2;
       $("#hero").css('margin-top',position[1]+'px');
       up=setTimeout("heroUp()",20);
   }
   function isdie(){//对英雄向上触碰、向下掉底直接死亡,设置nowHP=0,然后交给‘生命条显示’函数来做英雄死亡后的事件
       var y=parseInt($("#hero").css('margin-top'));
       if(y>=520||y<=9) nowHP=0;
       
   }

js 第八步 英雄与地板开始作用

var StandX;
 function check(){
     var allfloor=$(".floor");
     var n=allfloor.length;
     for(var i=0;i<=n;i++){
         var fx=parseInt(allfloor.eq(i).css("margin-left"));
         var fy=parseInt(allfloor.eq(i).css("margin-top"));
         var relativey=parseInt(allfloor.eq(i).attr("relative"));//将木板的relative值转化为int型
         var type=parseInt(allfloor.eq(i).attr("type"));//将木板的type值转化为int型
         var hx=position[0],hy=position[1];
         if(onIt(hx,hy,fx,fy)&&(ontheFloor==false))
             {
                 ontheFloor=true;
                 clearTimeout(down);
                 position[1]+=relativey;//每个地板加了一个属性relative,是人物相对于木板的距离,方便带刺木板人物位置摆放
                 if(relativey==10) {nowHP--;shansuo();}
                 if(type==2){
                     changefloor4(allfloor.eq(i));
                 }
                 else if(type==3){
                         floor5Move1(fx);
                 }
                 heroUp();
                 StandX=fx;
             }
         if((hx<StandX-32||hx>StandX+60)&&(ontheFloor==true))
             {ontheFloor=false;heroDown();clearTimeout(up);}

     }
     setTimeout("check()",.5);
 }

这算是核心代码了。
解释如下:

1,定义一个check函数,每0.5ms执行一次,一秒2000次。
2,每次都干什么事情呢?
   每次都获取当前页面存在的地板对象,放在一个数组里面。然后用for循环遍历(暴力方式,所以是小游戏,大游戏
   得考虑算法和数据结构优化的)每个对象是不是碰到英雄了,并且ontheFloor这个flag也很重要。
   onIt(hx,hy,fx,fy)函数是我刚开始封装的,判断英雄有没有站在地板上。
3,如果在地板上了,调用heroup函数,控制英雄与地板同步上升。之后开始判断是哪个地板。如果relative==10(带
	刺木板),那么英雄life-1,并且闪烁三次,并且再向下移动10px才行。如果是type==2(会消失的地板),那
	么英雄站上去之后,每隔300ms此地板换一个样式,三次之后木板消失,英雄继续下落。如果是type==3(水平传
	送带),那么……
4,如果英雄脚下没有地板了,那么停止heroup函数,执行herodown。

js 第九步 添加生命条、分数、声音显示

//分数显示
 var score_pic=new Array('css/img/0.png','css/img/1.png','css/img/2.png','css/img/3.png','css/img/4.png','css/img/5.png','css/img/6.png','css/img/7.png','css/img/8.png','css/img/9.png',);
 var score=0;
 function displayScore(){
     var s=score;
     var score0=s%10;
     var score1=parseInt(s/10)%10;
     var score2=parseInt(s/100)%10;
     var score3=parseInt(s/1000);
     $(".info_score_num img").eq(3).attr('src',score_pic[score0]);
     $(".info_score_num img").eq(2).attr('src',score_pic[score1]);
     $(".info_score_num img").eq(1).attr('src',score_pic[score2]);
     $(".info_score_num img").eq(0).attr('src',score_pic[score3]);
     setTimeout('displayScore()',50);
 }
 //生命条显示
 var deadflag=false;
 function displayLife(){
     isdie();
     $("#info_life").css('width',nowHP*8+'px');
     if(nowHP<=4&&nowHP>0) $("#info_life").css('background','red');
     if(nowHP==0&&deadflag==false) {playMusic(1);deadflag=true;}
     setTimeout('displayLife()',50);
 }
 function playMusic(i) {
     var player = $("#player")[0];
     if(i==1)
     {
         player.src='css/sound/dead.mp3';
         player.play();
     }
         
     
 }

分数显示:
我的分数是用图片显示的。就是获取score后,得到个、十、百、千位的值,然后对应我的数字(艺术字样式)的图片显示出来。和之前英雄的显示类似。
生命条显示:
我把生命分成12份,每少1,生命条的宽度小8.3%,当nowHP小于4,设置生命条颜色为红色。
声音:
当nowHP为0,执行声音函数,播放死亡的音效。

js 第十步 排行榜

排行榜,我有三种方法去实现。但是我这个游戏也不是多人玩的,不想做排行榜。

方法介绍给大家:
1,运用php+mysql。
用php写好之后,把获取的值转递给页面,页面来显示。
但是,php文件必须在xampp目录下才可以运行,意味着,我要把html、js文件都移过去。麻烦。
2,运用txt文本。
大家学c的时候,一定操作过用c来对txt流进行读和写吧。
就是这种思想。
第一,每次游戏结束后,你要对玩家的姓名和分数进行写入。
第二,每次打开排行榜,你要读取txt文本,获取值。因为txt文本的特性,所以读取之后你要进行数据提取稍微麻烦一点点(相信大家领会我的意思)。
3,用js/json文件,存数据。
但是好像只能读不能写。

进行下一个游戏的开发!

飞机大战h5小游戏开发
指尖大冒险、跳一跳升级版html5游戏全代码

总结

虽然引用了一些框架,但是都是浅尝辄止。而且对英雄和地板的判断那一块,都是靠for循环,和时间函数来暴力执行(一秒2000次,我都害怕)。所以多看点算法,数据结构,框架还是很重要的,可以进行代码的优化,使其效率更高、更准确。
继承也是一个很重要的地方。比如地板,我本可以定义一个父类,然后对每种类型的地板进行继承父类,然后重写函数,不但节约代码,效率也高。但是我看了找js的书,也没有找到一种好的办法来继承(因为floor里面还有一个Image对象,我其实操作的是Image对象,但是Image对象是不可以编写定义的),所以只好把所有的地板都放在一个类中,用不同的函数名来区分。

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
男人就下100层游戏源码,经典的flash游戏《是男人就下100层》登录win8平台了,支持surface 以及 surface pro, 操作方式支持键盘左右键和触摸操作,该游戏现在android版,ios版已经上线了,但是wp版现在才开发的,喜欢的朋友可以了解一下吧。 项目介绍 这毕竟是个小游戏,本身其实没有什么技术难点,主要在于项目的设计,分为如下几个小模块 1、玩家 (Player) 玩家类我用了单例模式,继承自CCSprite,因为贯穿游戏一直会有玩家存在,在这个版本里也不会有第二个,所以单例成了我很好的选择。 封装了 运动、血量 等。整体的游戏运动采取了背景运动而人不动的方式,感觉在这里这种要更容易掌控一些,分层很明显。 2、平台 这里我参照了 Floyd 的Js版本实现,以 BlockBase 作为所有平台游戏的基类,实现了向上运动,检测玩家碰撞,移除平台等基础功能。 然后根据不同的平台类型,继承该基类实现不同效果,比如跳起,伤害,左右平移等。 分别有:NormalBlock (最普通的平台) 、FlipBlock(让人弹跳的平台)、MissBlock(会破损的平台)、ThornBlock(带刺的平台)、LeftRunBlock、RightRunBlock (左右运动的平台) 还有个 BlockFactory 工厂类, 负责在恰当的时候创建合适的平台,创建的规则是随机类型,位置是从预先定义的几个里面随机取。 对于所有平台的管理, 本来最好应该是做个缓存池的,但是我发现这个性能降低实在是可以忽略,所以。。。 3、输入 输入这里,定义了一个基类,InputBase,因为最终肯定有几种输入的方式:PC(键盘、鼠标)、手势、重力感应等,所以这个从一开始就要考虑到。具体的处理方式是 给定一个固定的运动速度, 然后有输入事件的时候就让玩家按照这个速度来运行, 但是现在实际的效果感觉还不太理想。 4、场景 场景就是那么基础的几个了。。。游戏主界面采用了MVC的模式来设计,CCScene 作为 Controller ,其它的Layer 作为View。其它页面都比较简单,单Layer 实现。逻辑也都放在Layer里了。 另外,专门定义了一个 HideLayer ,目的是实现弹出对话框的效果,考虑到原场景中可能会有CCMenu,我将该 Layer 的 优先级设为了 与 CCMenu 相同,因为后添加的原因,所以总能屏蔽 Menu 的事件, 而且在 Layer 上再添加Menu 也不会有问题。 还有个比较有意思的是: 所有的场景我都继承了 IBackableScene 接口,这是我自己定义的一个抽象类,因为我发现对于 “后退” 按钮的处理在游戏中是非常常见的,所以这个接口里定义了 bool GoBack() = 0 函数, 所有需要响应后退事件的场景都要实现该方法,然后在该方法里实现具体的返回 代码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

征途黯然.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值