PhET开发概述
PhET是个好东西,最近在学习如何开发PhET仿真演示程序。本文同时也发布在我刚建一个主页,网址:PhET开发概述(http://www.circuits.top/phetdevelope/2.html),网站地址:http://www.circuits.top/
概述
PhET为科学和数学教学创建免费的开源的交互式仿真演示,您可以在PhET网站上找到这些交互式仿真演示。本文介绍了如何在HTML5中开发PhET交互式仿真演示项目的具体方式。此文档也可从http://bit.ly/phet-development-overview获得。有关讨论和反馈,请访问HTML5 Google群组Developing Interactive Simulations in HTML5 Google Group。
目录
- 入门(适用于Windows)
- 入门(适用于OS X)
- 构建和测试(Windows和OS X)
- 源代码和依赖
- 从GitHub检出HTML5代码
- 未正式发布的当前主要分支:访问严格测试的代码
- 以前的Java / Flash源代码
- 第三方依赖库
- 许可证
- 编码风格指南
- 平台
模块化和RequireJS - 布局
- 编译代码
- 离线操作
- 发布版本
- 开发过程和清单
- 用于开发和测试的实用工具
- 使用GitHub提出问题
- 在您的网站中嵌入仿真演示
入门(在Windows上)
为了获得现有PhET仿真演示的代码,您将需要下面这几个步骤(在PhET开发视频教程中也可以看到):
检出代码并在开发模式下运行它
- 从http://git-scm.com/downloads下载并安装Git
- 安装时请选择为“git bash” 创建桌面图标选项。
- 用Git克隆PhET代码仓库和模拟代码仓库
- 打开Git Bash(从桌面上的链接或通过开始菜单,并且下面的操作都是命令行下进行的)。
- 为您的开发创建一个目录:
mkdir phetsims - 将当前目录更改为phetsims:
cd phetsims - 运行这些git clone命令:
git clone https://github.com/phetsims/example-sim.git
git clone https://github.com/phetsims/assert.git
git clone https://github.com/phetsims/axon.git
git clone https://github.com/phetsims/babel.git
git clone https://github.com/phetsims/brand.git
git clone https://github.com/phetsims/chipper.git
git clone https://github.com/phetsims/dot.git
git clone https://github.com/phetsims/joist.git
git clone https://github.com/phetsims/kite.git
git clone https://github.com/phetsims/phet-core.git
git clone https://github.com/phetsims/phetcommon.git
git clone https://github.com/phetsims/scenery.git
git clone https://github.com/phetsims/scenery-phet.git
git clone https://github.com/phetsims/sherpa.git
git clone https://github.com/phetsims/sun.git
git clone https://github.com/phetsims/tandem.git
git clone https://github.com/phetsims/query-string-machine.git
- 从https://nodejs.org/en/下载并安装node 和 npm
- 在开发计算机上启动Node服务器程序
- 以命令行方式程序安装http-server。需要重新打开一个新的命令窗口,因为上面的命令窗口不能支行npm。
npm install http-server -g - 切换到phetsims目录(如果你还没有)。
cd phetsims / - 运行http服务器程序
http-server
- 以命令行方式程序安装http-server。需要重新打开一个新的命令窗口,因为上面的命令窗口不能支行npm。
- 在浏览器中打开网址:http:// localhost:8080/example-sim/example-sim_en.html
现在,您可以测试修改代码,并通过刷新浏览器查看更改。
如果你有公网IP,你还可以使用您的IP地址进行远程测试。
若有问题请直接发送到HTML5 Google群组Developing Interactive Simulations in HTML5 Google Group
入门(在OS X上)
为了获取现有PhET的代码,您需要按照以下步骤操作:
检出代码并在开发模式下运行它
- 从http://git-scm.com/downloads下载并安装Git
- 您可能需要设置允许系统运行从任何地方下载的应用程序。过程如下
- 打开Apple菜单
- 系统偏好
- 安全与隐私
- 单击锁定以进行更改
- 允许从“任何地方”下载的应用
- 安装git后,可以恢复以前的安全设置
- 您可能需要设置允许系统运行从任何地方下载的应用程序。过程如下
- 使用Git克隆PhET库和模拟代码
- 打开“终端”应用程序
- 单击桌面右上角的搜索图标(放大镜)
- 键入“Terminal”
- 单击终端图标
- b.为您的开发创建一个目录:
mkdir phetsims - c.将目录更改为phetsims:
cd phetsims - d.运行这些git clone命令:
git clone https://github.com/phetsims/example-sim.git
git clone https://github.com/phetsims/assert.git
git clone https://github.com/phetsims/axon.git
git clone https://github.com/phetsims/brand.git
git clone https://github.com/phetsims/chipper.git
git clone https://github.com/phetsims/dot.git
git clone https://github.com/phetsims/joist.git
git clone https://github.com/phetsims/kite.git
git clone https://github.com/phetsims/phet-core.git
git clone https://github.com/phetsims/phetcommon.git
git clone https://github.com/phetsims/scenery.git
git clone https://github.com/phetsims/scenery-phet.git
git clone https://github.com/phetsims/sherpa.git
git clone https://github.com/phetsims/sun.git
git clone https://github.com/phetsims/tandem.git
git clone https://github.com/phetsims/query-string-machine.git
当运行第一个git clone命令时,它可能会显示一个对话框,写着:“git”命令需要命令行开发工具。您要现在安装工具吗?在这种情况下,请按“安装”。
- 打开“终端”应用程序
- 从http://nodejs.org/download下载并安装node + npm
- 在开发计算机上启动Node服务程序
- 使用终端用http-server命令安装程序
npm install http-server -g
*如果出现类似“请尝试以root用户/管理员身份运行此命令”的错误,然后使用sudo命令运行如下:
sudo npm install http-server -g - 改成phetsims目录(如果你还没有)。
cd phetsims / - 运行http服务器程序
http-server
- 使用终端用http-server命令安装程序
- 在浏览器中打开模拟的网址:http://localhost:8080/example-sim/example-sim_en.html
现在,您可以测试修改代码,并通过刷新浏览器查看更改。
如果你有公网IP,你还可以使用您的IP地址进行远程测试。
若有问题请直接发送到HTML5 Google群组Developing Interactive Simulations in HTML5 Google Group
创建新模拟演示项目
在克隆下载完上面的依赖内容之后,您可以使用我们的模板创建自己的模拟演示项目。
- 使用git clone命令下载模板sim,名为’simula-rasa’:
cd phetsims
git clone https://github.com/phetsims/simula-rasa.git - 使用npm update安装sim项目的依赖。
cd simula-rasa
npm update - 使用npm update安装chipper依赖项。
cd ../chipper
npm update - 使用方便的’grunt’命令创建一个新的sim,如下所示:
若未安装 grut 先安装
npm install grunt-cli -g
cd ../simula-rasa
grunt create-sim –name=NAME –author=AUTHOR
例如,如果仿真演示将命名为Acceleration Lab,作者是来自PhET Interactive Simulations的Sam Reid,那么您的命令如下所示
grunt create-sim –name=acceleration-lab –author=”Sam Reid(PhET Interactive Simulations)” - 在浏览器中测试创建的模拟程序,以确保它能启动。它应该是一个空白模拟程序。
保证当前目录是在phetsims文件夹下,然后启动WEB服务
http-server
在浏览器中打开模拟的网址:http://localhost:8080/
在下方选择刚才创建的仿真演示程序
若有问题请直接发送到HTML5 Google群组Developing Interactive Simulations in HTML5 Google Group
构建+测试(Windows和OS X)
使用工具chipper构建模拟
- 打开Git Bash(Windows)或终端(OS X)
- cd example-sim
- npm update
- npm install grunt-cli -g
- cd ../chipper
- npm update
- cd ../example-sim
- grunt
- 打开浏览器到路径以进行测试
a. http://localhost:8080/example-sim/example-sim_en.html
使用Git和GitHub
- 拉取最新更改
- 提出问题
- 提交更新
- 发送拉取请求
提出问题
使用Chrome开发工具调试模拟演示程序
源代码和依赖
我们的模拟演示程序和依赖都在GitHub上公开发布
https://github.com/phetsims
我们有40多个用于模拟演示代码仓库程序及其依赖,所有这些都可以在这里找到:https://github.com/phetsims?tab=repositories。
下面是包含各个模拟演示程序所依赖的库和框架的列表。
- Scenery:用于渲染图形和处理输入的常用窗口图形。文档站点
- Axon:用于模型实现
- Assert:用于开发测试的断言框架
- phet-core:继承,扩展和其它功能
- phetcommon:高级通用依赖
- scenery-phet:PhET特定的窗口图形和输入处理程序
- Joist:应用程序加载,启动和处理的框架
- Dot:基于模型视图的数学框架
- Kit:图形库
- Sun:图形用户界面组件,如按钮,复选框等
- Sherpa:我们所有的第三方依赖
从GitHub检出HTML5代码
我们的example-sim代码仓库README.md包括一个git clone命令列表,它将检查示例模拟及其所有依赖项。
https://github.com/phetsims/example-sim
克隆一些我们的开发中的模拟演示代码:
git clone git://github.com/phetsims/forces-and-motion-basics.git
git clone git://github.com/phetsims/build-an-atom.git
所有代码仓库都应克隆到同一目录中,以便代码中的相对路径可以工作。
这里是所有phetsims 代码仓库的完整列表。如果仿真演示不启动,可能是由于缺少依赖,你可能需要检查出更多的这些代码仓库:
https://github.com/phetsims?tab=repositories
还要注意,这将检查所有的依赖代码仓库的“主”分支,如果你更新这此仓库,可能会偶然地遇到一些不兼容的更改。如果您遇到任何不兼容的更改,请立即通知我们。此外,我们建议您在公共仓库(如GitHub)上开发代码,以便在更改通用依赖代码仓库时测试和更新模拟。
未发布的不稳定主分支:访问严格测试的代码
PhET仿真演示代码仓库的主分支正在不断开发中,不能保证稳定。我们的意思是,模拟演示+库的主分支能够正确构建和运行,但有代码还在不断修改中,其中可能引入错误。另一方面,我们发布的模拟演示已经在18个平台上进行了严格的测试,是最稳定的选择。如果您正在调试PhET仿真演示,或者想要访问我们已经正式发布的版本的模拟演示代码,那么您将需要在所有相应的代码仓库中检查特定的SHA修订版本。当在模拟演示的发布候选分支上做开发时,时常签出下载错误修复和测试的也是重要的。这里是说明:
- 首先,确定要检查源代码的版本,例如:http://phet.colorado.edu/sims/html/area-builder/latest/area-builder_en.html
- 导航到同一路径下名为dependencies.json的文件,例如:http://phet.colorado.edu/sims/html/area-builder/latest/dependencies.json
- 将dependencies.json文件下载到模拟目录的根目录。
- 打开命令提示符,并cd进入模拟目录的根目录。
- 运行`grunt checkout-shas`。此步骤将从dependencies.json文件读取,并检查与文件中的条目对应的所有SHA。
- 要检查SHA的仿真本身,首先查找依赖文件中的SHA,将依赖文件移动到其他位置或删除它,然后使用`git checkout`检查相应的SHA。 (注意未来版本的`grunt checkout-shas`可能会处理这个最后一步)。
- 检查模拟演示程序及其依赖性,以确保“grunt checkout-shas”具有为每个代码仓库获得正确的SHA的预期效果
现在可以使用已发布的源代码。要将每个分支恢复为master分支,您可以运行`grunt checkout-master`。
例外和注意事项:
- 运行“grunt checkout-shas”在没有提交工作副本时给出错误。这些grunt命令目前只支持干净的git 代码仓库。这里可能会存在一些问题。此外,如果要使用与SHA不同的版本的依赖代码仓库,则必须手动完成。
- 当在分支中工作时,grunt checkout-master将检查主分支,若想要返回到期望的分支则需要额外的手动操作。例如,在操作brand的“adapted-from-phet”时就会存在这种问题。
以前的(Java / Flash)源代码
打开下面的链接获取以前Java和Flash版本的模拟演示的源代码:
http://phet.colorado.edu/en/about/source-code
签出代码可能需要30分钟以上,模拟演示的源代码位于(例如):
svn-checkout / trunk / simulations-java / simulations / force-and-motion-basics
第三方依赖代码仓库
PhET Simulations使用了大约3个开源第三方依赖代码仓库部署的源代码,它们大多用于构建阶段。它们都包含在sherpa代码仓库中的源代码检查中。库和许可证在第三方依赖性许可文档中描述
许可
新的模拟演示在GPLv3下发布,可重用的库依赖应该作为MIT发布。
编码风格指南
为了提高PhET仿真代码的可读性和可维护性,我们已经确定了几个用于编写代码和文档的样式建议。
我们提供三个主要机制,以确保代码是一个好的风格。 (1)样式指南见下面的细节;(2)chipper jshint任务,它报告在构建仿真演示期间的错误;(3)IntelliJ IDEA代码格式化样式,可以用于自动缩进和格式化代码。我们的示例仿真演示也显示了如何使用我们的库,以及一个很好的代码注释+文档的例子。
对于文件编码,请遵循idiomatic.js(https://github.com/rwldrn/idiomatic.js/)中列出的指南。和规范相比PhET添加了一些特别的规则:
- 所有源文件的第1行应是以下形式的版权注释:
// Copyright 2002-2015,University of Colorado Boulder - 所有源文件应具有一个或多个指示文件作者的@author注释。
- 变量应该在一行上声明,每个变量前面有一个单独的“var”。这使得移动和复制更容易。例如,
var x;
var y;
并不是
var x,y;
也可以是
var x,
y; - 命名(类型,变量,属性,…)应具有充分的描述性和具体性,并应避免使用非标准缩写。例如:
var numPart //不正确
var numberOfParticles // 正确var width //不正确
var beakerWidth //正确 - 在所有字符串两端使用单引号。例如:
console.log(‘This is a test。’); //正确
console.log(“This is a test。”); //不正确 - 所有JavaScript脚本都应该使用requirejs进行模块化,并且应该调用严格模式。例如:
define(function(require){
‘use strict’;
// tec.
}); - Require语句应该被组织成块,首先是代码模块,然后是字符串,图像和音频(字符串/图像/音频的顺序可互换)。对于模块,变量名称应与文件名匹配。示例如下。
//模块
var inherit = require(‘PHET_CORE / inherit’);
var Rectangle = require(‘SCENERY / nodes / Rectangle’);
var Line = require(‘SCENERY / nodes / Line’);// 字符串
var kineticString = require(‘string!ENERGY / energy.kinetic’);
var potentialString = require(‘string!ENERGY / energy.potential’);
var thermalString = require(‘string!ENERGY / energy.thermal’);// 图片
var energyImage = require(‘image!ENERGY / energy.png’);// 音频
var kineticAudio = require(‘audio!ENERGY / energy’); - 对于构造函数,使用没有默认值的参数。对具有默认值的项使用选项。这提高了调用的可读性,特别是当参数数量较大时。它还消除了使用参数所需的顺序依赖性。
例如,此构造函数使用所有参数。在调用时,参数的语义很难在不查看构造函数的情况下确定。
/ **
* @param {Ball} 球模型元素
* @param {Property。<boolean>} visibleProperty – 球是否可见?
* @param {Color | string} 填充 – 填充颜色
* @param {Color | string} 笔触笔触颜色
* @param {number} lineWidth – 笔画的宽度
* @constructor
* /
function BallNode(ball,visibleProperty,fill,stroke,lineWidth){
… …
}}
//调用时
var ballNode = new BallNode(ball,visibleProperty,’blue’,’black`,2);这里是相同的使用了适当选项的构造函数。调用时更容易阅读,选项的顺序是灵活的。
/ **
* @param {Ball} 球模型元素
* @param {Property。<boolean>} visibleProperty – 球是否可见?
* @param {Object} [options]
* @constructor
* /
function BallNode(ball,visibleProperty,options){
options = _.extend({
fill:’white`,// {Color | string} 填充颜色
stroke:`black`,// {Color | string}描边颜色
lineWidth:1 // {number}笔画的宽度
},options);
… …
}}//调用
var ballNode = new BallNode(ball,visibleProperty,{
fill: ‘blue`,
stroke: ‘black`,
lineWidth:2
}); - 构造函数和函数文档。应使用@param注释为每个函数和构造函数(如果有任何参数)明确指定参数类型和名称。每个参数的描述应该是连字符。原始类型应使用小写。构造函数应该另外包括@constructor注释。例如:
/ **
* PhetDeveloper负责创建模拟代码
*彻底记录他们的代码。
*:
* @param {string} name – 全名
* @param {number}年龄,以年为单位
* @param {boolean} isEmployee – 此开发人员是否是CU的员工
* @param {function} callback – 在咖啡消耗后立即调用
* @param {Property。<number>} hoursProperty – 累计工作时间
* @param {string []} friendNames – 朋友的名字
* @param {Object} [options] – 可选配置,请参阅构造函数
* @constructor
* /
function PhetDeveloper(name,age,isEmployee,callback,hoursProperty,friendNames,options){…} - 对于大多数函数,应使用与上述相同的形式,带有@return注释,用于标识返回值的类型和含义。函数还应记录任何副作用。对于仅仅是几行简单代码的非常简单的函数,可以使用缩写的行注释,例如://基于{Foo} foo计算{Number}距离。
- 如果需要引用封闭对象,例如对于闭包,应该使用“self”,但它只应在闭包中使用。除非在闭包中需要,否则不应该定义’self’变量。例:
var self = this;
someProperty.link(function(){
self.doSomething();
});
this.doSomethingElse(); - 因为JavaScript缺少作用域修饰符(public,protected,private),PhET使用JSdoc作用域注解来记录程序员的意图,并定义公共API。 JavaScript公开的任何内容都需要作用域注释。有关这些注释的信息可以在这里找到。 (注意,其他文档,比如Google Closure Compiler在某些情况下使用略有不同的语法,如果有区别,请遵照JSDoc是约定,例如,使用Array.<Object>或Object []而不是Array <Object>。 PhET指南的作用域注释如下:
- 使用@public声明是公共API。
- 使用@protected声明在子类型中可以使用。
- 使用@private声明为私有,不是公共或受保护的API。
- 将限定符放在注释后面的括号中,例如:
- 要指定某内容为只读,请使用“@public(read-only)”
- 要限定对特定存储库公开,请使用(例如)“@public(scenery-internal)”
- 用逗号分隔多个限定符。例如:“@public(scenery-interior,read-only)”
- 对于JSDoc样式的注释,注释应该显示在上下文中,如下所示:
/ **
* Creates the icon for the “Energy” screen, a cartoonish bar graph.
* @returns {Node}
* @public
* / - 对于行注释,注释可能如下所示:
// @public添加一个{function}侦听器
addListener:function(listener){…}
- 注释不应超过120列,并且应该插入换行符,以便在超出第120列的单词之前插入多行注释。如果代码行超过120列,它们也应该被分解。
- 在需要继承的地方,使用phetcore.inherit。通过适当的添加属性和静态函数来实现继承。空格应存在于函数名称之间,除非函数全部短且密切相关。例:
return inherit(Object,Line,{
// Convenience method for creating a line with a different color.
withColor:function(color){
return new Line(this.x1,this.y1,this.x2,this.y2,color);
},
toString:function(){
return’Line [x1 =’+ this.x1 +
‘y1 =’+ this.y1 +’x2 =’+ this.x2 +’y2 =’+ this.y2 +
‘rise =’+ this.rise +’run =’+ this.run +’color =’+
this.color.toString()+’]’;
},// Returns true if 2 points on specified line are also on this line.
same:function(line){
return(line!== null)&& this.onLineXY(line.x1,line.y1)&&
this.onLineXY(line.x2,line.y2);
},// Returns true if the slope is undefined.
undefinedSlope:function(){
return this.run === 0;
},// Gets the slope. Returns NaN if slope is undefined.
getSlope:function(){
if(this.undefinedSlope()){
return Number.NaN;
}}
else {
return this.rise / this.run;
}}
},/*
* Given x, solve y = m(x – x1) + y1. Returns NaN if the solution is
* not unique, or there is no solution (x can’t possibly be on the
* line.) This occurs when we have a vertical line, with no run.
*/
solveY: function( x ) {
if ( this.undefinedSlope() ) {
return Number.NaN;
}
else {
return ( this.getSlope() * ( x – this.x1 ) ) + this.y1;
}
}
} ); - 应该使用点运算符而不是括号运算符调用方法。有关更多详情,请参阅https://github.com/phetsims/gravity-and-orbits/issues/9
例如:不要这样:
self [isFaceSmile? ‘smile’:’grimace’]();
推荐如下
isFaceSmile? self.smile():self.grimace();
要么
if(isFaceSmile){
self.smile();
}}
else {
self.grimace();
}} - 属性的命名:所有AXON / Property实例应使用后缀`Property`声明。例如,如果添加了visible属性,它应该具有名称`visibleProperty`而不是简单的“visible”。这将保证与PropertySet创建的Properties一致,并有助于避免与原始(非Property)值的混淆。
- 在新的仿真演示代码中Property的使用优先于PropertySet。这主要是因为:PropertySet支持ES5 setter和getter,所以例如。 this.positionProperty可以作为this.position来访问或修改为this.position = new Vector2(1.23,4.56)。虽然方便,但是这会导致读者认为this.position是一个普通的变量还是一个PropertySet实例的简写而分辨不清。当使用Property时,赋值必须这样:
this.positionProperty.set(new Vector2(1.23,4.56)) 或
this.positionProperty.value = new Vector2(1.23,4.56)
虽然字多了些,但这种语法是明确的。同样,使用
this.positionProperty.get() 或
this.positionProperty.value
访问。 - 行注释前面应有空行。例如:
// Randomly choose an existing crystal to possibly bond to
var crystal = this.crystals.get( _.random( this.crystals.length – 1 ) );// Find a good configuration to have the particles move toward
var targetConfiguration = this.getTargetConfiguration( crystal ); - 行注释应该在//和行注释的第一个字母之间有空格。请参见前面的示例。
ESLint应该用于检查源代码的有效性。使用ESLint检查源代码将是构建和部署过程的自动步骤,如果未通过ESLint检查,将中止部署。
在返回类构造函数时,文件应命名类似于CamelCasing.js,或在返回函数时命名类似于lower-case-style.js。当返回构造函数时,构造函数名称应与文件名匹配。
HTML5 / CSS3 / JavaScript源代码必须有相当好的文档。这很难精确地指定,但是要指出的是,有中度经验的HTML5 / CSS5 / JavaScript的开发人员可以通过阅读评论,快速了解源代码的大概功能以及代码的整体流程。有关所需文档类型的示例,请参见示例模拟。
平台
仿真演示应该在下面链接的平台上进行测试和运行。根据我们迄今为止的经验,在iPad等平板电脑上经常需要进行一些优化以获得可接受的性能。
https://phet.colorado.edu/en/help-center/running-sims/general#q11-header
模块化和RequireJS
当前的JavaScript实现(ECMAScript 5)不直接支持模块化JavaScript开发。 RequireJS将用于支持JavaScript代码的模块化。关于RequireJS的信息可以在http://requirejs.org/找到。有关PhET如何使用的示例可以在https://github.com/phetsims/example-sim上的示例模拟代码中看到。特别说明,要下载config.js文件,grunt.js构建文件和js目录中的源文件。
PhET将考虑内置的AMD支持,它将成为ECMAScript 6的一部分。
布局
设计:
最小宽度x高度:768×504(1.52:1,在Mobile Safari内)
仿真演示应该等比例缩放,使得所有部分在任何分辨率下可见。这种类型的缩放示例可以在示例仿真演示中看到。
编译代码
压缩和合并的代码在我们的代码仓库 https://github.com/phetsims/chipper中实现。这可用于创建包含所有图像和音频的单文件HTML,并且适合下载以供离线使用。
离线操作
这是对所有PhET仿真演示一个要求,可以下载并在所有指定的浏览器中,从file:// URL离线运行。 PhET的chipper 构建过程(如上所述)产生可以下载以供离线使用的单个文件。请确保您没有使用任何线上APIs,以防止在离线时使用file:// URL正确启动和运行,并测试离线操作适用于您的仿真演示。
发布版本
这里是一些发布的仿真演示的链接,以便您可以看到仿真演示所应该具备的样式和功能:
http://phet.colorado.edu/en/simulations/category/html
开发过程和检查表
给定现有的Java / Flash版本或开发规范,创建完全功能的PhET仿真演示的步骤:
- 仿真及其代码:
- 必须以正确的方式使用合适的库
- 必须充分评论
- 必须没有死代码(即注释掉的代码,什么都不做的代码)
- 必须可维护
- 可重复使用的组件应优雅的移至适当的库
- 应该在运行chipper时通过所有jshint测试,并且应该编译成单个文件的HTML文件
- 在images /目录中出现的任何原始矢量图稿都应该被检入assets /目录。
- 必须使用异常处理(断言),而不会抛出任何错误信息
- 2.仿真和用户界面测试
- 测试我们支持的平台和标记不同浏览器上的问题
- 所有支持的平台上的性能必须足够快。
- 仿真演示应该在iPad3上在<8秒内启动
- .我们努力在iPad3上做到稳定的60fps
- 仿真演示应该使用断言进行测试
- 仿真演示应该测试触摸方式操作
- 代码审查
- 代码将由一个或多个PhET开发人员审查,以识别可能的错误或维护问题
- 将讨论审查中提出的问题
- 释放候选测试
- 在发布之前,创建发布候选分支,以便可以彻底测试分支,如果没有发现重大错误,则发布
- 正式发布
- 仿真演示在PhET网站上上架使用
- 维护
仿真演示被发布,学生或教师报告的任何错误都将被解决
用于开发和测试的实用程序和工具
仿真演示的许多方面必须正确地开发,并且工作良好,以便模拟在许多支持的平台上正确地运行。 PhET已经开发了几个实用程序和工具,使这个开发和测试更容易。查询参数的最新文档位于此处:
https://github.com/phetsims/chipper/blob/master/js/initialize-globals.js
- 查询参数:screenIndex此查询参数可用于指定仿真演示的初始屏幕。它可以单独指定,以启动仿真演示的特定屏幕。例如:
http://localhost:8080/energy-skate-park-basics/energy-skate-park-basics_en.html?screenIndex=1&standalone
启动Energy Skate Park:简单的使用第二种屏幕。 - Phet垃圾回收:对象实例分配跟踪,所以我们可以减少垃圾收集。请参阅https://github.com/phetsims/phet-core/blob/master/js/phetAllocation.js
使用示例:- 运行仿真演示并按你的要求进行设置
- 在JS控制台中,键入:window.alloc = {}
- 等待,直到您获取足够的数据
- 键入x=window.alloc; delete window.alloc;
现在可以检查变量x中包含的分配信息。
- 查询参数:ea。此参数用于“启用断言”。模拟器应该运行并且不会在此模式中触发任何断言错误。
- 查询参数:showPointerAreas。此查询参数显示鼠标和触摸输入事件的区域。在移动设备(有时是鼠标)上,必须为交互区域增加感知点。触摸区域显示为红色,自定义鼠标区域显示为蓝色。
- makeRandomSlowness()在启动仿真演示以模拟暂时运行缓慢的系统之后,可以调用此方法。这可以用于帮助复制仅在暂时运行缓慢的平台上发生的错误。要调用此方法,请启动仿真演示,显示开发人员控制台,然后键入如上所示的命令。
- makeEverythingSlow()这个方法可以在仿真演示启动后用来模拟底速系统之后被调用。这可以用于帮助复制暂时运行缓慢平台上发生的错误。要调用此方法,请启动仿真演示,显示开发人员控制台,然后键入如上所示的命令。
- 查询参数:’profiler’。使用profiler启动仿真演示将打印出创建每个屏幕的时间,并将显示一个直方图,每60帧更新一次,描述帧占用的时间(以毫秒为单位)。
Note: just showing the average FPS or ms/frame is not sufficient, since we need to see when garbage collections happen, which are typically a spike in a single frame. Hence, the data is shown as a histogram. After the first 30ms slots, there is a ++= showing the times of longer frames (in ms) - 单元测试的使用:更改其中一个代码仓库之后运行单元测试(参见test / qunit是否存在),运行单元测试(tests / qunit / unit-tests.html)以查看是否有任何问题。我们强烈建议检查“隐藏已通过的测试”,并等待所有测试完成(可能在首个测试完成时暂停)。
- 添加单元测试:如果要添加一个测试,将它添加到具有QUnit模块(‘…’)声明的测试/ qunit / js / *文件之一,并阅读QUnit教程以了解如何有用。您可以通过创建文件并在tests / qunit / js / unit-tests.js(其目的是加载这些文件)中引用它来添加具有更多测试的新文件。
- 单元测试和游乐场的命名空间:每个unit-tests.html使某些命名空间全局(e.g. Scenery’s makes window.scenery/kite/dot/axon/core for Scenery/Kite/Dot/Axon/phet-core respectively)。因为单元测试不直接使用require.js(对于Scenery / Kite / Dot,他们需要使用独立的构建库版本),命名空间用于访问类型。例如,使用“new scenery.Rectangle(…)”。
- Playground:如果存在,它将是一个tests/playground.html,并允许在控制台中测试代码。要使代码在控制台中可用,请检查playground使用的“main”文件,并在其中添加引用。例如,Scenery的playground.html将’main’加载到内部require()语句的第一个数组参数,并将其保存到window.scenery。在require.js中,这将js/main.js的返回值设置为window.scenery,而在Scenery的特定情况下,它返回在所有单元测试中使用的库命名空间。此外,使用单位测试的相同命名空间。
使用GitHub提出问题
当在GitHub提出的问题被解决了时,在问题回复中会提出解决方案,问题会重新发送给GitHub问题的提问者,以进行验证和关闭。在GitHub提出问题的还应该在提交消息中引用该问题,因此可以轻松地检查更改。
下面是一些示例问题,显示问题的创建,使用引用问题的提交消息解决问题,解决方案的解释以及重新发送给报告人以进行验证和关闭:
https://github.com/phetsims/color-vision/issues/15
https://github.com/phetsims/fraction-matcher/issues/56
https://github.com/phetsims/color-vision/issues/37
在您的网站中嵌入仿真演示
要在您的网站中嵌入仿真演示,请使用如下所示的iframe:
<iframe src=”http://phet.colorado.edu/sims/html/forces-and-motion-basics/latest/forces-and-motion-basics_en.html” width=”834″ height=”504″></iframe>
宽高比834×504用于新的仿真演示,因为它与流行设备上可用的宽高比相匹配。
要在上下文中查看完整的嵌入示例,请查看此页面的源代码:
http://www.colorado.edu/physics/phet/dev/html/acid-base-solutions/1.1.0/acid-base-solutions_en-iframe.html