【HSP】へにょりレーザー (改) テスト【STG一部】

【HSP】へにょりレーザー (改) テスト【STG一部】

わざわざ後で値を変えられるように変数に代入していた数値を書き換えたらバグったのでそこを修正。
あと、絶対時間で動き操作しようとすると面倒くさかったので、それぞれの弾 (レーザーの一部) が発生してからの時間 (相対的時間) で制御できるよう修正しました。
あと、あんまり変わらんかもですが、三角関数の値を出すところで、わざわざパイを足してからやっているか所を、三角比の公式使って書き換えたので本当はちょっぴり早くなっているはずです。(他の所で遅くなってると思うけど…orz)
弾速と方向を定数にしてしまいました。
敵の表示は仮です。
ループ内のそれぞれの処理をすべてサブルーチンにしました。

// モジュール
#module "kerupani_f"
; 角度を 0~2π の範囲に変換する関数
#defcfunc limit_pi double _p1
return (0.0+_p1)\(M_PI*2)+M_PI*2
#global
// スクリーン準備/画像読み込み
buffer 1,10,256
color : boxf
color 255,255,200
circle 0,0,9,255,1
color 255,255,127
repeat 2
circle cnt,cnt,9-cnt,255-cnt,0
loop
screen 0
// 変数準備
; 処理に使う変数 (システム)
dim timer,1 // ループの中で、時間を図るタイマー
; ユーザー指定する変数 (長方形→位置/サイズ)
ddim s_pos_x,16 // 長方形の中心のX座標
ddim s_pos_y,16 // 長方形の中心のY座標
ddim s_pos_s,16 // 長方形の角度
ddim s_pos_s2,16 // 長方形の見かけの角度
ddim s_size_x,16 // 長方形のXサイズ
ddim s_size_y,16 // 長方形のYサイズ
ddim s_speed,16 // 長方形のスピード
ddim s_speed_s,16 // 長方形の進む角度
dim s_f,16 // 各オブジェクトの有無
dim s_timer,16 // 各オブジェクトごとのタイマー
; 処理に使う変数 (位置/サイズ→頂点座標)
ddim l_a,1 // 長方形の中心から頂点までの角度 (回転前)
ddim l_s,4 // 長方形の中心から頂点までの角度 (回転後)
ddim l_l,1 // 長方形の中心から頂点までの距離
dim l_x,4 // 各頂点のX座標
dim l_y,4 // 各頂点のY座標
; 処理に使う変数 (元画像→頂点座標))
dim l_x2,4 // 各頂点のX座標
dim l_y2,4 // 各頂点のY座標
; その他使う変数
// 音声読み込み
; 作成中
// 他読込み
repeat 16
s_size_x(cnt)=10.0
s_size_y(cnt)=16.0
loop
// ゲームメインループ
gmode 2
*main
redraw 0
// 処理
; 発生処理
gosub *item_init
; 値変更処理
gosub *item_set
; 移動処理
gosub *item_move
// 表示
gosub *item_draw
// システム
gosub *item_system
redraw
await 15
goto *main

*item_init // 実際の発生処理を書き込む
; 敵
; 作成中
; レーザー
repeat 16
if 60<=timer & timer<89.779848 {
if int(0.537276*(timer-60))=cnt {
s_f(cnt)=1
s_timer(cnt)=timer
s_pos_x(cnt)=234.0 // ちょうどいい位置
s_pos_y(cnt)=240.0 // ちょうどいい位置
s_pos_s(cnt)=M_PI/2
s_pos_s2(cnt)=0.0
s_speed(cnt)=8.596417 // ちょうどいい速度
s_speed_s(cnt)=-0.05 // ちょうどいい角度
}
}
loop
return

*item_set // 実際の移動処理を書き込む
; 敵
; 作成中
; レーザー
repeat 16
if s_f(cnt)=1 {
if 300<=(timer-s_timer(cnt)) & s_speed_s(cnt)<-0.0 {
s_speed_s(cnt)+=0.001 // ちょうどいい角度
}
}
loop
return

*item_move // 移動処理を行ってくれるシステム
; 敵
; 作成中
; レーザー
repeat 16
if s_f(cnt)=1 {
s_pos_x(cnt)+=cos(s_pos_s(cnt)+s_speed_s(cnt))*s_speed(cnt)
s_pos_y(cnt)+=sin(s_pos_s(cnt)+s_speed_s(cnt))*s_speed(cnt)
s_pos_s(cnt)+=s_speed_s(cnt)*2
s_pos_s2(cnt)+=s_speed_s(cnt)*2
}
loop
return

*item_draw // 表示を行ってくれるシステム
; 背景
color : boxf
; アイテム
; 作成中
; 自機
; 作成中
; 敵弾
; 作成中
; レーザー
repeat 16
if s_f(cnt)=1 {
l_l=sqrt(s_size_x(cnt)*s_size_x(cnt)+s_size_y(cnt)*s_size_y(cnt))/2
l_a=atan(s_size_y(cnt),s_size_x(cnt))
#if 0 // 処理方法変更スイッチ ; 処理法1
l_s=limit_pi(s_pos_s2(cnt)+l_a),limit_pi(s_pos_s2(cnt)-l_a+M_PI),limit_pi(s_pos_s2(cnt)+l_a+M_PI),limit_pi(s_pos_s2(cnt)-l_a)
if cnt=0 {
l_x=int(s_pos_x(cnt)+cos(l_s(0))*l_l),int(s_pos_x(cnt)+cos(l_s(1))*l_l),int(s_pos_x(cnt)+cos(l_s(2))*l_l),int(s_pos_x(cnt)+cos(l_s(3))*l_l)
l_y=int(s_pos_y(cnt)+sin(l_s(0))*l_l),int(s_pos_y(cnt)+sin(l_s(1))*l_l),int(s_pos_y(cnt)+sin(l_s(2))*l_l),int(s_pos_y(cnt)+sin(l_s(3))*l_l)
} else {
l_x=l_x(3),l_x(2),int(s_pos_x(cnt)+cos(l_s(2))*l_l),int(s_pos_x(cnt)+cos(l_s(3))*l_l)
l_y=l_y(3),l_y(2),int(s_pos_y(cnt)+sin(l_s(2))*l_l),int(s_pos_y(cnt)+sin(l_s(3))*l_l)
}
#else ; 処理法2
l_s=limit_pi(s_pos_s2(cnt)+l_a),limit_pi(s_pos_s2(cnt)-l_a),limit_pi(s_pos_s2(cnt)+l_a),limit_pi(s_pos_s2(cnt)-l_a)
if cnt=0 {
l_x=int(s_pos_x(cnt)+cos(l_s(0))*l_l),int(s_pos_x(cnt)-cos(l_s(1))*l_l),int(s_pos_x(cnt)-cos(l_s(2))*l_l),int(s_pos_x(cnt)+cos(l_s(3))*l_l)
l_y=int(s_pos_y(cnt)+sin(l_s(0))*l_l),int(s_pos_y(cnt)-sin(l_s(1))*l_l),int(s_pos_y(cnt)-sin(l_s(2))*l_l),int(s_pos_y(cnt)+sin(l_s(3))*l_l)
} else {
l_x=l_x(3),l_x(2),int(s_pos_x(cnt)-cos(l_s(2))*l_l),int(s_pos_x(cnt)+cos(l_s(3))*l_l)
l_y=l_y(3),l_y(2),int(s_pos_y(cnt)-sin(l_s(2))*l_l),int(s_pos_y(cnt)+sin(l_s(3))*l_l)
}
#endif
l_x2=0,int(s_size_x(cnt)-1),int(s_size_x(cnt)-1),0
l_y2=cnt*s_size_y(cnt),cnt*s_size_y(cnt),(cnt+1)*s_size_y(cnt)-1,(cnt+1)*s_size_y(cnt)-1
gsquare 1,l_x,l_y,l_x2,l_y2
}
loop
; 敵表示
; 作成中
color 255,127,127 : circle 234-10,240-10,234+10,240+10 ; 仮
;
return

*item_system // 一番根本的なことを行うシステム
timer++
return

あと、前回言っていた?ように、円の軌道の出し方を。
1フレームごとに、図のように移動し、向きも変えたとします。
これは中学生~高校生ならできますよね。
余弦定理を使い、Lの長さを式にすると、(HSPの式っぽく書いています。それっぽく)
L*L=r*r+r*r-2*r*r*cos(θ)
L=sqrt(2*r*r*(1-cos(θ)))
これで移動速度は出ました。
次に、進む角度と、物体が向きを変える角度を出します。
小学生で習ったことを使うんですよ?
まずは移動の方から
角度θの頂点から辺Lに補助線を下すと、
θ/2、π/2、?の角度の三角形になります。(?の値はすぐ求まりますが、必要ないので省きます)
外角の定理より、角度?の外角はθ/2+π/2です。
元いた場所で円と接する線を基準にするなら、90度引けばよいので、θ/2になります。
ここで気を付けなければならないのが、初期の角度はこの角度でいいとして、2回目以降はもともと角度が加わっているので、その分も動かさなければいけません。
なので、2回目以降は倍してθづつ変えます。
物体の動く角度は、
元いた場所で円と接する線と、のちの場所で円と接する線と、辺Lで囲まれた三角形を見てやれば、またまた外角の定理 (あと、2等辺三角形なことを利用するのですが、その証明は省略) でθと求まります。
算数・数学ってちょっと覚えれば全部いけちゃうんでほんとに面白いです。
(実は余弦定理使う場所は覚えていながら式忘れてた…orz 文系の人と逆パターン?)
これからも数学・プログラミング、ともに大切していきますよ。(無論ほかにも大切にするものあるけど)
ではまたいつかお会いしましょう~。
↓クリックしてね~