ひとつ前の記事で迷路を生成したので、その中を歩いてみるプログラムを書きました。OpenGL を使っています。Ruby 2.3.3, Linux Mint 18.3 で動作確認。
赤い床のマスがゴールです。"←" で左回転、"→" で右回転、"↑" で前進します。迷路は実行のたびに新たに生成されます。
ぐぐってみても意外とこんな単純なゲーム(?)の実装がないのですよねえ。
walk_maze.rb
require_relative 'miniopengl'
require_relative 'maze'
module WalkMaze
def self.start(width, height, yokokabe, tatekabe)
MiniOpenGL.app width: 400, height: 400, depth_buffer: :on, title: "maze" do
px, pz = width - 1, height - 1
dir = [0, -1]
draw do
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
self.color_alpha = 0.9
glEnable(GL_DEPTH_TEST)
clear
color(0, 1, 1)
(height + 1).times {|z| line3(0, 0, z, width, 0, z)}
(width + 1).times {|x| line3(x, 0, 0, x, 0, height)}
color(0, 0.8, 0)
(height + 1).times do |z|
width.times do |x|
next if yokokabe[x + z * width].zero?
vtx = [x, 0, z, x + 1, 0, z, x + 1, 1, z, x, 1, z]
draw_vertex(GL_QUADS, 3, vtx)
end
end
(width + 1).times do |x|
height.times do |z|
next if tatekabe[z + x * height].zero?
vtx = [x, 0, z, x, 0, z + 1, x, 1, z + 1, x, 1, z]
draw_vertex(GL_QUADS, 3, vtx)
end
end
color(1, 0, 0)
draw_vertex(GL_QUADS, 3, [0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1])
display
end
set_eye = ->{
init_modelview
x = px + 0.5
z = pz + 0.5
look_at(x, 0.5, z, x + dir[0], 0.5, z + dir[1], 0, 1, 0)
}
reshape do |w, h|
viewport(0, 0, w, h)
init_projection
perspective(120, w / h.to_f, 0.2, 20)
set_eye.()
end
check = ->{
if dir[0].zero?
z = (dir[1] < 0) ? pz : pz + 1
f = yokokabe[z * width + px]
else
x = (dir[0] < 0) ? px : px + 1
f = tatekabe[x * height + pz]
end
f.zero?
}
end_f = false
key_in2 do |key|
exit if end_f
case key
when GLUT_KEY_LEFT
dir = [dir[1], -dir[0]]
when GLUT_KEY_RIGHT
dir = [-dir[1], dir[0]]
when GLUT_KEY_UP
if check.()
px += dir[0]
pz += dir[1]
end
end
set_eye.()
redisplay
if px.zero? and pz.zero?
puts "Goal!"
end_f = true
end
end
end
end
end
Width, Height = 10, 10
yokokabe, tatekabe = Maze.new(Width, Height).generate
WalkMaze.start(Width, Height, yokokabe, tatekabe)
maze.rb はひとつ前の記事です。miniopengl.rb はこちらを参照。
なお、Linux の OpenGL についてはこちらも参照。
※追記
これの立体版も作ってみました。
obelisk.hatenablog.com