全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2025-01-20_我用js做了个超级玛丽

您的位置:首页 >> 新闻 >> 行业资讯

我用js做了个超级玛丽 点击关注公众号,“技术干货”及时达! 前言从刚接触编程起,作者就一直有一个做游戏的梦,奈何水平比较差,做不出啥太像样的游戏,最近趁着下班和周末时间折腾折腾,怀旧一下童年最爱玩的超级玛丽。本文将讲述如何用js写一个MVP版本的超级玛丽游戏,主要用到框架有leaferjs + vue,leaferjs负责做图形渲染,vue负责界面和地图编辑,leafer的api用起来还是很舒服的,学习成本低,作者也非常热情,这里帮忙推荐一下~ 本文会尽可能简单的少贴代码,并把核心的流程讲清楚,先上一张运行后的效果图,源码和体验地址在最下面 开始我们的游戏梦1、创建背景就是游戏背后的蓝天白云背景,背景素材如下 在游戏中,背景会随人物前进而后退,但是由于素材宽度有限,不可能无限后退,所以做了个逻辑,当背景的x到达边界的时候,把x设置成0,达到类似无限循环背景的效果 这里使用leafer的Group + Rect实现,由一个Background类来实现,用leafer实现简单很多 2、创建场景场景用来承接和绘制游戏中的精灵,所以需要有个存放精灵的数组,以及一个run方法来绘制精灵(这里使用leafer的Canvas实现),具体要绘制什么,解耦给各个精灵内部自由实现 class Scene { sprites = []; // 添加内容 add(sprite) { this.sprites.push(sprite); } run() { // 绘制内容,传入canvas上下文 this.sprites.forEach((sprite) = { sprite.draw(context) }) ... } } 3、创建精灵精灵是指场景中的元素,比如玛丽、砖块、成长蘑菇、敌人蘑菇等,我们可以为这些精灵创建一个基类Sprite,有x、y表示位置,有width、height表示宽高,vx、vy表示水平和垂直方向速度 class Sprite { constructor(options) { const { x, y, width, height, vx, vy } = options; this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.width = width; this.height = height; } } 场景中所有精灵都可以继承于他,同时上面也说到了绘制精灵由精灵自身来决定,所以有个draw方法,且由于受到速度的影响,精灵的x和y需要做更新 class SpriteMario extends Sprite { constructor(options) { super(options); // ... } draw(context) { this.x += this.vx; this.y += this.vy; context.drawImage(this.resource, this.x, this.y, this.width, this.height) } } 精灵需要根据自身的状态在当前类内维护自己的动画帧,比如当玛丽的vx 0,要绘制的图片就是玛丽向右走的动画帧,实现后,效果如下(这里我降低了gif的帧数,实际运行是很流畅的,下面的gif也是) 然后我们依次绘制出其他砖块、石块、道具等精灵,这里先提前说一下,背景的运动、场景的绘制、包括底下的相机跟随、物理引擎都在每一帧即requestAnimationFrame中执行,代码如下 run() { // 运行物理引擎 this._physicsEngine.run({ camera: this.camera, scene: this.scene, }); // 运行场景中的精灵 this.scene.run(); // 运行背景 this._background.run(); // 相机跟随玛丽 this.camera.x = this._mario.x MARIO_VIEW_OFFSET ? 0 : this._mario.x - MARIO_VIEW_OFFSET; requestAnimationFrame(this.run.bind(this)); } 实现后,效果如下 看起来很有感觉有没有!接下来开始做物理引擎 4、物理引擎 - 重力最先要实现的当然就是重力拉,运用初中物理知识,使用公式套进去 class PhysicsEngine { run (options) { // ... // 为了防止过快给了个10的速度阈值 sprite.vy = Math.min(10, sprite.vy + G); } } 效果如下 5、物理引擎 - 碰撞检测加上重力后,玛丽会往下掉,然后来实现碰撞检测,这里的思路比较简单,用到的是矩形之间的碰撞检测,先校验两个矩形是否发生碰撞,如果发生碰撞在校验碰撞来源的方向,并根据方向做位置修补,防止碰撞后嵌入,感兴趣可以看看源码,加上之后的效果如下 6、物理引擎 - 跳跃跳跃套用上抛运动公式实现,给他一个默认的初速度v0 sprite.v0 -= G; sprite.vy = -sprite.v0; 然后当长按 "上键" 的时候,增大v0,达到按得越久跳的越高的效果,效果如下 7、物理引擎 - 其他精灵间的碰撞这里就挑几个主要的来讲,其他实现都大同小异 7.1、人物顶到问号问号中的道具会缓缓升起,前者的实现逻辑是给个参数active来指定当前道具精灵状态,当active为false不会受到物理引擎影响,所以我们可以在问号被碰撞后,让道具y值不断变小,当完全露出时设置其active为true,并给道具一个vx,效果如下 顺便说一下,当玛丽的头碰撞到建筑的底部时,会取消其上抛运动状态,使其只受重力影响 7.2、人物吃成长蘑菇这个就比较简单了,当人物和蘑菇发生碰撞,将蘑菇销毁,人物的height变高,然后更新人物动画帧,效果如下 7.3、人物顶碎砖块当人物的顶部碰撞到砖块的底部时,砖块销毁,然后将砖块拆成4个,向四周做抛物线运动,抛物线轨迹实现主要用一元二次方程实现,这里贴下核心代码 this.animatedX += 2; this.animatedY = 0.1 * this.animatedX * this.animatedX - b * this.animatedX; 运行后,效果如下 8、引入相机这里的相机不是 webgl 的相机,可以理解成视图窗口,引入这个概念的目的是为了让绘制和物理引擎的执行只有在视口内才会执行,即只会绘制相机视口的内容,然后我们让相机的 x 跟随玛丽,这样就能达到跟随人物前进的效果 camera.x = mario.x 效果如下 9、 引入分数系统击杀怪物、吃道具、顶碎石砖,会出现数字,数字会跟随对应精灵,这里用的是leafer的Text很轻松就能实现,效果如下 10、增加胜利机制创建旗帜,当人物和旗帜发生碰撞后,判定胜利,效果如下 11、编辑地图游戏做完后,要开始做地图了,由于地图要一个个手动去敲x、y很麻烦,就用vue做了个地图编辑器,可以通过鼠标来创建精灵自定义关卡,效果如下 结语上面只是一个超级玛丽的MVP版本,还有挺多没实现的,比如音乐、乌龟等等,胜利的动画也比较简陋,后续如果有空再慢慢完善他,源码已经发布github,这里是源码地址[1]和体验地址[2],喜欢的话求个star~ 点击关注公众号,“技术干货”及时达! 阅读原文

上一篇:2023-11-17_2023 MEET教育科技创新峰会定档11月22日 下一篇:2025-07-26_WAIC机器人探展:我被全场最靓的崽「Moz1」种草了

TAG标签:

21
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价