;
; 射撃するサンプル
; 地面で反射
; 敵に衝突すると消滅
;
#include "e3dhsp.as"
;/////////////////
;
; 初期化
;
E3DInit
dim keybuf, 256 ;キー入力
E3DCreateFont 24,12,400,,,,"MS ゴシック",fontid ;フォントの設定
fkabe = 0 ;壁データとの当たり判定(0:off / 1:on)
g100 = -100 ;重力加速度g×100 [単位/s^2](1.00/60 [単位/コマ^2])
dim keybufon,256 ;キーをトリガータイプで検出するためのフラグ(0:前回ループ時に押されていなかった、1:前回ループ時に押されていた)
arrayleng = 5
dim confbbid, arrayleng ;ビルボード衝突判定用変数
;/////////////////
;
; カメラの初期化
; ライトの設定
;
【いつもどおりなので省略】
;/////////////////
;
; 形状データのロード
;
sdim mediadir, 2048
mediadir = curdir + "\\tako.sig"
;PC
E3DSigLoad mediadir, hsid1
; E3DSetPos hsid1, 5000, 0, 5000
E3DSetPos hsid1, 5000, 500, 5000
E3DSetBeforePos hsid1
;NPC
E3DSigLoad mediadir, hsid3
E3DSetPos hsid3, 5000, 0, 1000
E3DSetBeforePos hsid3
E3DCreateQ axisqid
;ビルボード作成
sdim mediadir2, 2048
mediadir2 = curdir + "\\shot01.bmp" ;適当なサイズのbmpファイルを指定してください。
;画像サイズ取得
buffer 2 : picload mediadir2
px = winx : py = winy
gsel 0, 1
;モデル配置
#define SHOTMAX 20 ;弾丸予約数(120フレーム/6フレーム毎発=20発)
#define SHOTLIFECOUNT 120 ;弾丸寿命
dim bbid, 6, SHOTMAX ;弾丸情報用配列変数(パラメータ、弾丸ストック)
;bbid.0.id ビルボードID
;bbid.1.id 弾丸フラグ(0:OFF,1:ON)
;bbid.2.id 寿命カウンタ(射撃後から経過したフレーム数をカウントする)
;bbid.3.id x方向速度
;bbid.4.id y方向速度
;bbid.5.id z方向速度
;/////////////////
;
; 地面の作成
;
【いつもどおりなので省略】
;////////////////////////////////////////////////////////////////
;/////////////////
;
; メインループ
;
*main
E3DGetKeyboardState keybuf ;キー状態取得
if keybuf.VK_ESCAPE = 1 : goto *bye ; [ESC]で終了
gosub *MoveChara ;キャラクター移動
gosub *GravChr ;重力制御
;バックバッファへの書き込み作業を行う
E3DBeginScene ;-----シーンスタート
;モデルが、視野内にあるか判定
E3DChkInView hsid1 ;キャラクター
E3DChkInView hsid3 ;NPC
E3DChkInView hsid0 ;地面
E3DChkInView hsid2 ;壁
gosub *ChkShot ;弾丸のあたり判定と移動
gosub *ChkConf ;地面との当たり判定(E3DChkInViewより後で呼ぶ)
gosub *MoveCamera ;カメラ移動
;バックバッファにレンダリングする。
E3DRender hsid1, 0
E3DRender hsid3, 0
E3DRender hsid0, 0
E3DRenderBillboard ;全ビルボードの描画
;メッセージ表示
textposy=0
repeat confnum
textposy += 20
strchk8 = "hit billboard id :" + confbbid.cnt
E3DDrawText 0, textposy, 1, 255,255,255, strchk8
loop
textposy = 40
repeat SHOTMAX
textposy+=14
strchk8 = "("+cnt+")id="+bbid.0.cnt+", f="+bbid.1.cnt+", time="+bbid.2.cnt+" ( "+bbid.3.cnt+", "+bbid.4.cnt+", "+bbid.5.cnt+" )"
E3DDrawText 0, textposy, 1, 255,255,255, strchk8
loop
E3DEndScene ;-----シーン終了
E3DPresent ;バックバッファの内容を、プライマリバッファに転送。描画する。
E3DSetBeforePos hsid1
E3DSetBeforePos hsid3
E3DWaitbyFPS 60 : await 0
goto *main
;////////////////////////////////////////////////////////////////
;
; サブルーチン
;
;/////////////////
;
; 終了処理
;
*bye
【いつもどおりなので省略】
;/////////////////
;
; キャラクター移動
;
*MoveChara
forwardstep = 100 ;移動速度(前進)
backstep = -forwardstep ;移動速度(後退)
degstep = 5
mdegstep = -degstep
E3DGetDirQ2 hsid1, axisqid
; 射撃
;連射
cnttrg++ ;トリガーカウント
if keybuf.'Z' = 1 {
if cnttrg>=6 { ;6フレームごとに1回射撃(60フレームにつき10回射撃)
gosub *make_shot
}
}
;単発
if keybuf.'X' = 1 {
if keybufon.'X' = 0 { ;スペースキーが前回ループ時に押されていなかった場合
gosub *make_shot
}
keybufon.'X' = 1
} else {
keybufon.'X' = 0
}
; ジャンプ
if keybuf.VK_SPACE = 1{
;地表にいるときと一番高くジャンプした点で加速できる。
;地表にいるときだけジャンプできるようにしたかったが、うまく地表が検出できなかったので苦肉の策。
if vely =0 : vely = 50
}
; 移動と方向転換
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 ;矢印右
;速度による移動計算
E3DGetPos hsid1, posx, posy, posz
E3DSetPos hsid1, posx+velx, posy+vely, posz+velz
; title "速度ベクトル:"+velx+", "+vely+", "+velz
return
;/////////////////
;
; カメラ移動(キャラクター追跡型)
;
*MoveCamera
【いつもどおりなので省略】
;/////////////////
;
; キャラクタの地面との当たり判定
;
*ChkConf
【いつもどおりなので省略】
;/////////////////
;
; 重力(gravity)
;
*GravChr
【いつもどおりなので省略】
;/////////////////
;
; 弾丸作成
;
*make_shot
; 弾丸作成
;空いている配列を使用して弾丸を作成する
repeat SHOTMAX
if bbid.1.cnt = 0 {
E3DCreateBillboard mediadir2, px*3, py*3, 1, bbid.0.cnt, 1, 1 ;表示画像サイズの調整はここでやる。
E3DSetBlendingMode -1, bbid.0.cnt,1
E3DSetRenderState -1, bbid.0.cnt, D3DRS_LIGHTING, 0
shotnum = cnt
break
} else {
shotnum = -1
}
loop
;弾丸の初期設定
if shotnum ! -1 {
;弾丸発射位置調整
E3DGetPos hsid1, saveposx1, saveposy1, saveposz1
E3DMultQVec axisqid, 0, 600, -700, x, y, z
E3DSetBillboardPos bbid.0.shotnum, saveposx1+x, saveposy1+y, saveposz1+z
;初速度設定
E3DMultQVec axisqid, 0, 0, -500, vlctysid1x, vlctysid1y, vlctysid1z ;弾丸速度
bbid.3.shotnum = vlctysid1x ;初速度設定
bbid.4.shotnum = vlctysid1y
bbid.5.shotnum = vlctysid1z
bbid.1.shotnum = 1 ;弾丸フラグon
cnttrg = 0 ;トリガーカウントリセット
}
return
;/////////////////
;
; 弾丸の衝突判定と移動処理
;
*ChkShot
;弾丸との衝突判定
E3DChkConfBillboard hsid3, 1, result, confbbid, arrayleng, confnum
if result ! 0 {
repeat SHOTMAX
if bbid.0.cnt = confbbid.0 : bbid.1.cnt = 0
loop
}
;弾丸にパラメータの内容を反映させる
repeat SHOTMAX
if (bbid.1.cnt = 1)&(bbid.2.cnt <= SHOTLIFECOUNT) {
; 弾丸移動
bbid.2.cnt++
E3DGetBillboardInfo bbid.0.cnt, x,y,z, texname,transparent,w,h ;ビルボードの座標取得
E3DSetBillboardPos bbid.0.cnt, bbid.3.cnt+x, bbid.4.cnt+y, bbid.5.cnt+z ;現在位置と速度から移動後の座標を計算
} else {
; 弾丸消滅
if bbid.0.cnt!0 : E3DDestroyBillboard bbid.0.cnt ;弾丸削除
bbid.0.cnt = 0
bbid.1.cnt = 0 ;弾丸フラグoff
bbid.2.cnt = 0 ;寿命カウンタリセット
;速度ゼロ
bbid.3.cnt = 0
bbid.4.cnt = 0
bbid.5.cnt = 0
}
loop
;弾丸と地面との衝突判定とその後の動作
repeat SHOTMAX
if bbid.1.cnt = 1 {
E3DGetBillboardInfo bbid.0.cnt, x,y,z, texname,transparent,w,h ;ビルボードの座標取得
;現在座標と移動後の予定座標との線分で計算する
E3DChkConfGround2 x+bbid.3.cnt, y+bbid.4.cnt, z+bbid.5.cnt, x,y,z, hsid0, 0, mapheight, mapminy, result, ax,ay,az, nx,ny,nz
if result = 1 {
; z = 10 : E3DSetBillboardPos bbid.0.cnt, ax-(bbid.3.cnt/z),ay-(bbid.4.cnt/z),az-(bbid.5.cnt/z) ;なぜか地表の座標に移動するとうまくいかない場所がある。
;地面の法線ベクトルから弾丸の反射方向ベクトルを計算する。
E3DVec3Length bbid.3.cnt, bbid.4.cnt, bbid.5.cnt, ln1
E3DDot nx,ny,nz, -bbid.3.cnt, -bbid.4.cnt, -bbid.5.cnt, 2*ln1, ln2
E3DVec3Normalize nx,ny,nz, ln2, nx2,ny2,nz2
bbid.3.cnt = nx2 + bbid.3.cnt
bbid.4.cnt = ny2 + bbid.4.cnt
bbid.5.cnt = nz2 + bbid.5.cnt
}
}
loop
return
|