2017-12-05 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 JavaScript实现ZLOGO子集: 前进+转向的更多相关文章
- 2017-12-09 JavaScript实现ZLOGO子集: 测试用例
续前文JavaScript实现ZLOGO子集: 前进+转向. 在添加新功能之前, 先添加测试用例, 以应对日益复杂的代码. 选择使用QUnit编写运行测试用例. 暂时对比较复杂和I/O无关的部分进行测 ...
- 2017-12-06 JavaScript实现ZLOGO子集: 单层循环功能
前文JavaScript实现ZLOGO子集: 前进+转向的示例代码很累赘, 因此尝试实现基本的循环功能, 使得前面的11行代码缩减为7行: 开始 循环4次 前进200 左转144度 到此为止 前进20 ...
- 【2017.12.05 智能驾驶/汽车电子】转载:如何成为一名无人驾驶工程师 By刘少山
之前对无人驾驶的理解就是通过刘少山老师的书:第一本无人驾驶技术书 通读之后,对智能驾驶有了一个初步的认识,如感知.决策.控制都涉及哪些领域,有哪些可以利用的技术: 但经过一段时间的实践,发现即使是在我 ...
- 2018-12-14 JavaScript实现ZLOGO: 前进方向和速度
系列前文: JavaScript实现ZLOGO子集: 前进+转向 JavaScript实现ZLOGO子集: 单层循环功能 JavaScript实现ZLOGO子集: 测试用例 JavaScript实现Z ...
- JavaScript实现ZLOGO: 用语法树实现多层循环
原址: https://zhuanlan.zhihu.com/p/32571516 照例先上演示弱效果图. 演示地址照旧: 代码如下: 开始 循环4次 循环4次 前进50 左转90度 到此为止 右转9 ...
- 2018-01-02 JavaScript实现ZLOGO: 用语法树实现多层循环
原址: https://zhuanlan.zhihu.com/p/32571516 照例先上演示弱效果图. 演示地址照旧: 代码如下: 开始 循环4次 循环4次 前进50 左转90度 到此为止 右转9 ...
- 【web开发 | 移动APP开发】 Web 移动开发指南(2017.01.05更新)
版本记录 - 版本1.0 创建文章(2016.12.30) - 版本1.1 更正了hybird相关知识:增加了参考文章(2017.01.05): + Web APP更正为响应式移动站点与页面,简称响应 ...
- Gitlab一键端的安装汉化及问题解决(2017/12/14目前版本为10.2.4)
Gitlab的安装汉化及问题解决 一.前言 Gitlab需要安装的包太TM多了,源码安装能愁死个人,一直出错,后来发现几行命令就装的真是遇到的新大陆一样... ... 装完之后感觉太简单,加了汉化补丁 ...
- app后端设计(11)-- 系统架构(2014.12.05更新)
个人认为,在小型的创业团队中,特别是以应用产品为主,在架构后台的时候,需要集中精力解决自身业务上的问题,不是花时间解决第三方已经解决的问题,简单点来说,就是能用第三方服务就使用第三方的服务.基于这个原 ...
随机推荐
- [转] 语音识别基本原理介绍----gmm-hmm中的embedded training (嵌入式训练)
转自:http://blog.csdn.net/wbgxx333/article/details/38986507 本文是翻译Speech and Language Processing: An in ...
- “全栈2019”Java多线程第三十七章:如何让等待的线程无法被中断
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Android开发工程师文集-Activity生命周期,启动方式,Intent相关介绍,Activity详细讲解
前言 大家好,给大家带来Android开发工程师文集-Activity生命周期,启动方式,Intent相关介绍,Activity详细讲解的概述,希望你们喜欢 Activity是什么 作为一个Activ ...
- location-alias
location /images/ { alias /project/pic/; } 给定的路径对应于location的"/url" 这个URL; /images/f.jpg -- ...
- [Leetcode]394.字符串解码
题目与解释 给定一个经过编码的字符串,返回它解码后的字符串. 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次.注意 k 保证为正 ...
- Nginx+Keepalived 实现高可用
Keepalived 是一个高性能的 服务器高可用 或 热备解决方案,Keepalived主要来防止服务器单点故障的问题,可以通过其与Nginx的配合来实现web服务端的高可用. Keepalived ...
- spring cloud(断路器——初学四)
在分布式架构中,当某个服务单元发生故障后,能通过断路器的故障监控,向调用方返回一个错误响应,而不是长时间的等待. Netflix Hystrix 在Spring Cloud中使用了Hystrix 来实 ...
- Create and Embed an Application Manifest (UAC)
http://msdn.microsoft.com/en-us/library/bb756929.aspx 可以在VS2008中设置当执行exe时弹出提升管理员权限对话框:xx Property-&g ...
- (原创)UML要点总结
今天我们总结要点: 我们就从这张图慢慢讲. 一.类图部分 基础: 类图→长方形表示.类名在最上栏,下面是数据,第三栏是方法.其存在两种关系:关联和泛化 属性: 全形: 可见性 名:类型 重 ...
- HTTP请求代码整理
HTTP请求代码整理 类别 代码 注释 1xx – 信息提示 100 继续 101 切换协议 2xx - 成功 200 确定.客户端请求已成功 201 已创建 202 已接受 203 非权威性信息 2 ...