第28章 案例开发

2023-11-04

第28章 案例开发

视频讲解:23分钟)

对于JavaScript初学者来说,尝试开发小型的难度适中的应用程序或游戏,能够培养学习乐趣,激发开发热情。本章将通过两个相对复杂的案例,帮助读者上机进行JavaScript实战训练,为日后的开发实习积累经验。

【学习重点】

▲ 使用JavaScript开发Web应用程序

▲ 使用HTML5+JavaScript开发Web游戏

28.1 设计小程序:万年历

本例设计一个既可以查看公历,又可以查看农历的万年历,并且在日期的下面显示了公历与农历的各个节日及农历的节气,运行结果如图28-1所示。

图28-1 万年历演示效果

本例主要利用Date对象来获取指定日期的相关信息,并用Lunar对象将指定日期转换成相应的农历日期。Date对象是一个有关日期和时间的对象,详细说明和用法请参阅第10章内容。

【操作步骤】

第1步,新建文档,保存为index.html,在页面中插入一个表单

标签,在其中嵌套一个表格。定义表格7列,两行,其中第1行为合并单元格,第2行为标题行,手动输入一周简称,代码如下:

第2步,使用JavaScript代码在Menu组件中动态添加下拉菜单(年)。

第3步,使用JavaScript代码在Menu组件中动态添加下拉菜单(月)。

第4步,使用JavaScript代码在表格中添加6行7列的单元格,代码如下:



第5步,下面介绍如何编写用于实现公历日历与农历日历的JavaScript代码。在头部位置插入<script type=“text/<span id=” sensitive"="" class=“keyword-match”>JavaScript">标签。


第6步,使用数组记录日历中的相关信息。



第7步,使用数组保存公历的节日。



     //公历节日
var sFtv=new Array(
“0101元旦”,
“0214情人节”,
“0308妇女节”,
“0312植树节”,
“0315消费者权益日”,
“0401愚人节”,
“0501劳动节”,
“0504青年节”,
“0512护士节”,
“0601儿童节”,
“0701建党节”,
“0801建军节”,
“0910教师节”,
“0928孔子诞辰”,
“1001国庆节”,
“1006老人节”,
“1024联合国日”,
“1224平安夜”,
“1225圣诞节”)


第8步,使用数组保存农历的节日。



     var lFtv=new Array(
“0101春节”,
“0115元宵节”,
“0505端午节”,
“0707七夕情人节”,
“0715中元节”,
“0815中秋节”,
“0909重阳节”,
“1208腊八节”,
“1224小年”)


第9步,自定义函数lYearDays(y),用于返回农历y年的总天数。



第10步,自定义函数leapDays(y),用于返回农历y年闰月的天数。



第11步,自定义函数leapMonth(y),用于判断y年的农历中哪个月是闰月,不是闰月返回0。



第12步,自定义函数monthDays(y,m),用于返回农历y年m月的总天数。



第13步,自定义函数Dianaday(),用于计算出当前月第一天的农历日期和当前农历日期下一个月农历的第一天日期。



第14步,自定义函数solarDays(y,m),用于返回公历y年m+1月的天数。



第15步,自定义函数calElement()用于记录公历和农历某天的日期。



第16步,自定义函数sTerm(y,n)用于返回某年的第n个节气为几日(从小寒算起)。



第17步,自定义函数calendar(y,m)用于保存y年m+1月的相关信息。



第18步,自定义函数cDay(d),用中文显示农历的日期。



第19步,自定义函数drawCld(SY,SM),在表格中显示公历和农历的日期以及相关节日。





第20步,自定义函数changeCld(),在下拉列表中选择年或月时,调用自定义函数drawCld()显示公历和农历的相关信息。



第21步,自定义函数initial(),打开网页时,在下拉列表中显示当前年月,并调用自定义函数drawCld(),显示公历和农历的相关信息。



第22步,在页面初始化完成事件onload中调用自定义函数initial()。



28.2 设计游戏:俄罗斯方块


俄罗斯方块是一款单机休闲小游戏。在俄罗斯方块的游戏界面中,有一组正在下落的方块,方块通常有4个,组合成各种不同的形状,游戏玩家需要控制正在下落的方块的移动,将这组方块摆放到合适的位置。只要下面某一行全部充满方块,没有空缺,那么这行就可以消除,上面的所有方块会整体掉下来。


俄罗斯方块的游戏界面比较简单,游戏的实现逻辑也不太复杂,非常适合JavaScript初学者作为进阶训练项目。本例采用HTML5的canvas来绘制游戏界面,用Local Storage来记录游戏状态。游戏演示效果如图28-2所示。


28.2.1 设计游戏界面

俄罗斯方块的游戏界面分为两个区域:速度、积分显示区;主游戏界面区。


【操作步骤】


第1步,新建网页文档,保存为index.html。




图28-2 俄罗斯方块游戏演示效果



第2步,使用

包含框定义一个提示信息框,作为速度、积分显示区,该区域包含3个 标签,用于显示当前速度、当前积分、最高积分。代码如下:



第3步,游戏主界面通过HTML5的canvas进行绘制,由JavaScript动态生成。在网页头部区域插入<script type=“text/<span id=” sensitive"="" class=“keyword-match”>JavaScript">标签。


第4步,为了让程序可以动态地改变界面大小,canvas的大小是由程序动态计算得到的,下面是动态计算、生成画布的JavaScript脚本。



上面代码动态创建了一个canvas组件,该组件的高度、宽度是由程序动态计算得到,同时使用路径绘制了横向、竖向的线条,用于表示俄罗斯方块游戏界面上的网格。


28.2.2 设计游戏模型

俄罗斯方块的游戏界面是一个N×M的网格,每个网格上显示一张图片,这个网格用一个二维数组来定义,而每个网格上所显示的色块,对于底层的数学模型来说,不同的色块对应于不同的数值即可。本例直接使用一个二维数组来保存游戏的状态数据,不过由于JavaScript是动态语言,因此使用二维数组时依然是一维数组。


【操作步骤】


第1步,俄罗斯方块的游戏界面上还有一组正在下落的方块。这组正在下落的方块通常有4个,这4个方块的位置随时在改变,因此采用一个长度为4的数组来记录这4个方块的位置。



在上面数组中,每个数组元素都是一个对象,对象包括x、y、color 3个属性,分别代表了该方块所在的位置、颜色值。


第2步,为了初始化游戏状态,创建一个二维数组,这个二维数组记录了游戏界面上每个位置的方块值(不同的值代表不同的颜色)。具体代码如下:



上面代码创建了一个二维数组,并将这个二维数组的每个数组元素都赋值为NO BLOCK(也就是0),这代表该游戏界面上还没有方块。


第3步,为了能随机生成各种向下掉的方块组合(4个方块组成一组),预先把各种组合定义出来,然后每次需要开始掉落新的方块组时,随机取出一组即可。下面是随机获取掉落的方块组的代码:




上面的代码先定义了一个数组,这个数组定义了所有可能出现的方块组合,这里一共定义了7种组合。由于程序随机从上面的数组中取出可能出现的方块组合,因此在游戏中完全可能出现上面7种掉落的方块组合。


28.2.3 实现游戏功能

定义了游戏状态模型之后,接下来处理方块组合的掉落,在掉落过程中还需要处理方块组合左移、右移、旋转等动画。


【操作步骤】


第1步,处理方块掉落。


让方块组合掉落,只需把每个方块的y属性增加1即可,但在处理方块组合掉落之前,需要判断方块组合是否可以掉落。如果出现如下两种情况,方块组合则不能掉落。


☑ 如果方块组合中任意一个方块已经到了最底部。


☑ 如果方块组合中任意一个方块的下面已有方块。


如果方块组合可以掉落,需要把方块组合原来所在位置的颜色清除,再把方块组合中每个方块的y属性增加1,最后把当前方块所在位置涂上相应的颜色。


当每次方块掉落之后,还需要逐行扫描每一行,判断是否某一行的方块已满,当方块已满时,将该行方块消除,并增加积分。


下面moveDown()函数定义了方块掉落的实现方法:




上面的代码先定义了一个canDown变量,该变量用于标识方块组合是否能掉落。如果方块组合的任一方块已经到了最底下,或者方块组合的任一方块下方已有方块,将canDown变量值设为false。


当方块组合能掉落时,则先清除该方块组合所在位置的背景色,然后控制方块组合向下掉落,最后把掉落一格后的方块组合所在位置的背景涂上相应的颜色。


当方块组合不能向下掉落时,则执行如下几个任务:


☑ 如果某个方块已经到了最上面,则表明游戏已经结束,玩家输了。当游戏结束时,需要再执行如下几个任务。


▶ 清空Local Storage中的当前游戏积分、当前游戏速度、当前游戏状态。


▶ 使用confirm对话框提示用户。


▶ 将isPlaying变量设为false。


▶ 清除计时器,该计时器控制方块组合不断地向下掉落。


☑ 判断是否有可消除的行。


☑ 使用Local Storage记录当前俄罗斯方块的游戏状态。


☑ 调用initBlock()方法开始一组新的方块。


上面的代码采用了Local Storage记录当前俄罗斯方块的游戏状态,就是把记录游戏状态的二维数组转换为字符串后写入Local Storage,这样即可保证游戏状态不会丢失,下次打开浏览器时还可以接着上次的游戏状态继续。


initBlock()函数用来判断是否有可消除的行,如果发现某一行的方块已满,则程序处理积分增加,并且该行上面的所有行整体下移一行。下面是lineFul()函数的详细代码:



当某行的所有位置都有方块之后,需要增加curScore游戏积分。除此之外,如果游戏积分已经达到了升级界限,将增加游戏速度,并清空原有的计时器,根据现有的游戏速度启用新的游戏计时器。


当游戏消除了指定某一行的所有方块之后,需要调用drawBlock()函数绘制tetris_status数组中的所有方块。drawBlock()函数代码如下:



上面的drawBlock()函数负责把俄罗斯方块的数据模型转换成可视化的方块图。


第2步,处理方块左移。


先给键盘事件绑定事件监听器,当用户按下不同按键时,调用不同的方法进行处理。下面是为按键事件绑定监听器的代码:



在上面的代码中,当按下向左箭头时,如果还处于游戏中,则调用moveLeft()函数处理方块组合左移;相反按下向右箭头时,如果还处于游戏中,则调用moveRight()函数处理方块组合右移;当按下向上箭头时,如果还处于游戏中,则调用rotate()函数处理方块组合旋转。


方块组合左移实现比较简单,只要将方块组合中所有方块的x属性减1即可。但在左移之前先要判断是否可以左移。如果方块组合已经到了最左边,或者方块组合的左边已有方块,那么方块组合就不能左移。详细代码如下:




第3步,处理方块右移。


与方块组合左移的思路基本相似,都是先判断方块组合能否右移,如果可以右移,则将方块移动之前位置的背景色清空,将每个方块的x属性加1,再将移动后的方块所在位置的背景涂上相应的颜色即可。详细代码如下:



第4步,处理方块旋转。


处理方块旋转是最复杂的,因为需要动态地计算方块旋转后的坐标。当然,在对方块组进行旋转之前,同样需要先判断是否可以旋转方块,只有当方块可以旋转时才去进行旋转。下面是控制方块组合逆时针旋转的代码:




第5步,初始化游戏状态。


在游戏过程中,使用了Local Storage保存游戏状态,包括游戏的当前积分、游戏速度、已有方块的状态等。为了正常使用Local Storage所记录的游戏状态,可以在页面初始化后通过Local Storage读取这些数据,并把这些数据显示出来,具体代码如下:



上面的代码在游戏开始时需要完成如下事情。


☑ 调用createCanvas创建canvas组件。


☑ 读取Local Storage记录的已有方块的状态。


☑ 读取Local Storage记录的当前积分数据。


☑ 读取Local Storage记录的当前速度数据。


☑ 读取Local Storage记录的最高积分数据。


☑ 初始化正在掉落的方块。


☑ 启动计时器,控制方块掉落。


【小结】在学习本例时,读者需要熟悉本游戏的玩法,然后能够理解界面设计的思路和实现途径。同时应该熟练掌握使用JavaScript操控canvas和Local Storage技术的能力。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第28章 案例开发 的相关文章

  • 设计模式--命令模式

    命令模式 属于行为型模式基本原理 请求以命令的形式包裹在对象中 并传给调用对象 调用对象寻找可以处理该命令的合适的对象 并把该命令传给相应的对象 该对象执行命令 主要流程 1 创建命令对象 该对象中包含请求 和执行请求 2 创建请求类 其中

随机推荐

  • 我问chatGPT,在JavaScript中构造函数和类的区别

    问 构造器函数和面向中的类是同样的东西吗 答 构造器函数和面向对象中的类并不是同样的东西 它们之间有些许不同 在面向对象编程中 类是一种抽象的概念 它描述了一类具有相同属性和行为的对象 类可以看作是对象的蓝图 包含了对象的属性和方法 而对象
  • 如何进行弱网测试?专项测试中最实用的方法了解一下……

    目录 引言 一 什么是弱网测试 二 为何要进行弱网测试 三 如何做弱网测试 四 弱网测试工具 引言 如今这个高度互联的时代里 网络环境对于应用程序的影响越来越重要 而弱网测试就是用来检验应用程序在恶劣网络环境下的表现 如果你是一名开发人员或
  • 【linux shell】服务器系统自动化巡检脚本资源状况统计

    运维服务器系统的时候需要定期检查服务器系统资源状况 如CPU 内存 硬盘这些资源消耗信息统计 在这种情况下也可以用开源的监控系统导出相应的需求信息或者直观的通过监控平台去查看资源状况 本文将介绍另一种方式通过Linux shell脚本实现服
  • 0xA00F4244<NoCamerasAttached>相机打不开解决办法

    0xA00F4244 NoCamerasAttached 依次排查 ctrl s 搜索 设备管理器 打开找到 照相机 如图1 如果为灰色 说明设置里头相机权限没有打开 可以去设置打开如图2 也可以fn f10 打开之后 返回 设备管理器 窗
  • 基于fasttext的新客服文本分类

    基于fasttext的新客服文本分类效果评估 具体步骤如下 数据处理 模型搭建 效果评估 结论 第一部分数据处理包括 数据读取 数据标准化格式处理 训练集和验证集数据准备 数据读取 import pandas as pd df pd rea
  • City Horizon

    http acm hust edu cn 8080 judge contest viewProblem action pid 45728 Description Farmer John has taken his cows on a tri
  • C语言文件读写命令

    C语言把磁盘文件看成是字符 或字节 的序列 按照存储信息的形式来说 文件主要是有文本文件和二进制文件 文本文件由一个个字符组成 每个字节存放一个ASCII码制 代表一个字符 二进制文件把内存中的数据按其在内存中的存储形式原样放入磁盘空间 二
  • Linux编程基础之文本文件末尾自动加换行

    目录 前言 hello txt 文件内容 证明 总结 前言 操作系统 Fedora 文本文件末尾会自动加换行 利用 off t oldpos lseek fd 0 SEEK END 指针定位会到最后一个字符 都是换行符 后面一位 相当于什么
  • c++基础学习

    创建c 程序 include
  • ISCC2023全国大学生网络信息安全竞赛

    竞赛入口 http www isclab org cn 1 竞赛简介 信息安全已涉及到国家政治 经济 文化 社会和生态文明的建设 信息系统越发展到它的高级阶段 人们对其依赖性就越强 从某种程度上讲其越容易遭受攻击 遭受攻击的后果越严重 网络
  • linux创建新用户

    1 添加用户 adduser test 设置密码 passwd test 2 添加root权限 1 chmod 755 etc sudoers vi etc sudoers 文件 找到下面一行 把前面的注释 去掉 Allows people
  • 数据集市项目的总结

    本人毕业就在某银行信用卡中心工作 做了数据集市项目 据说投资3000万 后来在阿里做数据产品经理的工作 想把过去的工作总结一下 不管成功和失败 都是一种经历 于是有了下面的文字
  • 使用二分法实现在一个有序列表中查找指定的元素

    二分法是一种快速查找的方法 时间复杂度低 逻辑简单易懂 总的来说就是不断的除以2除以2 例如需要查找有序数组arr里面的某个关键字key的位置 那么首先确认arr的中位数或者中点center 下面分为三种情况 1假如arr center g
  • es多字段分组去重统计

    es多字段分组去重统计 oracle中sql select a1 b1 from dual group by a1 b1 或 select DISTINCT a1 b1 from dual es分组去重统计 话不多说 直接贴代码 Terms
  • 【云原生之kubernetes】kubernetes集群下ConfigMap使用方法

    云原生之kubernetes kubernetes集群下ConfigMap使用方法 一 ConfigMap介绍 1 ConfigMap介绍 2 ConfigMap特点 二 生成一个ConfigMap示例 1 命令生成 2 configmap
  • uboot学习之Makefile之配置过程

    uboot 1 1 6源码分析 分析配置过程 1 安装交叉编译工具arm linux gcc 否则编译报错 2 执行make canmb config MKCONFIG a canmb ppc mpc5xxx canmb 1 MKCONFI
  • 自动化测试入门

    1 初识自动化测试 如果以前没有做过自动化测试 那么就不了解自动化测试 可能会觉得自动化测试比较神秘 但是 我们在日常的计算机操作中 可能会碰到一些自动化处理的过程 这些过程和自动化测试比较接近 例如 Windows操作系统的控制面板中 有
  • windows 控制台通过密码连接redis

    Redis 访问密码设置 1 修改密码 打开redis conf文件 先使用字符匹配查找到requirepass foobared对应的位置 然后修改foobared成自己想要的密码 并删除当前行前面的 注释 然后保存退出 2 重启redi
  • Vulkan-NCNN 编译

    首先安装一些依赖 sudo install build essentials git cmake libprotobuf dev protobuf compiler libvulkan dev glslang tools vulkan to
  • 第28章 案例开发

    第28章 案例开发 视频讲解 23分钟 对于JavaScript初学者来说 尝试开发小型的难度适中的应用程序或游戏 能够培养学习乐趣 激发开发热情 本章将通过两个相对复杂的案例 帮助读者上机进行JavaScript实战训练 为日后的开发实习