自機の作成
注意
ph3には使えない内容です。v0.xにだけ使えます。
- 注意
- 1 最初にやること
- 2 最低限必要な部分
- 3 自機の画像を表示
- 4 基本的な内容の実装
- 移動速度
- かすり判定
- アイテム回収ライン
- 初期ボム数
- 残機画像
- 当たり判定
- 5 ショットの実装
- 6 ボムの実装
- +1 作成した自機で分岐をするには
- +2 特殊な軌道の弾
1 最初にやること
やっておいたほうがいいこと。
th_dnhフォルダ内にplayerフォルダを作る 混乱を避けるためにさらにフォルダを作っておく (名前は適当に決めてください。ここではTestという名前にしておきます)
Testフォルダの中にスクリプトを入れていきます。
2 最低限必要な部分
まずはTestフォルダの中に「TestPlayer.txt」というファイルを作ってください。
次に、↓をコピーしたり入力したりして下さい。
#東方弾幕風[Player] //自機スクリプトであることを示す #ScriptVersion[2] //スクリプトバージョンが2であることを示す #Menu[Sample] //自機を選ぶときに表示される部分、自機の名前 #Text[] //自機の説明 #Image[] //自機を選ぶときに表示される画像 #ReplayName[Sample] //リプレイに記載される自機の名前(半角8文字以内) script_player_main { @Initialize { // 初期化 } @MainLoop { // 毎フレーム実行される } @Missed { // 被弾したとき@MainLoopの代わりに実行される } @SpellCard { // スペルカードを発動した瞬間に実行される } @DrawLoop { // 描画するとき実行される } @Finalize { // 後始末 } }
ここに色々と書き込んでいきます。とりあえずこれが骨組みだと分かればいいです。
3 自機の画像を表示
自機の画像はふつう、
・正面を向いている状態
・左を向いている状態
・右を向いている状態
この3つがあります。
これらの画像を区別させるには、「キーが押されているか否か」で分岐することで実装できます。
キーを押しているかどうかはGetKeyStateで取得できるので、
この関数を使ってif文などで分岐させましょう。
尚、ここでは最初からplayerフォルダに入っているRumia.pngを借用します。
予めTestPlayer.txtがあるフォルダにRumia.pngを入れておいてください。
後、下の例では.\Rumia.pngと書かれていますが、
実際のプログラムには.¥Rumia.pngと書いてください。(¥は半角)
@Initialize{ LoadGraphic(".\Rumia.png"); } @DrawLoop{ SetTexture(".\Rumia.png"); if((GetKeyState(VK_LEFT) == KEY_PUSH) | | (GetKeyState(VK_LEFT) == KEY_HOLD)) { SetGraphicRect(1, 133, 49, 188); }else if((GetKeyState(VK_RIGHT) == KEY_PUSH) | | (GetKeyState(VK_RIGHT) == KEY_HOLD)) { SetGraphicRect(1, 69, 49, 124); }else{ SetGraphicRect(1, 5, 49, 60); } DrawGraphic(GetPlayerX, GetPlayerY); } @Finalize{ DeleteGraphic(".\Rumia.png"); }
解説
4 基本的な内容の実装
移動速度
関数SetSpeedを使う。宣言は@Initializeで行う。
SetSpeed(引数:2) //1:高速移動速度 //2:低速移動速度
かすり判定
関数SetGrazeCircleを使う。宣言は@Initializeで行う。
SetGrazeCircle(引数:1) //1:かすり判定の半径
アイテム回収ライン
関数SetItemCollectLineを使う。宣言は@Initializeで行う。
SetItemCollectLine(引数:1) //1:アイテムを回収するライン(y軸)
初期ボム数
関数SetInitialBombCountを使う。宣言は@Initializeで行う。
SetInitialBombCount(引数:1) //1:初期ボム数
残機画像
関数SetPlayerLifeImageを使う。宣言は@Initializeで行う。
SetPlayerLifeImage(引数:5) //1:描画する画像のパス //2:矩形x軸最小値 //3:矩形y軸最小値 //4:矩形x軸最大値 //5:矩形y軸最大値
当たり判定
関数SetIntersectionCircleを使う。宣言は@MainLoopで行う。
SetIntersectionCircle(引数:3) //1:当たり判定の中心座標 x軸 //2:当たり判定の中心座標 y軸 //3:当たり判定の半径
5 ショットの実装
自機ショットを作成する関数があります。それは
CreatePlayerShot01(引数:7) //1:x座標 //2:y座標 //3:速度 //4:角度 //5:威力 //6:貫通力 //7:ID値
これです。勘の良い方なら(ry、この関数には「画像」を指定する引数がありません。
その代わりに、「ID値」なるものを指定しなければならないようです。
公式ヘルプを見ると、「定義済みの画像のID値」とあります。
「定義済みの画像」、つまり画像を先に定義しておかなければならないのです。
画像の定義は別のスクリプトで行います。新しいファイルを作ってください。
場所はplayerフォルダ内ならどこでもおkです。名前も適当に
スクリプトにまず書いてもらいたいのが、これ
#PlayerShotData
これは何か?というと、「#東方弾幕風」←これと同じようなものです。
PCに「このスクリプトは自機画像の定義をしている」ということを伝えるのです。
わかんないなら何も考えずに書きましょう。意味はそんなに重要じゃないですから
次に書くのは画像のパスです。
ShotImage = "画像のパス"
画像のパスは今までどおりに書いておkです。
今回も初期から入ってる画像を流用させてもらいましょう。
ShotImage = "player\Rumia\RumiaShot.png"
あ、そうそう 「;」を忘れてるじゃんって思ってる人もいると思いますが、
別に忘れてるわけじゃなくてこれにはつけないだけですからね。文法ですからね?
次は画像の定義です。
文法はこんな感じ
ShotData { id = 1 rect = (1, 1, 31, 31) render = ADD alpha = 64 angular_velocity = rand(-5, 5) }
これらも;はいりません。
まず id ですね。これはそのまま、CreatePlayerShot01で指定するID値を決めます。
次に rect 。これは画像の矩形を指定します。
render は画像の描画方法です。ALPHA, ADD 等があります。
ALPHA は半透明描画、ADD は加算描画です。詳しくはヘルプへ
加算描画:重なるとどんどん白くなっていく描画方法のこと。
原作では大弾や火炎弾などがこれにあたる。
alpha は透明度を指定します。普通に255だと、他の弾と見間違え易くなるので、なるべく低い値を入れましょう。低すぎると見えませんが
angular_velocity は画像の回転速度です。右回りの速さなので、左回りにしたい時はマイナスの値を指定しましょう。
今回の画像は円いので回転させますが、札などを回転させると違和感があります。
回転させるか否かは考えましょう。
んで、さっきのCreatePlayerShot01に指定したID値を入れると、ちゃんとショットが出来たと思います。
ですが、すごい連射ですね。威力が低め(1とか)でも、結構な威力になってしまっています。
これの解決方法はif文を使うことです。
変数ShotCountとかを用意して、毎フレーム増加させ、
if文で分岐させればできます。例はコチラ
let ShotCount = 0; @MainLoop { if(ShotCount % 5 == 0){ CreatePlayerShot01(GetPlayerX, GetPlayerY, 20, -90, 3, 1, 1); } ShotCount += 1; }
こんな感じで良いんじゃないでしょうか。
ShotCount % 5 == 0 っていうのは、「ShotCountの値を5で割った余りが0」ということ、
つまり「ShotCountが5の倍数のとき」という判定をしているのです。
数値を大きくすれば連射しなくなるし、逆に小さくすればチート威力です。
あえて威力低くして擬似レーザーなんてのも面白いかも
公式ヘルプにも「複雑な挙動の弾はObjShotとかObjLaserで作ってください」って書いてあります。
具体的に言えば、ホーミング弾ですね。その辺は+で説明しようと思ってたり
6 ボムの実装
+1 作成した自機で分岐をするには
GetPlayerScriptNameで自機スクリプトの名前を取得して、それをif文などで分岐させる。会話の分岐などに使える
let PlayerName = GetPlayerScriptName; if(PlayerName == "TestPlayer1.txt"){ //分岐内容1 }else if(PlayerName == "TestPlayer2.txt"){ //分岐内容2 }
+2 特殊な軌道の弾
特殊な軌道の弾は、公式ヘルプにもあるように
「ObjShotやObjLaserを使って実装できます」。
ObjShotには、威力や貫通力を指定できる関数があります。
ObjShot_SetDamage(引数:2);
ObjShot_SetPenetration(引数:2);
この2つですね。これらを使って、
task HomingShot { let obj = Obj_Create(OBJ_SHOT); Obj_SetPosition(obj, GetPlayerX, GetPlayerY); /* 省略 */ ObjShot_SetGraphic(obj, 2); //ここには定義済みのID値を入れます ObjShot_SetDamage(obj, 4); ObjShot_SetPenetration(obj, 1); while(!Obj_BeDeleted(obj)){ yield; } }
このwhileの中で角度を敵の方向に毎フレーム調整すればホーミング弾の出来上がり。
- 最終更新:2016-04-11 04:55:23