; ; 3Dサウンド ; NPC音源 ; #include "e3dhsp.as" ;///////////////// ; ; 初期化 ; E3DInit dim keybuf, 256 ;キー入力 E3DCreateFont 24,12,400,,,,"MS ゴシック",fontid ;フォントの設定 fkabe = 0 ;壁データとの当たり判定(0:off / 1:on) fcolibound = 1 ;PCとNPCが衝突したとき重ならないようにする(0:off / 1:on) ;///////////////// ; ; カメラの初期化 ; E3DSetProjection 100, 50000 ;///////////////// ; ; ライトの設定 ; E3DCreateLight lid1 ;光源を作成 lightdirx1 = 1 ;平行光の向き lightdiry1 = -1 lightdirz1 = 0 lightr1 = 255 ;平行光の色 lightg1 = 255 lightb1 = 255 E3DSetDirectionalLight lid1, lightdirx1, lightdiry1, lightdirz1, lightr1, lightg1, lightb1 ;光源を平行光源に設定 ;///////////////// ; ; 形状データのロード ; sdim mediadir, 2048 mediadir = curdir + "\\data\\tako.sig" E3DSigLoad mediadir, hsid1 E3DSetPos hsid1, 5000, 0, 5000 E3DSetBeforePos hsid1 ;NPC E3DSigLoad mediadir, hsid3 E3DSetPos hsid3, 15000, 0, 25000 E3DSetBeforePos hsid3 E3DCreateQ axisqid ;///////////////// ; ; 地面の作成 ; sdim pathbuf, 2048, 4 pathbuf.0 = curdir + "\\data\\yama.bmp" ;地面の座標情報 pathbuf.1 = curdir + "\\data\\michi.bmp" ;地面の道の情報 pathbuf.2 = curdir + "\\data\\kawa.bmp" ;地面の川の情報 pathbuf.3 = curdir + "\\data\\bazou.bmp" ;地面、道、川の模様を決める、BMPファイル ;地面作成用の値 mapsize = 60000 ;X,Z座標の最大値 mapdiv = 120 ;座標の分割数 mapheight = 3000 ;高さの最大値 E3DLoadGroundBMP pathbuf.0, pathbuf.1, pathbuf.2, pathbuf.3, mapsize, mapsize, mapdiv, mapdiv, mapheight, hsid0 ; 壁の作成 ;道のマップをそのまま壁の生成に使います。 E3DSetMovableArea pathbuf.1, mapsize, mapsize, mapdiv, mapdiv, mapheight+100, hsid2 ;///////////////// ; ; サウンドの用意 ; sdim pathbuf, 2048 ; 音ファイルの読み込み pathbuf = curdir + "\\data\\sbounce.wav" E3DLoadSound pathbuf, soundid2, 1 ;音の識別番号取得 E3DSetSoundLoop soundid2, 1 ;繰り返し再生 ;3Dサウンドの設定 E3DSet3DSoundListener 100, 100 ;実世界に同じ E3DSet3DSoundDistance soundid2, 1000*100, 20000*10000 ;再生開始 E3DPlaySound soundid2, 0, DMUS_SEGF_GRID ;//////////////////////////////////////////////////////////////// ;///////////////// ; ; メインループ ; *main E3DGetKeyboardState keybuf ;キー状態取得 if keybuf.VK_ESCAPE = 1 : goto *bye ; [ESC]で終了 gosub *MoveChara ;キャラクター移動 gosub *MoveNPChara gosub *PlaySound ;音声再生 ;バックバッファへの書き込み作業を行う E3DBeginScene ;-----シーンスタート ;モデルが、視野内にあるか判定 E3DChkInView hsid1 ;キャラクター(PC) E3DChkInView hsid3 ;キャラクター(NPC) E3DChkInView hsid0 ;地面 E3DChkInView hsid2 ;壁 gosub *ChkConfAxis ;キャラクター同士の当たり判定 gosub *ChkConf ;地面、壁との当たり判定(キャラクター同士の判定の後)(押し出し防止) gosub *MoveCamera ;カメラ移動 ;バックバッファにレンダリングする。 E3DRender hsid1, 0 E3DRender hsid3, 0 E3DRender hsid0, 0 E3DEndScene ;-----シーン終了 E3DPresent ;バックバッファの内容を、プライマリバッファに転送。描画する。 E3DSetBeforePos hsid1 E3DSetBeforePos hsid3 E3DWaitbyFPS 60 : await 0 goto *main ;//////////////////////////////////////////////////////////////// ; ; サブルーチン ; ;///////////////// ; ; 終了処理 ; *bye E3DDestroyLight lid1 ;ライトを破棄 E3DBye end ;///////////////// ; ; キャラクター移動 ; ; PC *MoveChara forwardstep = 200 ;移動速度(前進) backstep = -forwardstep ;移動速度(後退) degstep = 5 mdegstep = -degstep if keybuf.VK_UP = 1 : E3DPosForward hsid1, forwardstep ;矢印上 if keybuf.VK_DOWN = 1 : E3DPosForward hsid1, backstep ;矢印下 if keybuf.VK_LEFT = 1 : E3DRotateY hsid1, mdegstep ;矢印左 if keybuf.VK_RIGHT = 1 : E3DRotateY hsid1, degstep ;矢印右 return ; NPC *MoveNPChara forwardstep = 50 ;移動速度(前進) ; backstep = -forwardstep ;移動速度(後退) degstep = 2;5 mdegstep = -degstep E3DRotateY hsid3, mdegstep, 3 E3DPosForward hsid3, forwardstep return ;///////////////// ; ; カメラ移動(キャラクター追跡型) ; *MoveCamera ;キャラクターを後ろに2500移動して座標を取得。backpos E3DGetPos hsid1, saveposx1, saveposy1, saveposz1 E3DPosForward hsid1, -2500 E3DGetPos hsid1, backposx, backposy, backposz E3DSetPos hsid1, saveposx1, saveposy1, saveposz1 ;カメラをキャラクタ後方に設置 E3DSetCameraPos backposx, backposy + 1500, backposz E3DSetCameraTarget saveposx1, saveposy1 + 800, saveposz1, 0, 1, 0 return ;///////////////// ; ; キャラクタの地面との当たり判定 ; *ChkConf ; 壁データとキャラクター if fkabe ! 0 { ; 壁(hsid2)とキャラクタ(hsid1)のあたり判定 resultwall = 0 E3DChkConfWall hsid1, hsid2, 10, resultwall, adjustx1, adjusty1, adjustz1, nx1, ny1, nz1 if resultwall!0 { E3DDrawTextByFontID fontid, 10,10,"壁に激突しました!", 255,255,255,255 ;壁に激突したときのメッセージ。 E3DSetPos hsid1, adjustx1, adjusty1, adjustz1 } } ; 地面データとキャラクター mapminy = -100 ;地面データのY座標の最小値。実際の最小値より、少し小さな値を入れる。 repeat 2 ;キャラ2つ if cnt = 0 : hsid_c = hsid1 if cnt = 1 : hsid_c = hsid3 E3DChkConfGround hsid_c, hsid0, 1, mapheight, mapminy, result, adjustx, adjusty, adjustz, nx, ny, nz if ( result != 0 ) : E3DSetPos hsid_c, adjustx, adjusty, adjustz ;地面の上に移動 loop return ;///////////////// ; ; キャラクタどうしの当たり判定 ; *ChkConfAxis E3DChkConflict hsid1, hsid3, confflag if confflag!0 { if fcolibound ! 0 { ;衝突したときにキャラクターが重ならないように移動する ;PCを衝突したNPCと反対方向に50移動させる E3DGetPos hsid1, posx1, posy1, posz1 E3DGetPos hsid3, posx3, posy3, posz3 posx = posx1 - posx3 ;NCPからPCに向かうベクトル posy = posy1 - posy3 posz = posz1 - posz3 ;ベクトルを正規化(長さ1に)して、長さを50倍する。 E3DVec3Normalize posx, posy, posz, 50, posx, posy, posz posx = posx + posx1 ;移動ベクトルに現在位置を加算 posy = posy + posy1 posz = posz + posz1 E3DSetPos hsid1, posx, posy, posz } E3DDrawTextByFontID fontid, 10,40,"NPCと激突しました!", 255,255,255,255 ;激突したときのメッセージ。 } return *PlaySound ;音源とリスナー間の距離を表示 E3DGetPos hsid1, posx1, posy1, posz1 E3DGetPos hsid3, posx3, posy3, posz3 posx = posx1 - posx3 ;NCPからPCに向かうベクトル posy = posy1 - posy3 posz = posz1 - posz3 E3DVec3Length posx, posy, posz, length title "音源との距離:"+length ;音源とリスナーの位置・向き情報を設定 E3DSet3DSoundMovement soundid2, posx3, posy3, posz3 E3DSet3DSoundListenerMovement hsid1 return |