Dripです。
おぼさん、こんにちは。
まずHSPではC#などのように他所から高速描画のためのライブラリを
別途大量に読み込んで下準備、という考え方は基本的には不要です。
その辺はHSPや拡張機能の開発者がしてくれているので、それに乗っかる形で開発をします。
(逆にHSP上で自分で他所の言語用のライブラリを別途取り込む場合は相当な手間がかかります。
勿論、それをやっている方も最近では多くいらっしゃいますが…^^;)
なので、例えば標準のHSPを利用してソフト開発をしようとすると、
自動的にWindowsGDIでの原始的な描画システムが標準で使われ、
ひとたびソースコードに #include "hgimg3.as" などと記述した途端、
Direct3Dを用いた3D描画システムやスプライト機能が追加されます。
次にDishの話に移ります。
DishはOpenHSPというプロジェクトから派生したシステムで、完成した作品を
Windowsの他にAndroidやiOS用アプリとしても出力できることを目的にして作られています。
#include "hsp3dish.as" とソースコードに記述した時点でWindows上では
OpenGLを用いた高速描画システムが用いられるようになり、
おまけに音声の同時再生やボリュームコントロール機能などもついてきます。
描画システムが高速になる代わりに、標準描画システムは破棄されてしまいます。
マルチプラットフォーム出力機能の代償として標準HSPで出来た高度な処理の多くは
使用不可能になることにも注意が必要です。
さて、弾幕シューティングに話を変えますが、
拡張機能(hgimg3やhspdx等)が提供するスプライトという考え方を使わない限り、
どれで開発しても基礎構造は変わりません。
(自分でスプライトの枠組みを設計することになるからです)
自分が開発したいゲームの規模や処理速度と相談して何を使うか考えてみてください。
現代のパソコンでは処理速度がかなり速くなって来ており、
一昔前からHSPの標準命令での弾幕STGも見かけるようになりました。
カラーモードや解像度を絞ればかなりの描画速度向上が見込めます。
中間処理言語のHSPではループ処理が重く苦手です。
これを改善するために拡張機能(hgimg4,hgimg3,hspdx等)がスプライトの概念を
提供している場合があります。華やかな弾幕を表示するためにそうした機能を使うか、
あるいは自分で工夫を凝らすか、クリエイターのセンスが問われてくる部分です。
殆どの描画システムは併用が不可能です。仕様をよく確認して取り入れてみてください。
以下に併用の例をいくつか挙げてみます。
・Artlet2DでのGDI+とWindowsGDIとの共存:完全に共存可能
・hgimg3でのDirect3DとWindowsGDI:一部共存可能
・HSP3DishでのOpenGLとWindowsGDI:一切共存不可能
などなど…拡張機能にも個性があります。
以下にHSP3DishとHSP標準機能の両方で利用できる弾幕シューティングのサンプルを示します。
スクリプトエディタに貼り付けてF5実行してみてください。
(カーソルキーで移動、Ctrlキーで射撃、当たり判定はありますが敵味方双方死にません。)
(1行目に着目してください。#include文を消去すれば、OpenGLから標準GDIに切り替わります。
ゲームの見た目は変わりませんが、起動時のタイトルバーの表示や処理速度に違いがあります。)
#include "hsp3dish.as" //★この行があるとDishのOpenGL描画になる。消すだけで標準HSPのGDI描画になる。
#define ss 10 //★キャラクターのサイズ
screen 0,320,480 //解像度はDish標準に合わせる。Dishでの変更方法はマニュアル参照
wx=double(ginfo_winx): wy=double(ginfo_winy) //画面解像度を変数に格納しておく
px=0.5*wx: py=0.8*wy //プレイヤーの初期座標を定義
*main
//●敵の行動
ex=sin(0.01*timer)*wx*0.4+wx/2 //敵のX移動(というか直座標指定^^;)
ey=cos(0.01*timer)*10+60 //敵のY移動
if timer\2=0:{ //敵のショット発射
gosub *newShotID //新しいIDを取得
shotID(id)=2 //敵のショットIDは2
shotX(id)=ex: shotY(id)=ey //座標を敵の位置に
shotAng(id)=sin(0.5*timer)/2 //弾の角度を設定
}
//●プレイヤーの行動
stick ky,15+64 //カーソルキーとCtrlキーの状態を連続取得
if ky&1:px-=1.0:if px<0.0:px=0.0 //左移動
if ky&4:px+=1.0:if px>wx:px=wx //右移動
if ky&2:py-=1.0:if py<wy/4:py=wy/4 //上移動
if ky&8:py+=1.0:if py>wy:py=wy //下移動
if ky&64:if timer\5=0:{ //射撃
repeat 3 //スリーウェイショット!
gosub *newShotID
shotID(id)=1 //プレイヤーのショットID
shotX(id)=px: shotY(id)=py //ショット座標
shotAng(id)=m_pi-0.5+0.5*cnt //弾の角度
loop
}
timer++ //時間経過
//●キャラクターと背景描画
redraw 0:color:boxf //画面をリフレッシュ
gmode 0,ss,ss //描画サイズ定義
color 255:grect ex,ey,m_pi/4 //敵を描画
color ,255,255:grect px,py //プレイヤーを描画
//●弾幕の処理
gmode 0,3,ss //描画サイズ定義
repeat length(shotID) //配列分の弾の処理をする
if shotID(cnt):{ //弾が存在していれば処理
if shotX(cnt)<-ss | shotY(cnt)<-ss | shotX(cnt)>wx+ss | shotY(cnt)>wy+ss:{
shotID(cnt)=0:continue //画面外に弾が消えた
}
if shotID(cnt)=1:{ //プレイヤーの弾の動きと描画
shotX(cnt)+=sin(shotAng(cnt))*6 //座標移動X
shotY(cnt)+=cos(shotAng(cnt))*6 //座標移動Y
if absf(shotX(cnt)-ex)<ss & absf(shotY(cnt)-ey)<ss:{ //弾が敵に衝突
color 255,255:boxf ex-ss,ey-ss,ex+ss,ey+ss //爆炎描画
}
color ,255,255 //プレイヤーの弾の描画(水色の棒(角度つき))
grect shotX(cnt),shotY(cnt),-shotAng(cnt)
}else{ //敵の弾の動きと描画
shotX(cnt)+=sin(shotAng(cnt)) //座標移動X
shotY(cnt)+=cos(shotAng(cnt)) //座標移動Y
if absf(shotX(cnt)-px)<ss & absf(shotY(cnt)-py)<ss:{ //弾がプレイヤーに衝突
if timer\2:color 255,255:boxf px-ss,py-ss,px+ss,py+ss //爆炎描画
}
color 255,,255 //敵の弾の描画(紫の丸)
circle shotX(cnt)-ss/2,shotY(cnt)-ss/2,shotX(cnt)+ss/2,shotY(cnt)+ss/2
}
}
loop
redraw 1: await 15 //画面を更新してアイドルを取る
if timer\60=0 & timer>120:title "最大弾数:"+max //時々弾の最大数をタイトルに表示
goto *main
*newShotID //変数 id に新しい弾のIDを取得するサブルーチン
id=length(shotID)
repeat id
if shotID(cnt)=0:id=cnt:break
loop
if id>max:max=id //最大数を更新
return
HSPは古来のBasicの雰囲気を色濃く残しており、変数空間も意識しなければ基本的にglobalで、
無骨なソースコードにはなりますが、整形して100行もかからず弾幕シューティングっぽい
ものが完結することに魅力を感じたなら、きっとHSPを楽しめることと思いますよ。
色々試行錯誤しながら挑戦してみてください。