前回のスクリプトにカメラの移動とキャラクタの移動・ジャンプを追加しました。マップチップの明るさは距離に応じた変化に限定しています。
ここまでくるとRPGというよりはアクションに近いものがありますね。
カメラの位置に合わせてカーソルキーで移動する方向を変化させる処理や、ビルボードのようにキャラクタを常に手前を向ける処理など、三角関数を多用しているので、今回のスクリプトはさすがに読みづらいと思います。d3setlocal命令によって多少は読みやすくなっていますが……。興味のある方はぜひ式を解いてみてください。// カーソルキーでキャラクタの移動
// Ctrl同時押しでカメラの移動(回転)
// Spaceでジャンプ
#include "d3m.hsp"
#include "hspmath.as"
#const CELL_SIZE 100 // d3m上のマップチップサイズ
#const IMG_SIZE 64 // bmpのマップチップサイズ
#const CAM_DIST 500
#const CHAR_SPEED 15
#const MAP_WIDTH 18
#const MAP_HEIGHT 15
// マップチップのロード
buffer 1 : picload dir_exe + "/sample/game/testchr.bmp"
// 影用の画像を用意する
color : boxf IMG_SIZE * 3, 0, IMG_SIZE * 4, IMG_SIZE
color 255,255,255 : circle IMG_SIZE * 3, 0, IMG_SIZE * 4, IMG_SIZE, 1
gsel 0
// 変数の初期化
cam_theta = M_PI * 2 / 5 // カメラの角度
cam_phi = -M_PI / 2
char_x = 0.0 // キャラクタの位置
char_y = 0.0
char_z = 0.0
char_vz = 0.0 // キャラクタの速度
// マップ作成
dim map, MAP_WIDTH, MAP_HEIGHT
repeat length2( map )
y = cnt
repeat length( map )
map( cnt, y ) = rnd( 3 )
loop
loop
gosub *draw
*main
stick keys, 15 + 64
gosub *move
if ( is_jumping ) | ( ( keys & 15 ) > 0 ) : gosub *draw
wait 3
goto *main
*move
if ( keys >> 4 & 1 ) & ( is_jumping == 0 ) {
char_vz = 20.0 // ジャンプ開始
is_jumping = 1 // ジャンプ中フラグをON
}
char_vz -= 2.0 // 重力による加速
char_z += char_vz // Z方向の移動
if char_z < 0.0 {
// 着地時の演算
char_z = 0.0
char_vz = 0.0
is_jumping = 0
}
if keys & 64 {
// ctrl同時押し…カメラの移動
cam_theta = limitf( cam_theta + 0.05 * ((keys >> 3 & 1) - (keys >> 1 & 1)), 0.01, M_PI / 2 - 0.01 )
cam_phi += 0.05 * ((keys >> 2 & 1) - (keys & 1))
} else {
// ctrlを押さない…キャラクタの移動
keys_x = (keys >> 2 & 1) - (keys & 1)
keys_y = (keys >> 3 & 1) - (keys >> 1 & 1)
char_x = limitf( char_x - ( sin( cam_phi ) * keys_x - cos( cam_phi ) * keys_y ) * CHAR_SPEED, -MAP_WIDTH/2*CELL_SIZE, (MAP_WIDTH-1)/2*CELL_SIZE)
char_y = limitf( char_y + ( cos( cam_phi ) * keys_x + sin( cam_phi ) * keys_y ) * CHAR_SPEED, -MAP_HEIGHT/2*CELL_SIZE, (MAP_HEIGHT-1)/2*CELL_SIZE)
}
return
*draw
// カメラの設定
d3setcam cos(cam_phi)*sin(cam_theta)*CAM_DIST + char_x, sin(cam_phi)*sin(cam_theta)*CAM_DIST + char_y, cos(cam_theta)*CAM_DIST, char_x, char_y, 0
redraw 0
color : boxf
gz = 0, 0, 0, 0 // d3texture用の配列
repeat MAP_WIDTH, -MAP_WIDTH/2 : x = cnt
repeat MAP_HEIGHT, -MAP_HEIGHT/2 : y = cnt
dx = ( x * CELL_SIZE - char_x ) / CELL_SIZE
dy = ( y * CELL_SIZE - char_y ) / CELL_SIZE
gmode GMODE_ALPHA, , , 255.0 / pow( dx * dx + dy * dy + 1, 0.25 )
// d3texture用の配列を準備
gx( 0 ) = x * CELL_SIZE - CELL_SIZE / 2, x * CELL_SIZE + CELL_SIZE / 2
gx( 2 ) = gx( 1 ), gx( 0 )
gy( 0 ) = y * CELL_SIZE + CELL_SIZE / 2 : gy( 1 ) = gy( 0 )
gy( 2 ) = y * CELL_SIZE - CELL_SIZE / 2 : gy( 3 ) = gy( 2 )
d3texture gx, gy, gz, 1, IMG_SIZE * map( x + MAP_WIDTH/2, y + MAP_HEIGHT/2 ), 0, IMG_SIZE, IMG_SIZE
loop
loop
d3setlocal char_x, char_y, 0, sin(cam_phi),cos(cam_phi),0,-cos(cam_phi),sin(cam_phi),0,0,0,1
// 影を描画
gmode GMODE_SUB,,,32
gx( 0 ) = -CELL_SIZE / 2, CELL_SIZE / 2
gx( 2 ) = gx( 1 ), gx( 0 )
gy( 0 ) = CELL_SIZE / 2 : gy( 1 ) = gy( 0 )
gy( 2 ) = -CELL_SIZE / 2 : gy( 3 ) = gy( 2 )
gz( 0 ) = 0, 0, 0, 0
d3texture gx, gy, gz, 1, IMG_SIZE * 3, 0, IMG_SIZE, IMG_SIZE
// キャラクターを描画
gmode GMODE_RGB0
gy( 0 ) = 0, 0, 0, 0
gz( 0 ) = CELL_SIZE + char_z : gz( 1 ) = gz( 0 )
gz( 2 ) = int( char_z ) : gz( 3 ) = gz( 2 )
d3texture gx, gy, gz, 1, IMG_SIZE * 1, IMG_SIZE, IMG_SIZE, IMG_SIZE
redraw 1
return
2007年10月2日火曜日
俯瞰型RPGマップの描画 2
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿