“是男人就下一百层”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对象是不可以编写定义的),所以只好把所有的地板都放在一个类中,用不同的函数名来区分。