# 11 sample_vpadmod.hsp

sample\ 11 sample_vpadmod.hsp

    #include "hsp3dish.as"

    #include "mod_layerbutton-vpad.hsp"

    #packopt xsize 1040
    #packopt ysize 480
    	;
    	;  HSPTV!掲示板「d3moduleで一人称視点ゲームが作りたい」内
    	;  - 法貴優雅 氏 サンプルスクリプト // thanks!
    	;  https://hsp.tv/play/pforum.php?mode=pastwch&num=81890#81895
    	;
    	;    layerbuttonモジュールで動作するように改造
    	;    mod_layerbutton-vpadでゲームパッドを使用するサンプル
    	;
    	;    同梱されている以下のゲームパッド画像のライセンスは
    	;    Creative Commons CC0 (クリエイティブ・コモンズ・ゼロ) なので、
    	;    どなたでも自由に使うことができます。
    	;    - bean.png
    	;    - btn.png
    	;    - btn2x.png
    	;    - jujikey.png
    	;    - nub.png
    	;    - pad.png
    	;    製作者: Kenney - https://kenney.nl/assets/mobile-controls
    	;
    	;    CC0で公開された作品は、利用者が商用利用、加工、再配布を含め、
    	;    どのような目的や方法でも自由に使用、再配布することができます。
    	;
    #include "d3m.hsp"

    #const MV	0.5	// 移動速度

    	// スクリーンサイズ
    	sx = 1040
    	sy = 480

    	// 画面中心座標
    	scx = sx / 2
    	scy = sy / 2

    	// 設置する箱の位置情報（てきとー）
    	bx = 240, 160, 80, 40, -60, -90, -120, -200
    	by = 200, -80, 40, -120, 120, -80, 20, -160
    	bs = 10 // 箱のサイズ

    	// スクリーン設定
    	screen 0, sx, sy, 0
    	title "mod_layerbutton-vpad サンプル"

    	;mouse ginfo_wx1 + frmx + scx, ginfo_wy1 + frmy + scy

    	// HSP3Dish.js用データフォルダ設定
    	info_os = sysinfo(0)
    	if instr(info_os,0,"Emscripten")>=0 : mm_dir="" : else : mm_dir="data/"

    	// 画像読み込み
    	celload mm_dir+"pad.png", -1
    	cel_pad = stat : celdiv cel_pad,128,128, 64,64
    	celload mm_dir+"nub.png", -1
    	cel_nub = stat : celdiv cel_nub,64,64, 32,32
    	celload mm_dir+"btn.png", -1
    	cel_btn = stat : celdiv cel_btn,64,64
    	celload mm_dir+"bean.png", -1
    	cel_bean = stat : celdiv cel_bean,64,42, 32,21
    	celload mm_dir+"jujikey.png", -1
    	cel_juji = stat : celdiv cel_juji,64,64

    	// バーチャルパッドの設置
    	pos 140,ginfo_sy-130
    	rates = 1.2, 1.0, 1.0
    	AnalogCon cel_pad, cel_nub, rates, 0, analogLx, analogLy, 1
    	pos ginfo_sx-300,ginfo_sy-75
    	rates = 1.0, 0.8, 0.8
    	AnalogCon cel_pad, cel_nub, rates, 1, analogRx, analogRy, 1
    	pos ginfo_sx-140,ginfo_sy-130
    	ButtonCon cel_btn, 20, 1.0, 2, btnkey, $2
    	pos ginfo_sx-93,ginfo_sy-228
    	BeanCon cel_bean, 45.0/180.0*M_PI, 0.9, 3, beankey, 0
    	pos 300,ginfo_sy-75
    	JujikeyCon cel_juji, 4, 0.7, 4, jujikey, 0
    	laybtn_enable 4, 0  ; 十字キーコントローラだけ最初は非表示 (vpadはenableで無効にすると非表示になる)

    	cameraMode="UD: Normal, LR: Normal"
    	// カメラの初期設定
    	ch = 0.0	// カメラ水平角度
    	cv = 0.0	// カメラ垂直向き
    	cx = 0.0	// カメラ位置
    	cy = 0.0
    	cz = 10.0
    	clx = 0.0	// カメラターゲット位置
    	cly = 0.0
    	clz = 0.0
    	gosub *updatecam

    	cam_UD = 1.0 : cam_LR = 1.0  // カメラリバース設定

    *main
    // 動作処理
    	// ダッシュ [上側ボタン]
    	if btnkey & $2 : dash = 1 : squat = 0 : else : dash = 0
    	// しゃがみ [右側ボタン]
    	if btnkey & $4 : squat ^= 1 : dash = 0
    	// ジャンプ [下側ボタン]
    	if jumpCounter > 0 : jumpCounter++
    	if btnkey & $8 : if jumpCounter==0 : jumpCounter = 1 : squat = 0
    	// 弾 [左側ボタン]
    	if btnkey & $1 {
    		repeat length(bulletCounters)+1
    			// 重なり順を気にしなくていいので空いてる所にテキトーに代入
    			if cnt >= length(bulletCounters) : bulletCounters(cnt) = 10 : break
    			if bulletCounters(cnt) == 0 : bulletCounters(cnt) = 10 : break
    		loop
    		needDrawBullet = 1
    	}
    	// カメラリバース設定 [十字キーボタン]
    	if jujikey & 1 : cam_UD= 1.0:cam_LR= 1.0 : cameraMode="UD: Normal, LR: Normal"
    	if jujikey & 2 : cam_UD=-1.0:cam_LR= 1.0 : cameraMode="UD: Reversed, LR: Normal"
    	if jujikey & 4 : cam_UD=-1.0:cam_LR=-1.0 : cameraMode="UD: Reversed, LR: Reversed"
    	if jujikey & 8 : cam_UD= 1.0:cam_LR=-1.0 : cameraMode="UD: Normal, LR: Reversed"
    	// 十字キーコントローラ 表示/非表示 [メニューボタン]
    	if beankey {
    		laybtn_enable 4, -1  ; 十字キーコントローラ(グループ4)の有効/無効を確認
    		laybtn_enable 4, (1-stat)  ; 有効 ⇔ 無効 切り替え
    	}

    	//カメラの状態を更新
    	gosub *updatecam

    // 描画処理
    	redraw 0
    	// 画面クリア
    	color 255, 255, 255 : boxf

    	// 床描画
    	color 0, 192, 0
    	repeat 32
    		d3line 256, 256 - (cnt * 16), 0, -256, 256 - (cnt * 16), 0
    		d3line 256 - (cnt * 16), 256, 0, 256 - (cnt * 16), -256, 0
    	loop

    	// 箱描画
    	color 0, 0, 255
    	repeat 8
    		d3box bx(cnt), by(cnt), 0, bx(cnt) + bs, by(cnt) + bs, bs
    	loop

    	// 弾描画
    	gmode 3,,,128
    	color 255, 255, 0
    	if needDrawBullet {
    		needDrawBullet = 0
    		foreach bulletCounters
    			if bulletCounters(cnt) > 0 {
    				bulletCounters(cnt)--
    				L = 7*bulletCounters(cnt)*bulletCounters(cnt)
    				a = scx-L, scx+L, scx+L, scx-L : b = scy-L, scy-L, scy+L, scy+L
    				gsquare -1, a, b
    				needDrawBullet = 1
    			}
    		loop
    	}

    	// サイト描画
    	color 255, 0, 0
    	line scx - 8, scy, scx + 8, scy
    	line scx, scy - 8, scx, scy + 8

    	// フレームレート表示
    	color 0, 0, 0
    	pos 50, 0:mes "fps:" + d3getfps()
    	mes "AnalogL=("+analogLx+", "+analogLy+")"
    	mes "AnalogR=("+analogRx+", "+analogRy+")"
    	mes "btnkey="+btnkey
    	mes "beankey="+beankey
    	mes "jujikey="+jujikey
    	mes "CamMode= "+cameraMode
    	mes "dash="+dash
    	mes "squat="+squat
    	mes "jump="+jumpCounter
    	mes "fmv="+fmv
    	mes "fdir="+fdir
    	redraw 1

    	await (1000 / 60)	// fps60位のウェイト

    goto *main

    // カメラ更新
    *updatecam
    // カメラ位置の更新
    	if (analogLx != 0.0 || analogLy != 0.0) {
    		// 移動してる場合だけ更新
    		fdir = ch
    		fmv = sqrt(analogLx*analogLx+analogLy*analogLy) * (10 + (11*dash)) * (10 - (3*squat)) / 100  ; 速度補正
    		fdir = ch + atan(analogLx,-analogLy)

    		fx = sin(fdir)
    		fy = cos(fdir)
    		fz = 1.0

    		// 正規化
    		len = sqrt((fx * fx) + (fy * fy) + (fz * fz))
    		if (len != 0.0) {
    			fx /= len
    			fy /= len
    			fz /= len
    		}

    		// カメラ移動
    		fx *= fmv
    		cx += fx
    		fy *= fmv
    		cy += fy
    	}

    // カメラ視点の更新
    // LookAtカメラしかないみたいなので、ターゲット位置を算出する
    	fx = cam_LR * analogRx * 15.0
    	fy = cam_UD * analogRy * 15.0

    	ch += fx / 500.0
    	cv -= fy / 100.0
    	// リミッター
    	if ch < -6.2832:ch += 6.2832
    	if ch >  6.2832:ch -= 6.2832
    	if cv < -10.0:cv = -10.0
    	if cv >  10.0:cv =  10.0

    	// 水平方向のベクトルを算出する
    	fx = sin(ch)
    	fy = cos(ch)
    	fz = 1.0
    	// 正規化
    	len = sqrt((fx * fx) + (fy * fy) + (fz * fz))
    	if len != 0.0 {
    		fx /= len
    		fy /= len
    		fz /= len
    	}

    	clx = cx + (fx * 10)
    	cly = cy + (fy * 10)
    	clz = cz + cv

    	czJump = 0
    	if jumpCounter > 0 : czJump = int(15.0 * sin(0.1*jumpCounter)) : if czJump < 0 : czJump = 0 : jumpCounter = 0
    	// カメラ更新
    	d3setcam cx, cy, cz - squat*(cz/2) + czJump, clx, cly, clz - squat*(cz/2) + czJump, 1.0

    return