JavaScript实现ZLOGO子集: 前进+转向
在前文《中文编程语言之Z语言初尝试: ZLOGO 4》与相关讨论后, 萌生了用JavaScript编写类似语言以便在线编程的想法. 于是使用 @TKT2016 (知乎账号)的ZLOGO语法设计, 在《编程语言试验之Antlr4+JavaScript实现"圈4"》基础上, 通过p5js的绘图功能, 实现了基本的两个ZLOGO功能. 如图(动态效果看起来更爽一点, 当然要耐心等它画完, 请自行尝试):
源码库: program-in-chinese/quan3, 导出代码到本地后, 在浏览器中打开"圈3.html"即可在本地实践编程.
在线演示: 【见原文】
由于还不支持循环, 实现这个五角星的代码很重影:
开始 前进200 左转144度 前进200 左转144度 前进200 左转144度 前进200 左转144度 前进200 结束
下面是编程语言试验之Antlr4+JavaScript实现"圈4"之后添加的主要部分:
语法文件(圈3.g4):
声明 : 前进 | 转向; 前进 : '前进' T数 ; 转向 : T转向 '转' T数 '度' ; T转向 : '左' | '右' ;
主要修改在"定制监听器.js":
命名还比较粗糙, 一些用语最好更加一致(比如"长度","距离","前进量"虽在不同上下文, 实际指的是一个东西), 需要改进. 当然算法肯定也可以改进, 暂时是实现功能优先.
var 常量_指令名_前进 = "前进"; var 常量_指令名_转向 = "转向"; var 序号 = 0; var 画布尺寸 = {x: 1000, y: 800}; var 原点 = {x: 画布尺寸.x/2, y: 画布尺寸.y/2}; var 前进角度 = 90; // 默认向上, 对应弧度: 90 * Math.PI / 180 // 指令格式: 名称 (转向, 前进, 笔色等等); 参数 (转向角度--右为负,左为正; 前进长度-像素数等等); var 指令序列 = []; 定制监听器.prototype.enter程序 = function(ctx) { 重置状态(); // 只需调用一次 // https://p5js.org/reference/#/p5/setup 构图 = function() { 新画布(画布尺寸.x, 画布尺寸.y); } }; function 重置状态() { 序号 = 0; 原点 = {x: 画布尺寸.x/2, y: 画布尺寸.y/2}; 前进角度 = 90; 指令序列 = []; } // 根据指令序列, 生成路径分段描述(段起止点坐标, 颜色等等) // 如: 前进50, 左转90度, 前进50 应返回(假设起点为{x: 200, y: 200}): // {起点: {x: 200, y: 200}, 终点: {x: 200, y: 150}, 长度: 50}, // {起点: {x: 200, y: 150}, 终点: {x: 150, y: 150}, 长度: 50} function 生成路径表(指令序列) { // 段: {起点: {x, y}, 终点: {x, y}, 长度, 颜色} var 路径表 = []; var 起点 = 原点; for(var i = 0; i < 指令序列.length; i++ ){ var 指令 = 指令序列[i]; var 指令名 = 指令.名称; var 段 = {起点: 起点}; if (指令名 === 常量_指令名_前进) { var 距离 = 指令.参数; var x增量 = Math.cos(前进角度 * Math.PI / 180); var y增量 = Math.sin(前进角度 * Math.PI / 180); 段.终点 = {x: 起点.x + x增量 * 距离, y: 起点.y - y增量 * 距离}; 段.长度 = 距离; 路径表.push(段); 起点 = 段.终点; } else if (指令名 === 常量_指令名_转向) { 前进角度 += 指令.参数; } } return 路径表; } 定制监听器.prototype.exit程序 = function(ctx) { var 路径表 = 生成路径表(指令序列); 绘制 = function() { var 当前序号 = 序号; background(255, 255, 255); for (var i = 0; i < 路径表.length; i++ ) { var 段 = 路径表[i]; var 起点 = 段.起点; var 终点 = 段.终点; var 距离 = 段.长度; if (当前序号 < 距离) { line(起点.x, 起点.y, 起点.x + (终点.x - 起点.x) * 当前序号 / 距离, 起点.y + (终点.y - 起点.y) * 当前序号 / 距离); break; } else { line(起点.x, 起点.y, 终点.x, 终点.y); 当前序号 = 当前序号 - 段.长度; } } 序号 ++; } }; 定制监听器.prototype.exit前进 = function(上下文) { var 前进量 = 上下文.getChild(1).getText() 指令序列.push({名称: 常量_指令名_前进, 参数: parseInt(前进量)}); }; 定制监听器.prototype.exit转向 = function(上下文) { var 方向 = 上下文.getChild(0).getText(); var 角度 = parseInt(上下文.getChild(2).getText()); 角度 = 角度 * (方向 === "左" ? 1 : -1); 指令序列.push({名称: 常量_指令名_转向, 参数: 角度}); };
2017-12-05
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
编写Visual Studio Code插件初尝试
参考官方入门: Your First Visual Studio Code Extension - Hello World 源码在: program-in-chinese/vscode_helloWorld 创建插件过程中, 发现identifier和publisher name不允许中文命名(报错: invalid xxx): ? What type of extension do you want to create? New Extension (TypeScript) ? What's the name of your extension? 吃了么 ? What's the identifier of your extension? hello ? What's the description of your extension? 吃了么 ? What's your publisher name (more info: https://code.visualstudio.com/docs/tools/vscecli#_publishing-extensions)? nobody...
- 下一篇
Python爬虫入门教程 11-100 行行网电子书多线程爬取
行行网电子书多线程-写在前面 最近想找几本电子书看看,就翻啊翻,然后呢,找到了一个 叫做 周读的网站 ,网站特别好,简单清爽,书籍很多,而且打开都是百度网盘可以直接下载,更新速度也还可以,于是乎,我给爬了。本篇文章学习即可,这么好的分享网站,尽量不要去爬,影响人家访问速度就不好了 http://www.ireadweek.com/ ,想要数据的,可以在我博客下面评论,我发给你,QQ,邮箱,啥的都可以。 这个网站页面逻辑特别简单 ,我翻了翻 书籍详情页面 ,就是下面这个样子的,我们只需要循环生成这些页面的链接,然后去爬就可以了,为了速度,我采用的多线程,你试试就可以了,想要爬取之后的数据,就在本篇博客下面评论,不要搞坏别人服务器。 http://www.ireadweek.com/index.php/bookInfo/11393
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS8编译安装MySQL8.0.19