#!ruby -Ku # -*- mode: ruby; coding: utf-8 -*- # Last updated: <2016/05/04 21:34:52 +0900> # # グリッド状態の座標群をスクロールさせる仕組みがちゃんと動くかテスト require "dxruby" # 道路生成用クラス class Road attr_accessor :idx def initialize @imgs = Image.loadTiles("tex.png", 1, 3) # 画像読み込み @Point = Struct.new("Point", :x, :z) # 座標記録用 @Face = Struct.new("Face", :indexes, :visible, :tex) # ポリゴン記録用 @road_w = 80 # 道路の幅 @side_w = 32 # 道路脇の一片の幅 @dist = 32 # 道路の一片の長さ @side_num = 6 # 道路脇の片の数(片側分) @rownum = 8 # 道路片の数 @colnum = (@side_num + 1) * 2 # 横一列分の頂点数 @x, @z = 0, 0 # 道路生成の基準座標 @idx = 0 # インデックス値 @ang = 270 # 初期角度 @p = [] # 頂点群の情報 @road_lines = [] # 道路の線分情報 @faces = [] # ポリゴン群の情報 # 座標格納用配列を確保 @rownum.times do |i| @road_lines.push([@Point.new(0,0), @Point.new(0,0)]) @colnum.times { |j| @p.push(@Point.new(0, 0)) } end # 座標群を初期化 @rownum.times do |i| set_oneline(i, @ang, @dist, @road_w, @side_w, @side_num) @ang += rand(-20..20) end # ポリゴンの頂点リストを設定 @rownum.times do |row| v = (row < (@rownum - 1))? true : false texk = row % 2 i0 = (row * @colnum) % @p.length i1 = ((row + 1) * @colnum) % @p.length (@colnum - 1).times do |i| tk = (i == @side_num)? texk : 2 lst = [ i1 + i, i1 + i + 1, i0 + i + 1, i0 + i, ] @faces.push(@Face.new(lst, v, tk)) end end end # 道路の横一列分の座標群を設定 # # @param idx [Integer] 更新場所のインデックス値 # @param ang [Number] 角度 # @param dist [Number] 道路一片の長さ # @param road_w [Number] 道路の横幅 # @param side_w [Number] 道路脇一片の横幅 # @param side_num [Integer] 道路脇の数(片側分) def set_oneline(idx, ang, dist, road_w, side_w, side_num) # 線分の開始座標を記録 @road_lines[idx][0].x = @x @road_lines[idx][0].z = @z # 座標群を更新 l = side_num + 1 i0 = idx * @colnum i1 = i0 + @colnum - 1 rad0 = deg2rad(ang - 90) rad1 = deg2rad(ang + 90) r = side_w * side_num + (road_w / 2) l.times do |j| @p[i0 + j].x = @x + r * Math.cos(rad0) @p[i0 + j].z = @z + r * Math.sin(rad0) @p[i1 - j].x = @x + r * Math.cos(rad1) @p[i1 - j].z = @z + r * Math.sin(rad1) r -= side_w end # 次の基準座標を設定 rad = deg2rad(ang) @x += dist * Math.cos(rad) @z += dist * Math.sin(rad) # 線分の終了座標を記録 @road_lines[idx][1].x = @x @road_lines[idx][1].z = @z end # 道路を1マス進める def inc_index set_oneline(@idx, @ang, @dist, @road_w, @side_w, @side_num) fnum = @colnum - 1 # 非表示ポリゴンの表示を有効にする f0 = ((@idx + @rownum - 1) % @rownum)* fnum fnum.times do |i| @faces[f0 + i].visible = true end # 一部のポリゴンを非表示にする f0 = @idx * fnum fnum.times do |i| @faces[f0 + i].visible = false end # インデックス値を更新 @idx = (@idx + 1) % @rownum # 角度を更新 @ang += rand(-20..20) end # 度からラジアンに変換 # # @param deg [Number] 度 # @return [Number] ラジアン def deg2rad(deg) return deg * Math::PI / 180.0 end # ポリゴンを描画 # # @param bx [Number] 描画をずらす量 x # @param by [Number] 描画をずらす量 y def draw(bx, by) @faces.each do |f| next unless f.visible idxs = f.indexes x1, y1 = @p[idxs[0]].x + bx, @p[idxs[0]].z + by x2, y2 = @p[idxs[1]].x + bx, @p[idxs[1]].z + by x3, y3 = @p[idxs[2]].x + bx, @p[idxs[2]].z + by x4, y4 = @p[idxs[3]].x + bx, @p[idxs[3]].z + by Window.drawMorph(x1, y1, x2, y2, x3, y3, x4, y4, @imgs[f.tex]) end end # 道路の線分上の座標値を取得 # # @param idx [Integer] インデックス値 # @param t [Number] 割合。0.0 - 1.0 の値 # @param [Array] x,z座標を返す def get_roadlinepos(idx, t) idx = (idx + @rownum) % @rownum l0, l1 = @road_lines[idx] x = l0.x + (l1.x - l0.x) * t z = l0.z + (l1.z - l0.z) * t return x, z end end road = Road.new t = 0 Window.loop do break if Input.keyPush?(K_ESCAPE) # 時間を進める t += (1.0 / 60.0) if t >= 1.0 t -= 1.0 road.inc_index # 道路の座標群を一部更新 end bx, by = road.get_roadlinepos(road.idx + 2, t) road.draw(-bx + Window.width / 2, -by + Window.height / 2) end