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

Project1

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

[RMVA发布] 【小游戏】《2048~》RMVA版v0.2

[复制链接]

Lv2.观梦者

梦石
0
星屑
629
在线时间
464 小时
注册时间
2011-4-4
帖子
58
跳转到指定楼层
1
发表于 2014-3-26 09:31:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 swebok 于 2014-3-31 21:05 编辑

最近《2048~》这个小游戏挺火的,昨晚思考了一下写了这么个脚本,算法是自己琢磨的。本人RUBY初学者,写的不好请多多包涵,如果出现问题了请@我。
得分和界面功能还没有实现,有时间再填上。


原游戏地址:
http://gabrielecirulli.github.io/2048/


游戏规则:
HOW TO PLAY:Use yourarrow keysto move the tiles. When two tiles with the same number touch, theymerge into one!
NOTE:This site is the official version of 2048. You can play it on your phone via.All other apps or sites are derivatives or fakes, and should be used with caution.
Created by Gabriele Cirulli.Based on 1024 by Veewo Studioand conceptually similar to Threes by Ashe Vollmer.[1]
游戏规则很简单,每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。系统给予的数字方块不是2就是4,玩家要想办法在这小小的16格范围中凑出“2048”这个数字方块。


工程下载:
http://pan.baidu.com/s/1hqomlt6


2014.3.30更新
参照taroxd的建议修改了工程,具体代码见1L&2L。


RUBY 代码复制
  1. #==============================================================================
  2. # □ Scene_Game2048
  3. # 2048小游戏,RMVA版作者:swebok,转载需保留该信息!
  4. # [url]http://rpg.blue/thread-357532-1-1.html[/url]
  5. #==============================================================================
  6. class Scene_Game2048 < Scene_Base
  7.   #--------------------------------------------------------------------------
  8.   # ● 开始处理
  9.   #--------------------------------------------------------------------------
  10.   def start
  11.     super
  12.     init_game
  13.     draw_box
  14.   end
  15.   #--------------------------------------------------------------------------
  16.   # ● 结束处理
  17.   #--------------------------------------------------------------------------
  18.   def terminate
  19.     super
  20.     @background_sprite.dispose
  21.   end
  22.   #--------------------------------------------------------------------------
  23.   # ● 刷新处理
  24.   #--------------------------------------------------------------------------
  25.   def update
  26.     super
  27.     if Input.trigger?(:LEFT)
  28.       @game2048.move(:left)
  29.       judge
  30.       clear_box
  31.       Sound.play_cursor
  32.       draw_box
  33.     end
  34.     if Input.trigger?(:RIGHT)
  35.       @game2048.move(:right)
  36.       judge
  37.       clear_box
  38.       Sound.play_cursor
  39.       draw_box
  40.     end
  41.     if Input.trigger?(:UP)
  42.       @game2048.move(:up)
  43.       judge
  44.       clear_box
  45.       Sound.play_cursor
  46.       draw_box
  47.     end
  48.     if Input.trigger?(:DOWN)
  49.       @game2048.move(:down)
  50.       judge
  51.       clear_box
  52.       Sound.play_cursor
  53.       draw_box
  54.     end
  55.   end
  56.   #--------------------------------------------------------------------------
  57.   # ● 初始化
  58.   #--------------------------------------------------------------------------
  59.   def init_game
  60.     @game2048 = Game2048.new
  61.     @background_sprite = Sprite.new
  62.     @background_sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height)
  63.     draw_box
  64.   end
  65.   #--------------------------------------------------------------------------
  66.   # ● 擦除格子
  67.   #--------------------------------------------------------------------------
  68.   def clear_box
  69.     @background_sprite.bitmap.clear
  70.   end
  71.   #--------------------------------------------------------------------------
  72.   # ● 描画格子
  73.   #--------------------------------------------------------------------------
  74.   def draw_box
  75.     for i in 0...4
  76.       for j in 0..4
  77.         if @game2048.[](i, j) != nil
  78.           @background_sprite.bitmap.draw_text(130+80*j, 100+60*i, 60, 24, @game2048.[](i, j), 1)
  79.         end
  80.       end
  81.     end
  82.   end
  83.   #--------------------------------------------------------------------------
  84.   # ● 判定结束
  85.   #--------------------------------------------------------------------------
  86.   def judge
  87.     if @game2048.lose?
  88.       clear_box
  89.       draw_box
  90.       @background_sprite.bitmap.draw_text(120, 320, 300, 24, "无法移动,你失败了!", 1)
  91.       $data_system.gameover_me.play
  92.       abs_wait(180)
  93.       SceneManager.goto(Scene_Map)
  94.     end
  95.     if @game2048.win?
  96.       clear_box
  97.       draw_box
  98.       @background_sprite.bitmap.draw_text(120, 320, 300, 24, "达到2048,恭喜您胜利!", 1)
  99.       $game_system.battle_end_me.play
  100.       abs_wait(180)
  101.       SceneManager.goto(Scene_Map)
  102.     end
  103.   end
  104.   #--------------------------------------------------------------------------
  105.   # ● 等待(快进无效)
  106.   #--------------------------------------------------------------------------
  107.   def abs_wait(duration)
  108.     duration.times {|i| update_for_wait }
  109.   end
  110.   #--------------------------------------------------------------------------
  111.   # ● 更新画面(等待用)
  112.   #--------------------------------------------------------------------------
  113.   def update_for_wait
  114.     update_basic
  115.   end
  116. end



预计更新:
游戏界面;自定义文字、图片信息(比如可以做成2个包子合成一个馒头啦)。
(最近比较忙,预计会龟速更新,但愿别太监就行...)

点评

就是定义每一个方格里写什么【大概这样】只是提一下而已……  发表于 2014-3-31 19:38
更新  发表于 2014-3-31 08:48
更新了一下2L和4L,欢迎使用  发表于 2014-3-30 13:14
其实我本来就是想做命令行版2048,做完就把核心代码扔过来了  发表于 2014-3-27 18:32

评分

参与人数 2星屑 +600 收起 理由
fux2 + 500 好顶赞
喵呜喵5 + 100 精品文章

查看全部评分


老塞风流史

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

2
发表于 2014-3-27 08:44:20 | 只看该作者
本帖最后由 taroxd 于 2014-3-31 18:45 编辑

写了个纯Ruby类,用来处理2048(然后自己做了个命令行版本),仅供参考。

得分功能只要修改move_left即可。楼主可以看一下move_right等方法是怎么写的

目测 @Max 要被坑

RUBY 代码复制
  1. class Game2048
  2.  
  3.   include Enumerable
  4.   attr_reader :size
  5.  
  6.   def initialize(size = 4, max = 2048)
  7.     @size, [url=home.php?mod=space&uid=25307]@Max[/url] = size, max
  8.     @data = Array.new(size) { Array.new(size) }
  9.     2.times { generate }
  10.   end
  11.  
  12.   def move(direction)
  13.     last = to_a
  14.     send :"move_#{direction}"
  15.     return if last == to_a
  16.     generate
  17.     self
  18.   end
  19.  
  20.   def [](i, j)
  21.     @data[i][j]
  22.   end
  23.  
  24.   def each
  25.     return to_enum(__method__) { @size**2 } unless block_given?
  26.     @data.each {|row| row.each {|n| yield n } }
  27.   end
  28.  
  29.   def each_index
  30.     return to_enum(__method__) { @size**2 } unless block_given?
  31.     @size.times {|i| @size.times {|j| yield i, j } }
  32.   end
  33.  
  34.   def each_with_index
  35.     return to_enum(__method__) { @size**2 } unless block_given?
  36.     each_index {|i, j| yield @data[i][j], i, j }
  37.   end
  38.  
  39.   def to_a
  40.     @data.flatten
  41.   end
  42.  
  43.   def lose?
  44.     each_with_index.all? do |n, i, j|
  45.       n && @data[i][j + 1] != n && (i >= @size - 1 || @data[i + 1][j] != n)
  46.     end
  47.   end
  48.  
  49.   def win?
  50.     any? {|n| n && n >= @max }
  51.   end
  52.  
  53.   private
  54.  
  55.   def move_left
  56.     @data.each do |row|
  57.       row.compact!
  58.       (@size - 1).times do |i|
  59.         if row[i] && row[i] == row[i + 1]
  60.           row[i] = merge_value(row[i])
  61.           row.delete_at(i + 1)
  62.         end
  63.       end
  64.       row.push(nil) until row.size >= @size
  65.     end
  66.   end
  67.  
  68.   def move_right
  69.     reverse { move_left }
  70.   end
  71.  
  72.   def move_up
  73.     transpose { move_left }
  74.   end
  75.  
  76.   def move_down
  77.     transpose { move_right }
  78.   end
  79.  
  80.   def transpose
  81.     @data = @data.transpose
  82.     yield
  83.   ensure
  84.     @data = @data.transpose
  85.   end
  86.  
  87.   def reverse
  88.     @data.each(&:reverse!)
  89.     yield
  90.   ensure
  91.     @data.each(&:reverse!)
  92.   end
  93.  
  94.   def generate
  95.     i, j = each_index.select {|m, n| @data[m][n].nil? }.sample
  96.     @data[i][j] = first_value if i
  97.   end
  98.  
  99.   def first_value
  100.     rand < 0.8 ? 2 : 4
  101.   end
  102.  
  103.   def merge_value(n)
  104.     n * 2
  105.   end
  106. end
               

点评

因为并不会脚本所以……  发表于 2014-3-31 19:37
好厉害!学习中......  发表于 2014-3-27 17:38
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
12845
在线时间
1459 小时
注册时间
2012-7-24
帖子
1302
3
发表于 2014-3-27 14:54:13 | 只看该作者
沙发了过来膜拜大神早就听说这个游戏很好玩了,虽然我是没有玩过啦

欢迎大家加我
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

4
发表于 2014-3-27 18:46:09 | 只看该作者
本帖最后由 taroxd 于 2014-3-30 13:11 编辑

看了一下楼主的代码
draw_box方法为什么不用循环?
另外,失败条件并不是场上没有空格,还是无法进行下一次的移动

欢迎楼主直接用2L的代码做这个场景,我觉得会好很多。公有方法都写在上面了。(我是用nil来表示空格子的)
如果要使用的话,把每个 to_enum 后面跟的{ @size ** 2 } 去掉。这个block是给ruby2.0用的

点评

已经参照修改了~  发表于 2014-3-30 16:01
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

5
发表于 2014-3-30 16:03:06 | 只看该作者
本帖最后由 taroxd 于 2014-3-31 18:45 编辑

RUBY 代码复制
  1. def draw_box
  2.     for i in 0...4
  3.       for j in 0..4
  4.         if @game2048.[](i, j) != nil
  5.           @background_sprite.bitmap.draw_text(130+80*j, 100+60*i, 60, 24, @game2048.[](i, j), 1)
  6.         end
  7.       end
  8.     end
  9.   end


汗,明明定义了each_with_index还这样玩……而且j的范围还打错了(虽然没什么大碍)

美观大方~
RUBY 代码复制
  1. def draw_box
  2.     @game2048.each_with_index do |n, i, j|
  3.       @background_sprite.bitmap.draw_text(130+80*j, 100+60*i, 60, 24, n, 1) if n
  4.     end
  5.   end


另外 @game2048.[](i, j) 写成 @game2048[i, j] 就好

还有update方法可以写简单点, 改起来也方便~ 比如加个移动失败的功能
RUBY 代码复制
  1. def update
  2.     super
  3.     [:left, :right, :up, :down].each do |dir|
  4.       if Input.trigger? dir.upcase
  5.         if @game2048.move dir
  6.           judge
  7.           clear_box
  8.           Sound.play_cursor
  9.           draw_box
  10.         else
  11.           Sound.play_buzzer # 移动失败
  12.         end
  13.       end
  14.     end
  15.   end


然后,如果要加得分功能的话,可以对merge_value重定义,来增加@score即可
当然score要初始化为零,并且做好attr_reader :score

点评

学习了。  发表于 2014-3-31 09:08
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
2012
在线时间
1018 小时
注册时间
2011-6-19
帖子
633

极短24参与开拓者

6
发表于 2014-3-30 19:16:05 | 只看该作者
仰望,话说RM的键盘操作特适合移植这个啊,不过不知道能不能加入让使用者自定义文字信息的功能?目前扫了一眼,似乎……没发现orz

点评

没加密的游戏直接改脚本不就好了?  发表于 2014-3-31 13:07
自定义文字信息?  发表于 2014-3-31 09:09
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-25 05:34

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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