HSP3Dish.js ゲームサンプル『シンプルシューティング』


更新:2022年8月15日   HSPトップへもどる

◆大きな画面タブレット用サンプルスクリプトを追加しました

『 シンプルシューティング 』  ◆ブラウザ上で動作するページ

★このスクリプトは WebDish素材のみ使用し、独自画像を使用していませんので、WebDishサービスにそのまま登録できます

シンプルシューティング

いちばん簡単なシューティングゲームのサンプルスクリプトです。
HSP3Dish の 標準命令だけを使っています。

【そのほかの開発方法】
短時間で豪華なシューティングゲームを作りたいときは、
HSP公式が提供している
・『ドットフレームワーク(β)』
をためしてみるのもよいかもしれません

こちらも参考になります
標準スプライトプログラミングガイド

HSPでは、配列変数の表記のしかたが二種類あり、どちらもおなじ意味です

 hairetu.0
 hairetu(0)
どちらも「配列の一つ目(インデックス0番目)の変数」

// いちばん簡単なシューティングゲーム
//	むかしのHSP公式サンプル(ver2.5時代)を hsp3Dish.js で動作するように修正したスクリプト
#include "hsp3dish.as"

	screen 0,320,400			// メイン画面(ID 0)のサイズを設定
	buffer 1,128,128
	celload "chr.png",1,0		// 画像は好きな素材に変更してもよい
	celdiv	1,48,48,0,0			// 1セルのサイズが変わったら変更する
	gsel 0

	//ボタンオブジェクト	
	objsize 60,30
	pos 320-64,400-32 : button "Shot ON!", *shot_on
	autoshot = 0		//自動ショットフラグ
	//--------------------------- 自機の初期設定
	px=144 : py=352		// 自機の初期位置
	tmx=3				// 自機弾の最大数
	hp=5				// 自機の耐久値(★この数値をあげると強くなります!
	dim tf,tmx			// 自機弾発射中フラグ
	dim tx,tmx : dim ty,tmx			// 弾位置の配列変数
	repeat tmx : tf.cnt=0 : loop	// 自機弾発射中フラグ(1で発射中)
	//--------------------------- 敵の初期設定
	emx=4				// 敵の数
	ecn=emx				// 敵の全滅チェック用
	dim ehp,emx					// 敵の耐久値
	dim ex,emx : dim ey,emx		// 敵の位置
	dim dx,emx : dim dy,emx		// 移動方向の配列変数
	repeat emx					// 敵の数だけ繰り返す
		ehp.cnt=3							// 敵の耐久値
		ex.cnt=rnd(288) : ey.cnt=rnd(168)	// 位置
		r=rnd(5) : dx.cnt=(r-2)*4 : r=rnd(5) : dy.cnt=(r-2)*4	// 移動方向を設定
	loop

	etmx=8						// 敵弾の数
	dim etf,etmx				// 敵弾発射中フラグ
	dim etx,etmx : dim ety,etmx	// 弾の位置
	dim tdx,etmx : dim tdy,etmx	// 弾移動方向の配列変数
	repeat etmx : etf.cnt=0 : loop	// 敵弾発射中フラグ(1で発射中)

	gmode 2		//モードを透明色ありに設定
//===============================================↓このまま突入
// メインループ
*main
	redraw 0			// 画面描画を一時停止
	color 0,0,0 : boxf	// 画面を黒に塗りつぶす
	stick ky,15			//キー入力検知(1+2+4+8=15 方向キー4つは非トリガータイプ指定)
	if ky&1 : px-=8 : if px<8 : px=8		// 自機の移動
	if ky&4 : px+=8 : if px>280 : px=280
	if ky&2 : py-=8 : if py<200 : py=200
	if ky&8 : py+=8 : if py>360 : py=360
	// 《 タッチ検出 》
	mtlist touchid			//現在タッチされている情報を持つポイントIDリストを取得
	id = touchid(0)			//シングルタッチのみ対応
	mtinfo touch,id
	if touch(0) = 1 {	//タッチしているあいだは実行
		//どこがタッチされたか判定
		y = touch(2) : x = touch(1)		//タッチされたxy座標
		// 自機サイズが48*48なのでその中心を基準にするため+24して判定
		if x<px+24 : px-=8 : if px<8 : px=8		// 自機の移動
		if x>px+24 : px+=8 : if px>280 : px=280	 
		if y<py+24 : py-=8 : if py<200 : py=200
		if y>py+24 : py+=8 : if py>360 : py=360		
	}	
 	//-----------------------------------------------------------------------
	repeat tmx			// 自機弾の数だけ繰り返す (スペースキーはトリガタイプ)

		if tf.cnt=0 {	// 自機弾の発射準備

			if autoshot=1 {
				tx.cnt=px+8 : ty.cnt=py-16 : tf.cnt=1 : ky=0
			}else{
				if ky&16 : tx.cnt=px+8 : ty.cnt=py-16 : tf.cnt=1 : ky=0
			}
	
		else { ty.cnt-=16 : if ty.cnt<0 : tf.cnt=0 // 自機弾をまっすぐ移動
		}
		if tf.cnt=1 : n=cnt : gosub *hitchk	//自機弾判定(自機弾が敵に当たったか?)
	loop
 	//-----------------------------------------------------------------------
	pos px,py : celput 1,0,1.0,1.0,0.0		// 自機を表示
	repeat emx								// 敵の数だけ繰り返す
		if ehp.cnt>0 {						// 存在する(HPが1以上ある)敵だけ
			r=rnd(10)						// 動きを乱数で決定
			if r=0 : r=rnd(5) : dx.cnt=(r-2)*4 : r=rnd(5) : dy.cnt=(r-2)*4
			x=ex.cnt : ex.cnt+=dx.cnt
			if (ex.cnt<8)|(ex.cnt>280) : ex.cnt=x : dx.cnt=-dx.cnt
			y=ey.cnt : ey.cnt+=dy.cnt
			if (ey.cnt<8)|(ey.cnt>168) : ey.cnt=y : dy.cnt=-dy.cnt
			pos ex.cnt,ey.cnt : celput 1,3,1.0,1.0,0.0	// 敵を表示			
		}
	loop
 	//-----------------------------------------------------------------------
	r=rnd(etmx) : e=rnd(emx)					// 敵弾の発射準備
	if (etf.r=0)&(ehp.e>0) { etx.r=ex.e+8 : ety.r=ey.e+16
		x=rnd(5) : tdx.r=(x-2)*4 : y=rnd(2) : tdy.r=(y+1)*8
		etf.r=1
	}
	repeat etmx			// 敵弾の数だけ繰り返す(敵弾が自機に当たったか?)
		x=etx.cnt : y=ety.cnt
		if ((((etf.cnt=1)&((px+32)>x))&((x+16)>px))&((py+32)>y))&((y+16)>py) {
			etf.cnt=0 : hp- : if hp<1 : end	// 自機の耐久値がゼロになったらゲームオーバー
		}

		if etf.cnt=1 { pos etx.cnt,ety.cnt : celput 1,2,1.0,1.0,0.0	// 敵弾の表示
			etx.cnt+=tdx.cnt : ety.cnt+=tdy.cnt						// 敵弾の移動
			if ((etx.cnt<0)|(etx.cnt>304))|(ety.cnt>384) : etf.cnt=0
		}
	loop
 	//-----------------------------------------------------------------------
	redraw 1				// 描画した画面を更新
	await 100				// ★この数値を変えるとゲームスピードを調整できます!
	if ecn>0 : goto *main	// 敵が全滅するまでメインへループ↑
stop
//=================================================================================
// あたり判定(自機弾が敵に当たったか?)
*hitchk
	repeat emx			// 敵の数だけ繰り返す
		x=ex.cnt : y=ey.cnt
		if ((((ehp.cnt>0)&((x+32)>tx.n))&((tx.n+16)>x))&((y+32)>ty.n))&((ty.n+16)>y) {
			tf.n=0 : ehp.cnt- : if ehp.cnt<1 : ecn-		// 敵の耐久値が0以下なら消滅
		} else {
			pos tx.n,ty.n : celput 1,1,1.0,1.0,0.0		// 自機弾の表示
		}
	loop
return
//=================================================================================
//自動ショットボタンをONにした
*shot_on
	if autoshot=0 : autoshot=1 : else : autoshot=0
	goto *main
//=================================================================================

・このサンプルスクリプトは、むかしのHSP公式サンプル(ver2.5時代)を hsp3Dish.js で動作するように2022年7月に、私(用賀じゅんちゃんおじさん)が修正したスクリプトです。


8/15 サンプル追加:

大きな画面タブレット用サンプルスクリプト

  ◆ブラウザ上で動作するページ

画面サイズを変数で指定するようになっています

// いちばん簡単なシューティングゲーム
//	むかしのHSP公式サンプル(ver2.5時代)を hsp3Dish.js で動作するように修正したスクリプト
// iPadサイズ
#include "hsp3dish.as"

	sc_w=768 : sc_h=872	// 9.7インチiPad 縦 
								//★この数値を変更すれば画面サイズ変更できます
								// 変換時の.html の ENV.HSP_WX も直接修正
								// または hsp3dish.ini で変更する

	screen 0,sc_w,sc_h			// メイン画面(ID 0)のサイズを設定
	//screen 0,320,400	
	buffer 1,128,128
	celload "chr.png",1,0		// 画像は好きな素材に変更してもよい
	celdiv	1,48,48,0,0			// 1セルのサイズが変わったら変更する
	gsel 0

	//ボタンオブジェクト	
	objsize 60,30
	pos sc_w-64,32 : button "Shot ON!", *shot_on
	autoshot = 0		//自動ショットフラグ
	//--------------------------- 自機の初期設定
	//px=144 : py=352			// 自機の初期位置
	px=sc_w/2-24 : py=800	//(sc_h-48)	// 自機の初期位置
	tmx=3				// 自機弾の最大数
	hp=5				// 自機の耐久値(★この数値をあげると強くなります!
	dim tf,tmx			// 自機弾発射中フラグ
	dim tx,tmx : dim ty,tmx			// 弾位置の配列変数
	repeat tmx : tf.cnt=0 : loop	// 自機弾発射中フラグ(1で発射中)
	//--------------------------- 敵の初期設定
	emx=4				// 敵の数
	ecn=emx				// 敵の全滅チェック用
	dim ehp,emx					// 敵の耐久値
	dim ex,emx : dim ey,emx		// 敵の位置
	dim dx,emx : dim dy,emx		// 移動方向の配列変数
	repeat emx					// 敵の数だけ繰り返す
		ehp.cnt=3							// 敵の耐久値
		//ex.cnt=rnd(288) : ey.cnt=rnd(168)	// 位置
		ex.cnt=rnd(sc_w-48) : ey.cnt=rnd(sc_h-200)	// 位置
		r=rnd(5) : dx.cnt=(r-2)*4 : r=rnd(5) : dy.cnt=(r-2)*4	// 移動方向を設定
	loop

	etmx=8						// 敵弾の数
	dim etf,etmx				// 敵弾発射中フラグ
	dim etx,etmx : dim ety,etmx	// 弾の位置
	dim tdx,etmx : dim tdy,etmx	// 弾移動方向の配列変数
	repeat etmx : etf.cnt=0 : loop	// 敵弾発射中フラグ(1で発射中)

	gmode 2		//モードを透明色ありに設定
//===============================================↓このまま突入
// メインループ
*main
	redraw 0			// 画面描画を一時停止
	color 0,0,0 : boxf	// 画面を黒に塗りつぶす
	stick ky,15			//キー入力検知(1+2+4+8=15 方向キー4つは非トリガータイプ指定)
	if ky&1 : px-=8 : if px<0 : px=0		// 自機の移動
	if ky&4 : px+=8 : if px>sc_w-48 : px=sc_w-48	 //280
	if ky&2 : py-=8 : if py<200 : py=200
	if ky&8 : py+=8 : if py>sc_h-48 : py=sc_h-48		//360
	// 《 タッチ検出 》
	mtlist touchid			//現在タッチされている情報を持つポイントIDリストを取得
	id = touchid(0)			//シングルタッチのみ対応
	mtinfo touch,id
	if touch(0) = 1 {	//タッチしているあいだは実行
		//どこがタッチされたか判定
		y = touch(2) : x = touch(1)		//タッチされたxy座標
		// 自機サイズが48*48なのでその中心を基準にするため+24して判定
		if x<px+24 : px-=8 : if px<0 : px=0		// 自機の移動
		if x>px+24 : px+=8 : if px>sc_w-48 : px=sc_w-48	 //280
		if y<py+24 : py-=8 : if py<200 : py=200
		if y>py+24 : py+=8 : if py>sc_h-48 : py=sc_h-48		//360		
	}	
 	//-----------------------------------------------------------------------
	repeat tmx			// 自機弾の数だけ繰り返す (スペースキーはトリガタイプ)

		if tf.cnt=0 {	// 自機弾の発射準備

			if autoshot=1 {
				tx.cnt=px+8 : ty.cnt=py-16 : tf.cnt=1 : ky=0
			}else{
				if ky&16 : tx.cnt=px+8 : ty.cnt=py-16 : tf.cnt=1 : ky=0
			}
	
		else { ty.cnt-=16 : if ty.cnt<0 : tf.cnt=0 // 自機弾をまっすぐ移動
		}
		if tf.cnt=1 : n=cnt : gosub *hitchk	//自機弾判定(自機弾が敵に当たったか?)
	loop
 	//-----------------------------------------------------------------------
	pos px,py : celput 1,0,1.0,1.0,0.0		// 自機を表示
	repeat emx								// 敵の数だけ繰り返す
		if ehp.cnt>0 {						// 存在する(HPが1以上ある)敵だけ
			r=rnd(10)						// 動きを乱数で決定
			if r=0 : r=rnd(5) : dx.cnt=(r-2)*4 : r=rnd(5) : dy.cnt=(r-2)*4
			x=ex.cnt : ex.cnt+=dx.cnt
			
			if (ex.cnt<8)|(ex.cnt>sc_w-48) : ex.cnt=x : dx.cnt=-dx.cnt	//280
			y=ey.cnt : ey.cnt+=dy.cnt
			if (ey.cnt<8)|(ey.cnt>sc_h-48) : ey.cnt=y : dy.cnt=-dy.cnt		//168
			pos ex.cnt,ey.cnt : celput 1,3,1.0,1.0,0.0	// 敵を表示			
		}
	loop
 	//-----------------------------------------------------------------------
	r=rnd(etmx) : e=rnd(emx)					// 敵弾の発射準備
	if (etf.r=0)&(ehp.e>0) { etx.r=ex.e+8 : ety.r=ey.e+16
		x=rnd(5) : tdx.r=(x-2)*4 : y=rnd(2) : tdy.r=(y+1)*8
		etf.r=1
	}
	repeat etmx			// 敵弾の数だけ繰り返す(敵弾が自機に当たったか?)
		x=etx.cnt : y=ety.cnt
		if ((((etf.cnt=1)&((px+32)>x))&((x+16)>px))&((py+32)>y))&((y+16)>py) {
			etf.cnt=0 : hp- : if hp<1 : end	// 自機の耐久値がゼロになったらゲームオーバー
		}

		if etf.cnt=1 { pos etx.cnt,ety.cnt : celput 1,2,1.0,1.0,0.0	// 敵弾の表示
			etx.cnt+=tdx.cnt : ety.cnt+=tdy.cnt						// 敵弾の移動
			//if ((etx.cnt<0)|(etx.cnt>304))|(ety.cnt>384) : etf.cnt=0
			if ((etx.cnt<0)|(etx.cnt>sc_w-16))|(ety.cnt>sc_h-16) : etf.cnt=0
		}
	loop
 	//-----------------------------------------------------------------------
	redraw 1				// 描画した画面を更新
	await 100				// ★この数値を変えるとゲームスピードを調整できます!
	if ecn>0 : goto *main	// 敵が全滅するまでメインへループ↑
stop
//=================================================================================
// あたり判定(自機弾が敵に当たったか?)
*hitchk
	repeat emx			// 敵の数だけ繰り返す
		x=ex.cnt : y=ey.cnt
		if ((((ehp.cnt>0)&((x+32)>tx.n))&((tx.n+16)>x))&((y+32)>ty.n))&((ty.n+16)>y) {
			tf.n=0 : ehp.cnt- : if ehp.cnt<1 : ecn-		// 敵の耐久値が0以下なら消滅
		} else {
			pos tx.n,ty.n : celput 1,1,1.0,1.0,0.0		// 自機弾の表示
		}
	loop
return
//=================================================================================
//自動ショットボタンをONにした
*shot_on
	if autoshot=0 : autoshot=1 : else : autoshot=0
	goto *main
//=================================================================================

   HSPトップへもどる