设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 1485|回复: 5
打印 上一主题 下一主题

[胡扯] 抑制不住内心的激动,Shoes实在是太令人振奋了

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1245
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

跳转到指定楼层
1
发表于 2011-10-23 01:15:29 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
感觉 wxRuby , Tcl/Tk ,Gtk+ 的Ruby绑定都不及shoes的优雅,虽然shoes是集万家长处与一身,跨平台等特点。

项目地址:https://github.com/shoes/shoes

写一些中小型App或者本地-Web的交互界面(豆瓣的哪个Oenring?),Shoes还是很由潜力的。今天突然想起有这么一个东西,玩了一下,的确很振奋人心。以后慢慢渗入。

此处释出几例App运行图示:


绘制Arc演示


简易计算器


绘制简单form演示


用shoes制成的一个IRB


字典APP


扫雷,这个sample运行起来小卡


某种棋,不是很会玩……


很多sample可供参考。

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42013
在线时间
7657 小时
注册时间
2009-7-6
帖子
13527

开拓者贵宾

2
发表于 2011-10-23 01:21:21 | 只看该作者
听起来蛮不错的样子,明早用电脑看看范例试试。
RGDirect - DirectX驱动的RGSS,点我了解.
(排满,暂停)RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv2.观梦者

(?????)

梦石
0
星屑
787
在线时间
1327 小时
注册时间
2011-7-18
帖子
3184

贵宾

3
发表于 2011-10-23 05:26:12 | 只看该作者
想不出连扫雷都会小卡究竟有什么应用长处 = = b
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1245
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

4
 楼主| 发表于 2011-10-23 09:05:18 | 只看该作者
各种压力的猫君 发表于 2011-10-23 05:26
想不出连扫雷都会小卡究竟有什么应用长处 = = b

可能是因为我用的是Intel D915GAV芯片组的集显的缘故。

既然是中小型应用,自然不会有什么太大的压力。
  1. #
  2. # Shoes Minesweeper by que/varyform
  3. #
  4. LEVELS = { :beginner => [9, 9, 10], :intermediate => [16, 16, 40], :expert => [30, 16, 99] }

  5. class Field
  6.   CELL_SIZE = 20
  7.   COLORS = %w(#00A #0A0 #A00 #004 #040 #400 #000)
  8.   
  9.   class Cell
  10.     attr_accessor :flag
  11.     def initialize(aflag = false)
  12.       @flag = aflag
  13.     end
  14.   end
  15.   
  16.   class Bomb < Cell
  17.     attr_accessor :exploded
  18.     def initialize(exploded = false)
  19.       @exploded = exploded
  20.     end
  21.   end
  22.   
  23.   class OpenCell < Cell
  24.     attr_accessor :number
  25.     def initialize(bombs_around = 0)
  26.       @number = bombs_around
  27.     end
  28.   end
  29.   
  30.   class EmptyCell < Cell; end
  31.   
  32.   attr_reader :cell_size, :offset
  33.   
  34.   def initialize(app, level = :beginner)
  35.     @app = app
  36.     @field = []
  37.     @w, @h, @bombs = LEVELS[level][0], LEVELS[level][1], LEVELS[level][2]
  38.     @h.times { @field << Array.new(@w) { EmptyCell.new } }
  39.     @game_over = false
  40.     @width, @height, @cell_size = @w * CELL_SIZE, @h * CELL_SIZE, CELL_SIZE
  41.     @offset = [(@app.width - @width.to_i) / 2, (@app.height - @height.to_i) / 2]
  42.     plant_bombs
  43.     @start_time = Time.now
  44.   end
  45.   
  46.   def total_time
  47.     @latest_time = Time.now - @start_time unless game_over? || all_found?
  48.     @latest_time
  49.   end
  50.   
  51.   def click!(x, y)
  52.     return unless cell_exists?(x, y)
  53.     return if has_flag?(x, y)
  54.     return die!(x, y) if bomb?(x, y)
  55.     open(x, y)
  56.     discover(x, y) if bombs_around(x, y) == 0
  57.   end  

  58.   def flag!(x, y)
  59.     return unless cell_exists?(x, y)
  60.     self[x, y].flag = !self[x, y].flag unless self[x, y].is_a?(OpenCell)
  61.   end  
  62.   
  63.   def game_over?
  64.     @game_over
  65.   end
  66.   
  67.   def render_cell(x, y, color = "#AAA", stroke = true)
  68.     @app.stroke "#666" if stroke
  69.     @app.fill color
  70.     @app.rect x*cell_size, y*cell_size, cell_size-1, cell_size-1
  71.     @app.stroke "#BBB" if stroke
  72.     @app.line x*cell_size+1, y*cell_size+1, x*cell_size+cell_size-1, y*cell_size
  73.     @app.line x*cell_size+1, y*cell_size+1, x*cell_size, y*cell_size+cell_size-1
  74.   end
  75.   
  76.   def render_flag(x, y)
  77.     @app.stroke "#000"
  78.     @app.line(x*cell_size+cell_size / 4 + 1, y*cell_size + cell_size / 5, x*cell_size+cell_size / 4 + 1, y*cell_size+cell_size / 5 * 4)
  79.     @app.fill "#A00"
  80.     @app.rect(x*cell_size+cell_size / 4+2, y*cell_size + cell_size / 5,
  81.       cell_size / 3, cell_size / 4)
  82.   end
  83.   
  84.   def render_bomb(x, y)
  85.     render_cell(x, y)
  86.     if (game_over? or all_found?) then # draw bomb
  87.       if self[x, y].exploded then
  88.         render_cell(x, y, @app.rgb(0xFF, 0, 0, 0.5))
  89.       end
  90.       @app.nostroke
  91.       @app.fill @app.rgb(0, 0, 0, 0.8)
  92.       @app.oval(x*cell_size+3, y*cell_size+3, 13)
  93.       @app.fill "#333"
  94.       @app.oval(x*cell_size+5, y*cell_size+5, 7)
  95.       @app.fill "#AAA"
  96.       @app.oval(x*cell_size+6, y*cell_size+6, 3)
  97.       @app.fill @app.rgb(0, 0, 0, 0.8)
  98.       @app.stroke "#222"
  99.       @app.strokewidth 2
  100.       @app.oval(x*cell_size + cell_size / 2 + 2, y*cell_size + cell_size / 4 - 2, 2)
  101.       @app.oval(x*cell_size + cell_size / 2 + 4, y*cell_size + cell_size / 4 - 2, 1)
  102.       @app.strokewidth 1
  103.     end
  104.   end
  105.   
  106.   def render_number(x, y)
  107.     render_cell(x, y, "#999", false)
  108.     if self[x, y].number != 0 then
  109.       @app.nostroke
  110.       @app.para self[x, y].number.to_s, :left => x*cell_size + 3, :top => y*cell_size - 2,
  111.         :font => '13px', :stroke => COLORS[self[x, y].number - 1]
  112.     end
  113.   end
  114.   
  115.   def paint
  116.     0.upto @h-1 do |y|
  117.       0.upto @w-1 do |x|
  118.         @app.nostroke
  119.         case self[x, y]
  120.           when EmptyCell then render_cell(x, y)
  121.           when Bomb then render_bomb(x, y)
  122.           when OpenCell then render_number(x, y)
  123.         end
  124.         render_flag(x, y) if has_flag?(x, y) && !(game_over? && bomb?(x, y))
  125.       end
  126.     end
  127.   end  

  128.   def bombs_left
  129.     @bombs - @field.flatten.compact.reject {|e| !e.flag }.size
  130.   end  

  131.   def all_found?
  132.     @field.flatten.compact.reject {|e| !e.is_a?(OpenCell) }.size + @bombs == @w*@h
  133.   end  

  134.   def reveal!(x, y)
  135.     return unless cell_exists?(x, y)
  136.     return unless self[x, y].is_a?(Field::OpenCell)
  137.     if flags_around(x, y) >= self[x, y].number then
  138.       (-1..1).each do |v|
  139.         (-1..1).each { |h| click!(x+h, y+v) unless (v==0 && h==0) or has_flag?(x+h, y+v) }
  140.       end
  141.     end      
  142.   end  
  143.   
  144.   private
  145.   
  146.   def cell_exists?(x, y)
  147.     ((0...@w).include? x) && ((0...@h).include? y)
  148.   end
  149.   
  150.   def has_flag?(x, y)
  151.     return false unless cell_exists?(x, y)
  152.     return self[x, y].flag
  153.   end
  154.   
  155.   def bomb?(x, y)
  156.     cell_exists?(x, y) && (self[x, y].is_a? Bomb)
  157.   end
  158.   
  159.   def can_be_discovered?(x, y)
  160.     return false unless cell_exists?(x, y)
  161.     return false if self[x, y].flag
  162.     cell_exists?(x, y) && (self[x, y].is_a? EmptyCell) && !bomb?(x, y) && (bombs_around(x, y) == 0)
  163.   end  
  164.   
  165.   def open(x, y)
  166.     self[x, y] = OpenCell.new(bombs_around(x, y)) unless (self[x, y].is_a? OpenCell) or has_flag?(x, y)
  167.   end
  168.   
  169.   def neighbors
  170.     (-1..1).each do |col|
  171.       (-1..1).each { |row| yield row, col unless col==0 && row == 0 }
  172.     end  
  173.   end
  174.   
  175.   def discover(x, y)
  176.     open(x, y)
  177.     neighbors do |col, row|
  178.       cx, cy = x+row, y+col
  179.       next unless cell_exists?(cx, cy)
  180.       discover(cx, cy) if can_be_discovered?(cx, cy)
  181.       open(cx, cy)
  182.     end
  183.   end  

  184.   def count_neighbors
  185.     return 0 unless block_given?
  186.     count = 0
  187.     neighbors { |h, v| count += 1 if yield(h, v) }
  188.     count
  189.   end
  190.   
  191.   def bombs_around(x, y)
  192.     count_neighbors { |v, h| bomb?(x+h, y+v) }
  193.   end
  194.   
  195.   def flags_around(x, y)
  196.     count_neighbors { |v, h| has_flag?(x+h, y+v) }
  197.   end
  198.   
  199.   def die!(x, y)
  200.     self[x, y].exploded = true
  201.     @game_over = true
  202.   end

  203.   def plant_bomb(x, y)
  204.     self[x, y].is_a?(EmptyCell) ? self[x, y] = Bomb.new : false
  205.   end
  206.   
  207.   def plant_bombs
  208.     @bombs.times { redo unless plant_bomb(rand(@w), rand(@h)) }
  209.   end

  210.   def [](*args)
  211.     x, y = args
  212.     raise "Cell #{x}:#{y} does not exists!" unless cell_exists?(x, y)
  213.     @field[y][x]
  214.   end
  215.   
  216.   def []=(*args)
  217.     x, y, v = args
  218.     cell_exists?(x, y) ? @field[y][x] = v : false
  219.   end
  220. end

  221. Shoes.app :width => 730, :height => 450, :title => 'Minesweeper' do
  222.   def render_field
  223.     clear do
  224.       background rgb(50, 50, 90, 0.7)
  225.       flow :margin => 4 do
  226.         button("Beginner") { new_game :beginner }
  227.         button("Intermediate") { new_game :intermediate }
  228.         button("Expert") { new_game :expert }
  229.       end
  230.       stack do @status = para :stroke => white end
  231.       @field.paint
  232.       para "Left click - open cell, right click - put flag, middle click - reveal empty cells", :top => 420, :left => 0, :stroke => white,  :font => "11px"
  233.     end  
  234.   end
  235.   
  236.   def new_game level
  237.     @field = Field.new self, level
  238.     translate -@old_offset.first, -@old_offset.last unless @old_offset.nil?
  239.     translate @field.offset.first, @field.offset.last
  240.     @old_offset = @field.offset
  241.     render_field
  242.   end
  243.   
  244.   new_game :beginner
  245.   animate(5) { @status.replace "Time: #{@field.total_time.to_i} Bombs left: #{@field.bombs_left}" }
  246.   
  247.   click do |button, x, y|
  248.     next if @field.game_over? || @field.all_found?
  249.     fx, fy = (([email protected]) / @field.cell_size).to_i, (([email protected]) / @field.cell_size).to_i
  250.     @field.click!(fx, fy) if button == 1
  251.     @field.flag!(fx, fy) if button == 2
  252.     @field.reveal!(fx, fy) if button == 3

  253.     render_field
  254.     alert("Winner!\nTotal time: #{@field.total_time}") if @field.all_found?
  255.     alert("Bang!\nYou loose.") if @field.game_over?
  256.   end
  257. end
复制代码

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (暗夜天使)

名侦探小柯

梦石
0
星屑
3432
在线时间
3629 小时
注册时间
2006-9-6
帖子
37402

开拓者贵宾第3届短篇游戏大赛主流游戏组亚军第5届短篇游戏比赛亚军

5
发表于 2011-10-23 09:07:49 | 只看该作者
看上去是各种默认界面很美好?
回复 支持 反对

使用道具 举报

Lv2.观梦者 (管理员)

八云紫的式神

梦石
0
星屑
619
在线时间
1243 小时
注册时间
2008-1-1
帖子
4282

烫烫烫

6
发表于 2011-10-23 11:20:45 | 只看该作者
越前リョーマ 发表于 2011-10-23 09:07
看上去是各种默认界面很美好?

Linux/MAC的默认控件比Win漂亮的原因
rm for linux(wine)制作中,期待夏娜SAMA能实现到webrm上
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2025-7-24 05:10

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表