Skip to content

Instantly share code, notes, and snippets.

@mieki256
Last active March 14, 2016 10:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mieki256/c596014d24e1c80b323e to your computer and use it in GitHub Desktop.
Save mieki256/c596014d24e1c80b323e to your computer and use it in GitHub Desktop.
一本道を延々と走り続ける何か、のDXRubyスクリプト
#!ruby -Ku
# -*- mode: ruby; coding: utf-8 -*-
# Last updated: <2016/03/14 19:32:28 +0900>
#
# 道路を生成するテスト
require 'dxruby'
require 'pp'
class Road
attr_accessor :idx
def initialize
@idx = 0
@pos_list = []
@w = 160 / 2 # 道路の幅(片方の幅)
@dist = 32 # 道路の一片の長さ
@tex_num = 0 # テクスチャ番号(0 or 1)
@t = 0 # 時間(進行度)
@v_begin = 270 # スタート角度
@v_duration = 1.0
set_next_change_value
@x = 320
@y = 480
@pos_list.push([@x - @w, @y, @x + @w, @y, @tex_num])
update_texnum
# 座標を生成して配列に格納
64.times do |i|
push_new_pos
end
end
# 角度の変化量と変化速度を更新
def set_next_change_value
@v_change = rand(180) - 90
@t_spd = rand(0.025..0.08)
end
# 時間(進行度)を進める
def set_next_time
@t += @t_spd
if @t >= 1.0
@t -= 1.0
@v_begin += @v_change
set_next_change_value
end
end
# 座標を生成して配列に格納
def push_new_pos(idx = nil)
cx, cy, x0, y0, x1, y1 = get_next_pos(@x, @y, @w, @dist, @t,
@v_begin, @v_change, @v_duration)
if idx == nil
@pos_list.push([x0, y0, x1, y1, @tex_num])
else
@pos_list[idx] = [x0, y0, x1, y1, @tex_num]
end
update_texnum
@x = cx
@y = cy
set_next_time
end
# 道路片参照インデックスを更新。新座標値を生成して配列に格納
def inc_index
push_new_pos(@idx)
@idx += 1
@idx %= @pos_list.length
end
# テクスチャ番号を更新
def update_texnum
@tex_num = (@tex_num + 1) % 2
end
# 道路片用の座標値を得る
# @param x [Number] 基準座標 x
# @param y [Number] 基準座標 y
# @param w [Number] 道路片の幅(片方の幅)
# @param h [Number] 道路片の長さ
# @param t [Number] 時間(進行度)
# @param v_begin [Number] 角度開始値
# @param v_change [Number] 角度変化量
# @param v_duration [Number] 距離?
# @return [Array] 新基準 x, y, 道路片左座標 x, y, 右座標 x, y を配列で返す
def get_next_pos(x, y, w, h, t, v_begin, v_change, v_duration)
ang = ease_in_out_quad(t, v_begin, v_change, v_duration)
d = deg2rad(ang)
cx = h * Math.cos(d) + x
cy = h * Math.sin(d) + y
d = deg2rad(ang - 90)
x0 = w * Math.cos(d) + cx
y0 = w * Math.sin(d) + cy
d = deg2rad(ang + 90)
x1 = w * Math.cos(d) + cx
y1 = w * Math.sin(d) + cy
return cx.to_i, cy.to_i, x0.to_i, y0.to_i, x1.to_i, y1.to_i
end
# 道路片のポリゴン座標を得る
# @param idx [Integer] 参照インデックス値
# @param dx [Number] 座標補正値 x (スクロール処理用)
# @param dy [Number] 座標補正値 y (スクロール処理用)
# @return [Array] 4点の座標群を配列で返す
def get_poly(idx, dx = 0, dy = 0)
i0 = idx % @pos_list.length
i1 = (idx + 1) % @pos_list.length
x0, y0, x1, y1, t0 = @pos_list[i1]
x3, y3, x2, y2, t1 = @pos_list[i0]
x0 += dx
y0 += dy
x1 += dx
y1 += dy
x2 += dx
y2 += dy
x3 += dx
y3 += dy
return x0, y0, x1, y1, x2, y2, x3, y3, t1
end
# 道路片の中央の線分を得る
# @param idx [Integer] 参照インデックス値
# @param dx [Number] 座標補正値 x (スクロール処理用)
# @param dy [Number] 座標補正値 y (スクロール処理用)
# @return [Array] 2点の座標群、x0, y0, x1, y1 を配列で返す
def get_line_pos(idx, dx = 0, dy = 0)
x0, y0, x1, y1, x2, y2, x3, y3, t1 = get_poly(idx)
cx0 = (x2 + x3) / 2
cy0 = (y2 + y3) / 2
cx1 = (x0 + x1) / 2
cy1 = (y0 + y1) / 2
cx0 += dx
cy0 += dy
cx1 += dx
cy1 += dy
return cx0, cy0, cx1, cy1
end
# quadratic ease in out
# @param t [Number] 時間(0.0 - 1.0)
# @param b [Number] 基準値
# @param c [Number] 変化量
# @param d [Number] 1.0
# @return [Number] 結果
def ease_in_out_quad(t, b, c, d)
t /= (d / 2.0)
return (c / 2.0 * t * t + b) if t < 1.0
t -= 1.0
return -c / 2.0 * (t * ( t -2.0) - 1) + b
end
# 角度からラジアンに変換
def deg2rad(ang)
return ang * Math::PI / 180.0
end
end
# BGスクロール用座標その他を得る
# @param road [Object] Roadクラスインスタンス
# @param t [Number] 時間(進行度) 0.0-1.0 の値
# @return [Array] ワールド座標基準値x,y, 中心座標x,y, 角度、を配列で返す
def get_bg_pos(road, t)
# 現在乗ってる道路の線分を得る
ridx = road.idx
cx0, cy0, cx1, cy1 = road.get_line_pos(ridx + 24)
d = Math.atan2(cy1 - cy0, cx1 - cx0)
ang = d * 180.0 / Math::PI
# 線分のどのあたりに居るかを得る
lx = cx0 + (cx1 - cx0) * t
ly = cy0 + (cy1 - cy0) * t
# スクロール用の補正値を得る
bx = lx - 320
by = ly - 240
return bx, by, lx, ly, ang
end
# ----------------------------------------
# 初期設定
fnt = Font.new(16)
# 道路テクスチャを読み込み
imgs = [
Image.load("road_tex0.png"),
Image.load("road_tex1.png"),
]
# BG定義
bgimgs = Image.loadTiles("bg_chip.png", 1, 1)
bg = []
30.times do |y|
l = []
40.times do |x|
l.push(0)
end
bg.push(l)
end
# 車画像を読み込み
carimg = Image.load("car.png")
carshadowimg = Image.load("car_shadow.png")
road = Road.new
t = 0
# メインループ
Window.loop do
break if Input.keyPush?(K_ESCAPE)
# BGスクロール用座標その他を取得
bx, by, lx, ly, ang = get_bg_pos(road, t)
lx -= bx
ly -= by
bx = bx.to_i
by = by.to_i
# BG描画
Window.draw_tile(0, 0, bg, bgimgs, bx, by, 20, 15)
# 道路を描画
ridx = road.idx
ridx.upto(ridx + 48) do |i|
x0, y0, x1, y1, x2, y2, x3, y3, tn = road.get_poly(i, -bx, -by)
img = imgs[tn]
Window.drawMorph(x0, y0, x1, y1, x2, y2, x3, y3, img)
# cx0, cy0, cx1, cy1 = road.get_line_pos(i, -bx, -by)
# Window.drawLine(cx0, cy0, cx1, cy1, C_WHITE)
end
# 車を描画
lx -= carimg.width / 2
ly -= carimg.height / 2
Window.draw_ex(lx + 6, ly + 4, carshadowimg,
:centerx => nil, :centery => nil, :angle => ang,
:alpha => 160 ) # 車の影を描画
Window.draw_rot(lx, ly, carimg, ang) # 車本体を描画
# 道路片参照インデックス値やCPU使用率を描画
msg = sprintf("idx=%03d CPU:%03d%", road.idx, Window.getLoad.to_i)
Window.drawFont(8, 8, msg, fnt)
# 時間(進行度)を進める
t += 0.2
if t >= 1.0
road.inc_index
t -= 1.0
end
end
@mieki256
Copy link
Author

License は、ソースも、画像も、 CC0 / Public Domain ってことで。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment