Nightさんへのお返事です。
十進BASICは、リアルタイム系ゲームの作成には不向きです。
・ビットマップ画像を高速に処理できない。(切り出し表示など)
・3Dは自前で処理する必要がある。また、他のライブラリを利用できない。
以前作成したものです。参考にしてください。
!ファミコン時代の2D RPGを作る
!マップの構成
! 「正面見下ろし」形式のチップ画像を用意して、タイル状に配置する。
! フィールド、オブジェクトの2層で構成される。
! オブジェクト層が移動可能判定の対象とする。
!チップ画像
! 十進BASICはビットマップ画像を扱うのが苦手のため、ベクトル図形(PLOT文)で描画する。
! X、Yとも-1~1の範囲の座標で表現して、描画単位はPICTURE文でまとめる。
!
!マップの展開
! 十進BASICの問題座標にマップ全体をDRAW文で描画する。
! フィールド、オブジェクトの順に描画する。
!マップの表示(ビュー)
! SET WINDOWS文でビューを構成して、マップの一部を画面に表示する。
!ビューのスクロール
! PC(Player Character)の「中央固定」で追従する。
!キャラクタの移動
! チップ単位、上下左右の4方向。
! 仮想ゲームパッドからの入力をサポートする。
! 移動キー:カーソルキー
! Aボタン:SPACEキー
! Bボタン:
!マップの定義
DATA 15,12 !マップの大きさ
READ msx,msy !マップ情報を読み込む
DATA 1,1,1,2,2, 2,1,1,1,1, 2,2,2,1,1 !チップ配置情報(フィールド)
DATA 1,1,1,2,2, 2,1,1,1,1, 2,2,2,1,1
DATA 1,1,1,2,2, 2,1,1,1,1, 1,1,1,1,1
DATA 1,1,1,1,2, 1,1,1,1,1, 1,1,1,1,1
DATA 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1
DATA 1,2,2,1,1, 1,1,1,1,1, 1,1,1,1,1
DATA 1,2,2,1,1, 1,2,2,2,1, 1,1,1,1,1
DATA 2,2,1,1,1, 1,2,2,2,1, 3,3,1,1,1
DATA 2,2,1,1,1, 1,2,2,2,1, 3,2,2,1,1
DATA 2,2,2,2,1, 1,1,1,1,1, 3,2,2,1,1
DATA 2,2,2,2,1, 1,1,1,1,1, 3,3,2,1,1
DATA 1,1,1,1,1, 1,1,1,1,1, 3,3,3,1,1
DIM mapFld(msy,msx)
MAT READ mapFld
DATA 0, 0, 0, 0,12, 0, 0, 0, 0,11, 0,12,12, 0, 0 !チップ配置情報(オブジェクト)
DATA 0, 0, 0, 0,12, 0, 0, 0, 0,11, 0, 0,12, 0, 0
DATA 0, 0, 0, 0,12, 0, 0, 0, 0,11, 11, 0, 0, 0, 0
DATA 0, 0, 0, 0, 0, 0, 0, 0,11,11, 0, 0, 0, 0, 0
DATA 0, 0 ,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
DATA 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
DATA 0,12,12, 0, 0, 0, 0, 0,12, 0, 0, 0, 0, 0, 0
DATA 0, 0,11,11, 0, 0, 0,21,12, 0, 13,13, 0, 0, 0
DATA 0,12,11,11, 0, 0, 0, 0,12, 0, 13,12, 0, 0, 0
DATA 0,12,12,12, 0, 0, 0, 0, 0, 0, 13,12,12, 0, 0
DATA 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0
DATA 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
DIM mapObj(msy,msx)
MAT READ mapObj
!ゲーム画面の定義
LET GAME_TITLE=1 !タイトル
LET GAME_MOVE=2 !移動
LET GAME_TALK=3 !会話
LET GAME_BATTLE=4 !戦闘
LET gs=GAME_TITLE !タイトル画面から
!ビューポートの定義
LET vsx=15 !ビューポートの大きさ(1/2チップ単位)
LET vsy=15
LET vx=0 !位置(左下。※問題座標)
LET vy=0
!移動方向の定義
LET MOVE_NONE=-1 !なし
LET MOVE_RIGHT=0 !右
LET MOVE_UP=2 !上
LET MOVE_LEFT=4 !左
LET MOVE_DOWN=6 !下
!会話文の定義
DATA "はじめる:Aボタン(SPACEキー)" !#1 ※4行単位
DATA "おわる:ESCキー"
DATA ""
DATA "移動:十字(カーソルキー)、OK:Aボタン"
DATA "" !#2
DATA ""
DATA ""
DATA ""
DATA "コーヒータイム♪" !#3
DATA ""
DATA "「休憩をとったら出発だ!」"
DATA ""
DATA "「残念、ぼくは泳げないんだ。」" !#4
DATA "「飛び越えられないぞ...」"
DATA ""
DATA ""
DATA "" !#5
DATA ""
DATA ""
DATA ""
DIM ms$(4*5)
MAT READ ms$
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 !イベント配置情報
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 4,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,4,4, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,3,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DATA 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0
DIM mapEvt(msy,msx)
MAT READ mapEvt
LET evt=0
!ゲームの初期化
LET x=6 !キャラクタの位置(チップ単位)
LET y=5
LET d=MOVE_DOWN !向き
CALL SetViewPort !ビューポート移動
LET t0=TIME
LET fRun=-1 !ゲーム開始
DO WHILE fRun<0 !ゲームループ
IF gs=GAME_TITLE THEN !タイトル画面なら
SET DRAW mode hidden !ちらつき防止(開始)
CLEAR
DRAW Hiro(6,d) WITH SHIFT(vx+8,vy+8) !キャラクタ
PLOT TEXT ,AT vx+6,vy+11: "チョコボの冒険"
CALL DrawSpeak(0,0)
SET DRAW mode explicit !ちらつき防止(終了)
CALL GetAButton(t0) !Aボタンの入力
END IF
IF gs=GAME_MOVE THEN !移動画面なら
CALL GetMoveKey(dx,dy,dr,t0) !移動キーの入力
IF dx<>0 OR dy<>0 THEN !移動なら
LET d=dr !移動方向に向く
LET xx=x+dx !仮に移動する(チップ単位)
LET yy=y+dy
IF xx>0 AND xx<=msx AND yy>0 AND yy<=msy THEN !マップ内で
IF mapObj(yy,xx)=0 THEN !障害物がなければ
LET x=xx !実際に移動させる
LET y=yy
END IF
END IF
CALL SetViewPort !ビューポート移動
LET evt=CheckEvent(mapEvt,x,y) !フィールド上のイベントを確認
END IF
CALL DrawView !ビュー表示
END IF
IF gs=GAME_TALK THEN !会話画面なら
CALL DrawView !ビュー表示
CALL GetAButton(t0) !Aボタンの入力
END IF
IF GetKeyState(27)<0 THEN LET fRun=0 !ESCキーで終了
LOOP
SUB GetMoveKey(dx,dy,dr,t0) !移動キーの入力を確認する
LET dx=0 !移動量
LET dy=0
LET dr=MOVE_NONE !移動方向
IF TIME-t0>0.2 THEN !200ミリ秒ごとに
IF GetKeyState(37)<0 THEN !いずれか1つのみ
LET dx=-1
LET dr=MOVE_LEFT !左カーソルキー
ELSE
IF GetKeyState(38)<0 THEN
LET dy=-1
LET dr=MOVE_UP !上
ELSE
IF GetKeyState(39)<0 THEN
LET dx=1
LET dr=MOVE_RIGHT !右
ELSE
IF GetKeyState(40)<0 THEN
LET dy=1
LET dr=MOVE_DOWN !下
END IF
END IF
END IF
END IF
LET t0=TIME !次へ
END IF
END SUB
SUB GetAButton(t0) !Aボタンの入力を確認する
IF TIME-t0>0.2 THEN !200ミリ秒ごとに
IF GetKeyState(32)<0 THEN LET gs=GAME_MOVE !SPACEキー
LET t0=TIME !次へ
END IF
END SUB
SUB SetViewPort !ビューポートの設定する
LET vx=2*x-vsx/2-1 !「キャラクタの中央固定」でビューポートを追従させる
LET vy=2*(msy-y)-vsy/2+1
SET WINDOW vx,vx+vsx,vy,vy+vsy
END SUB
SUB DrawView !マップ、キャラクタを表示する
SET DRAW mode hidden !ちらつき防止(開始)
CLEAR
CALL DrawLayer(mapFld,msx,msy) !フィールド
CALL DrawLayer(mapObj,msx,msy) !オブジェクト
DRAW Hiro(6,d) WITH SHIFT(2*x-1,2*(msy-y)+1) !キャラクタ
IF gs=GAME_TALK THEN CALL DrawSpeak(evt,0) !会話文
SET DRAW mode explicit !ちらつき防止(終了)
END SUB
SUB DrawSpeak(n,v) !会話文を表示する
SET AREA COLOR 199 !ふきだし
PLOT AREA: vx+1,vy+1; vx+vsx-1,vy+1; vx+vsx-1,vy+5; vx+1,vy+5
SET LINE COLOR 1
SET LINE width 3
PLOT LINES: vx+1,vy+1; vx+vsx-1,vy+1; vx+vsx-1,vy+5; vx+1,vy+5; vx+1,vy+1
SET TEXT HEIGHT 0.4
FOR i=1 TO 4 !4行単位
PLOT TEXT ,AT vx+2,vy+4.75-i*0.75: ms$(n+i)
NEXT i
END SUB
FUNCTION CheckEvent(e(,),x,y) !フィールド上のイベントを確認する
LET a=e(y,x)
IF a>0 THEN LET gs=GAME_TALK !会話画面へ
LET CheckEvent=4*(a-1)
END FUNCTION
END
続く