|
|
2015/10/28(Wed) 15:40:44|NO.72583
マインクラフト風なというかブロックの上を歩けるだけでもいいので...
自分ではいつの線でできたブロックが一つのものしかできませんでした(一応動けます)
アドバイスでもいいのでお願いします。
(0,0,0を超えると操作方法が逆になっちゃいます あと 視線もマウスで操作もどうしたらいいのかわかりません。)
|
|
2015/10/28(Wed) 16:04:37|NO.72584
|
|
2015/10/28(Wed) 16:05:27|NO.72585
HGIMG3を利用しています。
ブロックはXファイルを大量に用意するごり押しです。
|
|
2015/10/29(Thu) 16:46:27|NO.72605
それとこんなことに返信していただいてありがとうございます。
Houtouさんのマインクラフトはとても本格的でマインクラフトにテクスチャパック
を入れたみたいでした。
いつかそれぐらいのマインクラフト的なものを作れるようになりたいです。
これからもご指導・アドバイス等をお願いします (>_<)/
|
|
2015/10/29(Thu) 19:13:10|NO.72611
私も、作ってみたいです!
|
|
2015/10/29(Thu) 20:15:06|NO.72614
面白そうですねぇ...
|
|
2015/10/29(Thu) 20:17:29|NO.72615
manjyuu_yukkuriさん、僕も作ってみたいので参考に
ソースを張ってもらえると嬉しいです!
頭が馬鹿なもんで...
|
|
2015/10/29(Thu) 22:44:21|NO.72619
manjuu_yukkuriじゃなくてHoutouさんですよぉーー!!
|
|
2015/10/29(Thu) 22:59:53|NO.72623
すみません間違えました。
改めて、
manjyuu_yukkuriさん、僕も作ってみたいので参考に
ソースを張ってもらえると嬉しいです!
頭が馬鹿なもんで...
コピペですみません...
|
|
2015/10/30(Fri) 01:06:25|NO.72625
簡単なボックス設置と自分移動ジャンプ、カメラ追尾回転
#include "hgimg3.as"
screen 0,640,480,0
cls 4
Player_id=1024 //自分のキャラID
NormalBox_id=1 //地形のキャラID
mapx_max=25 //地形X軸のボックス数
mapy_max=10 //地形Y軸のボックス数
mapz_max=25 //地形Z軸のボックス数
boxsize=5.0 //箱のサイズ
offset_px=-boxsize*mapx_max/2 //表示座標オフセット(マップデータの中央がワールド座標X=0,Y=0,Z=0になるように)
offset_py=-boxsize*mapy_max/2
offset_pz=-boxsize*mapz_max/2
hgsetreq SYSREQ_MAXOBJ ,3000 //オブジェクト最大数
hgini
texload dir_exe+"\\sample\\hgimg3\\q.bmp" ; テクスチャの登録
tex_id=stat
texload dir_exe+"\\sample\\hgimg3\\btex.bmp" ; テクスチャの登録
boxtexA_id=stat
; BOXオブジェクトを登録
addbox my_mdid,boxsize,boxsize,tex_id ; 自分用BOXモデルを作成
modelcols my_mdid,boxsize,boxsize,boxsize //判定サイズ設定
addbox b_mdid,boxsize,boxsize,boxtexA_id ;地形用BOXモデルを作成
modelcols b_mdid,boxsize,boxsize,boxsize
dim map,mapx_max,mapy_max,mapz_max //マップデータ用3次元配列 map(X,Y,Z)
//縦中間層に地形用キャラIDを代入
repeat mapx_max
bx=cnt
repeat mapz_max
map(bx,mapy_max/2,cnt)=NormalBox_id //とりあえず地面を敷詰める
loop
loop
//適当にボックスを配置
repeat 50
map(rnd(mapx_max),mapy_max/2-1-rnd(3),mapz_max/2-rnd(mapz_max/2))=NormalBox_id
loop
map(mapx_max/2,mapy_max/2-1,mapz_max/2)=Player_id //マップ中央の地面の上に自分のキャラIDを代入
mygroup=1
enegroup=2
//マップデ−タを見ながらオブジェクト配置
repeat mapy_max
by=cnt
repeat mapx_max
bx=cnt
repeat mapz_max
map_f= map(bx,by,cnt)
if map_f {//何かのキャラが設定されてる
if map_f=Player_id {//自分のオブジェクトを配置
regobj my_chr,my_mdid ; BOXモデルをオブジェクトとして登録
setpos my_chr,offset_px+boxsize*bx,offset_py+boxsize*by,offset_pz+boxsize*cnt
setcoli my_chr,mygroup,enegroup //コリジェングループを設定
}
if map_f=NormalBox_id {//地形を配置
regobj box_obj,b_mdid ; BOXモデルをオブジェクトとして登録
setpos box_obj,offset_px+boxsize*bx,offset_py+boxsize*by,offset_pz+boxsize*cnt
setcoli box_obj,enegroup,mygroup
}
}
loop
loop
loop
//カメラ初期角度
cam_rx=-0.3
cam_ry=0.0
cam_rz=0.0
jump_f=0
jump_spd=0.0
*main
; 描画メイン
;
stick k,$fff
if k&128 : goto *owari ; [ESC]で終了
if k&512 {//マウス右ドラッグでカメラ回転
if mouse_Rmov=0 {//前回はドラックされてなかった
mouse_Rmov=1 //ドラッグ開始フラグセット
}else{//ドラッグ中なので前回のマウス座標から今回を引いてカメラ角度に加算
cam_rx-=0.01*(mousey-mousey_Rstart)
cam_ry-=0.01*(mousex-mousex_Rstart)
}
mousex_Rstart=mousex//今回のマウス座標を保存
mousey_Rstart=mousey
}else{
mouse_Rmov=0//ドラッグキャンセル
}
if k&16 {//スペース
if jump_f=0 {//地面なのでジャンプセット
jump_spd=-0.5 //セット
jump_f=1 //空中フラグセット
}
}
if jump_f=1 {//空中なのでジャンプ速度を現在の座標に加算
addpos my_chr,0,jump_spd,0
jump_spd+0.02 //上昇初速を落下方向に加算
}
getkey A_key,'A'
getkey W_key,'W'
getkey D_key,'D'
getkey S_key,'S'
if A_key { addpos my_chr,-0.1,0,0}
if D_key { addpos my_chr,0.1,0,0}
if W_key { addpos my_chr,0,0,-0.1}
if S_key { addpos my_chr,0.0,0,0.1}
getpos my_chr,my_px,my_py,my_pz //自分の座標取得
getcoli val,my_chr,1.0 //地形との判定
if val>=0 {//地形に当ってる
jump_f=0
jump_spd=0.0
getpos val,gx,gy,gz //当ったボックスの座標
my_py=gy-boxsize //ボックスの上に乗せる座標
setpos my_chr, my_px,my_py,my_pz //自分の座標を説定
}else{//空中
jump_f=1
}
setang HGOBJ_CAMERA,cam_rx,cam_ry,cam_rz //カメラ角度設定
fvset cam_fv,cam_rx,-cam_ry,cam_rz //カメラ角度を計算用配列に代入(Y回転は逆になるので-)
fvdir cam_fv,0,-5,30 //カメラ角度に自分からのローカル座標を回転
setpos HGOBJ_CAMERA,my_px+cam_fv(0),my_py+cam_fv(1),my_pz+cam_fv(2) ; 自分の座標に回転させた座標を加算してカメラ座標に設定
hgdraw ; 描画処理
color 255
hgline 310,240,330,240
hgline 320,230,320,250
hgsync 10 ; 時間待ち
goto *main
*owari
end
| |
|
2015/10/30(Fri) 13:28:25|NO.72630
ブロックを置いたりするにはどうすればいいでしょうか?
教えてくれるとありがたいです!
|
|
2015/10/30(Fri) 22:18:44|NO.72636
う〜ん確かに私もやってみましたがバグって駄目ですね
|
|
2015/10/30(Fri) 22:44:00|NO.72637
MCとウォウはIPが同じ
|
|
2015/10/31(Sat) 00:03:00|NO.72642
兄と、一緒に使っています!
兄 : ウォウ
僕 : MC
|
|
2015/11/2(Mon) 23:07:49|NO.72712
ブロックを置く処理は
弾を発射する処理を使えば出来るかなとやってみたら
それっぽいのが出来たんでいちようアップしときます
ですがこの先はもっと難しくなってくると思うので
ちょっと無理かも^^;
カーソルキーで前後移動
スペースキーでジャンプ
左クリックで箱追加
右ドラッグで視点移動
マウス操作は暇人さんのをお借りしました
#include "hgimg3.as"
screen 0,640,480,0
hgsetreq SYSREQ_MAXOBJ ,3000
hgini
setsizef 1.0, 1.0// BOXのXYZサイズ
setscale HGOBJ_LIGHT,255,255,255
setdir HGOBJ_LIGHT,128,128,128
cam_rx=0.0
cam_ry=0.0
dim map,10,10,10
repeat 10
xx=cnt
repeat 10
yy=cnt
map(xx,9,yy)=1 //底に箱を敷き詰める
loop
loop
repeat 100
map(rnd(10),8-rnd(5),rnd(10))=1//ランダムに箱を作る
loop
texload dir_exe+"\\sample\\hgimg3\\btex.bmp"//テクスチャの登録
boxtexA_id=stat
repeat 10
zz=cnt
repeat 10
yy=cnt
repeat 10
xx=cnt
if map(xx,yy,zz)=1 {
addbox mdid,,,boxtexA_id//BOXモデルを作成
regobj mybox,mdid//BOXモデルをオブジェクトとして登録
setpos mybox,xx,yy,zz//座標の指定
}
loop
loop
loop
// カメラ位置設定
cammode CAM_MODE_NORMAL
x=5*40:y=2*40:z=5*40:mysize=20:mapsize=40
xd=0.0:yd=0.0:zd=0.0
setefx HGOBJ_CAMERA , 3.14/2 , 0.1 , 768.0
// 描画メイン
repeat
ax=0:az=0:ar=0
stick stk,$eff
if stk&512 {//マウス右ドラッグでカメラ回転
if mouse_Rmov=0 {//前回はドラックされてなかった
mouse_Rmov=1 //ドラッグ開始フラグセット
}else{//ドラッグ中なので前回のマウス座標から今回を引いてカメラ角度に加算
cam_rx-=0.01*(mousey-mousey_Rstart)
cam_ry-=0.01*(mousex-mousex_Rstart)
}
mousex_Rstart=mousex//今回のマウス座標を保存
mousey_Rstart=mousey
}else{
mouse_Rmov=0//ドラッグキャンセル
}
if stk&2 : ar=-4.0
if stk&8 : ar=4.0
if stk&16 : if stk_flg=0 : ay=-14 : stk_flg=1
if stk&256 : gosub *add_box
//自分の移動処理 x軸
ax=sin(cam_ry)*ar
x+=ax
if x>(9*40+19) : x=9*40+19
if x<0 : x=0
gosub *hantei
if aa>0 {
if ax>=0 {x=bbx*mapsize-mysize-1}
else {x=aax*mapsize+mapsize}
}
//自分の移動処理 z軸
az=cos(cam_ry)*ar
z+=az
if z>(9*40+19) : z=9*40+19
if z<0 : z=0
gosub *hantei
if aa>0 {
if az>=0 {z=bbz*mapsize-mysize-1}
else {z=aaz*mapsize+mapsize}
}
//自分の移動処理 y軸
ay++
y+=ay
if y>(9*40+19) : y=9*40+19
if y<0 : y=0
gosub *hantei
if aa>0 {
if ay>=0 {y=bby*mapsize-mysize-1:ay=0:stk_flg=0}
else {y=aay*mapsize+mapsize:ay=0}
}
//カメラの処理
xd=double(x)/mapsize-0.25
yd=double(y)/mapsize-0.25
zd=double(z)/mapsize-0.25
setpos HGOBJ_CAMERA , xd , yd, zd
setang HGOBJ_CAMERA,cam_rx,cam_ry,cam_rz//カメラ角度設定
hgdraw // 描画処理
color 255
hgline 310,240,330,240
hgline 320,230,320,250
hgsync 32 // 時間待ち
loop
*hantei
//自分の移動用 当たり判定
aax=x/mapsize : bbx=(x+mysize)/mapsize
aay=y/mapsize : bby=(y+mysize)/mapsize
aaz=z/mapsize : bbz=(z+mysize)/mapsize
//自分は正方形なので8頂点の当たり判定をする
aa=map(aax,aay,aaz)+map(bbx,aay,aaz)+map(aax,bby,aaz)+map(bbx,bby,aaz)
aa+=map(aax,aay,bbz)+map(bbx,aay,bbz)+map(aax,bby,bbz)+map(bbx,bby,bbz)
return
*add_box
//箱の追加処理
add_x=xd : add_y=yd : add_z=zd
//カメラの視線方向に設定
add_ax=-sin(cam_ry)/40.0
add_az=-cos(cam_ry)/40.0
add_ay=-tan(cam_rx)/40.0
//少しずつ進み当たれば箱追加
repeat 400
add_cx=int(add_x+add_ax+0.5)
add_cy=int(add_y+add_ay+0.5)
add_cz=int(add_z+add_az+0.5)
//範囲外か?
if add_cx<0 or add_cx>=10 or add_cy<0 or add_cy>=10 or add_cz<0 or add_cz>=10 : break
//範囲内で箱に当たれば少し手前に箱を作る
if map(add_cx,add_cy,add_cz)=1 {
add_cx=int(add_x+0.5)
add_cy=int(add_y+0.5)
add_cz=int(add_z+0.5)
map(add_cx,add_cy,add_cz)=1
addbox mdid,,,boxtexA_id// BOXモデルを作成
regobj mybox1,mdid // BOXモデルをオブジェクトとして登録
setpos mybox1,add_cx,add_cy,add_cz// 座標の指定
break
}else{
add_x+=add_ax
add_y+=add_ay
add_z+=add_az
}
loop
return
| |
|
2015/11/3(Tue) 09:49:36|NO.72719
おぉーー、すげーーー!!
|
|
2015/11/6(Fri) 21:33:38|NO.72818
皆様のスクリプト、非常に優れていて私も勉強させていただいております。
しかし、addboxはテクスチャを一つしか設定できない
(ひょっとしたら私が知らないだけで複数使えるのかもしれません、
ご存じの方がおられましたら教えてください。)
関係上、マインクラフトを作るのには限界があると思います。
暇人様、k様のスクリプトを改良すれば非常にいいプログラムになると思います。
|
|
2015/11/6(Fri) 23:49:15|NO.72823
そうですね addbox では複数面は無理なので
やはり xファイルを使う addxfile ですね
昔、形状ファイルを作ったことがあったので追加してみました
しかし、たくさん箱を作っていくとどうしても処理が重くなってくるので
マインクラフトのような広大なマップを再現するのは
なにか工夫が必要になってくるでしょうね
参考になれば幸いです
#include "hgimg3.as"
boxmodel = {"
xof 0303txt 0064
Material mat0 {1.0;1.0;1.0;;}
Material mat1 {1.0;1.0;1.0;;}
Material mat2 {1.0;1.0;1.0;;}
Material mat3 {1.0;1.0;1.0;;}
Material mat4 {1.0;1.0;1.0;;}
Material mat5 {1.0;1.0;1.0;;}
Mesh {
24;
-0.5;-0.5;-0.5;, 0.5;-0.5;-0.5;,-0.5;-0.5; 0.5;, 0.5;-0.5; 0.5;,
-0.5; 0.5;-0.5;, 0.5; 0.5;-0.5;,-0.5; 0.5; 0.5;, 0.5; 0.5; 0.5;,
-0.5;-0.5;-0.5;, 0.5;-0.5;-0.5;,-0.5; 0.5;-0.5;, 0.5; 0.5;-0.5;,
-0.5;-0.5; 0.5;, 0.5;-0.5; 0.5;,-0.5; 0.5; 0.5;, 0.5; 0.5; 0.5;,
-0.5;-0.5;-0.5;,-0.5;-0.5; 0.5;,-0.5; 0.5;-0.5;,-0.5; 0.5; 0.5;,
0.5;-0.5;-0.5;, 0.5;-0.5; 0.5;, 0.5; 0.5;-0.5;, 0.5; 0.5; 0.5;;
6;// ポリゴン枚数
4;0,1,3,2;
4;5,4,6,7;
4;9,8,10,11;
4;12,13,15,14;
4;16,17,19,18;
4;21,20,22,23;;
MeshMaterialList {
6;6; // 使用するマテリアルの数,ポリゴン総数
0;1;2;3;4;5; //マテリアル番号
{mat0}{mat1}{mat2}{mat3}{mat4}{mat5}
}
MeshTextureCoords {
24;
0.0;1.0;1.0;1.0;0.0;0.0;1.0;0.0;
0.0;0.0;1.0;0.0;0.0;1.0;1.0;1.0;
1.0;1.0;0.0;1.0;1.0;0.0;0.0;0.0;
0.0;1.0;1.0;1.0;0.0;0.0;1.0;0.0;
0.0;1.0;1.0;1.0;0.0;0.0;1.0;0.0;
1.0;1.0;0.0;1.0;1.0;0.0;0.0;0.0;;
}
}
"}
memfile boxmodel
screen 0,640,480,0
hgsetreq SYSREQ_MAXOBJ ,3000
hgini
setsizef 1.0, 1.0// BOXのXYZサイズ
setscale HGOBJ_LIGHT,255,255,255
setdir HGOBJ_LIGHT,255,255,255
cam_rx=0.0
cam_ry=0.0
dim map,10,10,10
repeat 10
xx=cnt
repeat 10
yy=cnt
map(xx,9,yy)=1 //底に箱を敷き詰める
loop
loop
repeat 100
map(rnd(10),8-rnd(5),rnd(10))=1//ランダムに箱を作る
loop
texload dir_exe+"\\sample\\hgimg3\\btex.bmp"//テクスチャの登録
boxtexA_id=stat
texload dir_exe+"\\sample\\hgimg3\\chrome.bmp"//テクスチャの登録
boxtexB_id=stat
texload dir_exe+"\\sample\\hgimg3\\q.bmp"//テクスチャの登録
boxtexC_id=stat
repeat 10
zz=cnt
repeat 10
yy=cnt
repeat 10
xx=cnt
if map(xx,yy,zz)=1 {
addxfile mdid, "MEM:x.x"//BOXモデルを作成
regobj mybox,mdid//BOXモデルをオブジェクトとして登録
setxinfo mybox, 0, $2000, boxtexB_id;テクスチャ下
setxinfo mybox, 0, $2001, boxtexA_id;テクスチャ上
setxinfo mybox, 0, $2002, boxtexC_id;テクスチャ奥
setxinfo mybox, 0, $2003, boxtexC_id;テクスチャ手前
setxinfo mybox, 0, $2004, boxtexC_id;テクスチャ左
setxinfo mybox, 0, $2005, boxtexC_id;テクスチャ右
setpos mybox,xx,yy,zz//座標の指定
}
loop
loop
loop
// カメラ位置設定
cammode CAM_MODE_NORMAL
x=5*40:y=2*40:z=5*40:mysize=20:mapsize=40
xd=0.0:yd=0.0:zd=0.0
setefx HGOBJ_CAMERA , 3.14/2 , 0.1 , 768.0
// 描画メイン
repeat
ax=0:az=0:ar=0
stick stk,$eff
if stk&512 {//マウス右ドラッグでカメラ回転
if mouse_Rmov=0 {//前回はドラックされてなかった
mouse_Rmov=1 //ドラッグ開始フラグセット
}else{//ドラッグ中なので前回のマウス座標から今回を引いてカメラ角度に加算
cam_rx-=0.01*(mousey-mousey_Rstart)
cam_ry-=0.01*(mousex-mousex_Rstart)
}
mousex_Rstart=mousex//今回のマウス座標を保存
mousey_Rstart=mousey
}else{
mouse_Rmov=0//ドラッグキャンセル
}
if stk&2 : ar=-4.0
if stk&8 : ar=4.0
if stk&16 : if stk_flg=0 : ay=-14 : stk_flg=1
if stk&256 : gosub *add_box
//自分の移動処理 x軸
ax=sin(cam_ry)*ar
x+=ax
if x>(9*40+19) : x=9*40+19
if x<0 : x=0
gosub *hantei
if aa>0 {
if ax>=0 {x=bbx*mapsize-mysize-1}
else {x=aax*mapsize+mapsize}
}
//自分の移動処理 z軸
az=cos(cam_ry)*ar
z+=az
if z>(9*40+19) : z=9*40+19
if z<0 : z=0
gosub *hantei
if aa>0 {
if az>=0 {z=bbz*mapsize-mysize-1}
else {z=aaz*mapsize+mapsize}
}
//自分の移動処理 y軸
ay++
y+=ay
if y>(9*40+19) : y=9*40+19
if y<0 : y=0
gosub *hantei
if aa>0 {
if ay>=0 {y=bby*mapsize-mysize-1:ay=0:stk_flg=0}
else {y=aay*mapsize+mapsize:ay=0}
}
//カメラの処理
xd=double(x)/mapsize-0.25
yd=double(y)/mapsize-0.25
zd=double(z)/mapsize-0.25
setpos HGOBJ_CAMERA , xd , yd, zd
setang HGOBJ_CAMERA,cam_rx,cam_ry,cam_rz//カメラ角度設定
hgdraw // 描画処理
color 255
hgline 310,240,330,240
hgline 320,230,320,250
hgsync 32 // 時間待ち
loop
*hantei
//自分の移動用 当たり判定
aax=x/mapsize : bbx=(x+mysize)/mapsize
aay=y/mapsize : bby=(y+mysize)/mapsize
aaz=z/mapsize : bbz=(z+mysize)/mapsize
//立方体なので8頂点の当たり判定をする
aa=map(aax,aay,aaz)+map(bbx,aay,aaz)+map(aax,bby,aaz)+map(bbx,bby,aaz)
aa+=map(aax,aay,bbz)+map(bbx,aay,bbz)+map(aax,bby,bbz)+map(bbx,bby,bbz)
return
*add_box
//箱の追加処理
add_x=xd : add_y=yd : add_z=zd
//カメラの視線方向に設定
add_ax=-sin(cam_ry)/40.0
add_az=-cos(cam_ry)/40.0
add_ay=-tan(cam_rx)/40.0
//少しずつ進み当たれば箱追加
repeat 400
add_cx=int(add_x+add_ax+0.5)
add_cy=int(add_y+add_ay+0.5)
add_cz=int(add_z+add_az+0.5)
//範囲外か?
if add_cx<0 or add_cx>=10 or add_cy<0 or add_cy>=10 or add_cz<0 or add_cz>=10 : break
//範囲内で箱に当たれば少し手前に箱を作る
if map(add_cx,add_cy,add_cz)=1 {
add_cx=int(add_x+0.5)
add_cy=int(add_y+0.5)
add_cz=int(add_z+0.5)
map(add_cx,add_cy,add_cz)=1
addxfile mdid, "MEM:x.x"//BOXモデルを作成
regobj mybox1,mdid//BOXモデルをオブジェクトとして登録
setxinfo mybox1, 0, $2000, boxtexA_id;テクスチャ下
setxinfo mybox1, 0, $2001, boxtexC_id;テクスチャ上
setxinfo mybox1, 0, $2002, boxtexB_id;テクスチャ奥
setxinfo mybox1, 0, $2003, boxtexB_id;テクスチャ手前
setxinfo mybox1, 0, $2004, boxtexB_id;テクスチャ左
setxinfo mybox1, 0, $2005, boxtexB_id;テクスチャ右
setpos mybox1,add_cx,add_cy,add_cz// 座標の指定
break
}else{
add_x+=add_ax
add_y+=add_ay
add_z+=add_az
}
loop
return
| |
|
2015/11/8(Sun) 15:15:39|NO.72846
横からで申し訳ありません。
自分で改変すればいい話しではありますが。
ちょっと気になったので書かせて頂きます。
「↑↓→←&スペースキー&マウス移動&マウスクリック左右」のキー配置は
片手キーボード、片手マウスで、操作できるキー配置ではないような気がします。
ご存じかと思いますが、本家マイクラはWASDで移動です。
|
|
2015/11/9(Mon) 01:19:14|NO.72879
/*テストで使った数値のままだったので修正して再掲載*/
移動判定は自分の移動以外でも必要になるだろうからモジュールにしてみた
操作方法はマイクラと同じような感じ
マウス移動で視点移動
スペースでジャンプ
左クリックで破壊
右クリックで設置
Wキー2回で走る
SHIFT押しながらだと移動速度が遅くなりブロックから落ちない
F5で視点変更(一人称視点、三人称後方視点、三人称自由視点)
ホイール回転で設置キャラ選択
#include "hgimg3.as"
//必ず先にhgimg3.asをincludeする必要がある
#module "mod_3DBOXMAP"
//グリッド座標を3Dマップ座標に変換(ボックスの中心座標が返る)
#define global ctype GridToWorldX(%1) (_bs@mod_3DBOXMAP*(%1)+of_px@mod_3DBOXMAP)
#define global ctype GridToWorldY(%1) (_bs@mod_3DBOXMAP*(%1)+of_py@mod_3DBOXMAP)
#define global ctype GridToWorldZ(%1) (_bs@mod_3DBOXMAP*(%1)+of_pz@mod_3DBOXMAP)
//グリッド座標を3Dマップ座標に変換(ボックスの左上奥の座標が返る)
#define global ctype GridToCornerWorldX(%1) (_bs@mod_3DBOXMAP*(%1)+of_cpx@mod_3DBOXMAP)
#define global ctype GridToCornerWorldY(%1) (_bs@mod_3DBOXMAP*(%1)+of_cpy@mod_3DBOXMAP)
#define global ctype GridToCornerWorldZ(%1) (_bs@mod_3DBOXMAP*(%1)+of_cpz@mod_3DBOXMAP)
//3Dマップ座標をグリット計算用の3D座標に変換
#define global ctype WorldOffsetX(%1) ((%1)-of_cpx@mod_3DBOXMAP)
#define global ctype WorldOffsetY(%1) ((%1)-of_cpy@mod_3DBOXMAP)
#define global ctype WorldOffsetZ(%1) ((%1)-of_cpz@mod_3DBOXMAP)
//グリット計算用の3D座標をグリット座標に変換
#define global ctype WorldOffsetToGridX(%1) (0+(%1)/bs@mod_3DBOXMAP)
#define global ctype WorldOffsetToGridY(%1) (0+(%1)/bs@mod_3DBOXMAP)
#define global ctype WorldOffsetToGridZ(%1) (0+(%1)/bs@mod_3DBOXMAP)
//3Dマップ座標をグリット座標に変換
#define global ctype WorldToGridX(%1) (0+WorldOffsetX(%1)/bs@mod_3DBOXMAP)
#define global ctype WorldToGridY(%1) (0+WorldOffsetY(%1)/bs@mod_3DBOXMAP)
#define global ctype WorldToGridZ(%1) (0+WorldOffsetZ(%1)/bs@mod_3DBOXMAP)
//キャラタイプID
#const global TYPE_LIQUID 0 //水等でカーソル判定が無いもの(未実装)
#const global TYPE_GRASS $100 //草等でカーソル判定はあるが自分との当たり判定は無い(自分では置く事が出来ない)
#const global TYPE_FLOWERS $200 //花等でカーソル判定はあるが自分との当たり判定は無い(壁があっても空中には置けない)
#const global TYPE_STAIRS $1000 //階段等の自分との当り判定はあるが1ブロックに満たないもの(未実装)
#const global TYPE_TERRAIN_LEAF $10000 //地形の葉等で自分との当り判定が有り乗れる(柔らかい)
#const global TYPE_TERRAIN_SOIL $20000 //地形の土等で自分との当り判定が有り乗れる(普通)
#const global TYPE_TERRAIN_WOOD $50000 //地形の木等で自分との当り判定が有り乗れる(やや硬い)
#const global TYPE_TERRAIN_ROCK $A0000 //地形の岩等で自分との当り判定が有り乗れる(硬い)
#const global TYPE_MY $1000000 //自分
//判定種別マスク
#const global TYPEFILTER_ACCESSORIES $F00//カーソル判定はあるが障害物ではない($100〜$F00)「左クリック一回で壊れる」
#const global TYPEFILTER_FIGURINE $F000//大きさは1ブロック未満でカーソル判定と自分との判定はあるが障害物ではない($1000〜$F000)(未実装)
#const global TYPEFILTER_TERRAIN $F0000//地形で大きさは1ブロック固定で自分との当り判定が有り乗れる($10000〜$F0000)「数値が大きいほど硬い」
#const global TYPEFILTER_OBJECT (TYPEFILTER_FIGURINE | TYPEFILTER_TERRAIN)//自分とは重なれない物体
#const global TYPEFILTER_ALL (TYPEFILTER_ACCESSORIES | TYPEFILTER_FIGURINE | TYPEFILTER_TERRAIN)//カーソル判定がある物
//キャラIDからキャラナンバーを取得
#define global ctype getCharNo(%1) ((%1)&$ff)
//キャラIDからタイプナンバーを取得(タイプIDとは違いTYPE_GRASSは1、TYPE_STAIRSは17、TYPE_TERRAIN_LEAFは34になる通し番号)
#define global ctype getTypeNo(%1) ((((%1)&TYPEFILTER_ACCESSORIES)>>8) + (((%1)&TYPEFILTER_FIGURINE)>>12) + (((%1)&TYPEFILTER_TERRAIN)>>16)+((((%1)&TYPEFILTER_FIGURINE)!0)*16 +(((%1)&TYPEFILTER_TERRAIN)!0)*32))
////(モジュール初期設定)マップサイズと1ブロックのサイズとオフセットのモードを設定
//[ SetMapOffset map, boxsize, om ]
// map : マップデータ3次元配列
// boxsize : 1ブロックのサイズ
// om : オフセットのモード 「0=マップデータ中心が3D座標XYZが0,0,0になる、1=マップデータ要素数0,0,0が3D座標XYZが0,0,0になる」
#define global SetMapOffset(%1,%2,%3=-1) _SetMapOffset %1,%2,%3
#deffunc _SetMapOffset array map,double boxsize,int om
if om>=0 {_om=om}
mapptr=varptr(map)
_bs=boxsize*1.000001 //*1.000001は丸め誤差防止
bs=boxsize
mx_max=length(map)
my_max=length2(map)
mz_max=length3(map)
of_cpx=-bs*(mx_max*(_om=0)/2)
of_cpy=-bs*(my_max*(_om=0)/2)
of_cpz=-bs*(mz_max*(_om=0)/2)
of_px=of_cpx+bs/2.0
of_py=of_cpy+bs/2.0
of_pz=of_cpz+bs/2.0
Gap=bs*0.001//地形と判定するオブジェクトが同じ判定サイズだと1ブロックの間を通れなくなるので隙間をどれだけ開けるかの数値
return
////判定用グリッド座標設定(setCheckGrid()で判定するために設定)
//[ setCheckGrid oid, hsx, hsy, hsz ]
// oid : 判定用グリッドを設定するオブジェクトID
// hsx : 判定サイズX
// hsx : 判定サイズY
// hsz : 判定サイズZ
#deffunc setCheckGrid int oid,double hsx,double hsy,double hsz
getpos oid,px,py,pz
tmpx=px-of_cpx-hsx/2.0:minx=int(tmpx/bs):maxx=int((tmpx+(hsx-Gap))/bs)
tmpy=py-of_cpy+hsy/2.0-Gap:maxy=int(tmpy/bs):miny=int((hsy-Gap)/bs)
tmpz=pz-of_cpz-hsz/2.0:minz=int(tmpz/bs):maxz=int((tmpz+(hsz-Gap))/bs)
return
////設定されてるグリッド座標と指定したグリッド座標が重なるか取得(グリッド座標はsetCheckGrid()かMovHitCheck命令で設定されます)
//[ 変数 = setCheckGrid(oid, hsx, hsy, hsz) ]
// sgx : 判定するグリットX座標
// sgy : 判定するグリットY座標
// sgz : 判定するグリットZ座標
#defcfunc getHitCheck int sgx,int sgy,int sgz
if sgy>=miny and sgy<=maxy{
if sgx=minx or sgx=maxx {
if sgz=maxz or sgz=minz{
return 1
}
}
}
return 0
////マップデータの判定しながらオブジェクトを移動
//[ MovHitCheck oid, hsx, hsy, hsz, vx, vy, vz, map, boxsize, jf, jspd ]
// oid : 移動判定するオブジェクトID
// hsx : オブジェクトの判定Xサイズ
// hsx : オブジェクトの判定Yサイズ
// hsz : オブジェクトの判定Zサイズ
// vx : X移動量
// vy : Y移動量(ジャンプ速度はjspdで指定)
// vz : Z移動量
// map : 判定するマップデータ(3次元配列)
// boxsize : 1ブロックのサイズ
// jf : 動作フラグ(入出力)「0=地上に接地中(出力)、1=空中(出力)、2=警戒動作(入力)」//警戒動作は1ブロック以上の落下をしないように移動します
// jspd : ジャンプ移動量(入出力)「頭が天井に当ったり足元が地上に接地したときに0.0になる」
#deffunc MovHitCheck int oid,double hsx,double hsy,double hsz,double vx,double vy,double vz,array map,double boxsize,var jf,var jspd
if (varptr(map) ! mapptr) and (boxsize ! bs) {SetMapOffset map, boxsize}
getpos oid,px,py,pz
jvy=vy+jspd
addpos oid,vx, jvy, vz
selpos oid
//移動前のY軸のグリッド座標設定
tmpy=py-of_cpy+hsy/2.0-Gap
if jf=2 {UnderGrid=int((tmpy+bs)/bs)}else{UnderGrid=my_max} //2=警戒動作中
chkmax=1
minmaxy=int(tmpy/bs)
repeat minmaxy-int((tmpy+Gap-hsy)/bs),1
minmaxy(chkmax)=int((tmpy-bs*cnt)/bs)
if chkmax>0 {if minmaxy(chkmax)=minmaxy(chkmax-1){chkmax--}}//同じ高さなら削除
chkmax++
loop
//移動後のX軸のグリッド座標設定(マップ範囲外ならマップ内に移動させる)
tmpx=px-of_cpx-hsx/2.0+vx
if tmpx<0.0 {
objset1 0,of_cpx+hsx/2.0:tmpx=0.0:minx=0
}else{
minx=int(tmpx/bs)
tmpx+=hsx-Gap
if tmpx>=bs*mx_max {tmpx=0.0:maxx=mx_max-1:objset1 0,GridToCornerWorldX(mx_max)-hsx/2.0}else{maxx=int(tmpx/bs)}
}
//移動前のZ軸のグリッド座標設定
tmpz=pz-of_cpz-hsz/2.0:minz=int(tmpz/bs):maxz=int((tmpz+(hsz-Gap))/bs)
//X軸の判定移動
if tmpx!0.0 and vx!0.0{//objadd1 0,vx
if UnderGrid<my_max {
if ((map(minx,UnderGrid,minz) | map(minx,UnderGrid,maxz)| map(maxx,UnderGrid,minz) | map(maxx,UnderGrid,maxz)) & TYPEFILTER_TERRAIN)=0 {objadd1 0,-vx
if vx<0.0 {
maxx=LIMIT(maxx+1,0,mx_max-1)
}else{
minx=LIMIT(minx-1,0,mx_max-1)
}
}else{goto *@f}
}else{
*@f
if vx<0.0 {
repeat chkmax
if (map(minx,minmaxy(cnt),minz) | map(minx,minmaxy(cnt),maxz)) & TYPEFILTER_TERRAIN {minx++:objset1 0,GridToCornerWorldX(minx)+hsx/2.0:break}
loop
}else{
repeat chkmax
if (map(maxx,minmaxy(cnt),minz) | map(maxx,minmaxy(cnt),maxz)) & TYPEFILTER_TERRAIN {objset1 0,GridToCornerWorldX(maxx)-hsx/2.0:maxx--:break}
loop
}
}
}
//移動後のZ軸のグリッド座標設定(マップ範囲外ならマップ内に移動させる)
if vz!0.0 {
tmpz+vz
if tmpz<0.0 {
objset1 2,of_cpz+hsz/2.0:tmpz=0.0:minz=0
}else{
minz=int(tmpz/bs)
tmpz+=hsz-Gap
if tmpz>=bs*mz_max {maxz=mz_max-1:objset1 2,GridToCornerWorldX(mz_max)-hsz/2.0:tmpz=0.0}else{maxz=int(tmpz/bs)}
}
//Z軸の判定移動
if tmpz!0.0 {
if UnderGrid<my_max {
if ((map(minx,UnderGrid,minz) | map(minx,UnderGrid,maxz)| map(maxx,UnderGrid,minz) | map(maxx,UnderGrid,maxz)) & TYPEFILTER_TERRAIN)=0 {objadd1 2,-vz
if vz<0.0 {maxz=LIMIT(maxz+1,0,mz_max-1)}else{minz=LIMIT(minz-1,0,mz_max-1)}
}else{goto *@f}
}else{
*@f
if vz<0.0 {
repeat chkmax
if (map(minx,minmaxy(cnt),minz) | map(maxx,minmaxy(cnt),minz))&TYPEFILTER_TERRAIN {minz++:objset1 2,(hsz/2.0+GridToCornerWorldZ(minz)):break}
loop
}else{
repeat chkmax
if (map(minx,minmaxy(cnt),maxz) | map(maxx,minmaxy(cnt),maxz))&TYPEFILTER_TERRAIN {objset1 2,GridToCornerWorldZ(maxz)-hsz/2:maxz--:break}
loop
}
}
}
}
//移動後のY軸グリッド座標設定(マップ範囲外ならマップ内に移動させる)
tmpy+jvy
if tmpy>=(bs*my_max) {
maxy=my_max-1:objset1 1,GridToCornerWorldY(my_max)-hsy/2.0:tmpy=0.0:jvy=0.0:jspd=0.0:jf=0
}else{
maxy=int(tmpy/bs): tmpy-=hsy-Gap
if tmpy<0.0 {objset1 1,of_cpy+hsy/2.0:tmpy=0.0:miny=0:jspd=0.0:jvy=0.0:jf=1}else{miny=int(tmpy/bs)}
}
//Y軸の判定移動
if tmpy!0.0 and jvy!0.0{
jf=1
if jvy<0.0 {
if (map(minx,miny,minz) | map(maxx,miny,minz) | map(minx,miny,maxz) | map(maxx,miny,maxz))&TYPEFILTER_TERRAIN {miny++:objset1 1,GridToCornerWorldY(miny)+hsy/2.0:jspd=0.0}
}else{
if (map(minx,maxy,minz) | map(maxx,maxy,minz) | map(minx,maxy,maxz) | map(maxx,maxy,maxz))&TYPEFILTER_TERRAIN {objset1 1,GridToCornerWorldY(maxy)-hsy/2.0:maxy--:jf=0:jspd=0.0}
}
}
return
#global
#uselib "user32"
#func ShowCursor "ShowCursor" int //マウスカーソル( マウスポインタ)を表示または非表示にします。
screen 0,854,480,0
cls 4
//キャラIDはキャラタイプID+キャラナンバーで表す
#enum WhiteBox_id = TYPE_TERRAIN_SOIL+1
#enum BlueBox_id
#enum GrassPlate_id = TYPE_GRASS+1 //(右クリックで置く事が出来ないタイプを指定)
#enum TreePlate_id = TYPE_FLOWERS+1
#enum Player_id = TYPE_MY+1 //自分ID
//選択欄に出すキャラ
Charlist=WhiteBox_id,BlueBox_id,GrassPlate_id,TreePlate_id,-1,-1,-1,-1
selmax=length(Charlist) //キャラ数
selindex=0 //現在選択中のキャラインデックス[Charlist(selindex)でキャラID取得]
//キャラデータインデックス「Chardata()」
#enum CHARDATA_MID = 0 //モデルID
#enum CHARDATA_MODE //オブジェクトモ−ド
#enum CHARDATA_EFX //オブジェクトのα値(CHARDATA_MODEにOBJ_LATEが指定されてる時に使用される)
#enum CHARDATA_TID //テクスチャID
#enum CHARDATA_TSIZE //テクスチャサイズ
#enum CHARDATA_END
//キャラデータ用3次元配列
//Chardata(キャラデータインデックス,キャラタイプナンバー,キャラナンバー) //キャラタイプナンバーはgetTypeNo(キャラID)で取得できる(この時statが書き換わるので注意)
dim Chardata,CHARDATA_END,50,256
Debaggu=0 //1にすると全て一回で消えて、TYPE_GRASSタイプも設置出来る
mapx_max=16 //地形X軸のブロック数
mapy_max=32 //地形Y軸のブロック数
mapz_max=16 //地形Y軸のブロック数
High_zero=mapy_max-10 //地面の基準
boxsize=1.0 //地形箱のサイズ
viewermax=mapx_max //何ブロック先まで描画するか(これも狭くしても描画処理は軽くならない・・・)
dim map,mapx_max,mapy_max,mapz_max //キャラID配置用マップデータ3次元配列 map(X,Y,Z)
//-----------モジュール初期設定(必ず必要)----------------
SetMapOffset map,boxsize,0
dim map_id,mapx_max,mapy_max,mapz_max //オブジェクトID用データ3次元配列 map_id(X,Y,Z) //これは無くても必要なときにgetcoli等で取得スr場良いが、この方が楽なので
memset map_id,$ff,mapx_max*mapy_max*mapz_max*4 //-1で初期化
//自分の大きさ
mysizex=boxsize*0.4 //自分幅
mysizey=mysizex*4 //頭を含めた高さ
mysizez=mysizex //自分の奥行
myheadsize=mysizex*0.8 //頭の大きさ
range=boxsize*4.0 //3D上のカーソル有効距離
mygroup=1 //自分のコリジョングループ
enegroup=2 //設置物のコリジョングループ
hgsetreq SYSREQ_MAXOBJ ,mapx_max*(mapy_max-High_zero)*mapz_max //オブジェクト最大数
hgini
wait 10
hgsetreq SYSREQ_3DFILTER,D3DTEXF_POINT
hgsetreq SYSREQ_NOMIPMAP ,0 //オブジェクト最大数
setuv 0,0,64,64
addplate m_plate,1,1,1
texload dir_exe+"\\sample\\hgimg3\\efx.bmp"
texload2 dir_exe+"\\sample\\hgimg3\\q.bmp",128,128 ; テクスチャの登録
tex_id=stat
texload2 dir_exe+"\\sample\\hgimg3\\btex.bmp",128,128 ; テクスチャの登録
Chardata(CHARDATA_TID,getTypeNo(WhiteBox_id),getCharNo(WhiteBox_id))=stat,128
texload2 dir_exe+"\\sample\\hgimg3\\chrome.bmp",256,256 ; テクスチャの登録
Chardata(CHARDATA_TID,getTypeNo(BlueBox_id),getCharNo(BlueBox_id))=stat,256
texload2 dir_exe+"\\sample\\hgimg3\\tree.tga",256,256 ; テクスチャの登録
Chardata(CHARDATA_TID,getTypeNo(TreePlate_id ),getCharNo(TreePlate_id ))=stat,256
buffer 1,16,16
boxf
repeat 16
pos cnt,16
color 0,64+rnd(128)
line cnt+rnd(4),16-rnd(16)
loop
settex 16,16
Chardata(CHARDATA_TID,getTypeNo(GrassPlate_id),getCharNo(GrassPlate_id ))=stat,16
gsel 0
setfont 16,16,12,1 ; font Tex select(cx,cy,px,mode)
texload dir_exe+"\\sample\\hgimg3\\fontchr.bmp" ; フォントテクスチャの登録
//自分本体(非表示)
addbox my_Parent,1.0,1.0 //自分の判定用に使うボックス
modelcols my_Parent,(mysizex+boxsize)/2,(mysizey+boxsize)/2,(mysizez+boxsize)/2 //判定サイズ設定(地形からの判定を行うので両方合わせて2で割る)
regobj myParent_oid,my_Parent,OBJ_HIDE //自分用の本体オブジェクトとして非表示で作成(これを親として表示オブジェクトの体と頭をくっつける)
setcoli myParent_oid,mygroup,enegroup //コリジェングループを設定(getcoliが子オブジェクトには原点が違って使えないので判定は全てこれを使う)
//自分体(表示)
addbox my_Body,1.0,1.0, tex_id ; 自分体表示用BOXモデルを作成
modelscale my_Body,mysizex,mysizey-myheadsize,mysizez //頭サイズを高さから引いて設定
regobj myBody_oid,my_Body,OBJ_HIDE //頭以外の体用BOXオブジェクトとして登録
objchild myParent_oid,myBody_oid //本体オブジェクトを親として設定(objchildは子までしか使い物にならないので全て本体オブジェクトを親にしてる)
setpos myBody_oid,0,myheadsize/2,0 //本体オブジェクトとサイズがmyheadsize分違うので中心がずれて浮くのを位置調整
//自分頭(表示)
addbox my_Head,myheadsize,myheadsize,tex_id ; 自分頭表示用BOXモデルを作成
regobj myHead_oid,my_Head,OBJ_HIDE //my_chr(1)=腰、my_chr(2)=胴、my_chr(3)=頭 BOXオブジェクトとして登録
objchild myParent_oid,myHead_oid //本体オブジェクトを親として設定(objchildは子までしか使い物にならないので全て本体オブジェクトを親にしてる)
setpos myHead_oid,0.0,-mysizey/2+myheadsize/2,0.0//頭の位置辺りの座標を設定
//地形(ノーマルブロック)
ctno=getTypeNo(WhiteBox_id)
cno=getCharNo(WhiteBox_id)
addbox mdid,boxsize,boxsize,Chardata(CHARDATA_TID,ctno,cno) ;地形用BOXモデルを作成
modelcols mdid,boxsize,boxsize,boxsize //判定サイズ設定(スケールを判定サイズとして使用)
Chardata(CHARDATA_MID,ctno,cno)=mdid
//地形(青ブロック)
ctno=getTypeNo(BlueBox_id)
cno=getCharNo(BlueBox_id)
addbox mdid,boxsize,boxsize,Chardata(CHARDATA_TID,ctno,cno) ;地形用BOXモデルを作成
modelcols mdid,boxsize,boxsize,boxsize //判定サイズ設定(スケールを判定サイズとして使用)
Chardata(CHARDATA_MID,ctno,cno)=mdid
//草(右クリックで置く事が出来ないタイプ)
ctno=getTypeNo(GrassPlate_id)
cno=getCharNo(GrassPlate_id)
addsplate mdid,1,boxsize,boxsize,Chardata(CHARDATA_TID,ctno,cno)
modelcols mdid,boxsize,boxsize,boxsize
Chardata(CHARDATA_MID,ctno,cno)=mdid,(OBJ_TREE | OBJ_LATE),255
//小さい木
ctno=getTypeNo(TreePlate_id)
cno=getCharNo(TreePlate_id)
addsplate mdid,1,boxsize,boxsize,Chardata(CHARDATA_TID,ctno,cno)
modelcols mdid,boxsize,boxsize,boxsize,boxsize
Chardata(CHARDATA_MID,ctno,cno)=mdid,(OBJ_TREE | OBJ_LATE),255
randomize
repeat mapx_max
bx=cnt
repeat mapz_max
map(bx,High_zero,cnt)=WhiteBox_id //とりあえず地面を敷詰める
loop
loop
//適当に地面の上にボックスを配置
rndCharlist=WhiteBox_id,BlueBox_id
rndCharmax=length(AllCharlist)
repeat mapx_max*4
cid=rndCharlist(rnd(rndCharmax))
rndx=rnd(mapx_max):rndy=High_zero-rnd(mapy_max-High_zero)/3:rndz=rnd(mapz_max)
map(rndx,rndy,rndz)=cid
if map(rndx,rndy-1,rndz)=0 {//上に何も無いなら
if rnd(10)<6 {//草
map(rndx,rndy-1,rndz)=GrassPlate_id
}else{//小さい木
map(rndx,rndy-1,rndz)=TreePlate_id
}
}
loop
map(mapx_max/2,High_zero-1,mapz_max/2)=Player_id //マップ中央の地面の上に自分のキャラIDを代入
map(mapx_max/2,High_zero-2,mapz_max/2)=0 //自分と重なってるキャラがあるかもしれないのでクリア
repeat mapy_max
by=cnt
repeat mapx_max
bx=cnt
repeat mapz_max
map_f= map(bx,by,cnt)
if map_f {
if map_f=Player_id {//自分のオブジェクトを配置
map(bx,by,cnt)=0//自分が居たフラグをクリア
setpos myParent_oid,GridToWorldX(bx),GridToWorldY(by)+boxsize/2-mysizey/2,GridToWorldZ(cnt) //自分本体の座標設定
}else{//キャラを配置
dupptr Chardata_dup,varptr(Chardata(0,getTypeNo(map_f),getCharNo(map_f))),CHARDATA_END*4//3次元配列を使用するデータの一次元配列にする
regobj box_obj,Chardata_dup(CHARDATA_MID),Chardata_dup(CHARDATA_MODE)
if Chardata_dup(CHARDATA_MODE)&OBJ_LATE {
setefx box_obj,Chardata_dup(CHARDATA_EFX) //テクスチャの透明度を有効にしたいので
}
setpos box_obj,GridToWorldX(bx),GridToWorldY(by),GridToWorldZ(cnt) //自分本体の座標設定
setcoli box_obj,enegroup,mygroup
map_id(bx,by,cnt)=box_obj //ID用配列にマップデータと同じ位置にオブジェクトIDを代入
}
}
loop
loop
loop
setcolor 0,0,255
addbox tag_mdid,boxsize*1.01,boxsize*1.01 //選択視認用ボックス
modelshade tag_mdid,0 //ライト影響無し
regobj tag_box,tag_mdid,OBJ_LATE
//破壊時のエフェクト用
; イベントリストを登録
newevent ev1 ; 新しいイベントIDを取得
event_wait ev1,10
event_efx ev1, 16, $200, 0, 0
event_wait ev1,16
event_delobj ev1
; エミッターを登録
newemit em1, EMITMODE_RANDOM ; var, mode, model, objmode, id
emit_angmul em1, 1,1,1
emit_speed em1, 0.02,0.06
emit_model em1, m_plate, 0, OBJ_MOVE|OBJ_XFRONT, $2ff ; model,modelnum,objmode,efx
emit_event em1, ev1
//カメラ初期角度
cam_rx=-0.3
cam_ry=0.0
cam_rz=0.0
movspd=boxsize*0.05 //1フレームで進む移動量(boxsizeを基準にする事でボックスのサイズを変えても体感速度は変わらない)
Gravity=boxsize*0.009 //重力
jump_startspd=boxsize*0.15
jump_f=0
jump_spd=0.0
FOV=deg2rad(70) //視野角(70度)
NearZ=boxsize*0.1 //最小描画距離
FarZ= boxsize*viewermax //最大描画距離
setefx HGOBJ_CAMERA ,FOV , NearZ , FarZ
clscolor $4040 ; 背景色の設定
ShowCursor 0 //マウスカーソルを非表示
*main
main_cnt++
hggettime timA
k_bak=k
stick k,$fff
if (k&128)!0 and (k_bak&128)=0 { //[Esc]一回押すとマウスカーソルが出て、マウスカーソルが出てる状態でもう一回押すと終了
esc_f^1 //esc_fが0だったら1になる
ShowCursor 1 //マウスカーソル表示
if esc_f=0 {
goto *owari
}
}
if k&512 or esc_f=0{//マウス移動でカメラ回転(マウスカーソルが出てる状態で右クリックするとカーソルが非表示になる)
if esc_f=1 {ShowCursor 0:esc_f=0} //カーソルを非表示にし右クリック無しでもカメラ回転させるフラグ
if mouse_Rmov=0 {//前回はドラックされてなかった
mouse_Rmov=1 //ドラッグ開始フラグセット
}else{//ドラッグ中なので前回のマウス座標から今回を引いてカメラ角度に加算
dif_mx=ginfo_mx-mousex_Rstart
dif_my=ginfo_my-mousey_Rstart
if abs(dif_my)<2 {cam_rx-=0.001*dif_my}else{cam_rx-=0.002*dif_my}//プラマイ1の動きは通常より小さく回転
cam_rx=limitf(cam_rx,-M_PI/2,M_PI/2) //視点上下を90度に制限
if abs(dif_mx)<2 {cam_ry-=0.001*dif_mx}else{cam_ry-=0.002*dif_mx}
}
mouse ginfo_wx1+320,ginfo_wy1+240 //ウィンドウ中央辺りに固定
mousex_Rstart=ginfo_wx1+320//今回のマウススクリーン座標を保存
mousey_Rstart=ginfo_wy1+240
}else{
mouse_Rmov=0//ドラッグキャンセル
}
F5_key_bak=F5_key
getkey F5_key,116
if F5_key=1 and F5_key_bak=0 { //[F5]視点切替 vtype 0=三人称自由視点、1=一人称視点、2=三人称背後視点
vtype=(vtype+1)\3
setobjmode myBody_oid,OBJ_HIDE,1+(vtype=0) //一人称の時は自分を非表示にして、それ以外は表示設定
setobjmode myHead_oid,OBJ_HIDE,1+(vtype=0) //一人称の時は自分を非表示にして、それ以外は表示設定
}
getkey A_key,'A'
W_key_bak=W_key
getkey W_key,'W'
getkey D_key,'D'
getkey S_key,'S'
vec_x=0.0
if A_key {vec_x=-movspd}
if D_key {vec_x=movspd}
if W_key {//前進
if W_key_bak!W_key {
if (main_cnt-W_tim_down)<10 {//歩いてから10フレーム未満で押し直すと走る
mov_z=-movspd*1.5
}else{
mov_z=-movspd
W_tim_down=main_cnt
}
}
vec_z=mov_z
}else{vec_z=0.0}
if S_key {vec_z=movspd}
if jump_f=1 {//空中なのでジャンプ速度を現在の座標に加算
jump_spd+Gravity //上昇初速を落下方向に加算
}else{//前回地面に立ってた
jump_spd=Gravity //常に下方向の移動量をセット(とりあえず下に移動させて地面と当るか判定する)
}
if k&16 {//スペース
if jump_f=0 and (main_cnt-jump_tim)>20 {//地面なのでジャンプセット(前回のジャンプから20フレーム経過してるなら)
jump_spd=-jump_startspd //ジャンプ初速セット()
jump_f=1 //空中フラグセット
jump_tim=main_cnt
}
}
getkey SHIFT_key,16
if SHIFT_key {vec_x*0.5:vec_z*0.5:jump_f | 2}else{jump_f & 1}//シフトで速度半減(ジャンプフラグを変えないように2を入れたり消したり)
setang HGOBJ_CAMERA,cam_rx,cam_ry,cam_rz //カメラ角度設定
getang myParent_oid,my_rx,my_ry,my_rz //自分の角度取得
getpos myHead_oid,myhed_px,myhed_py,myhed_pz//頭部のローカル座標取得
if vtype=0 {//一人称視点
setang myParent_oid,0.0,cam_ry,0.0 //自分のY軸角度をカメラ角度と同じに設定
fvset my_fv,0.0,-cam_ry,0.0 //カメラY角度を計算用配列に代入(Y回転は逆になるので-)
fvdir my_fv,vec_x,0.0,vec_z //カメラ角度に自分の移動量を回転
//マップ判定しながら移動 my_fv(0),my_fv(2)に移動量が入ってるY移動量は0にしてjump_spdでジャンプ速度で指定、jump_fに地面に接地してれば0が空中なら1が返る、2を指定すると警戒動作になる
MovHitCheck myParent_oid,mysizex,mysizey,mysizez,my_fv,0.0,my_fv(2),map,boxsize,jump_f,jump_spd
getpos myParent_oid,my_px,my_py,my_pz //自分の座標取得
setpos HGOBJ_CAMERA,my_px,my_py+myhed_py,my_pz //自分の座標に頭部のローカル座標を加算してカメラ座標に設定
}else{//三人称視点
if vtype=2 {//三人称自由視点
setang myHead_oid,cam_rx,cam_ry-my_ry,cam_rz//頭部のローカル角度設定(親のY軸角度を引く)
fvset my_fv,0.0,-my_ry,0.0 //自分のY角度を計算用配列に代入(Y回転は逆になるので-)
}else{//三人称背後固定視点
setang myParent_oid,0.0,cam_ry,0.0 //自分のY軸角度をカメラ角度と同じに設定
setang myHead_oid,cam_rx,0.0,cam_rz //頭部のY軸以外の角度設定
fvset my_fv,0.0,-cam_ry,0.0 //カメラY角度を計算用配列に代入(Y回転は逆になるので-)
}
fvdir my_fv,vec_x,0.0,vec_z //カメラ角度に自分の移動量を回転
//マップ判定しながら移動 my_fv(0),my_fv(2)に移動量が入ってるY移動量は0にしてjump_spdでジャンプ速度で指定、jump_fに地面に接地してれば0が空中なら1が返る、2を指定すると警戒動作になる
MovHitCheck myParent_oid,mysizex,mysizey,mysizez,my_fv,0.0,my_fv(2),map,boxsize,jump_f,jump_spd
getpos myParent_oid,my_px,my_py,my_pz //自分の座標取得
fvset cam_fv,cam_rx,-cam_ry,cam_rz //カメラ角度を計算用配列に代入(Y回転は逆になるので-)
fvdir cam_fv,0.0,0.0,boxsize*4.0 //カメラ角度に自分からのローカル座標を回転
setpos HGOBJ_CAMERA,my_px+cam_fv(0),my_py+myhed_py+cam_fv(1),my_pz+cam_fv(2) // 自分の座標に頭部のローカル座標と回転させた座標を加算してカメラ座標に設定
}
//クリック動作処理(カーソルがキャラを選択した場合statにオブジェクトIDが返る、選択や配置が出来なかった場合-1が返る)
//k=stick、myParent_oid=自分の本体オブジェクトID、cam_rx,cam_ry,cam_rz=カメラ角度
gosub *_ClickEdit
if timC<10 {hgdraw :timC=0}else{hgdraw 6:timC-10} //前回の処理時間が10ms以上なら描画スキップ
color 255,255,255
hgline ginfo_sx/2-10,ginfo_sy/2,ginfo_sx/2+10,ginfo_sy/2
hgline ginfo_sx/2,ginfo_sy/2-10,ginfo_sx/2,ginfo_sy/2+10
selindex=(selindex+selmax-(mousew/100))\selmax
color
hgrect ginfo_sx/2,ginfo_sy-40,0,40*selmax,40
color 255
gmode 3,,,128
hgrect ginfo_sx/2+20+40*selindex-40*selmax/2,ginfo_sy-40,0,40,40
repeat selmax
pos ginfo_sx/2+20+40*cnt-40*selmax/2,ginfo_sy-40
if Charlist(cnt)>0{
ctno=getTypeNo(Charlist(cnt))
cno=Charlist(cnt)&$ff
tsize=Chardata(CHARDATA_TSIZE,ctno,cno)
gmode 0,tsize,tsize
hgrotate Chardata(CHARDATA_TID,ctno,cno),0,0,0,32,32
}
loop
fprt strf("PX:%.3f PY:%.3f PZ:%.3f",my_px,my_py,my_pz),0,0
fprt strf("GX:%d GY:%d GZ:%d",WorldToGridX(my_px),WorldToGridY(my_py),WorldToGridZ(my_pz)),0,18
fprt strf("CPX:%.3f CPY:%.3f CPZ:%.3f",cursor_px,cursor_py,cursor_pz),0,40
fprt strf("CGX:%d CGY:%d CGZ:%d",gx,gy,gz),0,40+18
hggettime timB
timC+=timB-timA //処理時間
hgsync 16 ; 時間待ち
goto *main
//k=stick、myParent_oid=自分の本体オブジェクトID、cam_rx,cam_ry,cam_rz=カメラ角度、
*_ClickEdit
//画面中心の+を2Dカーソルとして3Dカーソル座標準備
getpos HGOBJ_CAMERA,cam_px,cam_py,cam_pz //カメラ角度取得
getpos myParent_oid,my_px,my_py,my_pz //自分の座標取得
fvset c_fv,cam_rx,-cam_ry,cam_rz //カメラ角度を計算用配列に代入(Y回転は逆になるので-)
fvdir c_fv,0,0.0,-0.05 //カメラ角度にZ方向のベクトルを回転(視線のベクトルになる)//-0.01の方が制度は上がるが判定ループ回数が増える
addx=c_fv(0) //扱い易いように変数に代入
addy=c_fv(1)
addz=c_fv(2)
//最大ベクトルを探す
if absf(addx)>absf(addy) {
if absf(addx)>absf(addz) {maxvec==absf(addx)}else{maxvec=absf(addz)}
}else{
if absf(addy)>absf(addz) {maxvec=absf(addy)}else{maxvec=absf(addz)}
}
cursor_px=WorldOffsetX(my_px) //グリッド計算用座標
cursor_py=WorldOffsetY(my_py+myhed_py) //頭の位置
cursor_pz=WorldOffsetZ(my_pz)
setefx tag_box,0
tag_id=-1
gy=-1
repeat int(range/maxvec)
cursor_px+addx //次の座標
cursor_py+addy
cursor_pz+addz
if gx!(0+cursor_px/boxsize) or gy!(0+cursor_py/boxsize) or gz!(0+cursor_pz/boxsize) {//連続で同じグリッドを判定しないように
gx=0+cursor_px/boxsize //座標をグリッドポジションにする(0+はint()の代わり)
gy=0+cursor_py/boxsize
gz=0+cursor_pz/boxsize
if cursor_px<0 or gx>=mapx_max {break}//マップ外なら判定終了
if cursor_py<0 or gy>=mapy_max {break}
if cursor_pz<0 or gz>=mapz_max {break}
//グリッド座標を配列要素としてキャラが有るか判定
tagChar_ID=map(gx,gy,gz)
if tagChar_ID&TYPEFILTER_ALL {//何かある
tag_id=map_id(gx,gy,gz)
if tag_id>=0 {//ターゲットの座標に少し大きいボッウスを重ねる
getpos tag_id,tag_px,tag_py,tag_pz //ターゲットの座標取得
setpos tag_box,tag_px,tag_py,tag_pz
setefx tag_box,512.0+32.0+32.0*sin(0.15*main_cnt)
break
}
}
}
loop
if gx<0 or gy<=0 or gz<0 {return -1}//範囲外なのでキャンセル
if (k&512) or (k&256) {
if (rc_cnt\10)=0 {//クリック時以外は押されてたら10フレーム毎にクリック処理
if tag_id>=0 {
if k&256 {
if tag_id_del=tag_id {delcnt++}else{tag_id_del=tag_id:delcnt=0}
if delcnt>=(getTypeNo(tagChar_ID)-33)*4 or Debaggu {//キャラタイプナンバーを耐久値に利用してます
map(gx,gy,gz)=0 //キャラIDクリア
delobj tag_id //オブジェクト削除
map_id(gx,gy,gz)=-1 //オブジェクトIDクリア
if (tagChar_ID&TYPEFILTER_TERRAIN)!0 {//削除したキャラが地形なら上に乗ってる物を確認する処理に移行
if (map(gx,gy-1,gz) & TYPEFILTER_TERRAIN)=0 {//地形以外だった
if map(gx,gy-1,gz) {
delobj map_id(gx,gy-1,gz)
map(gx,gy-1,gz)=0
map_id(gx,gy-1,gz)=-1
}
}
}
}else{
hgemit em1,tag_px,tag_py,tag_pz
}
}else{
//getHitCheck()を使用するための準備
setCheckGrid myParent_oid,mysizex,mysizey,mysizez
cid=Charlist(selindex) //設置するキャラID取り出し
if cid>TYPE_FLOWERS or Debaggu{//設置するキャラIDがTYPE_FLOWERS以上
if tagChar_ID > TYPE_FLOWERS {//3DカーソルがTYPE_FLOWERS以上を選択中
taglr=(cursor_px\boxsize)-boxsize/2 //ボックスのどの部分を3Dカーソルが指してるか(マイナスなら左面、プラスなら右面の可能性有り)
tagtd=(cursor_py\boxsize)-boxsize/2//(マイナスなら上面、プラスなら下面の可能性有り)
tagfr=(cursor_pz\boxsize)-boxsize/2//(マイナスなら前面、プラスなら後面の可能性有り)
//絶対値でもっとも大きい箇所が選択される(ワールド座標上でのマイナス方向が左,上,前面になる)
if absf(taglr)>absf(tagtd) {
if absf(taglr)>absf(tagfr) {
gx+=(taglr>0.0)-(taglr<0.0) //左面が選択されたら-1、右面が選択されたら+1
}else{
gz+=(tagfr>0.0)-(tagfr<0.0) //前面が選択されたら-1、後が選択されたら+1
}
}else{
if absf(tagtd)>absf(tagfr) {
gy+=(tagtd>0.0)-(tagtd<0.0) //上面が選択されたら-1、下面が選択されたら+1
}else{
gz+=(tagfr>0.0)-(tagfr<0.0) //前面が選択されたら-1、後が選択されたら+1
}
}
if (gx<mapx_max and (gy+1)<mapy_max and gz<mapz_max) {
if gx<0 or gy<=0 or gz<0 {rc_cnt--:return -1}//範囲外なのでキャンセル
}else{rc_cnt--:return -1}//範囲外なのでキャンセル
if cid & TYPEFILTER_TERRAIN {//自分との判定があるキャラのみ
if getHitCheck(gx,gy,gz)=1 {rc_cnt--:return -1}//自分と重なってるのでキャンセル
}
if (map(gx,gy+1,gz)&TYPEFILTER_TERRAIN)=0 and (Charlist(selindex)&TYPEFILTER_ACCESSORIES)!0 {rc_cnt--:return -1}//上に乗せられないタイプ選択されていたのでキャンセル
}
if (map(gx,gy,gz)&TYPEFILTER_ALL) = TYPE_GRASS {//設置位置にTYPE_GRASSがあるので削除準備
if cid&TYPEFILTER_OBJECT {//自分とは重ねられない物を置こうとしてる
if getHitCheck(gx,gy,gz)=1 {rc_cnt--:return -1}//設置位置が自分と重なってるのでキャンセル
}
delobj map_id(gx,gy,gz)//設置位置にTYPE_GRASSがあるので削除準備
map(gx,gy,gz)=0
map_id(gx,gy,gz)=0
}
if (map(gx,gy,gz) < TYPE_FLOWERS) {//障害物が無いなら持ってる物を設置
dupptr Chardata_dup,varptr(Chardata(0,getTypeNo(cid),getCharNo(cid))),CHARDATA_END*4//3次元配列を使用するデータの一次元配列にする
regobj obj_id,Chardata_dup(CHARDATA_MID)
if Chardata_dup(CHARDATA_MODE)&OBJ_LATE {
setefx obj_id,Chardata_dup(CHARDATA_EFX) //テクスチャの透明度を有効にしたいので
}
setpos obj_id,GridToWorldX(gx),GridToWorldY(gy),GridToWorldZ(gz)
setcoli obj_id,enegroup,mygroup
map(gx,gy,gz)=cid //キャラIDをセット
map_id(gx,gy,gz)=obj_id //オブジェクトID
}
}
}
}
}
rc_cnt++
}else{delcnt=0: rc_cnt=0}
return tag_id
*owari
end
描画処理含めメイン処理に10ms以上かかったら描画スキップするようにしてみた
自分の環境だと秒間60フレームで動かすのはオブジェクト3000個ぐらいが限界
地面の中までオブジェクト作ると無理だな・・・
| |
|
2015/11/9(Mon) 22:23:11|NO.72895
ちょっと説明し忘れ
MovHitCheckの判定サイズ指定はY(高さ)に制限は無いが
XとZは1ブロックのサイズ以下にする必要がある
そうしないと、すり抜ける
後操作方法で(コメントの方では書いてるけど)
Escキーでマウスカーソルが出てその状態でもう一度押すと終了
自己レス
>地面の中までオブジェクト作ると無理だな・・・
見えないだろう部分はオブジェクトを作らないようにするのを試したけど
出来ない事も無い・・・
|
|
2015/11/10(Tue) 00:40:31|NO.72906
しばらくしてまた来てみたらすごい発展していて驚きです。
プログラムの軽量化ですが、私はブロックを描画する無駄を省くことである程度対処しています。
|
|
2015/11/10(Tue) 19:10:23|NO.72914
使用最大数が数千個なら非表示にするのは有効だけど
マイクラみたいに見えない部分で数十万必要な場合非表示オブジェの処理時間も馬鹿にならなくなる
(自分の環境では未使用の状態から5千個非表示で0.8ms程度増えた)
後、hgdrawは未使用でもSYSREQ_MAXOBJの設定分処理時間がかかるので(1万で0.1ms程度)
最初から数千個に制限して、なるべく必要な部分だけ作るようにした方がhgdrawの処理軽減にはなる
見た目綺麗に処理するのには検索順とか削除するタイミングとか色々面倒そうだが・・・
|
|
2015/11/10(Tue) 23:43:31|NO.72936
コメントに誤表記があるようなので報告させて頂きます。
mapx_max=16 //地形X軸のブロック数
mapy_max=32 //地形Y軸のブロック数
mapz_max=16 //地形Y軸のブロック数
mapz_max=16 //地形Z軸のブロック数かと思われます
|
|
2015/11/11(Wed) 00:24:29|NO.72939
ご指摘どうも
コピペして編集忘れ・・・
|
|
2015/11/13(Fri) 21:40:28|NO.72991
最初にマップ全体のXファイルを作ることで
かなりの数のポリゴンを表示しても処理落ちはしなくなりました
箱の追加、消去は setxinfo の座標とUVの変更でできそうなんですが
スプリクトが複雑になりそうなのでいったん中断しました^^;
今はxファイルを使わないaddboxでの追加のみです
WASDで動くようにしました^^
最初にマップの1辺のブロック数を書きます
ブロックは縦と横だけですが三角関数で山と谷を再現しています
1辺が100だとブロック数10000です
私の環境では200程度が限界のようです
500とか書いたら固まりました^^;
#include "hgimg3.as"
ddim boxd,100
boxd( 0)=0.0,0.0,1.0, 1.0,0.0,1.0, 1.0,1.0,1.0, 0.0,1.0,1.0;ポリゴン手前
boxd(12)=1.0,0.0,0.0, 0.0,0.0,0.0, 0.0,1.0,0.0, 1.0,1.0,0.0;ポリゴン奥
boxd(24)=0.0,1.0,1.0, 1.0,1.0,1.0, 1.0,1.0,0.0, 0.0,1.0,0.0;ポリゴン上
boxd(36)=0.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,1.0, 0.0,0.0,1.0;ポリゴン下
boxd(48)=1.0,0.0,1.0, 1.0,0.0,0.0, 1.0,1.0,0.0, 1.0,1.0,1.0;ポリゴン右
boxd(60)=0.0,0.0,0.0, 0.0,0.0,1.0, 0.0,1.0,1.0, 0.0,1.0,0.0;ポリゴン左
screen 0,640,480
map_line=50
objmode 2
font "MS ゴシック",20
pos 100,50
mes "1辺のブロック数を設定します"
pos 0,100
objsize 50,30
input map_line
pos 50,100
objsize 500,30
button "数値を入力してここをクリックください 10〜", *check
stop
*check
cls
if map_line<10 : map_line=10
pori_all=map_line*map_line*6
mes "マップデーター作成中 "+map_line+"*"+map_line+"*6で"+pori_all+"ポリゴン"
sdim savedata,map_line*map_line*1200
dim map,map_line,50,map_line
box_cnt=0
repeat map_line
z=cnt
zd=double(cnt)
repeat map_line
x=cnt
xd=double(cnt)
y=25-int((sin(xd/17.0)*cos((zd-32)/17.0))*17.0)
map(x,y,z)=1
box_cnt+
loop
loop
mes "xファイル作成中"
save_cnt=0
gosub *xfile_make
hgsetreq SYSREQ_MAXOBJ ,3000
hgini
setsizef 1.0, 1.0// BOXのXYZサイズ
setscale HGOBJ_LIGHT,255,255,255
setdir HGOBJ_LIGHT,255,255,255
cam_rx=0.0
cam_ry=3.14
texload dir_exe+"\\sample\\hgimg3\\btex.bmp"//テクスチャの登録
boxtexA_id=stat
texload dir_exe+"\\hsptv\\hsptv_img.bmp"//テクスチャの登録
boxtexD_id=stat
mes "xファイル登録"
memfile savedata,0,save_cnt
// カメラ位置設定
cammode CAM_MODE_NORMAL
x=0*40:y=10*40:z=0*40:mysize=20:mapsize=40:mysizeh=60
xd=0.0:yd=0.0:zd=0.0
setefx HGOBJ_CAMERA , 3.14/2 , 0.1 , 768.0
addxfile mdid, "MEM:x.x"//BOXモデルを作成
regobj mybox,mdid//BOXモデルをオブジェクトとして登録
setxinfo mybox, 0, $2000, boxtexd_id
setpos mybox,0.0,0.0,0.0// 座標の指定
// 描画メイン
repeat
title "x "+x/40+" y "+y/40+" z "+z/40
ax=0:az=0:ar=0
stick stk,$ee0
if stk&512 {//マウス右ドラッグでカメラ回転
if mouse_Rmov=0 {//前回はドラックされてなかった
mouse_Rmov=1 //ドラッグ開始フラグセット
}else{//ドラッグ中なので前回のマウス座標から今回を引いてカメラ角度に加算
cam_rx-=0.01*(mousey-mousey_Rstart)
cam_ry-=0.01*(mousex-mousex_Rstart)
}
mousex_Rstart=mousex//今回のマウス座標を保存
mousey_Rstart=mousey
}else{
mouse_Rmov=0//ドラッグキャンセル
}
getkey A_key,'A'
getkey W_key,'W'
getkey D_key,'D'
getkey S_key,'S'
if W_key=1 : ar=-4.0: ar_r=0.0
if S_key=1 : ar= 4.0: ar_r=0.0
if A_key=1 : ar=-4.0: ar_r=1.57
if D_key=1 : ar=-4.0: ar_r=-1.57
if stk&16 : if stk_flg=0 : ay=-14 : stk_flg=1
if stk&256 : gosub *add_box
//自分の移動処理 x軸
ax=sin(cam_ry+ar_r)*ar
x+=ax
if x>(map_line*40-21) : x=map_line*40-21
if x<0 : x=0
gosub *hantei
if aa>0 {
if ax>=0 {x=bbx*mapsize-mysize-1}
else {x=aax*mapsize+mapsize}
}
//自分の移動処理 z軸
az=cos(cam_ry+ar_r)*ar
z+=az
if z>(map_line*40-21) : z=map_line*40-21
if z<0 : z=0
gosub *hantei
if aa>0 {
if az>=0 {z=bbz*mapsize-mysize-1}
else {z=aaz*mapsize+mapsize}
}
//自分の移動処理 y軸
ay++
y+=ay
if y>(49*40+19) : y=49*40+19
if y<0 : y=0
gosub *hantei
if aa>0 {
if ay>=0 {y=bby*mapsize-mysize-1:ay=0:stk_flg=0}
else {y=aay*mapsize+mapsize:ay=0}
}
//カメラの処理
xd=double(x)/mapsize+0.25
yd=double(y)/mapsize-0.75
zd=double(z)/mapsize+0.25
setpos HGOBJ_CAMERA , xd , yd, zd
setang HGOBJ_CAMERA,cam_rx,cam_ry,cam_rz//カメラ角度設定
hgdraw // 描画処理
color 255
hgline 310,240,330,240
hgline 320,230,320,250
hgsync 17 // 時間待ち
loop
*hantei
//自分の移動用 当たり判定
aax=x/mapsize : bbx=(x+mysize)/mapsize
aay=y/mapsize : bby=(y+mysize)/mapsize
aaz=z/mapsize : bbz=(z+mysize)/mapsize
//立方体なので8頂点の当たり判定をする
aa=map(aax,aay,aaz)+map(bbx,aay,aaz)+map(aax,bby,aaz)+map(bbx,bby,aaz)
aa+=map(aax,aay,bbz)+map(bbx,aay,bbz)+map(aax,bby,bbz)+map(bbx,bby,bbz)
return
*add_box
//箱の追加処理
add_x=xd : add_y=yd : add_z=zd
//カメラの視線方向に設定
add_ax=-sin(cam_ry)/40.0
add_az=-cos(cam_ry)/40.0
add_ay=-tan(cam_rx)/40.0
//少しずつ進み当たれば箱追加
repeat 400
add_cx=int(add_x+add_ax+0.0)
add_cy=int(add_y+add_ay+1.0)
add_cz=int(add_z+add_az+0.0)
//範囲外か?
if add_cx<0 or add_cx>=map_line or add_cy<0 or add_cy>=50 or add_cz<0 or add_cz>=map_line : break
//範囲内で箱に当たれば少し手前に箱を作る
if map(add_cx,add_cy,add_cz)=1 {
add_cx=int(add_x+0.0)
add_cy=int(add_y+1.0)
add_cz=int(add_z+0.0)
map(add_cx,add_cy,add_cz)=1
addbox mdid,1.0,1.0,boxtexA_id
regobj mybox2,mdid//BOXモデルをオブジェクトとして登録
setpos mybox2,0.5+add_cx,-0.5+add_cy,0.5+add_cz// 座標の指定
break
}else{
add_x+=add_ax
add_y+=add_ay
add_z+=add_az
}
loop
return
*xfile_make
// xファイルヘッダ書き込み
td="xof 0303txt 0064":gosub *ntadd
td="Material mat0 {1.0;}":gosub *ntadd
td="Mesh {":gosub *ntadd
// 頂点数 登録
d=24*box_cnt : td=str(d)+";":gosub *ntadd
// 頂点 登録
b=0.0
repeat 50
e=cnt
c=0.0
repeat map_line
g=cnt
a=0.0
repeat map_line
f=cnt
if map(f,e,g)=1{
d=0
repeat 6
td =strf("%3.1f",boxd(d)-a)+";"+strf("%3.1f",boxd(d+1)+b)+";"+strf("%3.1f",boxd(d+2)+c)+";"
td+=strf("%3.1f",boxd(d+3)-a)+";"+strf("%3.1f",boxd(d+4)+b)+";"+strf("%3.1f",boxd(d+5)+c)+";"
td+=strf("%3.1f",boxd(d+6)-a)+";"+strf("%3.1f",boxd(d+7)+b)+";"+strf("%3.1f",boxd(d+8)+c)+";"
td+=strf("%3.1f",boxd(d+9)-a)+";"+strf("%3.1f",boxd(d+10)+b)+";"+strf("%3.1f",boxd(d+11)+c)+";"
gosub *ntadd
d+=12
loop
}
a-=1.0
loop
c+=1.0
loop
b-=1.0
title "xファイル作成 マップ "+cnt+"階層 文字数 "+save_cnt
await 0
loop
// ポリゴン枚数 登録
d=6*box_cnt : td=str(d)+";":gosub *ntadd
// ポリゴン頂点の番号登録
d=0
repeat 6*box_cnt
td="4;"+str(d)+";"+str(d+1)+";"+str(d+2)+";"+str(d+3)+";":gosub *ntadd
d+=4
loop
td="MeshMaterialList {":gosub *ntadd
// マテリアルの数 ポリゴン数 登録
d=6*box_cnt : td="1;"+str(d)+";":gosub *ntadd
// ポリゴンの使用マテリアル 登録
repeat box_cnt
td="0;0;0;0;0;0;":gosub *ntadd
loop
td="{mat0}":gosub *ntadd
td="} MeshTextureCoords {":gosub *ntadd
// UV数 登録
d=24*box_cnt : td=str(d)+";":gosub *ntadd
// UV 登録
repeat box_cnt
x=3+rnd(2) : y=5+rnd(3);マップチップ位置
a=x*1250+20 ;テクスチャ左辺
b=x*1250+1230 ;テクスチャ右辺
c=y*1250+20 ;テクスチャ上辺
d=y*1250+1230 ;テクスチャ下辺
repeat 6
td ="0."+strf("%04d",a)+";0."+strf("%04d",d)+";"
td+="0."+strf("%04d",b)+";0."+strf("%04d",d)+";"
td+="0."+strf("%04d",b)+";0."+strf("%04d",c)+";"
td+="0."+strf("%04d",a)+";0."+strf("%04d",c)+";"
gosub *ntadd
loop
if cnt\100=0 : title "xファイル作成 ポリゴン数 "+cnt*6+" 文字数 "+save_cnt : await 0
loop
title "xファイル作成 ポリゴン数 "+box_cnt*6+" 文字数 "+save_cnt
td="} }":gosub *ntadd
return
*ntadd
tl=strlen(td)
repeat tl
poke savedata,save_cnt,peek(td,cnt)
save_cnt+
loop
poke savedata,save_cnt,$0d
save_cnt+
poke savedata,save_cnt,$0a
save_cnt+
return
| |
|
2015/11/14(Sat) 14:10:58|NO.73011
NO.72991のに消す処理を簡単に入れるなら
頂点Indexを3次元配列に代入
メインループ前に
dim map_vi,map_line,50,map_line
repeat map_line*map_line
getxinfo vstr,mybox,0,$10000+cnt*4*4*6+20 //手前下の頂点Index(四角形をポリゴン化してるからか頂点Indexは4の倍数)
split vstr,",",strx,stry,strz
map_vi(0+strx,0-stry,0+strz)=cnt*4*4*6 //ボックス毎の最初の頂点Index
loop
消す処理
*add_box内の処理を途中まで利用して
vi=map_vi(add_cx,add_cy,add_cz) //当ったブロックの頂点Index
repeat 4*6
//本来なら奥に何か有るか確認してポリゴン化してないなら
//そのボックスを割り当てる必要があるけど・・・
setxinfo mybox,0, $10000+vi+cnt*4, 0.0 ,0.0 ,0.0
loop
map(add_cx,add_cy,add_cz)=0
但しgetxinfoの$10000で扱えるIndexは65535まで(これは仕様に問題あるな・・・)
4の倍数になってしまってるので使えるボックス数は680程度
|
|
2015/11/14(Sat) 16:40:55|NO.73012
おぉー…すごい...もう話がわからなくなってきたw
|
|
2015/11/15(Sun) 13:19:26|NO.73032
暇人さん
非表示にするというより、私はdelobjでオブジェクトを消しています。
消去にはあまり時間はかかりません。
|
|
2015/11/15(Sun) 21:19:47|NO.73039
あぁ、描画する無駄を省くだから非表示にしたのかと・・・
それでも描画距離64個超えると見える部分で4000個超えるから厳しいな・・・
エリア別けして近い部分は1ブロックの集まりにして
カーソルの範囲外のエリアは4*4*4ブロックぐらいに小分けして
見える可能性がある部分だけNO.72991の方法でXモデル化してオブジェクトにする
問題は200ポリ程度のaddxfileが8msぐらいかかる事・・・
地形を変えた時の移動時だけだからいけるかも
|
|
2015/11/17(Tue) 19:35:33|NO.73089
今頃だけどNO.72879のに間違いがありました。
> regobj obj_id,Chardata_dup(CHARDATA_MID)
は
regobj obj_id,Chardata_dup(CHARDATA_MID),Chardata_dup(CHARDATA_MODE)
でした。
|
|
2015/12/18(Fri) 23:05:00|NO.73675
暇人さんすげー!!!
|
|
2015/12/21(Mon) 12:13:08|NO.73708
暇人さんので.Xファイルって使えますか?
よろしくお願いします。
|
|
2015/12/21(Mon) 20:02:13|NO.73713
>暇人さんので.Xファイルって使えますか?
使えます。
> addbox mdid,boxsize,boxsize,Chardata(CHARDATA_TID,ctno,cno) ;地形用BOXモデルを作成
を
addxfile mdid,"x形式のモデルファイル"
に変えるだけです。(モデルのサイズと中心が合ってれば)
自己レス
>NO.73039
>カーソルの範囲外のエリアは4*4*4ブロックぐらいに小分けして
モデルの種類が増えると劇的に重くなるから
4*4*4ぐらいの分割じゃ使い物にならなかった
かと言ってこれより大きくすると登録に時間が・・・
今ちょっと放置ぎみだけど、見える可能性が無い物を削除して
マップデータは広く出来るようには出来てる
|
|
2015/12/21(Mon) 20:32:02|NO.73714
>今ちょっと放置ぎみだけど、見える可能性が無い物を削除して
>マップデータは広く出来るようには出来てる
参考にしたいので、お手数をかけますがスクリプト公開していただけませんでしょうか?
|
|
2015/12/23(Wed) 00:30:11|NO.73729
>NO.73714
>参考にしたいので、お手数をかけますがスクリプト公開していただけませんでしょうか?
色々突貫工事的に作ってたので整理できたらかな・・・
今年中は厳しいかも・・・
|
|
2015/12/23(Wed) 15:45:05|NO.73742
了解しました!
|
|
2016/1/2(Sat) 14:59:11|NO.73959
あじwdjw「
|
|
2016/1/7(Thu) 20:51:41|NO.74047
1エリア16*16でやってたけど1エリア最低256個必要になってエリア単位の表示非表示じゃ厳しいので
XZの8*8を1エリアに変更して、処理の殆どを
モジュール内でやるようにしてるからまだ時間掛かるかも・・・
今出来てる仕様としては
ボックスの面にボックスがくっついてない所をチェックして
一面でも空いてたらオブジェクトを作り(地中などで完全に塞がってるなら作らなくする)
一定のエリア外なら非表示にする
更にその外なら削除(1ボックス毎に画面内外の判定はしない)
|
|
2016/1/8(Fri) 22:47:54|NO.74060
暇人さんのコメントを参考にエリア分けして作ってみたところ
私は4*4*50で2次元の配列で管理するところに落ち着きました
地中は最初不確定ブロックとして表示をしないで
回りのブロックなどが壊されて見える状態になったときに
表示するとそこそこ軽くなりました
それでもカクカクしないのは視界10エリアですが・・
|
|
2016/1/8(Fri) 22:57:14|NO.74061
ソースコード見せてください
|
|
2016/1/9(Sat) 13:04:30|NO.74067
どうやってエリア分けするんですか?
教えてください!
|
|
2016/1/9(Sat) 20:39:15|NO.74075
操作は
WSADで移動、マウスで視点移動
スペースでジャンプ
短く左クリックで箱追加 長押しで消去
ホイール回転でボックス選択
マップは縦横800 高さ50ブロックです
ソース汚いです(^^;
#include "hgimg3.as"
#module
#deffunc xfile_make array map,int mapx,int mapy
save_cnt=0
map_line=4
box_cnt=0
repeat 50
e=cnt
repeat map_line
g=cnt+mapy
repeat map_line
f=cnt+mapx
if map(f,e,g)>0 & map(f,e,g)<10 : box_cnt+
loop
loop
loop
sdim savedata,box_cnt*1200
dim box_id,box_cnt
// xファイルヘッダ書き込み
td="xof 0303txt 0064":ntadd
td="Material mat0 {1.0;}":ntadd
td="Mesh {":ntadd
// 頂点数 登録
d=24*box_cnt : td=str(d)+";":ntadd
// 頂点 登録
b=0.0
box_cnt2=0
repeat 50
e=cnt
c=0.0+double(mapy)
repeat map_line
g=cnt+mapy
a=0.0-double(mapx)
repeat map_line
f=cnt+mapx
if map(f,e,g)>0 & map(f,e,g)<10{
box_id(box_cnt2)=map(f,e,g)-1
box_cnt2++
d=0
repeat 6
td =strf("%3.1f",boxd@(d)-a) +";"+strf("%3.1f",boxd@(d+1)+b) +";"+strf("%3.1f",boxd@(d+2)+c) +";"
td+=strf("%3.1f",boxd@(d+3)-a)+";"+strf("%3.1f",boxd@(d+4)+b) +";"+strf("%3.1f",boxd@(d+5)+c) +";"
td+=strf("%3.1f",boxd@(d+6)-a)+";"+strf("%3.1f",boxd@(d+7)+b) +";"+strf("%3.1f",boxd@(d+8)+c) +";"
td+=strf("%3.1f",boxd@(d+9)-a)+";"+strf("%3.1f",boxd@(d+10)+b)+";"+strf("%3.1f",boxd@(d+11)+c)+";"
ntadd
d+=12
loop
}
a-=1.0
loop
c+=1.0
loop
b-=1.0
loop
// ポリゴン枚数 登録
d=6*box_cnt : td=str(d)+";":ntadd
// ポリゴン頂点の番号登録
d=0
repeat 6*box_cnt
td="4;"+str(d)+";"+str(d+1)+";"+str(d+2)+";"+str(d+3)+";":ntadd
d+=4
loop
td="MeshMaterialList {":ntadd
// マテリアルの数 ポリゴン数 登録
d=6*box_cnt : td="1;"+str(d)+";":ntadd
// ポリゴンの使用マテリアル 登録
repeat box_cnt
td="0;0;0;0;0;0;":ntadd
loop
td="{mat0}":ntadd
td="} MeshTextureCoords {":ntadd
// UV数 登録
d=24*box_cnt : td=str(d)+";":ntadd
// UV 登録
repeat box_cnt
;x=3+rnd(2) : y=5+rnd(3);マップチップ位置
x=box_id(cnt)/3+3:y=box_id(cnt)\3+5
;x=4 : y=5;マップチップ位置
a=x*1250+20 ;テクスチャ左辺
b=x*1250+1230 ;テクスチャ右辺
c=y*1250+20 ;テクスチャ上辺
d=y*1250+1230 ;テクスチャ下辺
;テクスチャの情報手前、奥、上、下、右、左 まとめて記入
repeat 6
td ="0."+strf("%04d",a)+";0."+strf("%04d",d)+";"
td+="0."+strf("%04d",b)+";0."+strf("%04d",d)+";"
td+="0."+strf("%04d",b)+";0."+strf("%04d",c)+";"
td+="0."+strf("%04d",a)+";0."+strf("%04d",c)+";"
ntadd
loop
loop
td="} }":ntadd
memfile savedata,0,save_cnt
addxfile mdid, "MEM:x.x"//BOXモデルを作成
mmap@(mapx/4,mapy/4)=mdid
regobj mybox,mdid//BOXモデルをオブジェクトとして登録
bmap@(mapx/4,mapy/4)=mybox
setxinfo mybox, 0, $2000, boxtexd_id@
setpos mybox,0.0,0.0,0.0// 座標の指定
return
#deffunc ntadd
tl=strlen(td)
repeat tl
poke savedata,save_cnt,peek(td,cnt)
save_cnt+
loop
poke savedata,save_cnt,$0d
save_cnt+
poke savedata,save_cnt,$0a
save_cnt+
return
#global
#module
#deffunc add_box
//箱の追加消去処理
cam_x=xd@ : cam_y=yd@ : cam_z=zd@
//カメラの視線方向に設定
cam_addx=-sin(cam_ry@)/40.0
cam_addz=-cos(cam_ry@)/40.0
cam_addy=-tan(cam_rx@)/40.0
//少しずつ進み当たれば箱追加か消去
repeat 400
cal_x=int(cam_x+cam_addx+0.0)
cal_y=int(cam_y+cam_addy+1.0)
cal_z=int(cam_z+cam_addz+0.0)
//範囲外か?
if cal_x<0 or cal_x>=800 or cal_y<0 or cal_y>=50 or cal_z<0 or cal_z>=800 : break
//範囲内で箱に当たれば少し手前で追加消去処理をする
if map@(cal_x,cal_y,cal_z)!0 {
//箱追加
if add_flg@=1 {
cal_x=int(cam_x+0.0)
cal_y=int(cam_y+1.0)
cal_z=int(cam_z+0.0)
map@(cal_x,cal_y,cal_z)=selindex@+1
cal_cx=cal_x/4
cal_cy=cal_z/4
delobj bmap@(cal_cx,cal_cy)
delmodel mmap@(cal_cx,cal_cy)
xfile_make map@,4*cal_cx,4*cal_cy
}else {
//箱消去
dim map_dim,10
map@(cal_x,cal_y,cal_z)=0
map_set=(cal_x)/4+(cal_z)/4*1000
map_dim(0)=map_set+1
repeat 3,-1
cnt_x=cnt
repeat 3,-1
cnt_z=cnt
repeat 3,-1
cnt_y=cnt
if (cal_x+cnt_x)<800 and (cal_z+cnt_z)<800 and (cal_x+cnt_x)>=0 and (cal_z+cnt_z)>=0 and (cal_y+cnt_y)<=49{
if map@(cal_x+cnt_x,cal_y+cnt_y,cal_z+cnt_z)=10 {
map@(cal_x+cnt_x,cal_y+cnt_y,cal_z+cnt_z)=rnd(6)+1;地中ブロックならランダムにブロック配置
map_set=(cal_x+cnt_x)/4+(cal_z+cnt_z)/4*1000
map_set+
repeat 10
if map_dim(cnt)=map_set : break
if map_dim(cnt)=0 : map_dim(cnt)=map_set : break
loop
}
}
loop
loop
loop
//必要なエリアのみ再描画
repeat 10
if map_dim(cnt)=0 : break
map_set=map_dim(cnt)
map_set--
cal_cx=(map_set\1000)
cal_cy=(map_set/1000)
delobj bmap@(cal_cx,cal_cy)
delmodel mmap@(cal_cx,cal_cy)
xfile_make map@,4*cal_cx,4*cal_cy
loop
}
break
}else{
cam_x+=cam_addx
cam_y+=cam_addy
cam_z+=cam_addz
}
loop
return
#global
#module
#deffunc map_make
//マップの表示
bx=(x@/160) : by=(z@/160)
map_flg=0
if bmap@(bx,by)=0 { cx=bx:cy=by:map_flg=1}
else {
repeat 10 //マップの視界10エリア
map_cnt=cnt+1
repeat map_cnt*2
cx=cnt-map_cnt+bx :cy=-map_cnt+by :gosub *map_add_sub : if map_flg=1 : break
cx=-cnt+map_cnt+bx:cy=map_cnt+by :gosub *map_add_sub : if map_flg=1 : break
cx=-map_cnt+bx :cy=cnt-map_cnt+1+by :gosub *map_add_sub : if map_flg=1 : break
cx=map_cnt+bx :cy=-cnt+map_cnt-1+by:gosub *map_add_sub : if map_flg=1 : break
loop
if map_flg=1 : break
loop
}
if map_flg=1 {
xfile_make map@,4*cx,4*cy
}
//マップの消去
map_cnt=15//マップの消去 外周15
repeat map_cnt*2
cx=cnt-map_cnt+bx :cy=-map_cnt+by :gosub *map_kill
cx=-cnt+map_cnt+bx :cy=map_cnt+by :gosub *map_kill
cx=-map_cnt+bx :cy=cnt-map_cnt+1+by :gosub *map_kill
cx=map_cnt+bx :cy=-cnt+map_cnt-1+by:gosub *map_kill
loop
return
*map_kill
if cx>=0 and cy>=0 and cx<200 and cy<200 :if bmap@(cx,cy)!0 : delobj bmap@(cx,cy):delmodel mmap@(cx,cy):bmap@(cx,cy)=0
return
*map_add_sub
if cx>=0 and cy>=0 and cx<200 and cy<200 :if bmap@(cx,cy)=0 : map_flg=1
return
#global
ddim boxd,100
boxd( 0)=0.0,0.0,1.0, 1.0,0.0,1.0, 1.0,1.0,1.0, 0.0,1.0,1.0;ポリゴン手前
boxd(12)=1.0,0.0,0.0, 0.0,0.0,0.0, 0.0,1.0,0.0, 1.0,1.0,0.0;ポリゴン奥
boxd(24)=0.0,1.0,1.0, 1.0,1.0,1.0, 1.0,1.0,0.0, 0.0,1.0,0.0;ポリゴン上
boxd(36)=0.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,1.0, 0.0,0.0,1.0;ポリゴン下
boxd(48)=1.0,0.0,1.0, 1.0,0.0,0.0, 1.0,1.0,0.0, 1.0,1.0,1.0;ポリゴン右
boxd(60)=0.0,0.0,0.0, 0.0,0.0,1.0, 0.0,1.0,1.0, 0.0,1.0,0.0;ポリゴン左
screen 0,640,480
map_line=800
dim map,map_line,50,map_line
dim bmap,200,200
dim mmap,200,200
//マップ作成
mes "マップ作成中"
repeat map_line
z=cnt
zd=double(cnt)
repeat map_line
x=cnt
xd=double(cnt)
y=25-int((sin(xd/17.0)*cos((zd-32)/17.0))*17.0)
map(x,y,z)=6
repeat 49-y
map(x,y+1+cnt,z)=10
loop
if x>10 and x<790 and z>10 and z<790 {
if rnd(100)=0{
repeat 4
map(x,y-cnt,z)=3
loop
repeat 3
z1=cnt
repeat 3
x1=cnt
repeat 3
map(x-1+x1,y-4-z1,z-1+cnt)=4
loop
loop
loop
}
}
loop
await 0
title "z "+z
loop
hgsetreq SYSREQ_MAXOBJ ,3000
hgini
clscolor 0x404080
setsizef 1.0, 1.0// BOXのXYZサイズ
setscale HGOBJ_LIGHT,255,255,255
setdir HGOBJ_LIGHT,255,255,255
cam_rx=0.0
cam_ry=3.14
texload dir_exe+"\\hsptv\\hsptv_img.bmp"//テクスチャの登録
boxtexD_id=stat
// カメラ位置設定
x=0*40:y=10*40:z=0*40
mysize=20:mapsize=40:mysizeh=60
xd=0.0:yd=0.0:zd=0.0
cammode CAM_MODE_NORMAL
setefx HGOBJ_CAMERA , 3.14/2 , 0.1 , 768.0
// 描画メイン
bx=0:by=0:bz=0
repeat
ax=0:az=0:ar=0
stick stk,$fe0
if stk&512 {//マウス右ドラッグでカメラ回転
if mouse_Rmov=0 {//前回はドラックされてなかった
mouse_Rmov=1 //ドラッグ開始フラグセット
}else{//ドラッグ中なので前回のマウス座標から今回を引いてカメラ角度に加算
cam_rx-=0.01*(mousey-mousey_Rstart)
cam_ry-=0.01*(mousex-mousex_Rstart)
}
mousex_Rstart=mousex//今回のマウス座標を保存
mousey_Rstart=mousey
}else{
mouse_Rmov=0//ドラッグキャンセル
}
getkey A_key,'A'
getkey W_key,'W'
getkey D_key,'D'
getkey S_key,'S'
if W_key=1 : ar=-5.0: ar_r=0.0
if S_key=1 : ar= 5.0: ar_r=0.0
if A_key=1 : ar=-5.0: ar_r=1.57
if D_key=1 : ar=-5.0: ar_r=-1.57
if stk&16 : if stk_flg=0 : ay=-20 : stk_flg=1
if stk&256 : stk_flg2++
if stk_flg2>8 : stk_flg2=0 : stk_flg3=1:add_flg=0 : add_box
if stk=0 & stk_flg2>0 & stk_flg3=0 : stk_flg2=0 : add_flg=1 : add_box
if stk=0 & stk_flg3=1 : stk_flg3=0 : stk_flg2=0
//自分の移動処理 x軸
ax=sin(cam_ry+ar_r)*ar
x+=ax
if x>(800*40-21) : x=800*40-21
if x<0 : x=0
gosub *hantei
if aa>0 {
if ax>=0 {x=bbx*mapsize-mysize-1}
else {x=aax*mapsize+mapsize}
}
//自分の移動処理 z軸
az=cos(cam_ry+ar_r)*ar
z+=az
if z>(800*40-21) : z=800*40-21
if z<0 : z=0
gosub *hantei
if aa>0 {
if az>=0 {z=bbz*mapsize-mysize-1}
else {z=aaz*mapsize+mapsize}
}
//自分の移動処理 y軸
ay++
y+=ay
if y>(49*40+19) : y=49*40+19
if y<0 : y=0
gosub *hantei
if aa>0 {
if ay>=0 {y=bby*mapsize-mysize-1:ay=0:stk_flg=0}
else {y=aay*mapsize+mapsize:ay=0}
}
map_make //マップ表示処理
//カメラの処理
xd=double(x)/mapsize+0.25
yd=double(y)/mapsize-0.75
zd=double(z)/mapsize+0.25
title "x "+x/40+" y "+y/40+" z "+z/40
setpos mybox2,xd , yd, zd
setpos HGOBJ_CAMERA , xd , yd, zd
setang HGOBJ_CAMERA,cam_rx,cam_ry,cam_rz//カメラ角度設定
hgdraw // 描画処理
color 255
hgline 310,240,330,240
hgline 320,230,320,250
color 255
gmode 0,64,64
selindex=(selindex+6-(mousew/100))\6
hgrect 100+selindex*40,480-40,0,40,40
repeat 6
pos 100+40*cnt,480-40
hgrotate boxtexD_id,(cnt/3+3)*64,(cnt\3+5)*64,0,32,32
loop
hgsync 17 // 時間待ち
loop
*hantei
//自分の移動用 当たり判定
aax=x/mapsize : bbx=(x+mysize)/mapsize
aay=y/mapsize : bby=(y+mysize)/mapsize
aaz=z/mapsize : bbz=(z+mysize)/mapsize
//立方体なので8頂点の当たり判定をする
aa=map(aax,aay,aaz)+map(bbx,aay,aaz)+map(aax,bby,aaz)+map(bbx,bby,aaz)
aa+=map(aax,aay,bbz)+map(bbx,aay,bbz)+map(aax,bby,bbz)+map(bbx,bby,bbz)
return
| |
|
2016/1/17(Sun) 23:41:13|NO.74180
まだ時間かかりそう・・・
ちょっと仕様変更してキャラタイプIDを廃止して(必要ならキャラNOに含めれば良いし)
遮蔽情報、判定の有無(障害物とカーソル)、キャラNO(1〜4095)をマップデータに入れるようにして
他もいろいろテストしてたらどんどん深みに・・・
3000個で処理落ちする環境だとFPS60キープ(垂直同期とった時)できるのは48*48ブロック程度で
自分を中心にするから視界距離は24個程度・・・(これは自分のPCとhgdrawの限界だからどうしようもない)
向いてる方を優先的に作れば視界距離は伸ばせるけど回転した時や高いところから見たときの見栄えが・・・
|
|
2016/1/25(Mon) 20:30:23|NO.74295
遠方は4ブロック程度の塊の平均をとって
1ブロックの塊を作ればいけそうな気がするのですが
いざ作ってくださいと言われるとちょっと時間がかかりそう(^^;
|
|
2016/1/31(Sun) 05:41:49|NO.74384
当たり判定に手を出してしまったので更に時間が・・・
とりあえずジャンプせずに登れる高さを設定出来て
一つのキャラに判定ボックスを複数設定して
階段みたいに登れるようにはできた
処理量等を考えて妥協した仕様
登った結果頭が当たったら落ちる(そもそも登らないようにも出来るけど処理量が増えるので・・・)
登ってる途中で足場が無くなったり移動を停止すると落ちる(登るのに数フレーム使ってるので)
壁のような薄い判定範囲を設定した場合は移動速度が判定範囲を超えるとすり抜ける(すり抜けないようにも出来るが同上)
通常サイズの判定と登れる判定で動作が違う(改善できるかもしれない)
まだ設定方法等色々決まってない・・・
|
|
2016/3/7(Mon) 00:33:14|NO.74806
階段の判定出来るようになったから箱を組み合わせた様な形状なら
簡単にスクリプト上でx形式のモデルを作れるようにとか
テクスチャ用画像ファイルをx形式モデル作成時に一つに纏めて
(殆どの通常モデルはuv設定が反映されないので使えない)
モデルの数に関係なく(上限はあるが)テクスチャ1枚に収めるとか
色々やってたら3月過ぎてた・・・
|
|
2016/4/3(Sun) 16:28:11|NO.75167
age
|
|
2016/4/7(Thu) 22:41:15|NO.75191
>色々やってたら3月過ぎてた・・・
もう4月・・・
やっと本体の方に手が付けられる・・・
|
|
2016/4/9(Sat) 15:12:23|NO.75197
暇人さん暇ではないと思いますが
ありがとうございます
|
|
2016/5/1(Sun) 19:53:27|NO.75359
暇人さんもう5月ですよw
がんばってくださいv(>_<)v
|
|
2016/6/6(Mon) 23:18:41|NO.75758
もう6月・・・
一定距離以上離れたら有る程度纏めてモデルにしてって方法で
3000個が限界の環境でも64*64ブロック程度(視界距離32)まで出来るようになった
(エリア移動で処理落ちするのを無視すれば)
でも実際のゲームだと起伏や建造物や木とかあるから
結局現実的なのは48*48ぐらいかも・・・
64*64ブロックで視界距離32ブロックの画像(遠くのブロックは1エリア(8*8)か最大128個で1モデル)
http://ux.getuploader.com/himajin130414/download/34/ss.PNG
|
|
2016/6/12(Sun) 12:28:09|NO.75853
やっと原因不明のエラーを回避できるようになったみたいなので先に進める・・・
自分のモジュールを使ってないNO.74075のでもアプリケーションエラーが出てるので
hgimg3側の問題とは思ったが原因特定にかなり時間がかかった・・・
|
|