BASICで宇宙遊泳
この記事のプログラムはVL-BASICの仕様変更で
動かなくなりました。
BASICで日食(修正版)をみて下さい。
動画です。
下記ホームページからVL-BASICとブログで紹介した
BASICプログラム(~.bas)をダウンロードできます。
Readme.txtを読んで、遊んで見て下さい。
vl20326.zipの(vl/g/sun002.bas)です。
BASICで日食のプログラムを変更して
移動をブースター方式
(キーを押している間加速し、
離すと一定速度で動いたままになる)
にしました。
宇宙空間で宇宙船を操作している
気分を味わえるかもしれません。
時速と光速に対する割合も表示
しています。
キーは、'/', '\', カーソル
その他は下記LISTの最後に書いてあります。
プログラムリストは上記ホームページから
ダウンロードできますが、
以下に、LISTを載せておきます。
sun002.bas
1000 '----------------------------------------------------------------------
1010 ' BASICで日食
1020 '
1030 ' by ULproject for VL-BASIC 2020/2
1040 '----------------------------------------------------------------------
1050 'SCREEN 3,0,0,1
1060 'CLS 3
1070 CMD GPU ON '--- GPU命令を有効にする
1080 GPU SYNC(ON) '--- すべての表示をGPU描画に同期させる
1090 '
1100 GPU TRACE(VIEW.OFFSET,1000)'--- 左右スクリーン間隔(スクリーン長の倍数)
1110 STEREO = 0 '--- 0:Mono 1:Stereo -1:Cross
1120 TI = 0:T0=TIME(1000) '--- 1/1000s単位で経過時間を得る
1130 MS = T0 '--- 移動用経過時間(ms)
1140 VZ = 4E-3 '--- スクリーン視点間距離(離れると望遠)
1150 TA = 2 '--- 全体の回転速度
1160 '--- 開始
1170 *START
1180 '
1190 ' 半径(km), 軌道長半径(km), 自転周期(日), 自転角(°)
1200 RS = 696000: AS = 0
1210 RE = 6378: AE = 149600000: DE = 0.01/ 0.9973: TE = 180
1220 RM = 1738: AM = 384400: DM = 0.01/27.3217: TM = -0.7
1230 ' 光速 light velocity(km/s) , 地球の位置
1240 LV = 299792 : A0 = AE
1250 '
1260 RX = 0: RY = 0: RZ = 0
1270 TX = 0: TY = 0: TZ = 0
1280 '
1290 '
1300 GPU MATRIX(IDENTITY) '--- 単位行列にする(位置のリセット)
1310 GPU MATRIX(MODE,VIEW) '--- 行列をMODELからVIEWモードに
1320 GPU ROTATE(-90, 1, 0, 0) '--- 視点をx軸周りに 90°(景色移動方向)
1330 GPU ROTATE( 90, 0, 1, 0) '--- 視点をy軸周りに-90°(景色移動方向)
1340 GPU TRANSLATE(0, 0, A0-RE-0.1)'--- 視点をz軸方向に移動(景色移動方向)
1350 GPU ROTATE(180, 0, 1, 0) '--- 視点をy軸周りに180°(景色移動方向)
1360 GPU MATRIX(MODE,PREVIOUS) '--- 行列モードを前の状態(MODELモード)へ
1370 A$ = ""
1380 WHILE A$ <> "q" AND A$ <> CHR$(13)
1390 GPU TRACE(VIEW.R, 1E-3) '--- スクリーン半径r(視半径)
1400 GPU TRACE(VIEW.Z, VZ ) '--- スクリーン視点間距離
1410 GPU MATERIAL(PUSH) '--- 物体情報退避
1420 GPU MATRIX(PUSH) '--- 行列(位置)退避
1430 GOSUB *SUN '--- 光源の色など定義
1440 A = 1.0
1450 GPU MATERIAL(LIGHT , A, A, A) '--- 光源の光の色と強さ
1460 GPU MATERIAL(ATTENUATE, 1, 0, 0) '--- 光減衰(0,1,2乗の係数)
1470 GPU MATERIAL(LIGHTS , RS) '--- 光源半径(球の半陰のみ対応)
1480 GPU SPHERE(RS * 1.4) '--- 光源の球(フレア分大きめに)
1490 GPU MATRIX(POP) '--- 行列(位置)戻す
1500 GPU MATERIAL(POP) '--- 物体情報戻す
1510 GPU MATRIX(PUSH)
1520 GPU TRANSLATE(A0, 0, 0) '--- x軸方向に軌道半径移動
1530 GPU MATERIAL(PUSH)
1540 GPU MATRIX(PUSH)
1550 GPU ROTATE(23.44, 1, 0, 0) '--- x軸周りに回転(右手系)
1560 GPU ROTATE(TE , 0, 0, 1) '--- z軸周りに回転(右手系)
1570 TE = (TE + DE*TA) MOD 360
1580 GPU MATERIAL(DIFFUSE , 0.1, 0.1, 0.1) '--- 拡散反射係数(表面色)白
1590 GPU MATERIAL(REFLECT , 0.0, 0.0, 0.0) '--- 完全鏡面反射係数
1600 GPU MATERIAL(SPECULAR, 0.0, 0.0, 0.0) '--- 鏡面反射係数
1610 GPU MATERIAL(TEX, "Sky") '--- Textureを貼付ける
1620 GPU SPHERE(RE) '--- 地球を置く
1630 GPU MATERIAL(DIFFUSE , 0.9, 0.9, 0.9) '--- 拡散反射係数(表面色)白
1640 GPU MATERIAL(CLARITY , 0.8, 0.8, 0.8)
1650 GPU MATERIAL(REFRACT , 1 )
1660 GPU SPHERE(RE+2) '--- 大気+2km
1670 GPU MATRIX(POP)
1680 GPU MATERIAL(POP)
1690 GPU MATERIAL(PUSH)
1700 GPU ROTATE(TM , 0, 0, 1) '--- 自転周期で公転
1710 TM = (TM + DM*TA) MOD 360
1720 GPU TRANSLATE(-AM, 0, 0)
1730 GPU MATERIAL(DIFFUSE , 1.0, 1.0, 0.9) '--- 拡散反射係数
1740 GPU MATERIAL(SPECULAR, 0.0, 0.0, 0.0) '--- 鏡面反射係数
1750 GPU SPHERE(RM) '--- 月を置く
1760 GPU MATERIAL(POP)
1770 GPU MATRIX(POP)
1780 GOSUB *MOVE '--- 移動
1790 GOSUB *TRACE '--- 描画
1800 LVP = SQR(TX*TX + TY*TY + TZ*TZ)*1000 / (LV*60)
1810 KMPH = INT(LVP * LV * 3600 / 10000)
1820 LVP = INT(LVP * 100)
1830 TI=TI+1:T=TIME(1000)
1840 IF T-T0 >= 1000 THEN '--- VL-BASICではここにWENDは書かないように
1850 TI=CINT((TI*1000)/(T-T0))
1860 CLS
1870 PRINT TI;"fps ";
1880 PRINT KMPH;"万km/h ";
1890 PRINT "光速の";LVP;"%"
1900 ' PUT@(0,0),STR$(TI)+" fps",PSET,7,0
1910 TI=0:T0=T
1920 ENDIF
1930 WEND '--- VL-BASICではWHILEの数とWENDの数が違うと誤動作の可能性あり
1940 IF A$ = CHR$(13) THEN *START
1950 'GPU OFF
1960 END
1970 '--- Sun
1980 *SUN
1990 GPU MATERIAL(LIGHT , 1,1,1) '--- 光源の光の色と強さ(上にあるので不必要)
2000 GPU MATERIAL(ATTENUATE, 0,0,1) '--- 光の減衰、距離t(c+bt+att)に反比例
2010 S = 1.44
2020 GPU MATERIAL(SPECULAR , S,S*0.8,S*0.6) '--- 反射した光の色と強さ
2030 GPU MATERIAL(SHININESS, 20) '--- 大きいほど鋭く、小さいほど鈍く輝く
2040 GPU MATERIAL(DIFFUSE , 0,0,0) '--- 無色(黒)
2050 GPU MATERIAL(CLARITY , 1,1,1) '--- 完全に透明
2060 GPU MATERIAL(REFRACT , 1) '--- 屈折率1.0
2070 RETURN
2080 '--- Trace
2090 *TRACE
2100 IF STEREO THEN *TRACE.STEREO
2110 GPU CLEAR '--- 描画バッファをクリア
2120 GPU TRACE(BEGIN) '--- レイトレーシングの準備
2130 GPU TRACE(VIEWPORT.X, 0)
2140 GPU TRACE(VIEWPORT.Y, 0)
2150 GPU TRACE(VIEWPORT.W,640)
2160 GPU TRACE(VIEWPORT.H,400)
2170 GPU TRACE(VIEW.STEREO, 0) '--- 真ん中
2180 GPU TRACE '--- レイトレーシング
2190 GPU TRACE(END) '--- レイトレーシングの後始末(画面表示)
2200 RETURN
2210 '--- Trace stereo
2220 *TRACE.STEREO
2230 GPU CLEAR '--- 描画バッファをクリア
2240 GPU TRACE(BEGIN) '--- レイトレーシングの準備
2250 GPU TRACE(VIEWPORT.X, 0)
2260 GPU TRACE(VIEWPORT.Y,100)
2270 GPU TRACE(VIEWPORT.W,320)
2280 GPU TRACE(VIEWPORT.H,200)
2290 GPU TRACE(VIEW.STEREO,-STEREO) '--- 左へシフト
2300 GPU TRACE '--- レイトレーシング
2310 GPU TRACE(VIEWPORT.X,320)
2320 GPU TRACE(VIEWPORT.Y,100)
2330 GPU TRACE(VIEWPORT.W,320)
2340 GPU TRACE(VIEWPORT.H,200)
2350 GPU TRACE(VIEW.STEREO, STEREO) '--- 右へシフト
2360 GPU TRACE '--- レイトレーシング
2370 GPU TRACE(END) '--- レイトレーシングの後始末(画面表示)
2380 RETURN
2390 '--- Move
2400 *MOVE
2410 DRX = 0:DRY = 0:DRZ = 0:DTX = 0:DTY = 0:DTZ = 0:TH = 1:BK = 1
2420 DR = 0.002:DT = 0.00002 * LV
2430 IF NOT INP(&HE8) AND &H04 THEN DRX = -DR '--- → 右旋回
2440 IF NOT INP(&HEA) AND &H04 THEN DRX = DR '--- ← 左旋回
2450 IF NOT INP(&HE8) AND &H02 THEN DRY = -DR '--- ↑ 機首を下げる
2460 IF NOT INP(&HEA) AND &H02 THEN DRY = DR '--- ↓ 機首を上げる
2470 IF NOT INP(&HE4) AND &H01 THEN DRZ = DR '--- p 左傾き
2480 IF NOT INP(&HE5) AND &H08 THEN DRZ = -DR '--- [ 右傾き
2490 IF NOT INP(&HE7) AND &H80 THEN DTZ = -DT '--- \(_)前に並進
2500 IF NOT INP(&HE7) AND &H40 THEN DTZ = DT '--- / 後に並進
2510 IF NOT INP(&HE7) AND &H08 THEN DTX = -DT '--- ; 左に並進
2520 IF NOT INP(&HE5) AND &H20 THEN DTX = DT '--- ] 右に並進
2530 IF NOT INP(&HE2) AND &H01 THEN DTY = DT '--- @ 上に並進
2540 IF NOT INP(&HE7) AND &H04 THEN DTY = -DT '--- : 下に並進
2550 IF NOT INP(&HE7) AND &H20 THEN BK = 0.8 '--- Break
2560 IF NOT INP(&HE8) AND &H40 THEN TH = 5 '--- SHIFT 高速
2570 DRX = DRX * TH:DRY = DRY * TH:DRZ = DRZ * TH
2580 DTX = DTX * TH:DTY = DTY * TH:DTZ = DTZ * TH
2590 RX = RX + DRX:RY = RY + DRY:RZ = RZ + DRZ
2600 TX = TX + DTX:TY = TY + DTY:TZ = TZ + DTZ
2610 RX = RX * BK :RY = RY * BK :RZ = RZ * BK
2620 TX = TX * BK :TY = TY * BK :TZ = TZ * BK
2630 GPU MATRIX(MODE,VIEW) '--- 行列をMODELからVIEWモードに
2640 GPU ROTATE(-RY, 1, 0, 0) '--- x軸周りにRY°回転
2650 GPU ROTATE(-RX, 0, 1, 0) '--- y軸周りにRX°回転
2660 GPU ROTATE(-RZ, 0, 0, 1) '--- z軸周りにRZ°回転
2670 I = TIME(1000): T = I-MS:MS = I
2680 T = T*60/1000
2690 GPU TRANSLATE(-TX*T, -TY*T, -TZ*T) '--- VIEWモードは回転移動の符号が逆
2700 A$ = INKEY$
2710 IF A$ = " " THEN TZ = -TZ:GPU ROTATE(180, 0, 1, 0) '--- 後ろを向く
2720 GPU MATRIX(MODE,PREVIOUS) '--- 行列モードを前の状態(MODELモード)へ
2730 IF A$ = "0" THEN STEREO = 0 '--- Mono
2740 IF A$ = "-" THEN STEREO = 1 '--- Stereo
2750 IF A$ = "^" THEN STEREO = -1 '--- Cross
2760 IF A$ = "z" THEN VZ = VZ * 2
2770 IF A$ = "x" THEN VZ = VZ / 2
2780 IF A$ = "n" THEN TA = 2
2790 IF A$ = "m" THEN TA = 1000
2800 IF A$ = "," THEN TA = 0
2810 RETURN
2820 '----------------------------------------------------------------------
2830 ' 0 - ^ | 0通常表示 -並行ステレオ表示 ^交差ステレオ表示
2840 ' q | q終了
2850 ' p @ [ enter | p左傾き @上に移動 [右傾き enter初期位置へ
2860 ' ; : ] | ;左に移動 :下に移動 ]右に移動
2870 ' |
2880 ' ↑ | ↑機首下げ
2890 ' ← ↓ → space| ←左旋回 ↓機首上げ →右旋回 space後方に向く
2900 ' |
2910 ' / \(_) shift| /後進 \(_)前進 +shiftで速く移動
2920 ' |
2930 ' z x n m , . | z望遠 x広角 n通常 m高速回転 ,回転停止 .ブレーキ
2940 '----------------------------------------------------------------------