前端小游戏——植物大战僵尸【附源码】
今天一时兴起,想玩会儿游戏。突然想到了很久没有玩的植物大战僵尸,之前有一阵子我是非常迷恋这个游戏的。
相信大家玩过它的人不在少数,但是如何用自己学习的技术来实现游戏的功能呢?今天就来分享一下用原生JS+ES6语法,并通过canvas绘制的方式实现这个游戏的一些基本功能。
游戏页面展示


游戏引擎篇
在开发这个游戏的时候,我选择基于ES6的class的方式抽象了游戏相关函数,关于这个小游戏的核心引擎,主要的相关属性如下:
其实核心逻辑很简单,就是定义一个游戏引擎主函数,生成一个定时器以每秒60帧的频率不停在canvas画布上绘制游戏场景相关元素,然后在定时器函数中根据当前游戏状态(游戏准备
、游戏开始
、游戏运行
、游戏暂停
、游戏结束
)来绘制对应游戏场景。
loading
游戏状态:游戏引擎绘制了页面载入图片,并添加了一个开始游戏按钮 start
游戏状态:游戏开始读条倒计时,提醒用户游戏即将开始 running
游戏状态:绘制游戏运行时所需所有游戏场景素材 stop
游戏状态:游戏进入暂停阶段,游戏中如生成阳关、僵尸的定时器都将清除,角色动画处于静止状态 gameover
游戏状态:分为玩家获得胜利以及僵尸获得胜利两种情况,并分别绘制不同游戏结算画面
游戏场景篇
在这里我将游戏中所有可控制的元素都归于游戏场景中,并且将这些元素都抽象为类,方便管理,这里包括:植物类
、僵尸类
、阳光计分板类
、植物卡片类
、动画类
,子弹类
。
游戏场景中最核心的两个类为植物类
、僵尸类
,不过在这两个核心类中都会用到动画类
,这里我先介绍一下。
动画类(Animation)
动画类的作用是将每一个角色的不同动画序列保存起来,每隔一定时间切换当前显示的图片对象,达到播放动画的效果。
这里用到的images
,就是通过new Image()
的方式生成并添加到images
中组成的动画序列:
其中type
和section
用于判断当前需要加载植物或僵尸、哪一个动作所对应动画序列,count
和fps
用于控制当前动画的播放速度,而img
用于表示当前所展示的图片对象,即images[imgIdx]
,其关系类似于以下代码:
角色类(Role)
这里的角色类主要用于抽象植物类和僵尸类的公共属性,基本属性包括type
、section
、x
、y
、w
、h
、row
、col
,其中row
和col
属性用于控制角色在草坪上绘制的横纵坐标(即x
轴和y
轴方向位于第几个方格),section
属性用于区分当前角色到底是哪一种,如豌豆射手、双发射手、加特林射手、普通僵尸。
植物类(Plant)
植物类的私有属性包括idel
、attack
、bullets
、state
,其中idel
和attack
为动画对象,相信看过上面关于动画类
介绍的小伙伴应该能理解其作用,bullets
即用于保存当前植物的所有子弹对象(同动画类
,子弹类
也有属性、方法的配置,这里就不详细叙述了)。
关于植物的状态控制属性,如isHurt
属性会在植物受伤时,切换为true
,并由此给动画添加一个透明度,模拟受伤效果;isDel
属性会在植物血量降为0时,将植物从植物对象数组中移除,即不再绘制当前植物;state
属性用于植物在两种形态中进行切换,即普通形态、攻击形态,当前状态值为哪种形态,即播放对应形态动画,对应关系如下:
攻击形态的切换,这里就涉及需要循环当前植物对象与所有的僵尸对象所组成的数组,判断是否有僵尸处于当前植物对象的射程内(即处于同一行草坪,且进行屏幕显示范围)。
这里主要介绍了植物类的相关属性,其方法包括初始化植物对象
、植物绘制
、植物射击
、更新植物状态
、检测植物是否可攻击僵尸
...
僵尸类(Zombie)
这里就简单介绍下plants
、zombies
对象数组;当游戏运行时,所以种植的植物以及生成的僵尸都会配合其相关初始化参数plants_info
、zombies_info
进行实例化再分别保存在plants
、zombies
对象数组中。
后记
较以往的经验来看,关于游戏中相关的方法逻辑就不详细介绍了,这个分享主要是为了提供给对小游戏感兴趣,但是却不知如何下手的小伙伴一个思路和经验。