#include "hgimg4.as" #include "hsp3dish.as" #packopt xsize 960 #packopt ysize 640 ;#packdir "res/*" ;WindowsEXE用パックファイル指定(このままではBGMは再生されません) ;EXEファイルと同じディレクトリのresフォルダ内にBGMファイルを入れると再生できます #define COL_PL 1 #define COL_BLK 2 #define COL_SHOT 4 #define COL_EN 8 #define COL_ITEM 16 title "nayaのHGIMG4シンプルアクションサンプル(HSP3.7用)v1.7" ; nayaのHGIMG4シンプルアクションサンプル(HSP3.7用)v1.7 ; (c)2025 naya ; ; ≪説明≫ ; HGIMG4を使用した簡易的なアクションゲームのサンプルプログラムです。 ; アクションゲームに必要な基本的な機能は一通り搭載していますので、 ; 本サンプルを改造する事で比較的容易にアクションゲームを作成できると ; 思われます。 ; fvdirとgetang命令を使用しておりますので、HSP3.7を使用してください。 ; ; 本プログラムをHSP3DishJSで動作することを確認しました。 ; DishJS(ブラウザ版)ではテキストが途中までしか表示されませんが、 ; 今の所、原因は不明です(最新のリリースHSP3.7では表示できました)。 ; ブラウザでプレイする場合はブラウザの設定でグラフィックスアクセラレータを ; ONにしてください。 ; ブラウザでの快適な動作にはある程度のマシンパワーが必要かもしれません。 ; 作者のテストではブラウザで繰り返しプレイすると重くなる現象が発生しています。 ; ; 操作方法はカーソルキー左右で回転、上下で前進と後退、スペースキーで剣を ; 発射します。 ; 敵を倒して出てきた宝箱を12個拾うとフェードアウトして最初に戻ります。 ; プレイヤーの移動や壁との衝突判定にHGIMG4の物理エンジンは使用しておりません。 ; 必要な素材ファイルは全てresフォルダに入れてあります。 ; プレイヤーキャラは二つのモデルの表示を切り替えてアニメーションさせています。 ; モデルの基本サイズは16に統一してあります。 ; 変数fpsmodeを1に変更する事でFPS視点に変更できます。 ; ; v1.3よりミニ珠音ちゃんのモデルを作成、追加しました。resフォルダに ; "mini_tamane1_1","mini_tamane1_2"二つのgpbファイルが入っています。 ; テクスチャはHSPTV素材の"tamadot.bmp"をそのまま使用させていただきました。 ; プレイヤーモデルの部分を変更すると簡単にミニ珠音ちゃんに変更できます。 ; ; v1.5追加素材(resフォルダ) ; bg2.png(フロアBG)、mspr011.gpb(敵モデル) ; pbox2.gpb(ブロックモデル)、pbox3.gpb(ブロックモデル) ; ; v1.7よりチビ珠音ちゃんのモデルを作成、追加しました。resフォルダに ; "chibi_tamane1_1","chibi_tamane1_2"二つのgpbファイルが入っています。 ; テクスチャはHSPTV素材の"tamane16.bmp"をそのまま使用させていただきました。 ; ; ≪利用規約≫ ; 3Dモデル、画像、BGM等、素材ファイルの作者は私nayaで著作権は放棄して ; いませんが、特に制限は設けておりませんので、本プログラムを自由に ; 改造してオリジナルのアクションゲーム制作にお役立てください。 ; 作者(naya)への利用報告も不要です。 ; 作者(naya)は本プログラムのサポートと責任の義務は負わないものとします。 ; ; (25/10/24)v1.7:チビ珠音ちゃんモデルの追加 ; (25/10/23)v1.6:敵消滅時の爆発エフェクトを追加 ; (25/10/22)v1.5:素材の追加、コメントの追加 ; (25/10/21)v1.4:敵キャラの移動処理を修正 ; (25/10/19)v1.3:プログラム内コメントの修正 ; (25/10/18)v1.3:ミニ珠音ちゃんモデルの追加 ; (25/10/18)v1.2:メインループからgoto命令でループを抜ける誤りを修正 ; (25/10/18)v1.1:プログラム内コメントの修正 ; (25/10/17)v1.1:公開 ; (25/10/17)v1.0:プロトタイプ完成 ;BGM&効果音の読み込み mmload "res/tbgm1.mp3", 0, 1 mmload "res/se1.wav", 1, 0 mmload "res/se2.wav", 2, 0 mmload "res/se3.wav", 3, 0 mmload "res/se4.wav", 4, 0 ;初期設定 *init font "MS ゴシック", 16, 0 randomize ;乱数初期化 gpreset ;HGIMG4初期化 dim obj_prm, 1024 ;オブジェクト用パラメータ(敵のHPに使用) celload "res/black1.png", 1 ;フェードイン用黒画像 celdiv 1, 0, 0 celload "res/bp1.png", 2 ;スクリーン背景画像 celdiv 2, 0, 0 celload "res/num1.png", 3 ;数値画像1 celdiv 3, 16, 32 celload "res/num2.png", 4 ;数値画像2 celdiv 4, 16, 32 celload "res/icon1.png", 5 ;パラメータアイコン画像 celdiv 5, 0, 0 setcls CLSMODE_SOLID, $000000 ;画面クリア設定 ;プレイヤーモデル gpload mychr(0), "res/mspr007_1" ;gpload mychr(0), "res/mini_tamane1_1" ;ミニ珠音ちゃんモデルを使用する ;gpload mychr(0), "res/chibi_tamane1_1" ;チビ珠音ちゃんモデルを使用する setcoli mychr(0), COL_PL, COL_BLK setobjmode mychr(0), OBJ_BORDER|OBJ_FLIP, 0 gpload mychr(1), "res/mspr007_2" ;gpload mychr(1), "res/mini_tamane1_2" ;ミニ珠音ちゃんモデルを使用する ;gpload mychr(1), "res/chibi_tamane1_2" ;チビ珠音ちゃんモデルを使用する setcoli mychr(1), COL_PL, COL_BLK setobjmode mychr(1), OBJ_BORDER|OBJ_FLIP, 0 ;ブロック(壁モデル) gpload id_box,"res/pbox1" setpos id_box, 0, 8, 0 setcoli id_box, 0, 0 setobjmode id_box, OBJ_HIDE, 0 ;ショット gptexmat id_shotmat, "res/sh1b.png", GPOBJ_MATOPT_NOLIGHT gpplate id_sh, 16, 16, -1, id_shotmat ;板ノードを追加 setpos id_sh, 0, 8, 0 setcoli id_sh, 0, 0 setobjmode id_sh, OBJ_HIDE, 0 ;敵アニメイベント newevent ev_en1 repeat 2 event_addscale ev_en1, 0.025, 0.0, 0.025 event_wait ev_en1, 2 loop repeat 2 event_addscale ev_en1, -0.025, -0.0, -0.025 event_wait ev_en1, 2 loop repeat 4 event_wait ev_en1, 2 loop event_jump ev_en1, 0, 0 ;敵モデル gpload id_enm,"res/mspr009" setpos id_enm, 16+8, 8.0, 8 setcoli id_enm, 0, 0 setobjmode id_enm, OBJ_HIDE, 0 ;宝箱 gptexmat id_itemmat, "res/item1b.png", GPOBJ_MATOPT_NOLIGHT gpplate id_it, 16, 16, -1, id_itemmat ;板ノードを追加 setpos id_it, 0, 8, 0 setcoli id_it, 0, 0 setobjmode id_it, OBJ_HIDE, 0 ;爆風エフェクトイベント newevent ev_efc1 event_prmset ev_efc1, PRMSET_ALPHA, 256 event_setscale ev_efc1, 0.5, 0.5, 0.5, 1.0, 1.0, 1.0 repeat 8 event_fade ev_efc1, -8 event_addscale ev_efc1, 0.1, 0.1, 0.1 event_wait ev_efc1, 1 loop event_delobj ev_efc1 ;爆風 gptexmat id_efcmat, "res/efc01.png", GPOBJ_MATOPT_NOLIGHT|GPOBJ_MATOPT_BLENDADD ;爆発エフェクト画像 gpplate id_efc, 16, 16, -1, id_efcmat ;板ノードを追加 setcoli id_efc, 0, 0 setobjmode id_efc, OBJ_XFRONT|OBJ_HIDE, 0 ;フロア作成 gptexmat id_bgmat, "res/bg1.png" ;床ノードのテクスチャを追加 gpfloor id_floor, 256, 256, $404040, id_bgmat ;床ノードを追加 gppbind id_floor, 0 ;床の物理設定を行なう setborder 250, 250, 250, 0 ;画面端の設定 ;チェック用マップ配列の初期化 dim map, 16, 16 repeat 16 cy=cnt repeat 16 cx=cnt map(cy, cx)=0 loop loop ;プレイヤー初期位置の設定 px=rnd(16) py=rnd(16) map(py, px)=1 repeat 2 : setpos mychr(cnt), (px*16)-128+8, 8.0, (py*16)-128+8 : loop ;ランダムに32個のブロックを配置 repeat 32 repeat bx=rnd(8)*2 : bz=rnd(8)*2 if map(bz, bx)==0 : break loop map(bz, bx)=2 gpclone i, id_box ;最初のブロックをクローン setpos i, (16*bx)-128+8, 8, (16*bz)-128+8 ;位置を設定 setcoli i, COL_BLK, COL_PL|COL_SHOT setobjmode i, OBJ_HIDE, 1 loop ;敵をランダムに配置 repeat 12 repeat ex=rnd(8)*2+1 : ez=rnd(8)*2+1 if map(ez, ex)==0 : break loop map(ez, ex)=3 gpclone en, id_enm ;最初の敵をクローン setevent en, ev_en1, 0 setpos en, (16*ex)-128+8, 8, (16*ez)-128+8 ;位置を設定 setcoli en, COL_EN, COL_PL|COL_BLK|COL_EN setobjmode en, OBJ_MOVE|OBJ_FLIP|OBJ_BORDER, 2 obj_prm(en)=4+rnd(3) loop ;変数の初期化 ddim an, 4 ddim po, 4 ddim fv, 4 ddim gx, 1 ddim gy, 1 ddim gz, 1 ddim ax, 1 ddim ay, 1 ddim az, 1 fpsmode=0 ;fpsmodeを1にするとFPS視点に変更 muteki=30 ;mutekiが30以下の時はダメージ無し hp=20 ;初期HP item=0 ;初期アイテム数 fade=255 shw=0 rr=0.0 await 1000 mmplay 0 ;BGM再生 gosub *fade_in ;メインループ repeat stick key, 15+16 if key&128 : gosub *fade_out if (hp<1) : goto *sskip getpos mychr, gx, gy, gz ;プレイヤーの移動前の位置を記憶 ; カーソルキーでプレイヤーを動かす if (key&1) : kk=0.0 : addang mychr, 0, 0.05, 0 ;左回転 if (key&4) : kk=0.0 : addang mychr, 0, -0.05, 0 ;右回転 if (key&8) : kk=-0.5 : gosub *pl_move ;前進 if (key&2) : kk=0.5 : gosub *pl_move ;後退 chk=(key&16) if (chk!=0)&&(shw<0) { shw=20 ;ショット発射用ウェイト mmplay 1 gpclone sh, id_sh getpos mychr, po(0), po(1), po(2) ;fvadd po,0.0,-0.0,0.0 ;発射座標を調整(Y座標を調整) setpos sh, po(0), po(1), po(2) ;発射座標をセット getang mychr, an(0), an(1), an(2) ;自キャラの角度から setang sh, an(0), an(1), an(2) an(1)=an(1)*-1 ; fvdir an,0.0,0.0,4.0 ;弾の移動量を算出 setdir sh, an(0), an(1), an(2) ;移動量をセット setcoli sh, COL_SHOT, COL_EN|COL_BLK ;コリジョングループを設定 setobjmode sh, OBJ_MOVE|OBJ_XFRONT|OBJ_BORDER, 2 ;オブジェクトのモードを変更 } shw-- ;プレイヤー移動時の壁との衝突処理 findobj 0, COL_BLK|COL_EN repeat nextobj f if (f==-1) : break getcoli hit, f, 12 if (hit==mychr) { ;壁とプレイヤーが衝突 getpos f, po(0), po(1), po(2) setpos mychr, gx, gy, gz ;移動前に位置を戻す getangr mychr, ax, ay, az ay=ay/64 if (ay==1)||(ay==3) { setpos mychr, gx, gy, gz if (po(2)>=gz) : daa=-0.1 : else : daa=0.1 addpos mychr, 0, 0, daa } if (ay==0)||(ay==2) { setpos mychr, gx, gy, gz if (po(0)>=gx) : daa=-0.1 : else : daa=0.1 addpos mychr, daa, 0, 0 } } loop ;敵移動処理 getpos mychr, po(0), po(1), po(2) ff=frame if (ff-fs)>20 { findobj 0, COL_EN repeat nextobj f if (f<0):break rndchk=rnd(10) ;敵の行動を乱数で決める if (rndchk<=2) { ;ランダムに向きを変える addangr f, 0, rnd(256)-128, 0 } if (rndchk>=7) { ;プレイヤーの方を向く getpos f, fv(0), fv(1), fv(2) fvface fv, po(0), po(1), po(2) setang f, 0, fv(1)*-1, 0 addangr f, 0, 128, 0 } loop fs=ff } ;敵衝突判定 findobj 0, COL_EN repeat nextobj f if (f==-1) : break getpos f, po(0), po(1), po(2) getang f, fv(0), fv(1), fv(2) fv(1)*=-1 : fvdir fv, 0, 0, 0.2 addpos f,fv,0,fv(2) getcoli hit, f, 12.0 if (hit==mychr) { ;敵とプレイヤーが衝突 if (muteki>30) : mmplay 4 : hp-- : muteki=0 if (hp<1) : hp=0 : setobjmode mychr(0), OBJ_HIDE, 0 : setobjmode mychr(1), OBJ_HIDE, 0 : gosub *fade_out setpos f, po(0), po(1), po(2) ;移動前に位置を戻す } if (hit!=-1)&&(hit!=mychr) { getobjcoli hit_obj, hit if (hit_obj==COL_BLK)||(hit_obj==COL_EN) { ;ブロックか敵(同種)と衝突 setpos f, po(0), po(1), po(2) ;移動前に位置を戻す } } loop muteki++ ;ショットの当たり判定 findobj 0, COL_SHOT repeat nextobj f if (f==-1) : break getcoli hit, f, 12 if hit!=-1 { getobjcoli hit_obj, hit if (hit_obj==COL_BLK) { ;壁の時は消滅 delobj f } if (hit_obj==COL_EN) { ;敵のダメージ mmplay 2 obj_prm(hit)-- ;敵のHPから1引く if (obj_prm(hit)<1) { getpos f, po(0), po(1), po(2) ;宝箱を出す gpclone it, id_it setpos it, po(0), po(1), po(2) setcoli it, COL_ITEM, COL_PL setobjmode it, OBJ_FLIP|OBJ_BORDER|OBJ_XFRONT, 2 ;爆発エフェクトを出す repeat 4 gpclone efc, id_efc, OBJ_XFRONT|OBJ_LATE, ev_efc1 setobjmode efc, OBJ_HIDE, 1 setpos efc, po(0)+(rnd(16)-8), po(1)+(rnd(16)-8), po(2)+(rnd(16)-8) setcoli efc, 0, 0 loop delobj hit ;敵オブジェクトを消す } delobj f } } loop ;アイテムの当たり判定 findobj 0, COL_ITEM repeat nextobj f if (f==-1) : break getcoli hit, f, 10 if (hit==mychr) { mmplay 3 delobj f item++ if (item>=12)&&(fademode!=2) : gosub *fade_out } loop ;カメラ移動処理 getpos mychr, gx, gy, gz if (fpsmode==1) { ;FPS視点で前を見る setpos GPOBJ_CAMERA, gx, gy, gz getang mychr, ax, ay, az setang GPOBJ_CAMERA, ax, ay+3.14159263, az } else { ;プレイヤーを見ながらカメラ位置を回転させる setpos GPOBJ_CAMERA, sin(rr)*160, 120, cos(rr)*160 gplookat GPOBJ_CAMERA, gx, gy, gz ;カメラから指定した座標を見る } rr+=0.01 ;カメラ移動用角度 ;プレイヤーアニメーション処理 ptn=(ptn+1)\40 if (ptn<20) { ;表示するプレイヤーモデルを切り替える setobjmode mychr(0), OBJ_HIDE, 0 setobjmode mychr(1), OBJ_HIDE, 1 } else { ;表示するプレイヤーモデルを切り替える setobjmode mychr(0), OBJ_HIDE, 1 setobjmode mychr(1), OBJ_HIDE, 0 } getpos mychr(0), gx, gy, gz getang mychr(0), ax, ay, az setpos mychr(1), gx, gy, gz setang mychr(1), ax, ay, az *sskip redraw 0 ;描画開始 gmode 0 pos 0, 0 celput 2 ;壁紙の表示 gpdraw ;シーンの描画 gmode 2 pos 8, 24 celput 5 ;アイコン画像表示 ;数値の表示1(プレイヤーHP) ppp=hp ppx=48 ppy=24 ppb=4 gosub *put_prm ;数値の表示2(アイテム数) ppp=item ppx=48 ppy=24+32 ppb=3 gosub *put_prm ;メッセージ表示 color 255, 255, 255 pos 8, 0 : mes "nayaのHGIMG4シンプルアクションサンプル" ;フェードインアウト処理 if (fademode==1) { pos 0, 0 gmode 3, , , fade celput 1 gmode 0 fade-=4 if (fade<0) : fademode=0 } if (fademode==2) { pos 0, 0 gmode 3, , , fade celput 1 gmode 0 fade+=4 if (fade>=255) : fademode=0 : mmstop : await 1000 : break } redraw 1 ;描画終了 await 1000/60 ;待ち時間 frame++ ;title ""+hp loop goto *init ;フェードイン *fade_in fademode=1 fade=255 return ;フェードアウト *fade_out fademode=2 fade=0 return ;プレイヤーキャラの前進と後退処理 *pl_move getang mychr, fv, fv(1), fv(2) fv(1)*=-1 : fvdir fv, 0, 0, kk addpos mychr, fv(0), 0.0, fv(2) return ;数値画像の表示 *put_prm chk=""+(ppp) pps=strlen(chk) gmode 2 repeat pps n=strmid(chk, cnt, 1) ;文字列として数字を一つずつ取り出す if n="-" : continue ;マイナス記号はスキップ pos ppx+(cnt*16), ppy : celput ppb, 0+n loop gmode 0 return