迷路の中を歩く(Ruby)
ひとつ前の記事で迷路を生成したので、その中を歩いてみるプログラムを書きました。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 #Left, Top = 20, 20 #CellWidth = 20 # #fork { show_maze(Width, Height, yokokabe, tatekabe) } WalkMaze.start(Width, Height, yokokabe, tatekabe)
maze.rb はひとつ前の記事です。miniopengl.rb はこちらを参照。
なお、Linux の OpenGL についてはこちらも参照。
※追記
これの立体版も作ってみました。
obelisk.hatenablog.com