最近《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。
[pre lang="ruby" line="1"]#==============================================================================
# □ Scene_Game2048
# 2048小游戏,RMVA版作者:swebok,转载需保留该信息!
# http://rpg.blue/thread-357532-1-1.html
#==============================================================================
class Scene_Game2048 < Scene_Base
#--------------------------------------------------------------------------
# ● 开始处理
#--------------------------------------------------------------------------
def start
super
init_game
draw_box
end
#--------------------------------------------------------------------------
# ● 结束处理
#--------------------------------------------------------------------------
def terminate
super
@background_sprite.dispose
end
#--------------------------------------------------------------------------
# ● 刷新处理
#--------------------------------------------------------------------------
def update
super
if Input.trigger?(:LEFT)
@game2048.move(:left)
judge
clear_box
Sound.play_cursor
draw_box
end
if Input.trigger?(:RIGHT)
@game2048.move(:right)
judge
clear_box
Sound.play_cursor
draw_box
end
if Input.trigger?(:UP)
@game2048.move(:up)
judge
clear_box
Sound.play_cursor
draw_box
end
if Input.trigger?(:DOWN)
@game2048.move(:down)
judge
clear_box
Sound.play_cursor
draw_box
end
end
#--------------------------------------------------------------------------
# ● 初始化
#--------------------------------------------------------------------------
def init_game
@game2048 = Game2048.new
@background_sprite = Sprite.new
@background_sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height)
draw_box
end
#--------------------------------------------------------------------------
# ● 擦除格子
#--------------------------------------------------------------------------
def clear_box
@background_sprite.bitmap.clear
end
#--------------------------------------------------------------------------
# ● 描画格子
#--------------------------------------------------------------------------
def draw_box
for i in 0...4
for j in 0..4
if @game2048.[](i, j) != nil
@background_sprite.bitmap.draw_text(130+80*j, 100+60*i, 60, 24, @game2048.[](i, j), 1)
end
end
end
end
#--------------------------------------------------------------------------
# ● 判定结束
#--------------------------------------------------------------------------
def judge
if @game2048.lose?
clear_box
draw_box
@background_sprite.bitmap.draw_text(120, 320, 300, 24, "无法移动,你失败了!", 1)
$data_system.gameover_me.play
abs_wait(180)
SceneManager.goto(Scene_Map)
end
if @game2048.win?
clear_box
draw_box
@background_sprite.bitmap.draw_text(120, 320, 300, 24, "达到2048,恭喜您胜利!", 1)
$game_system.battle_end_me.play
abs_wait(180)
SceneManager.goto(Scene_Map)
end
end
#--------------------------------------------------------------------------
# ● 等待(快进无效)
#--------------------------------------------------------------------------
def abs_wait(duration)
duration.times {|i| update_for_wait }
end
#--------------------------------------------------------------------------
# ● 更新画面(等待用)
#--------------------------------------------------------------------------
def update_for_wait
update_basic
end
end[/pre]
预计更新:
游戏界面;自定义文字、图片信息(比如可以做成2个包子合成一个馒头啦)。
(最近比较忙,预计会龟速更新,但愿别太监就行...) 作者: taroxd 时间: 2014-3-27 08:44 本帖最后由 taroxd 于 2014-3-31 18:45 编辑
def initialize(size = 4, max = 2048)
@size, @Max = size, max
@data = Array.new(size) { Array.new(size) }
2.times { generate }
end
def move(direction)
last = to_a
send :"move_#{direction}"
return if last == to_a
generate
self
end
def [](i, j)
@data[j]
end
def each
return to_enum(__method__) { @size**2 } unless block_given?
@data.each {|row| row.each {|n| yield n } }
end
def each_index
return to_enum(__method__) { @size**2 } unless block_given?
@size.times {|i| @size.times {|j| yield i, j } }
end
def each_with_index
return to_enum(__method__) { @size**2 } unless block_given?
each_index {|i, j| yield @data[j], i, j }
end
def to_a
@data.flatten
end
def lose?
each_with_index.all? do |n, i, j|
n && @data[j + 1] != n && (i >= @size - 1 || @data[i + 1][j] != n)
end
end
def win?
any? {|n| n && n >= @max }
end
private
def move_left
@data.each do |row|
row.compact!
(@size - 1).times do |i|
if row && row == row[i + 1]
row = merge_value(row)
row.delete_at(i + 1)
end
end
row.push(nil) until row.size >= @size
end
end
[pre lang="ruby" line="1"]
def draw_box
for i in 0...4
for j in 0..4
if @game2048.[](i, j) != nil
@background_sprite.bitmap.draw_text(130+80*j, 100+60*i, 60, 24, @game2048.[](i, j), 1)
end
end
end
end[/pre]
汗,明明定义了each_with_index还这样玩……而且j的范围还打错了(虽然没什么大碍)
美观大方~
[pre lang="ruby" line="1"]
def draw_box
@game2048.each_with_index do |n, i, j|
@background_sprite.bitmap.draw_text(130+80*j, 100+60*i, 60, 24, n, 1) if n
end
end
[/pre]
另外 @game2048.[](i, j) 写成 @game2048[i, j] 就好
还有update方法可以写简单点, 改起来也方便~ 比如加个移动失败的功能
[pre lang="ruby" line="1"]
def update
super
[:left, :right, :up, :down].each do |dir|
if Input.trigger? dir.upcase
if @game2048.move dir
judge
clear_box
Sound.play_cursor
draw_box
else
Sound.play_buzzer # 移动失败
end
end
end
end
[/pre]