スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Ruby]8・15・24パズル

最近知ったRubyのゲーム用ライブラリDXRuby

使いやすさと軽い(らしい)ので,これからゲームを作るときはDXRubyを使ってみる予定です.

で,このライブラリをダウンロードしたときにいくつかサンプルがついてきたのですが,その中に8パズルという,まあよくあるイラストをスライドさせて正しい位置に持って行くゲームです.

それを改造して,難易度選択と十字キーでの操作ができるようにしてみました.
へちょいですが.

ソースコピペして,縦480横320の画像を,名前を3.jpg 4.jpg 5.jpg としてimgフォルダの中に入れておけばうごく……はずです.

ツッコミアドバイス罵倒大歓迎です.
あとは,スライド時にアニメーションさせたいけど,どうやったらいいんだろ…….

require 'dxruby'

# それぞれウインドウ横幅,縦幅,タイトル
Window.width = 320
Window.height = 480
Window.caption = "パズルパズルパズル"

# パズルゲーム本体
class Puzzle
def initialize(mode)
@mode = mode # 難易度=縦横の分割数
@last = @mode ** 2 - 1 # 全ピース配列の末尾の位置
@image = Image.loadToArray("img/#{@mode}.jpg", @mode, @mode) # 分割数×分割数のピースに分解された画像データが入った配列
@piece = Array.new(@mode ** 2) # ピースの順番が納められた配列
for i in 0..(@mode ** 2 - 1)
@piece[i] = i
end
shuffle
end

# 外部から画像オブジェクトとピースの情報と末尾の位置を読み取りだけできるように
attr_reader :image, :piece, :last

# クリック時の処理
def click(x, y)
i = @piece.index(@last)
if (((i % @mode) - x).abs == 1 and (i / @mode) == y) or (((i / @mode) - y).abs == 1 and (i % @mode) == x)
@piece[x + y * @mode], @piece[i] = @piece[i], @piece[x + y * @mode]
end
end

# ピースをシャッフルする
# シャッフルする回数は,縦・横のピース数×400(適当)
def shuffle
(@mode * 400).times do
click(rand(@mode), rand(@mode))
end
end

# ↑キーが押されたときの処理
def keyUp
i = @piece.index(@last)
unless ((@last - @mode + 1)..@last).include?(i)
@piece[i], @piece[i + @mode] = @piece[i + @mode], @piece[i]
end
end

# ↓キーが押されたときの処理
def keyDown
i = @piece.index(@last)
if i >= @mode
@piece[i], @piece[i - @mode] = @piece[i - @mode], @piece[i]
end
end

# →キーが押されたときの処理
def keyRight
i = @piece.index(@last)
unless i % @mode == 0
@piece[i], @piece[i - 1] = @piece[i - 1], @piece[i]
end
end

# ←キーが押されたときの処理
def keyLeft
i = @piece.index(@last)
unless i % @mode == (@mode - 1)
@piece[i], @piece[i + 1] = @piece[i + 1], @piece[i]
end
end
end

# 何かキーを押した場合,真が返る.仕組みはわからない.
def push?
for i in 0..255
return true if Input.keyPush?(i)
end
false
end

# メニュー画面用のデータ.
menu_mode = true
title = Font.new(80)
title_size = title.getWidth("Puzzle")
menu_f = Font.new(40)
menu = ["Easy", "Normal", "Hard", "Exit"]
cursor_id = 0

# ゲーム時に必要な変数
# どうも,Window.loop外で一度宣言する必要あり?
mode = puz = check = nil

# クリアフラグ.最初はクリアしてないので偽
clear = false

# プログラム本体
Window.loop do
# ==============================================================================================================
# メニュー画面.ここで難易度選択を行う
# ==============================================================================================================

# タイトルを表示.
# メニューは,カーソルIDと示しているメニューは白で,それ以外は灰色で表示
if menu_mode
Window.drawFont(Window.width / 2 - title_size / 2, 50, "Puzzle", title)
for i in 0..3
if cursor_id % 4 == i
Window.drawFont(110, 200 + i * 50, menu[i], menu_f)
else
Window.drawFont(110, 200 + i * 50, menu[i], menu_f, :color=>[150, 150, 150])
end
end

# ↑↓キーを押すことで,カーソル位置が移動する
cursor_id += 1 if Input.keyPush?(K_DOWN)
cursor_id -= 1 if Input.keyPush?(K_UP)

# EnterかZボタンを押した時点でのカーソル位置で,ゲームの難易度か終了するかを決定.
if Input.keyPush?(K_RETURN) or Input.keyPush?(K_Z)
break if cursor_id % 4 == 3 # カーソル位置がExitだった場合,ループを抜けてプログラムを終了させる.
mode = cursor_id % 4 + 3 # それ以外の場合,カーソルID+3を難易度としてパズルクラスを作る.
puz = Puzzle.new(mode)
check = Array.new(puz.piece.length)
puz.piece.each_index {|i| check[i] = i} # 0..ピース末尾までの,完成時の配列の並びを記憶した変数checkの作成
menu_mode = clear = false
end
next
end

# ==============================================================================================================
# ゲーム開始
# ==============================================================================================================

# スクリーンショット機能
if Input.keyPush?(K_F12) == true
if ! File.exist?("screenshot")
Dir.mkdir("screenshot")
end
Window.getScreenShot("screenshot/screenshot" + Time.now.strftime("%Y%m%d_%H%M%S") + ".jpg")
end

# ESCキーでメニュー画面へ
# クリア時,何かボタンを押してもメニュー画面へ
if Input.keyPush?(K_ESCAPE) or (clear and push?)
clear = false
menu_mode = true
end

# マウスを押した位置からどのピースをクリックしたかを判定して,クリック処理
if Input.mousePush?(M_LBUTTON) and !clear
puz.click(Input.mousePosX / puz.image[0].width, Input.mousePosY / puz.image[0].height)
end

# ピースがそろっていないとき,配列の末要素(空白ピース)以外を表示
# 配列checkにはピース数と同じ数の配列が入っているためeach_indexでループすればピースすべてを描画できる.
check.each_index do |j|
if puz.piece[j] != (puz.piece.length - 1)
Window.draw(j % mode * puz.image[0].width, j / mode * puz.image[0].height, puz.image[puz.piece[j]])
end
end

# ピースがそろっていたとき,全ピースを表示
# この時点で配列の末要素以外のピースはすべて↑のループで表示されているため,ここで表示するのは配列の末要素のみ
if puz.piece == check
Window.draw(puz.last % mode * puz.image[0].width, puz.last / mode * puz.image[0].height, puz.image[puz.piece[puz.last]])
clear = true
end

# クリア状態でないとき,十字キーでのピース移動を有効に
unless clear
puz.keyUp if Input.keyPush?(K_UP)
puz.keyDown if Input.keyPush?(K_DOWN)
puz.keyLeft if Input.keyPush?(K_LEFT)
puz.keyRight if Input.keyPush?(K_RIGHT)
end
end

テーマ : プログラミング - ジャンル : コンピュータ

コメント
コメントの投稿
管理者にだけ表示を許可する

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。