Javascript实现简单的超级马里奥小游戏

写在前面:

这是自己自学前端之路上第一次写博文,希望以此来巩固自己所学的知识,也希望能和大家多多交流!

这个小案例是韩顺平的js学习视频中的案例,视频中给出了一部分的实现,之后由本人补充了一些功能并改进了页面布局。

功能需求分析:

1)通过上下左右四个button控制马里奥的移动

2)使用面向对象的思想,设计Mario的类,并为Mario添加方法

3)注意Mario移动不能跑出游戏界面(边界检测)

4)Mario遇到得分物体获得加分(碰撞检测+得分统计)



页面初步布局:

设置控制中心,可通过table标签实现,表格中的内容可添加input标签, type="button" value="上/下/左/右"的箭头符号


控制中心初步效果

设置游戏区域div,命名为gamefield,并添加一张马里奥的图片,游戏主角,以及草莓的图片作为可得分物体。



游戏区域初步效果



核心功能实现:

1)该小案例是为了熟悉js的面向对象语法,所以设置Mario的类 通过构造函数 function Mario(){...}声明该类,类中需要实现的方法为this.move=function(direnction){.....},移动的情况分为上下左右四种情况,所以通过case语句来区分。当然其中还有很多细节,但是一步步先把整体框架搭建出来,之后再一步步修改细化。

构造函数写完之后,通过实例化才能生成一个Mario的对象,用这句话来实现

var mario=new Mario ();

接下来,在主程序中 声明一个全局函数,就可以调用mario的move方法了


移动 0-上 1-右 2-下 3-左



2)好了,接下来就是对Mario类中公有方法move的具体实现了。

想要移动mario,首先需要获取它的图片元素,js中获取单个元素的方法getElementById()

var mymario=document.getElementById("marioimg");

获得这个元素之后,我们还需要获得这个图片的位置。视频教程中对图片设置为了行内样式,其坐标位置就是相对于游戏区域gamefield的位置,其前提是gamefield的定位必须为obsolute,否则无法获取到。

直接通过obj.style.left和obj.style.top即可获得图片在游戏区域的相对位置。

用这个方法中间遇到了一些坑点,上网查了半天终于解决了!!!是这样说的:获取元素的位置通常有两种方法 

1.直接通过obj.style.left和obj.style.top,但是有局限性,这种获取的方法只能获取到行内样式的left和top的属性值,不能获取到style标签和link 外部引用的left和top属性值。(当时没按照教程来设置成了外部样式,半天都是空,获取不到值)

2使用obj.offsetLeft来获取对象的left属性值,用obj.offsetTop来获取对象的top属性值。  但这两个属性是只读的,不能赋值

var left=mymario.style.left; //取到的是带px的字符串

left=parseInt(left.substring(0,left.length-2));  //去掉px,转为int数字

var top=mymario.style.top;

top=parseInt(top.substring(0,top.length-2));

switch语句可以初步这样写出来:


改变mario的位置

这是设置好之后,就可以将全局函数marioMove(direction)绑定到button的onclick事件上,此时我们就可以通过button控制mario的移动了。但是现在还有很多不足,mario会跑出界,遇到其他图片没有响应,所以需要继续添加新的功能。



3)实现边缘检测功能,防止mario跑出游戏区域之外。直接上代码因该可以一目了然。


注:图片本身大小为60*60,所以判断宽高出界时要减去图片的宽高



4)实现碰撞检测功能,mario碰到其他物体可以得分

其基本原理如下图所示:


碰撞检测原理示意图

物体1只要处于上图的四条边界线之外的任意一种情况,就没有发生和物体2的碰撞,否则就发生了碰撞。具体代码如下:



碰撞检测



5)得分统计

道理也很简单,每检测到一个发生了碰撞检测,得分score变量就进行累加

var spanArray=document.getElementById("score").getElementsByTagName("span"); //ByTagName获取的是一组元素

var score=parseInt(spanArray[0].innerHTML); //元素必须转化为int型的分数

之后检测到碰撞之后就是:

score+=100;

spanArray[0].innerHTML=score;



6)得分物体随机生成(自己想出来的小功能)

一次碰撞之后,得分物体(草莓消失),在游戏区域的任意位置再次生成,所以这里的主要思路就是像获得mario的位置那样,获得草莓的位置,统计完得分后,生成随机数,重新改变草莓的位置。就可以实现。

//随机初始化草莓的位置

caomei.style.left=(Math.floor(Math.random()*42+1))*20+"px";

caomei.style.top=(Math.floor(Math.random()*17+1))*20+"px";

用到了random和floor函数,这里的参数是根据游戏区域大小,还有每次移动的步长而设置的。

接下来就放我的整体实现效果图了



最终效果图


完整的代码,请移步至我的github中去查看https://github.com/mermaidgaogao/EasyMario.git

写完了第一篇博文,内心还有点小激动,多多指教,哈哈!永远on the way

You don't have to be afraid of what you are......

你可能感兴趣的:(前端)