??xml version="1.0" encoding="utf-8" standalone="yes"?> q是六月初完成的一个游?/span> 两个月时间终于完成了我们的涂鸦秀U目Q与同类产品相比Q我们内Ҏ多些Q分为双人对战模式,多h模式Q相信可以同时在U很多h?/span> 技术上实践了一把前后端?/span>js的游戏。算是过了把瘾。用?/span>nodejsQ?/span>socket.ioQ?/span>phonegapQ?/span>express框架和其他细枝末节。一路上我们披荆斩棘Q果然爽?/span> 其实从项目需求到解决各个?/span>bugQ真是刷了若q个?/span> q样的项目特点就是能在各手机上玩Q包?/span>ipodQ?/span>pad?/span>Pc上只要支?/span>canvas也可以一LQ多好的一个大融合。当然其实要兼容ie6也不是什么难事,隑֜我根本没旉理了Q真不好意思。简单说是跨^台。适配的机器也较多Q能有较q的众基础?/span> 我们也有好友pȝQ分享,邀P当然不会做深Q我们的目标是先吸引住市场,然后再集中力量对用户喜欢的点做深入研发?/span> 做完后同学陪我玩好长旉Q他很喜Ƣ玩Q这一点让我比较欣慰。感觉画图游戏来源于人类的自恋,人类天然喜欢用图来表达意思。只是世界上的系l还是符L多?/span> 如图Q?/span> SouApp.comq给我们盖了章,我特地确认了一下,q是人家d盖的章。在审核的时候就下蝲了一癑֤ơ。当然我也不知道q算什么概c至觉得有人感兴趣Q其实这游戏对美术是乐事Q他们功底好Q?/span>pc上有自己的画图板Q画h非常专业。赢点小C品Ҏ不是问题。当然以后的版本会更好,更吸引h。已l有不少xQ可改进的地方也不少?/span> 如下是一些界面截?/span> 一些小作品 下蝲地址 http://souapp.com/app_detail/?appid=aaf7a621-205a-4c73-a88b-a5ef3ebb9431 http://www.appchina.com/soft_detail_291505_0_10.html 游戏地址 m.tuyaxiuxiu.com 360.tuyaxiuxiu.com google.tuyaxiuxiu.com 官网地址 两个月我们都做了什么? 术需求,协议定制Q详l编码,?/span>bugQ手机测试,E_服务Q官|搭建,后台搭徏Q推q运l。非常多的细节,充实有趣?/span> 现已通过sina,google{各大^収ͼ能搜到精选,分nQ当然不是我们自己弄的,比如下面q个_N,人家是还要注册才能下载的C。我们自己搞q种p头了?/span> 如果大家觉得两个月太长了Q其实试试就知道Q光推广够累的Q各个^台各U限制。不玩得技术欲仙欲L怪。官|,后台Q各U修Ҏ新。甚臛_都要自己Ҏ。开始半个月Q美术需求就写了10ơ,不敢说每ơ都很详l,但也够有调理和详l的了?/span> 不过从中也获得不经验,本来规划非常短的旉来完成,q个按照很理想的条g来处理的话。当然其实也准时完成了,只不q我们又要了加倍的功能Q而我们的人数从开始实施时减了一半。这L条g下,没报告什么特别的Q既然说了就做吧Q通宵很多个晚上,弄得我经常v不来?/span> 另一些感触就是积极加入各U思考分析中好Q根本不要去考虑回报Q这个世界上能去考虑回报的hq不多?/span> 其实其中有的地方不太CQ比如分享界面、官|、统计分析。只能等人来帮忙了?/span> 如下图是当时做的一个极限测?/span> 当时数据量一大就丢失数据。于是自己做了个~码方式Q减数据量Q这个图证明的就是只要网l能传输Q内容再多都能处理?/span> q个游戏的不好之处就是必L一定的玩家基数才能带动h。另外,我们开发很多功能其实没必要Q先开发主要功能,看市场反应,在进一步开发才有意义。于是有了下一个游戏,见下一?/span> 转眼又过了几个月Q但是这几个月做了好多游戏,疯狂了。其中做的第一ƾ游戏今天进?/span>google应用首页最上面的图。如图中Q有好多金币那个图,是我们的游戏。一个非常简单的游戏?/span> q个游戏名称叫砸金币水果机,我们做了英文版,中文版,ios?/span>,andriod版。如下就是英?/span>andriod版,模仿街机风格Q颇有怀旧的味道。当然技术上我ƈ不看好这ƾ游戏,但实际效果却不好_囄_Q物理效果不错,触发的神奇界面不,q游戏屌丝对街机是否着q了。估计也是这些原因导致被google推荐吧,我们也没׃Q何一分钱买推荐?/span> 其实我更x荐的是多人网上互动的手机游戏Q希望在下一给大家做介l?/span> 现在我们发现最火的语言成了javascriptQ原因是html5的推出,其实原理上讲Q这个语a也是必然要火的,首先人类交互最密集的地方{Ud互联|上了,人类交互的重要性是不言而喻的,p求我们的|页有更多的功能Q而这个功能的提供者第一个是jsQ且语言z,开源,q就奠定了它的竞争力基础。有了这些基后,最大数量的研究人员都会在这上面。如果将it产业比喻成火山,那么|络q部分就是岩部分,是变化最快的地方。一开始都是最专业的h研究底层Q当q些底层成熟后,应用层就快速发展v来,推陈出新非常快?/span>Html5推出h们最常用的应用以很简z的方式表达出来Q?/span>nodejs?/span>js推向后端Q?/span>socket.io加速交互效率和交互设计。当然有非常多的js框架都出来了。这里不具体说了?/span> q几个月的经验ȝ希望l大家一些启发, 如果我们做一个跨q_手机游戏发最好做好以下准?/span> Js熟好Q不要以为它真的很简单,要做手机游戏Q必d会优化,如果是客LQ要求很高,如果在绘图时M大堆对象Q?/span>andriod一定会q不ȝ。那么就一斚w研究jsQ我的徏议是Q不要去啃面向对象,代码清晰Q规范最重要Q,一斚wl读html5规范吧?/span> ?/span>java基础Q那么在?/span>phonegap打包?/span>andriodpȝ下时Q就能较快明白怎么做配|,怎么d插g和用?/span>Java?/span>js都不错的话那么写Ҏ件也不错。有的功能是必须用插件的哦?/span> 有点andriod设计的基Q我是没什么基Q所以也׃时间研IӞ其实qI它的一些配|关pR也会有烦h问题的?/span> 有点mac下的xcode基础Q?/span>xcode的基本的使用最好明白,否则q是要花不少旉摸烦Q对?/span>macpȝ的设计,我实在不太苟同,虽然我能挺快适应。至?/span>ocQ会一些也更好Q这h便用插件和写插件?/span> 惌?/span>app storeQ越早申误̎P早提交好Q遇到的问题非常之多。也许怪物英文不好Q?/span>mac不熟吧?/span> 当然g上最好有几个手机Q?/span>ipod,pad做测试,ipad3其要测?/span> 你还会遇到的问题Q比如手机屏q适配Q音乐的使用Q兼Ҏ览器{?/span> 另一个徏议就是认准了自己喜欢的,一头扎q去动手是了?/span> q篇文章M质量不高Q没l大家讲讲技术细节,商业游戏Q不太方便哈Q会l大家讲开源的。甚x的地方可能讲p也欢q批评指出。本完?/span> 游戏地址1Q?/span>http://app.baidu.com/273943 游戏地址2Q?/span> https://chrome.google.com/webstore/detail/jdjcanmclknahldoohmphkiicmggghdf?hl=zh-CN Q要?/span>chrome下安装过才可玩) 本来一直觉?/span>js是个让h混ؕ不堪的语aQ?/span>html5的出现改变了我对它的看法。到?/span>html5的时代,各种犀利的设计更明显的需?/span>js了。看了一些小游戏设计Q忽然来了兴,于是写了几个游戏,q是其中一个。已l开源,Ƣ迎下蝲https://github.com/yangyusong/ChainReaction?/span> 游戏叫连锁反应,q个游戏是看到有人在ipad上面玩的游戏Q觉得好玩,自己实现一遍。游戏是q样的,一小球在区域内弹来弹去,玩家鼠标点击一个地方,在一个圆的范围内Q小球碰上就会爆炸,爆炸的过E中其他球C也会发生爆炸Q这叫q锁反应。每一关爆破一定数量的球q胜利?/span> 我的设计中一个有20养I数值增长比较^和,q气不是太差的话都能一ơ通关。在说有个再玩本U的功能Q过一关的压力是一炚w没有。这栯计是Zl工作后的朋友缓解压力。我们轻杄一点就爆炸一片?/span> 看看截图 大的那个灰色的(其实是半透明的)圆是鼠标范围。其他是Ҏ弹去的小球。可以看刎ͼ球是各U颜色的?/span> 我们看看球的定?/span> function Circle(x, y, xSpeed, ySpeed, radius, color, liveTime, state){ //圆心坐标 this.x = x; this.y = y; //q动速度 this.xSpeed = xSpeed; this.ySpeed = ySpeed; //半径 this.radius = radius; //颜色 this.color = color; //生存计数?/span> this.liveTime = liveTime; //状态: this.state = state; } 其中生存计数器是要和状态结合用的Q状态分为如?/span>5个状?/span> //球状?/span> var SMALL = 0; var BIG = 1; var EXPEND = 2; var END = 3; var DIS_VISIBLE = 4; 当处?/span>EXPEND状态的时候,p明小球进入爆炸状态,q时候生存计数器q上了。计数器是个倒计Ӟ计时到零Q小球进?/span>DIS_VISIBLE状态。这时候小球就不再渲染出来?/span> 我们的小球有不同大小Q不同颜Ԍ看看球的初始化q道了Q代码在ObjectMgr.js?/span> for(i = 0; i < g_StepsArr[g_Steps].ballsNum; i++){ //_Util.dump_obj(_Color.color_str(new Color(Math.random(), Math.random(), Math.random()))); var raduis = _Util.random_range(SMALL_RADIUS1, SMALL_RADIUS2); this.circles.push(new Circle( _Util.random_range(raduis*2, this.canvasWidth-2*raduis), _Util.random_range(raduis*2, this.canvasHeight-2*raduis), _Util.random(SPEED_MIN, SPEED_MAX), _Util.random(SPEED_MIN, SPEED_MAX), raduis, _Color.color_rgba_str(new Color1(Math.random(), Math.random(), Math.random(), 0.8)), MID_LIVE_TIME, SMALL )); } 其中g_StepsArr负责我们兛_的管理,有这一关的球敎ͼ和通关需要爆破的球数。MQ这里按照本关需要的球数初始化球Q可以看到里面有很多的随机函C用。小球的半径处于如下两个C?/span> var SMALL_RADIUS1 = 3; var SMALL_RADIUS2 = 10; 通过random_range来进行这个范围随机。我们看到速度也是随机的,范围?/span> var SPEED_MIN = 10; var SPEED_MAX = 50; 颜色中的color_rgba_str函数的第四个参数说明我们的每个小球的透明度是0.8Q这h们就能在爆破的时候,或弹动的时候仍然看清其他小球。这D代码就说到q?/span> 我们讲讲主要程Q其实其中的详细注释Q我觉得已经可以教会很多初学者。不q还是讲讲好。主要流E就?/span>Main.js中。负责初始化Q渲染和循环。开始我们设|了一堆全局变量?/span> var g_ObjectMgr = null; var g_MouseEventDispatch = new MouseEventDispatch(); var g_MouseMgr = null;//g_MouseMgr?/span>g_ObjectMgr初始化后才初始化 //当前?/span> var g_Steps = 1;//todo 昄出来 //兛_数组 var g_StepsArr = []; g_StepsArr = stepsInit(); //爆炸开始标?/span> var _ExpendStart = false; if(DEBUG){ _CircleLib.test(); } var _Main = { 。。?/span> 包括兛_数组Q当前关敎ͼ爆炸标识{。居然还讄了一个是否调试的状态量Q其实我也不知道js调试怎样才好Q基本就按自q方式调?/span> _Main是个很大的结构。我更宁愿把它当做单例来思考。主要是Q它包括了渲染,q个渲染不具通用性,仅此一例就够。其他地方用了且不是d什么就难说了。当然已l设计其实我会更多考虑通用性的设计Q尽量不设计成这U单例?/span> q个_Mainl构中有我们的画?/span>canvas,我们的初始化函数Q每兌用一ơ,它来负责2d对象的初始化Q游戏对象的初始化。鼠标监听初始化。然后就是进入我们的循环。@环很单,干四g事情 /* * 循环l图 * 1.清空画面 * 2.游戏对象关系处理 * 3.渲染出来 * 4.循环调用 */ step: function(){ this.clear(); g_ObjectMgr.step(); this.render(); _this = this; this._st = setTimeout(function(){ _this.step(); }, 50); } 看看我们的下一关都q些什?/span> /* * 下一?/span> */ nextStep: function(){ clearTimeout(this._st); if(this.canvas.getContext) { g_MouseEventDispatch.start(); this.initObjects(); this.step(); } } 它就是清除计时器Q重新分配事Ӟ初始化对象。然后进入@环,Z么是q样呢?清除计时器以使我们之前的循环停止。因为我们马上有新的循环了,其实事g可以看做有两个状态,我们按下鼠标的时候,q个事g׃可用了,下次使用必须初始化。小球数量变了,必须按照本关的需求来初始化。进入@环,新的循环开始?/span> 看看再玩一ơ(本Q按钮的调用Q?/span> /* * 再玩一ơ(本Q?/span> */ again: function(){ this.nextStep() } Z么居然是调用下一兛_Q只能说我设计的太懒惎ͼnextStep()本nҎ不管兛_的变更。关卡的变更完全在爆炸检查函数里Q一旦发现小球爆炸,׃修改当前兛_。而单U调?/span>nextStep所使用的关卡是未改变过的,故而是在玩本?/span> 我们再看一?/span>ObjectMgr.js中的爆炸查函?/span> expendCheck: function(){ if(_ExpendStart){ this.expendNum = _CircleLib.intersect(this.circles, g_MouseMgr.mouseCircle); // _Util.dump_obj(g_StepsArr[g_Steps]) if(this.expendNum >= g_StepsArr[g_Steps].killNum){ var next = g_Steps + 1; alert("成功爆破过"+this.expendNum+"个小球,恭喜q入W?/span>"+ next + "养I\n\ 下一关需要爆?/span>" +g_StepsArr[g_Steps + 1].killNum + "个小?/span>"); g_Steps++; _Main.init(); } } } q记?/span>_ExpendStartq个变量的意思么Q就是说鼠标是否按下了,按下的话我们p查是否有球撞上鼠标范围或撞上爆怸的小球。其实这里的调用_CircleLib.intersectq个函数是有些小问题的。它是通过引用修改的当前小球的状态,至于Z么有很少量的球未修改状态,q个我还没弄明白。MQ这个函数检查了爆炸球的数量,一旦爆炸小球的数量W合本关的要求,那么可以进入下一养I可以看到我们q入下一关的提示是一个对话框Q不是很友好Q可以设计ؓ一个图片较好,可惜我没旉扄术?/span> 点击定Q我们玩下一?/span> 球多了很多Q找个好点的位置Q能捕捉很多球?/span> 看一下爆炸过E吧Q?/span> q是W十八关的一个爆炸情形,更具体的内容Ƣ迎看具体代码吧Q要不还讲好长时间?/span> 做完q个例子Q发现其实非常多的小游戏很好设计Q可惜没那么多时_再说设计别h设计q的游戏也不是我的目标。设计一些有的游戏到手机里,q个倒是个不错的方向
好在Q过了一D|_忽然想看看ruby的那两本书,然后q上这个语a了。于是做一些想做的试验Q一些试验需要做些配|,对安装目录也׃解了。下载一些插件居然自pCruby的下载页。看C面居然一个版本有3栯下的Q帮助文件和安装文g不就够了吗。还要一个mingw做工具么Q这个不是有自己的官|下载么。也没管。想起ruby目录下include中有i386-mingw32Q才联系h。应该是以mingw做make工具的。rails应该需要makeQ因为每ơ安装都抛出make出错信息。虽然有mingw官网Q但q里应该是做成自q插g。于是到下蝲http://rubyforge.org/frs/?group_id=167下蝲相应版本的mingw32工具解压覆盖到安装目录中Q要是怕出问题先对目录做备?br />
另外下蝲不了的都cross wall下蝲
C:\Documents and Settings\Administrator>gem install rails
ERROR: Error installing rails:
The 'json' native gem requires installed build tools.
Please update your PATH to include build tools or download the DevKit
from 'http://rubyinstaller.org/downloads' and follow the instructions
at 'http://github.com/oneclick/rubyinstaller/wiki/Development-Kit'
q有错,但明显不是曾l报的make错误了?br /> 按照|址下蝲和遵从上面的Ҏ安装卛_Q下面的命ox按照安装Ҏ安装的)
其中config.yml文g仅仅描述ruby所在\径,修改成你的ruby路径卛_
D:\>cd D:\Ruby192\devkit
D:\Ruby192\devkit>ruby dk.rb init
[INFO] found RubyInstaller v1.9.2 at D:/Ruby192
Initialization complete! Please review and modify the auto-generated
'config.yml' file to ensure it contains the root directories to all
of the installed Rubies you want enhanced by the DevKit.
D:\Ruby192\devkit>ruby dk.rb review
Based upon the settings in the 'config.yml' file generated
from running 'ruby dk.rb init' and any of your customizations,
DevKit functionality will be injected into the following Rubies
when you run 'ruby dk.rb install'.
D:/Ruby192
D:\Ruby192\devkit>ruby dk.rb install
[INFO] Updating convenience notice gem override for 'D:/Ruby192'
[INFO] Installing 'D:/Ruby192/lib/ruby/site_ruby/devkit.rb'
D:\Ruby192\devkit>gem install rdiscount --platform=ruby
Fetching: rdiscount-1.6.8.gem (100%)
Temporarily enhancing PATH to include DevKit...
Building native extensions. This could take a while...
Successfully installed rdiscount-1.6.8
1 gem installed
Installing ri documentation for rdiscount-1.6.8...
Installing RDoc documentation for rdiscount-1.6.8...
D:\Ruby192\devkit>ruby -rubygems -e "require 'rdiscount'; puts RDiscount.new('**
Hello RubyInstaller**').to_html"
<p><strong>Hello RubyInstaller</strong></p>
下面安装rails
D:\Ruby192\devkit>gem install rails
Temporarily enhancing PATH to include DevKit...
Building native extensions. This could take a while...
Fetching: rdoc-3.12.gem (100%)
Depending on your version of ruby, you may need to install ruby rdoc/ri data:
<= 1.8.6 : unsupported
= 1.8.7 : gem install rdoc-data; rdoc-data --install
= 1.9.1 : gem install rdoc-data; rdoc-data --install
>= 1.9.2 : nothing to do! Yay!
Fetching: railties-3.2.8.gem (100%)
Fetching: bundler-1.2.0.gem (100%)
Fetching: rails-3.2.8.gem (100%)
Successfully installed json-1.7.5
Successfully installed rdoc-3.12
Successfully installed railties-3.2.8
Successfully installed bundler-1.2.0
Successfully installed rails-3.2.8
5 gems installed
Installing ri documentation for json-1.7.5...
Installing ri documentation for rdoc-3.12...
unable to convert U+00A9 from UTF-8 to GBK for lib/rdoc/text.rb, skipping
Installing ri documentation for railties-3.2.8...
Installing ri documentation for bundler-1.2.0...
Installing ri documentation for rails-3.2.8...
Installing RDoc documentation for json-1.7.5...
Installing RDoc documentation for rdoc-3.12...
unable to convert U+00A9 from UTF-8 to GBK for lib/rdoc/text.rb, skipping
Installing RDoc documentation for railties-3.2.8...
Installing RDoc documentation for bundler-1.2.0...
Installing RDoc documentation for rails-3.2.8...
果然成功了,哈哈
D:\Ruby192\devkit>rails -v
Rails 3.2.8
惛_个实例,搜一下网上的书,q是不行Q那些书最新的2012的都不用命o行做Q?011的还是老的命o行方式。根本没法用Q上官网看就是了?br />D:\Ruby192\devkit>rails new D:/project/ruby/railsapp
create
create README.rdoc
create Rakefile
create config.ru
create .gitignore
create Gemfile
create app
create app/assets/images/rails.png
create app/assets/javascripts/application.js
create app/assets/stylesheets/application.css
create app/controllers/application_controller.rb
create app/helpers/application_helper.rb
create app/mailers
create app/models
create app/views/layouts/application.html.erb
create app/mailers/.gitkeep
create app/models/.gitkeep
create config
create config/routes.rb
create config/application.rb
create config/environment.rb
create config/environments
create config/environments/development.rb
create config/environments/production.rb
create config/environments/test.rb
create config/initializers
create config/initializers/backtrace_silencers.rb
create config/initializers/inflections.rb
create config/initializers/mime_types.rb
create config/initializers/secret_token.rb
create config/initializers/session_store.rb
create config/initializers/wrap_parameters.rb
create config/locales
create config/locales/en.yml
create config/boot.rb
create config/database.yml
create db
create db/seeds.rb
create doc
create doc/README_FOR_APP
create lib
create lib/tasks
create lib/tasks/.gitkeep
create lib/assets
create lib/assets/.gitkeep
create log
create log/.gitkeep
create public
create public/404.html
create public/422.html
create public/500.html
create public/favicon.ico
create public/index.html
create public/robots.txt
create script
create script/rails
create test/fixtures
create test/fixtures/.gitkeep
create test/functional
create test/functional/.gitkeep
create test/integration
create test/integration/.gitkeep
create test/unit
create test/unit/.gitkeep
create test/performance/browsing_test.rb
create test/test_helper.rb
create tmp/cache
create tmp/cache/assets
create vendor/assets/javascripts
create vendor/assets/javascripts/.gitkeep
create vendor/assets/stylesheets
create vendor/assets/stylesheets/.gitkeep
create vendor/plugins
create vendor/plugins/.gitkeep
run bundle install
Fetching gem metadata from https://rubygems.org/.........
Installing rake (0.9.2.2)
Installing i18n (0.6.1)
Installing multi_json (1.3.6)
Using activesupport (3.2.8)
Using builder (3.0.0)
Using activemodel (3.2.8)
Using erubis (2.7.0)
Using journey (1.0.4)
Using rack (1.4.1)
Using rack-cache (1.2)
Using rack-test (0.6.1)
Using hike (1.2.1)
Using tilt (1.3.3)
Using sprockets (2.1.3)
Using sprockets (2.1.3)
Using actionpack (3.2.8)
Installing mime-types (1.19)
Using polyglot (0.3.3)
Using treetop (1.4.10)
Using mail (2.4.4)
Using actionmailer (3.2.8)
Using arel (3.0.2)
Using tzinfo (0.3.33)
Using activerecord (3.2.8)
Using activeresource (3.2.8)
Using bundler (1.2.0)
Installing coffee-script-source (1.3.3)
Installing execjs (1.4.0)
Installing coffee-script (2.2.0)
Using rack-ssl (1.3.2)
Using json (1.7.5)
Using rdoc (3.12)
Installing thor (0.16.0)
Using railties (3.2.8)
Installing coffee-rails (3.2.2)
Installing jquery-rails (2.1.1)
Using rails (3.2.8)
Installing sass (3.2.1)
Installing sass-rails (3.2.5)
Using sqlite3 (1.3.6)
Installing uglifier (1.2.7)
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem
is installed.
D:\Ruby192\devkit>cd D:\project\ruby\railsapp
D:\project\ruby\railsapp>rails server
=> Booting WEBrick
=> Rails 3.2.8 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2012-09-01 06:44:40] INFO WEBrick 1.3.1
[2012-09-01 06:44:41] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2012-09-01 06:44:41] INFO WEBrick::HTTPServer#start: pid=2924 port=3000
览器中输入http://localhost:3000/Q熟悉的界面出现
所以ror厚厚的书d也没用,可能动手q代码都没机会敲?br />
另外也可以到|站http://railsinstaller.org/下蝲配置好的安装包,免L动配|啦?/div>
接着是讲讲内容了,大学学过~译原理很Ҏ理解q其中的内容。yrl文g是erlang中的满LALR-1规范的解析生成器Q相gyacc。会有很多文章做解释Q这里不详述。yrl文g或yacc中的.yq类文g是l我们写~译规则用的Q我们写好一个推理机Ӟ按照规范分解?部分Q放到这一个文件中Q那么yecc可以给我们生成一个符合这个推理规则的解析器,当然q里是生成.erl的源文gl我们用,其中会有parse作ؓ默认Ҏ提供l我们解析我们的字符丌Ӏ?br />
yrl文g中一共有四部分,其实三部分分别用Nonterminals Terminals Rootsymbol关键字来标识Q意义很明显Q非l结W,l结W,起始W(q个忘了怎么译Q。要解释一下也行,一个更好的理解方式是Q非l结W可以在推理W号Q?>Q的左边和右边,相当于函C用,最l分析ؓl结W的l合。终l符只能在推理符P->Q的双。意义就是一个符Ll的基本集合?Rootsymbol是其中一个非l结W,作ؓ推理的v始点。用一解析树来表C的话,Rootsymbol是根节炏VNonterminals是树枝。Terminals是树叶。Q何一个符合此推理规则的字W串都可以用q样一解析树表示出来Q我׃MQ?br />
除了上面说的三部分就剩下最重要的部分了:推理规则。其实这四部分都是列表,只不qRootsymbolq个表只有一个元素。规则列表有多条Q通常每行一条规则,和erlang一L.l束一条规则?br />l结W用单引号引P冒号后面是我们解析后的erlang表达式?1,$2,$3q种怼正则表达式规则,也说一下吧Q就是对冒号左边的元素作为列表ƈ?计数。再搞不懂就发邮局问吧Q呵c?br />
那么q样的一个规则列表就很好建立了,其实q个q程q是有很多规则可以遵循的Q其中这里遵循了左递归Q终l字W先出现的规则优先表达这两条规则。更多,你还可以M有限状态机Q做一下分析,化解Q做成闭包,某些q算q要考虑优先U之cR当然这里这样小的结构基本是最优了Q没什么化解的必要?br />
代码附上
Nonterminals list object kv_list v_list kv k v. % 7
Terminals ',' ':' 'element' '[' ']' '{' '}'. % 7
Rootsymbol object.
object -> '{' '}' : {}.
object -> '{' kv_list '}' : { '$2' }.
kv_list -> kv ',' kv_list : '$1' , '$3'.
kv_list -> kv : '$1'.
kv -> k ':' v : {'$1', '$3'}.
k -> 'element' : '$1'.
v -> 'element' : '$1'.
v -> list : '$1'.
v -> object : '$1'.
list -> '[' ']' : [].
list -> '[' v_list ']' : [ '$2' ].
v_list -> v ',' v_list : '$1' , '$3'.
v_list -> v.
其中objectQlist是json中最基本的结构。kv_list是剥离大括号后的键值对列表。v_list是剥M括号的列表?br />
再讲讲这个解析器的用吧Qjson_parser是yrl文g生成的解析器了,我们qq个解析器来做解析。文件use_json_parser对json_parser的用做了一个包装,那就是parser/1函数了,我们l它传入json字符串就q回解析后的erlang列表。例如我们输入use_json_parser:parser("{a, b, c}").׃q回[{'{',1},
{atom,1,a},
{',',1},
{atom,1,b},
{',',1},
{atom,1,c},
{'}',1},
{'$end',999}]?br /> q个文gq提供一个测试函Cunit_test_()。ؓ了方便大Ӟ我还是讲讲测试方法吧。在命o行输?br />cd erlang_json_parser
erl -pa ./ebin/ -eval "make:all([{d, 'EUNIT'},{outdir, \"./ebin/\"}, debug_info]) ,eunit:test(\"./ebin\",[]),init:stop()"
参考更多的解析器制作,可以参考erlang官网提供的计表辑ּ解析Qlist解析。也可以从其他网站搜到html,xml{的解析,当然如果你看得多一点还会看到aleppo,erlydtlq类的工E。希望更多的Z投入到这些更有意思的开发中。下ơ再写yeccQ就不写q么单的了。哈哈。不要期待在下一里出现哦?/div>
如图Q玩家在b点,点击了a点,a在一个障区Q红Ԍ玩家只能在障区外移刎ͼ。这时候玩家应该走到c点,我们需要计出c点,一个简单的数学题,用什么语a都没几行代码Q我qerlang写一下?br />
障碍物通常都不规则的,我们只能从a点开始一个个Ҏ试,直到不是障碍点,也就是x自增Qy=x*tan(A),然后试q个点,地图数据都是静态的数据Q方便测试,q里写M个x为障结束的地方作ؓ障碍函数?br />
我们q需要一个记录表C点Qtan函数在erlang中是有的Q但其实可以不用Q我们就直接要一个比|但需要一个向上取整的函数Q据说是round函数Q但试一下,不行Q难道是因ؓ不是最新otp
D:\NetBeanPj\mytest\src>erl
Eshell V5.8.1.1 (abort with ^G)
1> round(1.2).
1
所以这里我们要写的一个辅助函敎ͼ最后就是我们的重点Q取最q点Q用一个列表解析就够了Q剩下的q具体实现吧,q可以写个测试函敎ͼq次׃写成单元试了。好的我们看代码Q?br />-module(nearst_point).
-export([ceil/1, is_barrier/1, nearst_point/2]).
-export([p1/0, p2/0, test_1/0]).
%% 一个点
-record(point,{
x,
y
}).
%% 向上取整
ceil(Num) ->
Num1 = round(Num),
case Num1 >= Num of
true ->
Num1;
false ->
Num1+1
end.
%% 判断是否是障物
is_barrier(Point) ->
Point#point.x =/= 5 .
%% 查找最q点
nearst_point(Pointa,Pointb) ->
Tan = (Pointa#point.x - Pointb#point.x)/(Pointa#point.y - Pointb#point.y),
case Pointa#point.x > Pointb#point.y of
true ->
MaxX = Pointa#point.x,
MinX = Pointb#point.x;
false ->
MaxX = Pointb#point.x,
MinX = Pointa#point.x
end,
try
[
begin
Point = #point{
x = X,
y = ceil(X*Tan)},
case is_barrier(Point) of
true ->
ok;
false ->
throw(Point)
end
end|| X <- lists:seq(MinX, MaxX)]
catch
throw: Point ->
io:format("~p", [Point]),
Point
end.
%% 下面函数试用,可以Ҏ单元试Q这里就免了
p1() ->
#point{
x = 1,
y = 9}.
p2() ->
#point{
x = 15,
y = 25}.
test_1() ->
nearst_point(p1(),p2()).
~译和测?br />2> c(nearst_point).
{ok,nearst_point}
3> nearst_point:test_1().
{point,5,5}{point,5,5}
4>
我们的测试如预期的在5那个点得刎ͼ好像有个问题,怎么q个点输Z两次Q哦Q这不是问题Q一个点是代码里的io输出的,一个点是返回给shellQshell的输出,看来写代码的人太懒,疑惑也会增多啊。在nearst_point中用C一个小技巧,是用throw来蟩出@环(q个在erlang中还是挺有意思)Q这ơ到q,应该说写的很基础很难看。下ơ会来点有意思的Q欢q大家学习erlang?/div>
1. 我进了他的网站:http://www.bayke.com/Q内定w怸富,各种分类非常全,一个正规的购物cȝ站。我怿它的前途是好的Q只是知道的太少Q生信M要一D|间?/span>
2. 好像会定时自动刷斎ͼ也许是ؓ了实时性?/span>
3. 他是09q?/span>8月徏的网站,我是今年10月徏的网站。他的是商业|站Q我的是专业|站?/span>
4. 我给他查了一下收录情况,情况如下Q?br />
也就是说h对它的认同比较好Q收录了43个页面(或链接)Q有道,必应有都有一个链接,癑ֺ收录?/span>0Q这个我怀疑不是很准,用另一家的工具查看Q情况如?br />
癑ֺ?/span>26个反向链接,雅虎?/span>43个反向链接,说明哥们写了很多博文Q发了不链接,搜狗收录?/span>12个链接。百度没有收录或说很,我想原因?/span>3Q(1Q可能页面的定时h被百度认为是作弊Q(2Q可能关键词的密度太低,我不知道q个是否真重要到如此E度。(3Q百度是个中文网Q商品网站的词对癑ֺ来说基本都是熟词Q但癑ֺ几乎只收录不熟的Q感觉是原创的网c这些只是猜?/span>
5. 现在做一下密度测试,癑֮Q或baykeQ应该作站的一个关键词Q我们看如下查询l果Q?br />
l果告诉我们在首中Q关键词癑֮的密度是0.2%Q而正常的|页?/span>2%-8%比较恰当Q当焉常不用L在意?/span>
我们在查一?#8220;潇洒甯”分类中的关键字“癑֮”的密度,如图Q?br />
频率特别的小Q我?/span>bayke也在q两个页面查询,l果是一栗徏议站长在各页做长օ键词?/span>
6. 查了一下该站的死链接,做的特别好,没有死链接,如图
该站一׃癑֤站内链接Q?/span>20站外链接Q还能看出站长用的是php写的|站?/span>
7. |站出错时返?/span>404是最好的Q有很多|站Z观面Qd404错误做重定向Q导致出?/span>301{错误,q些错误是会受到引擎处罚的。贵站这点做的不错,q回的是404Q如图:
旉有限Q下ơ再接着分析。欢q到我的|站http://www.suchseo.com/了解更多具体seo内容和对|站的分析方法。一定要看看本站分析Qseo工具Q这些分c,你就知道今天的分析很单,也还实用?/span>
?/span>lzPack1-1
下一步如图:Q你发现?/span>lzPack本n的安装过E和界面是一LQ不q也已经够漂亮了Q是吧)Q以后都是下一步的图)
?/span>lzPack1-2
图lzPack1-3
图lzPack1-4
图lzPack1-5
图lzPack1-6
图lzPack1-7
图lzPack1-8
点击Done完成安装
看看我们sample的结构(卌安装的YӞ
?/span>lzPack1-9
看看安装好的文gl构
?/span>lzPack1-10
了一个文?/span>listenerQ多了一个文?/span>uninstaller,q入uninstaller双击uninstaller.jarq到卸载界面了Q超单的界面Q就不脓了)。我们在回头看看那个配置文ginstall.xml,如下Q?/span>
<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
- <!--
A sample installation file.
Use it as a base for your own installers :-)
To compile it :
- go in the bin directory where you installed IzPack
- call "compile ../sample/install.xml -b ../sample"
-->
- <installation version="1.0">
- <!--
The info section.
The meaning of the tags should be natural ...
-->
- <info>
<appname>Sample Installation</appname>
<appversion>1.4 beta 666</appversion>
- <authors>
<author name="JPz" email="jpz@superman.org" />
<author name="Hidden Man" email="hidden@hisdomain.com" />
</authors>
<url>http://www.anotherworld-inspace-website.net/</url>
</info>
- <!--
The gui preferences indication.
Sets the installer window to 640x480. It will not be able to change the size.
-->
<guiprefs width="640" height="480" resizable="no" />
- <!--
The locale section.
Asks here to include the English and French langpacks.
-->
- <locale>
<langpack iso3="eng" />
<langpack iso3="fra" />
</locale>
- <!--
The resources section.
The ids must be these ones if you want to use the LicencePanel and/or the InfoPanel.
-->
- <resources>
<res id="LicencePanel.licence" src="Licence.txt" />
<res id="InfoPanel.info" src="Readme.txt" />
</resources>
- <!--
The panels section.
We indicate here which panels we want to use. The order will be respected.
-->
- <panels>
<panel classname="HelloPanel" />
<panel classname="InfoPanel" />
<panel classname="LicencePanel" />
<panel classname="TargetPanel" />
<panel classname="PacksPanel" />
<panel classname="InstallPanel" />
<panel classname="FinishPanel" />
</panels>
- <!--
The packs section.
We specify here our packs.
-->
- <packs>
- <pack name="Base" required="yes">
<description>The base files</description>
<file src="Readme.txt" targetdir="$INSTALL_PATH" />
<file src="Licence.txt" targetdir="$INSTALL_PATH" />
<file src="script.bat" targetdir="$INSTALL_PATH" />
<parsable targetfile="$INSTALL_PATH/script.bat" />
- <!--
The file will be parsed
-->
</pack>
- <pack name="Docs" required="no">
<description>The documentation</description>
<file src="doc" targetdir="$INSTALL_PATH" />
- <!--
Reccursive adding
-->
</pack>
- <pack name="Sources" required="no">
<description>The sources</description>
<file src="src" targetdir="$INSTALL_PATH" />
</pack>
</packs>
</installation>
我算它是七段Q第一D?/span>
<installation version="1.0">
声明安装的版?/span>
W二D?/span>
<info>
<appname>Sample Installation</appname>
<appversion>1.4 beta 666</appversion>
- <authors>
<author name="JPz" email="jpz@superman.org" />
<author name="Hidden Man" email="hidden@hisdomain.com" />
</authors>
<url>http://www.anotherworld-inspace-website.net/</url>
</info>
声明软g的基本信息:名称、版本、各个作者和联系方式、公怸c对应图lzPack1-2?/span>
W三D?/span>
<guiprefs width="640" height="480" resizable="no" />
讄安装D的宽高等属性?/span>
W四D?/span>
<locale>
<langpack iso3="eng" />
<langpack iso3="fra" />
</locale>
语言选择Q对应图?/span>lzPack1-1?/span>
W五D?/span>
<resources>
<res id="LicencePanel.licence" src="Licence.txt" />
<res id="InfoPanel.info" src="Readme.txt" />
</resources>
提供两个资源l客户阅读,对应两个界面Q图lzPack1-3?/span>lzPack1-4。分别ؓ软g说明和基本条ƾ?/span>
W六D?/span>
<panels>
<panel classname="HelloPanel" />
<panel classname="InfoPanel" />
<panel classname="LicencePanel" />
<panel classname="TargetPanel" />
<panel classname="PacksPanel" />
<panel classname="InstallPanel" />
<panel classname="FinishPanel" />
</panels>
说明序下来都经q那些界面?/span>
W七D?/span>
<packs>
- <pack name="Base" required="yes">
<description>The base files</description>
<file src="Readme.txt" targetdir="$INSTALL_PATH" />
<file src="Licence.txt" targetdir="$INSTALL_PATH" />
<file src="script.bat" targetdir="$INSTALL_PATH" />
<parsable targetfile="$INSTALL_PATH/script.bat" />
- <!--
The file will be parsed
-->
</pack>
- <pack name="Docs" required="no">
<description>The documentation</description>
<file src="doc" targetdir="$INSTALL_PATH" />
- <!--
Reccursive adding
-->
</pack>
- <pack name="Sources" required="no">
<description>The sources</description>
<file src="src" targetdir="$INSTALL_PATH" />
</pack>
</packs>
提供了要复制的文件夹l构Q由<packs>标签包括
共有三个包,每个包由<pack>标签标识Q?/span> name=”base” 的包为基本包Q包括所有文件和文g夹的文g夹,其下包括三个文g?/span>$INSTALL_PATH卛_装\径,qL?/span>
?/span>Docs 是文件夹doc?/span>
<file >元素标明文g或文件夹Q?/span>src属性ؓ文g或文件夹名,targetdir属性ؓ要放到的路径
?/span>Sources是文件夹src?/span>
整个文gl构和关pd由最后这一D|阐释?/span>
另外Q包<pack>q可以有其他的用途,下一节是个较实用的实例,你会看到它的用途,要不我们打的包都?/span>izpack一样光U秃的,没快捷键Q没环境变量Q在实践中我们慢慢发现光明,原来有趣的东西等着我们L索?/span>
pY件的安装界面来看Q它打出来的包也Z错,q算一U自w思考吧。安装完毕时Q它叫保存什么东西?q什么格式也弄不清(好几个点呢)Q随便取名保存吧。失望的是,它没有弹q文Ӟ看看桌面上,从开始菜单进M看,有卸载和帮助Q就是没有启动。你是不是该怀疑你下蝲的东西被人做q手脚,可这是官方的呀。简单,问题来了。我们就惛_键字Q?/span>google上输入Y件名“IzPack”Q点ȝx?/span> “lzpack使用”。看了几个简l的Q教学大同小异,知道有大概策略,却无从下手,关键在于写文章的不像我一样喜Ƣ搞{略QL没我需要的实际Q高效。他们往往会讲重点Q但却不注意切入点,在大学听课也l常q样Q让你痛苦不Ԍ像被蚊子叮了,挠痒痒的只挠旁边。L看不C的存在?/span>
那些重点、难点你已经知道是那些就行了Q其实还不用知道Q知道是Z先蟩q)Q只l致的搜寻这你要的切入点。有一个网说有两三种?/span>IzPack的方法,只是概述那种也把责Q推给官方。不q看C|站q一D?#8220;q个software的基本思想是Q它l你提供了许多安装步骤所需要的panelQ比如选择安装路径、选择安装的内宏V观?/span>License{等Q,然后你自己写一?/span>install.xml文g你自己软g的信息、安装需要的步骤、以及安装的资源{等都写q这个文仉Q然后用它所提供?/span>compile批处理文件编译这个文?/span>(e.g. compile install.xml)Q它׃自动生成一?/span>install.jar的可执行Java包。至此,整个q程q束了Q双击这?/span>install.jarQ就能启?/span>install界面?#8221;Q可以想到应该用命o行的方式来用q个软gQ其实这个想法早出来了,因ؓQ桌面上也没?/span>lzPack的快h式。可我用命令上只会如 Javac xx.java q一U,不过q一点也够了Q我已经萌生了一个测试策略。不是命o加参数吗Q验证一下再看其他的?/span>
1. ?/span>cmdq入软g?/span>bin目录Q?/span>compile.bat在这里)
2. 软g附有样例q是常规Q进入Y件目?/span>IzPack下的sample(只有一?/span>xml,compile 处理的就应该?/span>xmlQd只有一个样例,当然所有东西全?/span>)Q全选,复制Q脓?/span>bin目录下(不用怕了,到时咱对照着删就是了Q?/span>
3. (输入什么呢Q应该以bat文g为命令吧Q以所要处理的文g为参数。那?/span>)输入
Compile install.xml
有输出,有许多文字在输出Q你已经露微W了Q不q命中,是q么用,一?/span>bin中多了个install.jar,更攑ֿ了。双ȝ看,哦,原来是个语言选择界面。那么你该处?#8220;{略垃圾”了,你同时打开bin目录?/span>sample目录Ҏ着?/span>bin中复制来的文件一个一个删掉(q只是一U严慎的行ؓQ因为错误M随时降Q?/span>
Bin未删sample里复制过来的文g时如下图Q?br />
你其实挺兴奋Q严D下你的第一ơ,以备以后快速进入和研究Q于是你q把cmd上留下的命o行输出复制出来留待研I。而且你的很多{略也出来了Q那?/span>sample是你参照的对象Q写xml可以仿写Q?/span>sample的结构有多复杂,你打包处理的软gp能有这么复杂。对Q?/span>start里面的帮助文档还没用呢Q下ơ肯定得用上。其实你在做q个试的时候都是数着步数的,因ؓ你想看看和上ơ相比,qY件最快的使用方式有多大差别,对,每次你都?/span>sample来数你开始的步伐了吗Q?/span>
q是?/span>cmd里的操作和输出,不是很有意义Q仅作ؓ一U完整性脓q?/span>
C:"Documents and Settings"yys>cd E:"Program Files"IzPack"bin
C:"Documents and Settings"yys>e:
E:"Program Files"IzPack"bin>compile install.xml
.:: IzPack - Version 4.1.0 ::.
< compiler specifications version: 1.0 >
- Copyright (c) 2001-2008 Julien Ponge
- Visit http://izpack.org/ for the latest releases
- Released under the terms of the Apache Software License version 2.0.
-> Processing : install.xml
-> Output : install.jar
-> Base path : .
-> Kind : standard
-> Compression : default
-> Compr. level: -1
-> IzPack home : .
Adding resource: IzPack.uninstaller
Setting the installer information
Setting the GUI preferences
Adding langpack: eng
Adding resource: flag.eng
Adding langpack: fra
Adding resource: flag.fra
Adding resource: LicencePanel.licence
Adding resource: InfoPanel.info
Adding content of jar: file:/E:/Program%20Files/IzPack/lib/standalone-compiler.j
ar!/bin/panels/HelloPanel.jar
Adding content of jar: file:/E:/Program%20Files/IzPack/lib/standalone-compiler.j
ar!/bin/panels/InfoPanel.jar
Adding content of jar: file:/E:/Program%20Files/IzPack/lib/standalone-compiler.j
ar!/bin/panels/LicencePanel.jar
Adding content of jar: file:/E:/Program%20Files/IzPack/lib/standalone-compiler.j
ar!/bin/panels/TargetPanel.jar
Adding content of jar: file:/E:/Program%20Files/IzPack/lib/standalone-compiler.j
ar!/bin/panels/PacksPanel.jar
Adding content of jar: file:/E:/Program%20Files/IzPack/lib/standalone-compiler.j
ar!/bin/panels/InstallPanel.jar
Adding content of jar: file:/E:/Program%20Files/IzPack/lib/standalone-compiler.j
ar!/bin/panels/FinishPanel.jar
Building installer jar: E:"Program Files"IzPack"bin"install.jar
[ Begin ]
Copying the skeleton installer
Copying 7 files into installer
Merging 7 jars into installer
Writing 3 Packs into installer
Writing Pack 0: Base
Writing Pack 1: Docs
Writing Pack 2: Sources
[ End ]
Build time: Thu Oct 30 20:08:24 CST 2008
E:"Program Files"IzPack"bin>
?/span>cmd输出的你能看到我用的命o是刚才写的Q就那么一条,然后输出它打包的q程Q?/span>xml配置有问题的话,׃~译不过厅R?br /> 同样izpack是个y的开源YӞ用大部分用java写的Q离不开java环境Q打出的包就一jar文gQ比起installsheildȝ多了Q但问题也来了,客户要安装你的Y件就要安装jdkQ以后我们会解决q问题?br /> 下节看看我们的结果ƈ单研I一下要配置的xml?/span>