简易语言

数字沟通

 

2011年6月24日

安装rails(ruby on rails)

  记得两年前使用ror做网站,自动生成功能记忆犹新,只是当时网络知识实在缺乏,体会不到其中的乐趣。现在了解的很多了,书也有两本,一直想重新体验最新版做个网站。安装这个过程实在有点坑爹,查找网上若干ror的书包括2012年版的书,按照上面的步骤都没法安装完成,搞得我一会在linux下试验,一会在windows下试验,都没成功,只好放下。时间花不少,很不爽的体验。

  好在,过了一段时间,忽然想看看ruby的那两本书,然后就爱上这个语言了。于是做一些想做的试验,一些试验需要做些配置,对安装目录也就了解了。下载一些插件居然自己跑到了ruby的下载页。看到上面居然一个版本有3样要下的,帮助文件和安装文件不就够了吗。还要一个mingw做工具么?这个不是有自己的官网下载么。也没管。想起ruby目录下include中有i386-mingw32,才联系起来。应该是以mingw做make工具的。rails应该需要make,因为每次安装都抛出make出错信息。虽然有mingw官网,但这里应该是做成自己的插件。于是到下载页http://rubyforge.org/frs/?group_id=167下载相应版本的mingw32工具解压覆盖到安装目录中,要是怕出问题先对目录做备份

  另外下载不了的都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'

  还有错,但明显不是曾经报的make错误了。
  按照网址下载和遵从上面的方法安装即可(下面的命令即是按照安装方法安装的)
  其中config.yml文件仅仅描述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

  想做个实例,搜一下网上的书,还是不行,那些书最新的2012的都不用命令行做,2011的还是老的命令行方式。根本没法用,上官网看就是了。
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/,熟悉的界面出现


  所以ror厚厚的书读完也没用,可能动手连代码都没机会敲。

  另外也可以到网站http://railsinstaller.org/下载配置好的安装包,就免去手动配置啦。

posted @ 2012-09-02 01:17 yangyusong 阅读(4663) | 评论 (0)编辑 收藏

涂鸦秀秀游戏项目介绍

  这是六月初完成的一个游戏

 

两个月时间终于完成了我们的涂鸦秀秀项目,与同类产品相比,我们内容更多些,分为双人对战模式,多人模式,相信可以同时在线很多人。

 

技术上实践了一把前后端都js的游戏。算是过了把小瘾。用到nodejssocket.iophonegapexpress框架和其他细枝末节。一路上我们披荆斩棘,果然爽。

 

其实从项目需求到解决各个小bug,真是刷了若干个夜

 

这样的项目特点就是能在各手机上玩,包括ipodpadPc上只要支持canvas也可以一起玩,多好的一个大融合。当然其实要兼容ie6也不是什么难事,难在我根本没时间理了,真不好意思。简单说就是跨平台。适配的机器也较多,能有较广的群众基础。

 

我们也有好友系统,分享,邀请,当然不会做深,我们的目标是先吸引住市场,然后再集中力量对用户喜欢的点做深入研发。

 

做完后同学陪我玩好长时间,他很喜欢玩,这一点让我比较欣慰。感觉画图游戏来源于人类的自恋,人类天然喜欢用图来表达意思。只是世界上的系统还是符号的多。

 

如图:

 

SouApp.com还给我们盖了章,我特地确认了一下,这是人家主动盖的章。在审核的时候就下载了一百多次。当然我也不知道这算什么概念。至少觉得有人感兴趣,其实这游戏对美术是乐事,他们功底好,pc上有自己的画图板,画起来非常专业。赢点小礼品根本不是问题。当然以后的版本会更好,更吸引人。已经有不少想法,可改进的地方也不少。

 

 

如下是一些界面截图


 

 

一些小作品

 


 

下载地址

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

官网地址

www.tuyaxiuxiu.com

 

两个月我们都做了什么?

美术需求,协议定制,详细编码,修bug,手机测试,稳定服务,官网搭建,后台搭建,推广运维。非常多的细节,充实有趣。

 

现已通过sina,google等各大平台,能搜到精选,分享,当然不是我们自己弄的,比如下面这个精选,人家是还要注册才能下载的社区。我们自己搞这种就过头了。

 

 

如果大家觉得两个月太长了,其实试试就知道,光推广就够累的,各个平台各种限制。不玩得技术欲仙欲死才怪。官网,后台,各种修改更新。甚至图都要自己改改。开始半个月,美术需求就写了10次,不敢说每次都很详细,但也够有调理和详细的了。

 

不过从中也获得不少经验,本来规划非常短的时间来完成,这个按照很理想的条件来处理的话。当然其实也准时完成了,只不过我们又要了加倍的功能,而我们的人数从开始实施时就减少了一半。这样的条件下,没报告什么特别的,既然说了就做吧,通宵很多个晚上,弄得我经常起不来。

 

另一些感触就是积极加入各种思考分析中就好,根本不要去考虑回报,这个世界上能去考虑回报的人并不多。

 

其实其中有的地方不太到位,比如分享界面、官网、统计分析。只能等人来帮忙了。

 

如下图是当时做的一个极限测试

 

当时数据量一大就丢失数据。于是自己做了个编码方式,减少数据量,这个图证明的就是只要网络能传输,内容再多都能处理。

 

这个游戏的不好之处就是必须有一定的玩家基数才能带动起来。另外,我们开发很多功能其实没必要,先开发主要功能,看市场反应,在进一步开发才有意义。于是有了下一个游戏,见下一篇。

posted @ 2012-07-18 15:49 yangyusong 阅读(853) | 评论 (0)编辑 收藏

进军手机游戏和一些建议

转眼又过了几个月,但是这几个月做了好多游戏,疯狂了。其中做的第一款游戏今天进了google应用首页最上面的图。如图中,有好多金币那个图,就是我们的游戏。一个非常简单的游戏。



这个游戏名称叫砸金币水果机,我们做了英文版,中文版,ios,andriod版。如下就是英文andriod版,模仿街机风格,颇有怀旧的味道。当然技术上我并不看好这款游戏,但实际效果却不好说,图片精美,物理效果不错,触发的神奇界面不少,就看游戏屌丝对街机是否着迷过了。估计也是这些原因导致被google推荐吧,我们也没花任何一分钱买推荐。

 

其实我更想推荐的是多人网上互动的手机游戏,希望在下一篇给大家做介绍。

 

现在我们发现最火的语言成了javascript,原因是html5的推出,其实原理上讲,这个语言也是必然要火的,首先人类交互最密集的地方转移到互联网上了,人类交互的重要性是不言而喻的,就要求我们的网页有更多的功能,而这个功能的提供者第一个是js,且语言简洁,开源,这就奠定了它的竞争力基础。有了这些基础后,最大数量的研究人员都会在这上面。如果将it产业比喻成火山,那么网络这部分就是岩浆部分,就是变化最快的地方。一开始都是最专业的人研究底层,当这些底层成熟后,应用层就快速发展起来,推陈出新非常快。Html5推出将人们最常用的应用以很简洁的方式表达出来,nodejsjs推向后端,socket.io加速交互效率和交互设计。当然有非常多的js框架都出来了。这里不具体说了。

 

这几个月的经验总结希望给大家一些启发, 如果我们做一个跨平台手机游戏发最好做好以下准备

 

Js越熟越好,不要以为它真的很简单,要做手机游戏,必须学会优化,如果是客户端,要求很高,如果在绘图时画一大堆对象,andriod一定会过不去的。那么就一方面研究js(我的建议是,不要去啃面向对象,代码清晰,规范最重要),一方面细读html5规范吧。

 

java基础,那么在用phonegap打包到andriod系统下时,就能较快明白怎么做配置,怎么添加插件和使用。Javajs都不错的话那么写点插件也不错。有的功能是必须用插件的哦。

 

有点andriod设计的基础,我是没什么基础,所以也花不少时间研究,其实就研究它的一些配置关系。也会有烦人问题的。

 

有点mac下的xcode基础,xcode的基本的使用最好明白,否则还是要花不少时间摸索,对于mac系统的设计,我实在不太苟同,虽然我能挺快适应。至于oc,会一些也更好,这样方便使用插件和写插件。

 

想进军app store,越早申请账号,越早提交越好,遇到的问题非常之多。也许怪物英文不好,mac不熟吧。

 

当然硬件上最好有几个手机,ipod,pad做测试,ipad3尤其要测。

 

你还会遇到的问题,比如手机屏幕适配,音乐的使用,兼容浏览器等。

 

 另一个建议就是认准了自己喜欢的,一头扎进去动手就是了。

 

这篇文章总体质量不高,没给大家讲讲技术细节,商业游戏,不太方便哈,会给大家讲开源的。甚至有的地方可能讲失误也欢迎批评指出。本篇完。

 

游戏地址1http://app.baidu.com/273943

游戏地址2

https://chrome.google.com/webstore/detail/jdjcanmclknahldoohmphkiicmggghdf?hl=zh-CN

(要在chrome下安装过才可玩)

posted @ 2012-06-13 04:26 yangyusong 阅读(1530) | 评论 (2)编辑 收藏

用yecc(erlang)写一个json解析器

  昨天写了个json的解析器。其实yecc早看过了,只是那时对自己要求太高,想一下子写个小语言。然后大脑就陷入混乱... 后来注意力转移了。就不那么急着去开发些难道大的。今天回来一看,觉得都理解了,实践一下,发现没人写json的,太好了。于是就在纸上写了一下。晚上没事都敲掉计算机里试试。果然很好用。废话就不多说了,不专业的我在readme里面已经写了不少废话了。主要也不知道git有没规范约束readme不能写废话。其实被google骗了一下,有人写过json的erlang解析,每次我搜yrl,它就主动搜url文件。还要点一下坚持搜索才行。看看https://github.com/jchris/erlang-json-eep-parser/downloads这上面就是一个解析器,还好我们写的不是太像,他写的更精细一点。我写的更容易使用上手。我写的就到这下载吧https://github.com/yangyusong/erlang_json_parser。

  接着就是讲讲内容了,大学学过编译原理就很容易理解这其中的内容。yrl文件就是erlang中的满足LALR-1规范的解析生成器,相似于yacc。会有很多文章做解释,这里不详述。yrl文件或yacc中的.y这类文件就是给我们写编译规则用的,我们写好一个推理机制,按照规范分解成4部分,放到这一个文件中,那么yecc就可以给我们生成一个符合这个推理规则的解析器,当然这里就是生成.erl的源文件给我们使用,其中会有parse作为默认方法提供给我们解析我们的字符串。

  yrl文件中一共有四部分,其实三部分分别用Nonterminals Terminals Rootsymbol关键字来标识,意义很明显,非终结符,终结符,起始符(这个忘了怎么翻译)。要解释一下也行,一个更好的理解方式就是,非终结符可以在推理符号(->)的左边和右边,相当于函数作用,最终分析为终结符的组合。终结符只能在推理符号(->)的右边。意义就是一个符号系统的基本集合。 Rootsymbol是其中一个非终结符,作为推理的起始点。用一棵解析树来表示的话,Rootsymbol就是根节点。Nonterminals就是树枝。Terminals就是树叶。任何一个符合此推理规则的字符串都可以用这样一棵解析树表示出来(我就不画了)。

  除了上面说的三部分就剩下最重要的部分了:推理规则。其实这四部分都是列表,只不过Rootsymbol这个表只有一个元素。规则列表有多条,通常每行一条规则,和erlang一样用.结束一条规则。
终结符用单引号引起,冒号后面是我们解析后的erlang表达式。$1,$2,$3这种相似正则表达式规则,也说一下吧,就是对冒号左边的元素作为列表并从1计数。再搞不懂就发邮局问吧,呵呵。

  那么这样的一个规则列表就很好建立了,其实这个过程还是有很多规则可以遵循的,其中这里遵循了左递归,终结字符先出现的规则优先表达这两条规则。更多,你还可以画个有限状态机,做一下分析,化解,做成闭包,某些运算还要考虑优先级之类。当然这里这样小的结构基本是最优了,没什么化解的必要。

代码附上
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.

  其中object,list就是json中最基本的结构。kv_list就是剥离大括号后的键值对列表。v_list是剥离中括号的列表。

  再讲讲这个解析器的使用吧,json_parser就是yrl文件生成的解析器了,我们就用这个解析器来做解析。文件use_json_parser对json_parser的使用做了一个包装,那就是parser/1函数了,我们给它传入json字符串就返回解析后的erlang列表。例如我们输入use_json_parser:parser("{a, b, c}").就会返回[{'{',1},
                                        {atom,1,a},
                                        {',',1},
                                        {atom,1,b},
                                        {',',1},
                                        {atom,1,c},
                                        {'}',1},
                                        {'$end',999}]。
  这个文件还提供一个测试函数了unit_test_()。为了方便大家,我还是讲讲测试方法吧。在命令行输入
cd erlang_json_parser
erl -pa ./ebin/ -eval "make:all([{d, 'EUNIT'},{outdir, \"./ebin/\"}, debug_info]) ,eunit:test(\"./ebin\",[]),init:stop()"

  参考更多的解析器制作,可以参考erlang官网提供的计算表达式解析,list解析。也可以从其他网站搜到html,xml等的解析,当然如果你看得多一点还会看到aleppo,erlydtl这类的工程。希望更多的人们投入到这些更有意思的开发中。下次再写yecc,就不写这么简单的了。哈哈。不要期待在下一篇里出现哦。

posted @ 2011-12-30 23:28 yangyusong 阅读(3447) | 评论 (0)编辑 收藏

一个小游戏ChainReaction的设计(html5)

本来一直觉得js是个让人混乱不堪的语言,html5的出现改变了我对它的看法。到了html5的时代,各种犀利的设计就更明显的需要js了。看了一些小游戏设计,忽然来了兴趣,于是写了几个小游戏,这是其中一个。已经开源,欢迎下载https://github.com/yangyusong/ChainReaction

 

游戏叫连锁反应,这个游戏是看到有人在ipad上面玩的游戏,觉得好玩,自己实现一遍。游戏是这样的,一群小球在区域内弹来弹去,玩家鼠标点击一个地方,在一个圆的范围内,小球碰上就会爆炸,爆炸的过程中其他小球碰上也会发生爆炸,这就叫连锁反应。每一关爆破一定数量的小球就算胜利。

 

我的设计中一个有20关,数值增长比较平和,运气不是太差的话都能一次通关。在说有个再玩本级的功能,过一关的压力是一点都没有。这样设计是为了给工作后的朋友缓解压力。我们轻松的一点就爆炸一片。

 

看看截图


 

大的那个灰色的(其实是半透明的)圆是鼠标范围。其他是弹来弹去的小球。可以看到,小球是各种颜色的。

 

我们看看小球的定义

function Circle(x, y, xSpeed, ySpeed, radius, color, liveTime, state){

    //圆心坐标

    this.x = x;

    this.y = y;

    //运动速度

    this.xSpeed = xSpeed;

    this.ySpeed = ySpeed;

    //半径

    this.radius = radius;

    //颜色

    this.color = color;

    //生存计数器

    this.liveTime = liveTime;

    //状态:

    this.state = state;

}

 

其中生存计数器是要和状态结合使用的,状态分为如下5个状态

//小球状态

var SMALL = 0;

var BIG = 1;

var EXPEND = 2;

var END = 3;

var DIS_VISIBLE = 4;

 

当处于EXPEND状态的时候,就说明小球进入爆炸状态,这时候生存计数器就用上了。计数器是个倒计时,计时到零,小球进入DIS_VISIBLE状态。这时候小球就不再渲染出来。

 

我们的小球有不同大小,不同颜色,看看小球的初始化就知道了,代码在ObjectMgr.js

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负责我们关卡的管理,有这一关的小球数,和通关需要爆破的小球数。总之,这里按照本关需要的小球数初始化小球,可以看到里面有很多的随机函数使用。小球的半径处于如下两个数之间

var SMALL_RADIUS1 = 3;

var SMALL_RADIUS2 = 10;

通过random_range来进行这个范围随机。我们看到速度也是随机的,范围是

var SPEED_MIN = 10;

var SPEED_MAX = 50;

颜色中的color_rgba_str函数的第四个参数说明我们的每个小球的透明度是0.8,这样我们就能在爆破的时候,或弹动的时候仍然看清其他小球。这段代码就说到这。

 

我们讲讲主要流程,其实其中的详细注释,我觉得已经可以教会很多初学者。不过还是讲讲好。主要流程就在Main.js中。负责初始化,渲染和循环。开始我们设置了一堆全局变量。

var g_ObjectMgr = null;

var g_MouseEventDispatch = new MouseEventDispatch();

var g_MouseMgr = null;//g_MouseMgrg_ObjectMgr初始化后才初始化

//当前关

var g_Steps = 1;//todo 显示出来

//关卡数组

var g_StepsArr = [];

g_StepsArr = stepsInit();

//爆炸开始标识

var _ExpendStart = false;

 

if(DEBUG){

    _CircleLib.test();

}

var _Main = { 。。。

 

包括关卡数组,当前关数,爆炸标识等。居然还设置了一个是否调试的状态量,其实我也不知道js调试怎样才好,基本就按自己的方式调。 _Main是个很大的结构。我更宁愿把它当做单例来思考。主要是,它包括了渲染,这个渲染不具通用性,仅此一例就够。其他地方用了且不是画出什么就难说了。当然已经设计其实我会更多考虑通用性的设计,尽量不设计成这种单例。

 

这个_Main结构中有我们的画布canvas,我们的初始化函数,每关调用一次,它来负责2d对象的初始化,游戏对象的初始化。鼠标监听初始化。然后就是进入我们的循环。循环很简单,就干四件事情

/*

     * 循环绘图

     * 1.清空画面

     * 2.游戏对象关系处理

     * 3.渲染出来

     * 4.循环调用

     */

    step: function(){

        this.clear();

        g_ObjectMgr.step();

        this.render();

        _this = this;

        this._st = setTimeout(function(){

            _this.step();

        }, 50);

    }

 

看看我们的下一关都干些什么

/*

     * 下一关

     */

    nextStep: function(){

        clearTimeout(this._st);

        if(this.canvas.getContext)

        {

            g_MouseEventDispatch.start();

            this.initObjects();

            this.step();

        }

    }

它就是清除计时器,重新分配事件,初始化对象。然后进入循环,为什么是这样呢?清除计时器以使我们之前的循环停止。因为我们马上有新的循环了,其实事件可以看做有两个状态,我们按下鼠标的时候,这个事件就不可用了,下次使用必须初始化。小球数量变了,必须按照本关的需求来初始化。进入循环,新的循环开始。

看看再玩一次(本级)按钮的调用:

/*

     * 再玩一次(本级)

     */

    again: function(){

        this.nextStep()

    }

 

为什么居然是调用下一关呢?只能说我设计的太懒惰,nextStep()本身根本不管关卡的变更。关卡的变更完全在爆炸检查函数里,一旦发现小球爆炸,就会修改当前关卡。而单纯调用nextStep所使用的关卡是未改变过的,故而是在玩本级。

 

我们再看一下ObjectMgr.js中的爆炸检查函数

 

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+"个小球,恭喜进入第"+ next + "关,\n\

下一关需要爆破" +g_StepsArr[g_Steps + 1].killNum + "个小球");

                g_Steps++;

                _Main.init();

            }

        }

    }

 

还记得_ExpendStart这个变量的意思么?就是说鼠标是否按下了,按下的话我们就要检查是否有小球撞上鼠标范围或撞上爆炸中的小球。其实这里的调用_CircleLib.intersect这个函数是有些小问题的。它是通过引用修改的当前小球的状态,至于为什么有很少量的小球未修改状态,这个我还没弄明白。总之,这个函数检查了爆炸小球的数量,一旦爆炸小球的数量符合本关的要求,那么就可以进入下一关,可以看到我们进入下一关的提示是一个对话框,不是很友好,可以设计为一个图片较好,可惜我没时间找美术。

 

点击确定,我们玩下一关

 

小球多了很多,找个好点的位置,能捕捉很多小球。

看一下爆炸过程吧:


这是第十八关的一个爆炸情形,更具体的内容欢迎看具体代码吧,要不还讲好长时间。

 

做完这个例子,发现其实非常多的小游戏很好设计,可惜没那么多时间,再说设计别人设计过的游戏也不是我的目标。设计一些有趣的小游戏到手机里,这个倒是个不错的方向

posted @ 2011-12-18 23:03 yangyusong 阅读(2124) | 评论 (2)编辑 收藏

游戏中最近可达点(用erlang写一个简单算法)

游戏中有点击障碍点,人物走到离障碍物最近点的算法。我这给一个简单的算法,这个问题可以复杂化,另外这个问题应该由客户端来完成。

如图,玩家在b点,点击了a点,a在一个障碍区(红色,玩家只能在障碍区外移到)。这时候玩家应该走到c点,我们就需要计算出c点,一个简单的数学题,用什么语言都没几行代码,我就用erlang写一下。


障碍物通常都不规则的,我们只能从a点开始一个个点测试,直到不是障碍点,也就是x自增,y=x*tan(A),然后测试这个点,地图数据都是静态的数据,方便测试,这里就写死一个x为障碍结束的地方作为障碍检测函数。

我们还需要一个记录表示点,tan函数在erlang中是有的,但其实可以不用,我们就直接要一个比值,但需要一个向上取整的函数,据说是round函数,但测试一下,不行,难道是因为不是最新otp
D:\NetBeanPj\mytest\src>erl
Eshell V5.8.1.1  (abort with ^G)
1> round(1.2).
1

所以这里我们要写的一个辅助函数,最后就是我们的重点,取最近点,用一个列表解析就够了,剩下的就看具体实现吧,还可以写个测试函数,这次就不写成单元测试了。好的我们看代码:
-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 .

%% 查找最近点
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.

%% 下面函数测试用,可以改成单元测试,这里就免了
p1() ->
    #point{
        x = 1,
        y = 9}.

p2() ->
    #point{
        x = 15,
        y = 25}.

test_1() ->
    nearst_point(p1(),p2()).

编译和测试
2> c(nearst_point).
{ok,nearst_point}
3> nearst_point:test_1().
{point,5,5}{point,5,5}
4>

我们的测试如预期的在5那个点得到,好像有个小问题,怎么这个点输出了两次?哦,这不是问题,一个点是代码里的io输出的,一个点是返回给shell,shell的输出,看来写代码的人太懒,疑惑也会增多啊。在nearst_point中用到了一个小技巧,就是用throw来跳出循环(这个在erlang中还是挺有意思),这次到这,应该说写的很基础很难看。下次会来点有意思的,欢迎大家学习erlang。

posted @ 2011-06-24 23:54 yangyusong 阅读(2868) | 评论 (0)编辑 收藏

导航

统计

常用链接

留言簿(3)

随笔分类

随笔档案

文章分类

搜索

最新评论

阅读排行榜

评论排行榜