# sample05_gamepad.hsp

sample\sample_gamepad\ sample05_gamepad.hsp

    #include "hsp3dish.as"

    #include "ezlocal-dish-js.hsp"
    ezLocalJS

    #include "mod_dish-js-gamepad.hsp"

    #packopt xsize 1040
    #packopt ysize 480
    	;
    	;  HSPTV!掲示板「d3moduleで一人称視点ゲームが作りたい」内
    	;  - 法貴優雅 氏 サンプルスクリプト // thanks!
    	;  https://hsp.tv/play/pforum.php?mode=pastwch&num=81890#81895
    	;
    	;    HSP3Dish.jsで動作するように改造
    	;    jsでゲームパッドを使用するモジュールのサンプル
    	;
    #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 "ゲームパッド接続サンプル"
    	mouse ginfo_wx1 + frmx + scx, ginfo_wy1 + frmy + scy

    	// カメラの初期設定
    	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

    	bt_BAYX = 0  // A⇔B, X⇔Y ボタンの入れ替え設定
    	cam_UD = 1.0 : cam_LR = 1.0  // カメラリバース設定

    *main
    // 動作処理
    	stick stk, $3C00F          ; 上下左右,WASDキーを非トリガー設定
    	JspadStick jspstk, $3C00F  ; 上下左右ボタン,Lスティック移動を非トリガー設定
    	stk |= jspstk              ; ゲームパッドのボタン状態をstickのキー状態に被せ合わせられる
    	                           ; - 被せ合わせてますが、このサンプルではゲームパッド,キーボードマウスどちらでも対応というところまでは作り込んでません
    	// ESC
    	if stk & $00080 :end
    	cm = 0	// カメラ移動フラグ
    	// 前進後退は同時押しさせない
    	if stk & $08000 {  // W
    		cm += 8
    	}else : if stk & $20000 {  // S
    		cm += 1
    	}
    	// 左移動右移動は同時押しさせない
    	if stk & $04000 {  // A
    		cm += 2
    	}else : if stk & $10000 {  // D
    		cm += 4
    	}
    	// ダッシュ
    	if stk & $01000000 : dash ^= 1 : squat = 0  ; Lスティック押し込み [JspadStick独自拡張]
    	// しゃがみ [スペースキー]
    	if stk & $00000010 : squat ^= 1 : dash = 0  ; 東ボタン: A(N)、○(DS4)、B(MS)
    	// ジャンプ [Ctrlキー]
    	if jumpCounter > 0 : jumpCounter++
    	if stk & $00000040 : if jumpCounter==0 : jumpCounter = 1 : squat = 0  ; 南ボタン: B(N)、×(DS4)、A(MS)
    	// 弾 [左クリック]
    	if stk & $00100 {  ; ZRボタン
    		repeat length(bulletCounters)+1
    			// 重なり順を気にしなくていいので空いてる所にテキトーに代入
    			if cnt >= length(bulletCounters) : bulletCounters(cnt) = 10 : break
    			if bulletCounters(cnt) == 0 : bulletCounters(cnt) = 10 : break
    		loop
    		needDrawBullet = 1
    	}
    	// カメラリバース設定 [Enter]
    	if stk & $00020 {  ; PLUSボタン
    		camera++ : camera \= 4
    		switch camera
    		case 0: cam_UD= 1.0:cam_LR= 1.0 :swbreak
    		case 1: cam_UD=-1.0:cam_LR= 1.0 :swbreak
    		case 2: cam_UD=-1.0:cam_LR=-1.0 :swbreak
    		case 3: cam_UD= 1.0:cam_LR=-1.0 :swbreak
    		swend
    	}
    	// A⇔B,X⇔Yボタン入れ替え設定
    	if stk & $04000000 : bt_BAYX ^= 1 : JspadSetBAYX bt_BAYX  ; HOMEボタン [JspadStick独自拡張]

    	//カメラの状態を更新
    	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
    	gfilter 1
    	pos 50, 0:mes "fps:" + d3getfps()
    	mes "stick="+stk
    	idstr = JspadGetID() :if idstr=="": idstr = "[ゲームパッドを接続してください]"
    	mes "ID="+idstr
    	mes "GetButtons="+JspadGetButtons()
    	mes "dash="+dash
    	mes "squat="+squat
    	mes "jump="+jumpCounter
    	mes "BtnBAYX="+bt_BAYX
    	mes "CamType="+camera
    	gfilter 0
    	redraw 1

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

    goto *main

    // カメラ更新
    *updatecam
    // カメラ位置の更新
    	if (cm > 0) {
    		// 移動してる場合だけ更新
    		fdir = ch
    		_MV = MV * (10 + (11*dash)) * (10 - (3*squat)) / 100  ; 速度補正
    		switch (cm)
    		case 8 // 前
    			fmv = _MV
    			swbreak

    		case 1 // 後
    			fmv = -_MV
    			swbreak

    		case 2 // 左
    			fmv = _MV
    			fdir = ch - 1.5707
    			swbreak

    		case 4 // 右
    			fmv = -_MV
    			fdir = ch - 1.5707
    			swbreak

    		case 10 // 右前
    			fmv = _MV
    			fdir = ch - 0.7853
    			swbreak

    		case 12 // 左前
    			fmv = -_MV
    			fdir = ch - 2.356
    			swbreak

    		case 3: // 右後
    			fmv = _MV
    			fdir = ch - 2.356
    			swbreak

    		case 5: // 左後
    			fmv = -_MV
    			fdir = ch - 0.7853
    			swbreak
    		swend

    		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 * JspadGetRightX() * 20.0
    	fy = cam_UD * JspadGetRightY() * 20.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