HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
1013
ねこ地雷の作り方19解決


ねこ

リンク

2020/10/13(Tue) 00:56:37|NO.91598

▼:近づいたら追尾
■:跳ね返り
●:追尾
となっています。赤い場所に1つでも敵が来たらxyに150範囲の中にいる敵を消し、5秒後に再び敵が現れるプログラムを作りたいです。何かヒントになるサイトを教えていただいたり、皆様の知識をお貸しいただければと思います。まだプログラミングを始めたばかりで至らない点などあると思いますが、どうぞよろしくお願いいたします。


title "変わる"
wx=600:wy=600 ; 画面サイズ
screen 0,wx,wy
color 0,150,150:boxf 0,0,600,600


mx=400:my=300 ; プレイヤーの座標
msp=4 ; プレイヤーの移動スピード
ms=20 ; 衝突判定円の半径
cx=500:cy=500 ;●の座標
ex=50:ey=50 ; ▼の座標
frame=0

;■
kx = 50:ky = 250;初期位置XとY
dx = 3:dy = 3 ;移動量XとY

;120秒間
countermax=120*60
counter=1

*game1
redraw 0 ; 画面更新開始
color 0,150,150:boxf 0,0,800,800

;自機
stick key,%11111 ; キー入力
;limit p1,p2,p3(一定範囲内の整数を返す) 対象となる値,最小値,最大値
;mx=400:my=300 プレイヤーの座標 :msp=4 移動量
;wx=800:wy=600 画面サイズ
if key&1 : mx=limit( mx-msp, 0, wx ) ; 左移動
if key&4 : mx=limit( mx+msp, 0, wx ) ; 右移動
if key&2 : my=limit( my-msp, 0, wy ) ; 上移動
if key&8 : my=limit( my+msp, 0, wy ) ; 下移動
pos mx-ms,my-ms
color
mes "自"


;●
;abs=整数の絶対値を返す(例: -5や+5は5) ;dist=●と自の距離をおく変数
;ms=22 衝突判定円の半径
dist=abs(cx-mx)+abs(cy-my) ; 敵との距離を簡易的に求める
if dist<(ms*2) : goto *gameover ; 衝突していたら*gameoverへ

;新しい座標=aline(現在の座標,追いかける座標)
cx=alien(cx,mx) ; ●のX座標を動かす
cy=alien(cy,my) ; Y座標を動かす


;▼
dist=abs(ex-mx)+abs(ey-my) ; 敵との距離を簡易的に求める
if dist<(ms*2) : goto *gameover ; 衝突していたら*gameoverへ
;▼と自機の距離
;sqrt=ルート(平方根)値を返す
if sqrt( (ex-mx) * (ex-mx) + (ey-my) * (ey-my) ) < 150 {
ex=alien1(ex,mx) ; 敵のX座標を動かす
ey=alien1(ey,my) ; 敵のY座標を動かす
}else{
ex=ex ;敵のX座標を動かさない
ey=ey ;敵のY座標を動かさない
}


pos 400,400:font "MS ゴシック",50:color 255,0,0:mes"・" ;地雷

;■
dist=abs(kx-mx)+abs(ky-my) ; 敵との距離を簡易的に求める
if dist<(ms*2) : goto *gameover ; 衝突していたら*gameoverへ
kx + dx
ky + dy
;画面外へ出たら方向転換
if(kx < 0 | kx > 570) {
dx *= -1
}
if(ky < 0 | ky > 570) {
dy *= -1
}
pos kx - 8 , ky - 8 ;サイズが60x60なので、xとyからそれぞれ-30を引いてあげることで、
 ; X,Y座標を中心として文字が描画される
color 255,255,255:gmode 4,0,0,256 ;画像背景の透明化
color
mes "■"


;●
gsel 0
pos cx-ms,cy-ms
color 255,255,255:gmode 4,0,0,256 ;画像背景の透明化
color
mes "●"


;▼
gsel 0
pos ex-ms,ey-ms
color 255,255,255:gmode 4,0,0,256 ;画像背景の透明化
color
mes "▼"


;タイマー
color 0,0,0
pos 0,570:font"MS ゴシック",30:mes "制限時間:"+(counter/60)

redraw 1 ; 画面更新終わり
await 1000/60 ; 1/60秒で画面を更新
if countermax<=counter{
gosub *gameover
}
counter++ ;カウンターの値を常に増やす
frame++ ; フレームを進める
goto *game1 ; 繰り返す


*gameover
; GAME OVER時の処理
font msgothic,80
color 0,0,0:pos 130,300
mes "GAME OVER"
redraw 1
stop

;●
#defcfunc alien int value1, int value2
; 敵が追いかけてくる関数
csp=2 ; 敵の移動スピード
res=limit( value2-value1, -csp, csp )
return value1+res

;▼
#defcfunc alien1 int value3, int value4
; 敵が追いかけてくる関数
esp=2 ; 敵の移動スピード
res=limit( value4-value3, -esp, esp )
return value3+res



この記事に返信する


んさーぷの熊

リンク

2020/10/19(Mon) 01:11:16|NO.91657

長文失礼します!!

地雷に触れた敵は、復活した時、どこに現れますか?
地雷は一度作動したら消えますか?

地雷が消えないなら、敵が地雷の位置に復活しては地雷でまたすぐに消えてしまいます。
また、敵が復活した場所に自機がいる場合も考えられます。
以上の問題が解決し、地雷について仕様が明確に決まったら、

まず敵が「消える」ことについて。
敵は今、「自身の座標」の情報のみを持っています。(exとか、cyとかの変数のこと)
地雷を実現するなら、これに加えて、「存在しているか」という情報を持つ必要があります。

変数は、それぞれの敵がcf,ef,kfを持っているとして。
これらが、
0ならばそいつは存在していない。
0以外ならば存在している。
と定義します。

地雷に当たったら、消えればいいです。(cf=0等すればいいですね)

「消える」って、どういう事でしょう。
あなたがスクリプトエディタから、敵に関する一切の記述を消して仕舞えば、敵はいなくなりますね。

「消えた」という事です。

ループの中で毎回実行される処理から、敵に関する処理を外して仕舞えば、敵はいなくなります。
if分を使えます。

hspのifは、0を「偽」、それ以外を「真」として、
与えられた値が真の場合のみカッコの中を実行します。

条件式も計算結果として真か偽(1とか0)を返します。
ifはその値を見てカッコの中を実行します。
いつも書いている条件式をmesなどで表示させてみると分かります。

話が逸れました。

ifはこう書けます。
if (cf) {
cfに関する処理(描画、移動等)
}

こうする事で、cfが0になればcの敵は消えます。

当たり判定の式は、書けそうですね。

復活までのタイマーですが、
例えばet、ft、ctという変数を作ります。
ここに復活までの時間を設定して、ループ毎に減らしていけばいいですね。
0になったらef=1とかすれば敵は出てきます。

ここまでで、同じようなことがe,c,kの敵に対してそれぞれ記述されていると思います。

合理的じゃないですね。
まとめられます。

同じようなことを何回も行うなら、配列変数とforeach〜loopが便利です。

敵はみんな「座標」と「消えてるか」と「復活までの時間」を持っているので、それらを
dim enemy_x,敵の数
dim enemy_y,敵の数
とかやって、全部配列に置き換えてしまいます。
マイナンバー制度みたいなイメージですね。
おい敵3番!時期に衝突したか!「してません!」
どっちかっていうと囚人?

でも、それぞれの敵は動作が違います。

敵の種類を定義します。
タイプ0:追尾
タイプ1:近づくと追尾
タイプ2:跳ね返り
それぞれの処理をifとかswitchとかで書きます。

if タイプ0なら
追尾する
if タイプ1なら
近づいてきたら追尾する
if タイプ2なら
とにかく跳ね返り続ける

そして、全てにおいて実行する必要のある処理を書きます

⚪時期に当たったらゲームオーバー
⚪描画処理
などなど

こいつらをforeach〜loopで括ってやればいいですね。
もちろん、「消えている」状態なら、その回はcontinueで飛ばすかして、実行しません。

こうすれば、pcスペックの許す限り、幾らでも敵を増量できます。
敵のパターンを増やすにしても、固有の動きについてだけ書けば、
後は何の変更もいりません。

長文失礼しました!!



ねこ

リンク

2020/10/19(Mon) 18:13:13|NO.91660

んさーぷの熊さん

回答していただきありがとうございます!

>地雷に触れた敵は、復活した時、どこに現れますか?
地雷は一度作動したら消えますか?
地雷は最初だけです。それ以降は出てきません。
地雷によって敵が消えた場合、5秒後に初期位置に再び出現させようと思っています。

>変数は、それぞれの敵がcf,ef,kfを持っているとして。…
cf=1や0で敵の有無フラグを作ってみました。下記の書き方で合っていますか?
if(cf=1){
gsel 0
pos cx-ms,cy-ms
color 255,255,255:gmode 4,0,0,256 ;画像背景の透明化
color
mes "●"
}

地雷に当たった時に消したいので地雷がある(400,400)の座標を使って
dist=abs(cx-400)+abs(cy-400)
if dist<(*2) :cf=0
とすればよいのでしょうか?それともjx=400,jy=400と表すべきですか?

地雷の当たり判定は下記の形でしょうか?
if sqrt( (cx-400) * (cx-400) + (cy-400) * (cy-400) ) < 150 {
cf=0
}

間違いだらけかもしれません。すみません…

>復活までのタイマーですが、…
ct=5(5秒経つ)として…すみません、どうやって消えた敵を5秒後に出現させられるかわかりません。理解力がなくすみません。細かく教えていただけると嬉しいです…。

>同じようなことを何回も行うなら、配列変数とforeach〜loopが便利です。
確かにコンパクトに済みますね…
時間があれば訂正したかったのですが、まだ追加でプログラムを書かなければいけないのと卒論の期限が残り2週間を切っているため、今の形式で進めていこうと思います。
丁寧に説明していただきありがとうございます。

再度ご教授よろしくお願いします。



んさーぷの熊

リンク

2020/10/19(Mon) 23:38:21|NO.91661

地雷が最初だけなら、地雷が一度作動したら消えなければならないので、
地雷があるかどうかの変数、例えばjfをcfとかの要領で作るといいかと。

敵の消える処理は、それだと表示は消えても、移動や当たり判定の処理は生きてしまいます。
見えない敵の完成です笑
消えたと思ったら実は寄ってきてて突然ゲームオーバーになっちゃうので、
そのif文の中に、その敵の移動や当たり判定の処理も入れるといいです。

すみません、地雷の当たり判定飛ばしましたけど分かりにくいですねこれは。
>>赤い場所に1つでも敵が来たらxyに150範囲の中にいる敵を消し
ということなので、
「敵が地雷に当たったか」
という判定と、
「敵がxy150の範囲にいるか」
という二つの判定をする必要があります。

赤い点と敵が接触したかの判定は、(*2)というのは、タイプミスか何かですかね。
適当な値を入れたら、それで、それっぽく動くと思います。
>>地雷の当たり判定は下記の形でしょうか?
それだと半径150の円で当たり判定になりますね。「xy150の範囲」がそういう意味でしたら、
それでいいと思います。
(150×150の正方形かと思いました。矩形の当たり判定であれば、調べたらたくさん出てくるかと。)

で、k,c,eそれぞれについて、地雷に当たったかの判定を行い、
どれか当たっていれば半径150の範囲の敵を消すので、

if kceいずれかが地雷と接触 {
kが半径150以内にいるなら消す
cが半径150以内にいるなら消す
eが半径150以内にいるなら消す


という具合に書くことになりますかね。

配列とかサブルーチン使うと見やすくなるんですけど直すの面倒ですよね笑

「地雷の座標を変数で管理するか」というのは、
後々地雷を移動させたりなんだするのであれば、変数でやったほうがいいですけど、
位置固定なのであれば、絶対に必要ということはないです。「良いプログラムではない」程度で。

タイマーは、敵が地雷で消える時に、用意した変数(ctとか)に、60fpsなら5s*60fpsで300と設定して
1フレーム毎に1減らして、0になれば復活って感じでいいんじゃないでしょうか。

私が人に物を教えるようなことは恐れ多いなと、なんだか今になって強く思い始めています笑
色々と偉そうに言ってしまってすみません・・・

時間がないみたいですね、頑張ってください!



ねこ

リンク

2020/10/20(Tue) 03:39:15|NO.91662

んさーぷの熊さん

回答していただきありがとうございます!

> 見えない敵の完成です笑
試しに地雷に直接当たったら敵を消す動作を行いましたが、敵が消えたにもかかわらずGAME OVERになったのはやはり見えないだけで敵は存在していたんですね…難しいです…。

> そのif文の中に、その敵の移動や当たり判定の処理も入れるといいです。
下記のやり方で実行しましたが表示されませんでした…どこを訂正すればいいのでしょうか。
;地雷
if(jf=1){
pos 400,400:font "MS ゴシック",50:color 255,0,0:mes"・"
if(cf=1){
sqrt( (cx-400) * (cx-400) + (cy-400) * (cy-400) ) < 150
}
}

> すみません、地雷の当たり判定飛ばしましたけど分かりにくいですねこれは。
こちらこそ理解が足らずすみません…ありがとうございます。
(*2)はタイプミスですね。申し訳ないです。

> if kceいずれかが地雷と接触 {
kが半径150以内にいるなら消す
cが半径150以内にいるなら消す
eが半径150以内にいるなら消す

下記のやり方で合っていますでしょうか…。

if sqrt( (cx-400) * (cx-400) + (cy-400) * (cy-400) ) < 150 || sqrt( (ex-400) * (ex-400) + (ey-400) * (ey-400) ) < 150 || sqrt( (kx-400) * (kx-400) + (ky-400) * (ky-400) ){
if sqrt( (cx-400) * (cx-400) + (cy-400) * (cy-400) ) > {
cf=0
if sqrt( (ex-400) * (ex-400) + (ey-400) * (ey-400) )>150{
ef=0
}if sqrt( (kx-400) * (kx-400) + (ky-400) * (ky-400) )>150
kf=0
}
}

> タイマーは、敵が地雷で消える時に、用意した変数(ctとか)に、60fpsなら5s*60fpsで300と設定して
fspとは秒のことでしょうか?それとも変数ですか?すみません、下記のプログラムしか思いつきませんでした…
for(ct=300){
5s*60fps
ct--
}


> 私が人に物を教えるようなことは恐れ多いなと、なんだか今になって強く思い始めています笑
とんでもないです。わからないまま期限がどんどん迫って本当に困っていたので助かりました。おかげさまで今とても救われています。ありがとうございます。

正しい書き方がわかりません…どうか書けば正解なのでしょうか…答えをそのまま書いていただいて説明していただくことはできますか?せっかく説明していただいてもなかなか理解できずにいて時間をとらせてしまい申し訳ないです。心に余裕がなくすみません…。
再度教えていただきたいのでどうかよろしくお願いいたします。



wl

リンク

2020/10/20(Tue) 23:00:09|NO.91664

ねこさんのを改造して、動くスクリプトをつくりました。

http://whitecats.dip.jp/up/download/1603202070/attach/1603202070.zip

諸事情により今ちょっと時間がないのでファイルだけ上げますね。

地雷実装.hspがそれです。
改造版は、配列とか使って複雑になってるやつです。
移動方式を変えて2種類入れました。
デバッグあまりしてません。



wl

リンク

2020/10/20(Tue) 23:01:09|NO.91665

わすれてました。合言葉「hsp」です。



んさーぷの熊

リンク

2020/10/21(Wed) 20:14:45|NO.91669

あっ名前かわってましたね・・・wlです。すみません。
質問時と名前分けようと思ってたら早速失敗しました笑
慣れないことするもんじゃないです。

>>おかげさまで今とても救われています。
私がなにか力になれるのでしたら、分かることは教えます!
ただ、あまり分かってないので変なこと教えてるかもしれません。教えてたらすみません。

>>せっかく説明していただいてもなかなか理解できずにいて時間をとらせてしまい申し訳ないです
大丈夫です。説明が悪いのが大きいと思いますし・・・。

アップロードした地雷実装.hspについての説明とかです。

>>下記のやり方で実行しましたが表示されませんでした。
「そのif文」というのは、敵を非表示にするifのことです。
敵の表示部分と、移動・判定部分を分けて書いてあるので、まとめてifで括ってしまう必要があります。
cfでやるとこんな感じです。

;● if cf { ;abs=整数の絶対値を返す(例: -5や+5は5) ;dist=●と自の距離をおく変数 ;ms=22 衝突判定円の半径 dist=abs(cx-mx)+abs(cy-my) ; 敵との距離を簡易的に求める if dist<(ms*2) : goto *gameover ; 衝突していたら*gameoverへ ;新しい座標=aline(現在の座標,追いかける座標) cx=alien(cx,mx) ; ●のX座標を動かす cy=alien(cy,my) ; Y座標を動かす gsel 0 pos cx-ms,cy-ms color 255,255,255:gmode 4,0,0,256 ;画像背景の透明化 color mes "●" }

cfが生きていれば
当たり判定
移動
表示

ってかんじです。cfに関する処理は全部入れてしまうということですね。

地雷の当たり判定部分は概ねその通りです!
ただし、爆発に巻き込まれたかどうかの条件式の不等号が逆ですね。
それと、cf=0だけでなく、ct=5*60(復活までのタイマーのセット)も入れる必要があります。
あ、zipに入れたスクリプトにそのまま使わせていただきました。
それと今確認したら、爆発の半径を150から200に勝手に変更してました。火力が欲しいお年頃。

fpsとは、frame per secondのことで、要するに、一秒間に何枚のフレームがあるかってことですね。(多分)
フレームっていうと画面なので、動画の用語なので、使い方おかしかったです。。
結局は、ねこさんのスクリプトだと1秒間に60回ループするので60fpsってことです。
タイマーの値はループ毎に1減っていくので、60を設定することで1秒間掛けて0になります。
例えばs秒にf回更新するなら、f/sがそれですね

タイマーは、初期値を-1にしています。
ループ中で0以上の値になったら、毎回1づつ引いて行って、0になったら復活させて、タイマーの値を-1にします。
別に0のままでいいんですが、0で復活させるので毎回cf=1とかやってしまって気持ち悪いので、
復活のタイミングで1回だけ処理をするようにしようとした結果です。
この処理も気持ち悪いので、何かもっと理に適った方法がある気がします。

あと、msゴシックの名前は「MS(全角大文字) (半角スペース)ゴシック」です。
こちらの環境では、デフォルトでmspゴシックかなんかの等間隔でないフォントが選択されて、
表示位置がずれていました。
自分も最初MS(半角)で指定した気になってました。

それと、勝手に変更した点がもう一つありまして、判定円のサイズを、敵&自機はms、地雷はjsで指定するようにして、
敵と地雷のフォントサイズが一緒だったので、fsで指定するようにしまして、
画像(文字)の中心座標(60*60の画像なら30,30)を、敵&地雷はfs/2、自機は個別にmfsとしました。
ほんとはそれぞれに設定すべき項目なのですが、なんか妥協してしまいました。
多分、もとは画像を表示されてたんですよね。
敵ごとにサイズが違う場合は、それぞれの中心座標変数を作ってやってください。(丸投げ)


改造版1と2は、それぞれ敵の移動方式が違います。自機は一緒です。変え忘れました。
勢いで作ったので入れました。
あまり綺麗では無いし説明もなく分かりにくいので別にいらなければ放っといてください。



ねこ

リンク

2020/10/22(Thu) 00:55:22|NO.91670

んさーぷの熊さん

回答していただきありがとうございます!

USBが破損してしまいパニックになりながら元の状態に戻すのに必死で返事が遅れてしまいました…すみません。まだ修復途中ですが何とかなりそうです。USB以外にバックアップを取ることの重要さを痛感しました。

ほかの方が答えてくださったのかと思いました笑 
私も以前同じことがありました…気にしないでください笑


>>半径を150から200に勝手に変更してました。
全然いいと思います、賛成です笑

たくさん細かく説明していただきありがとうございます。一つ一つのプログラムの意味が理解しやすくなりました。それから卒論発表の説明資料の参考にもなります。ありがとうございます。

>>私がなにか力になれるのでしたら、分かることは教えます!
お忙しい中、時間を割いて教えてくださり本当にありがとうございます。
何としてでも卒業します。
大変恐縮なのですがお言葉に甘えて教えていただきたいことがいくつかあります…
30秒経過したらアイテム(◆)が真ん中あたりを左から右に通過し、もし取れたらー機の色を5秒間変えてその間自機が敵に当たったら敵を消すプログラム(マリオでいうスターをゲットしたときのような無敵状態)、▲薀ぅ佞料寛麌 のどちらかを得ることができるというプログラムです…。自機に当たって消えた敵は地雷と同様5秒後に出てくるように考えています。
それと自機弾の当たり判定もうまくプログラムできません。自機弾に当たった敵は地雷の時と同様です。
下記のプログラムは自機弾やアイテム出現で私なりに考えた追加のプログラムです。下記のプログラムの中には間違いが何個もあると思うので修正していただきながら、んさーぷの熊さんが送ってくださったファイルのプログラムに追加していただければと思います…。
長々とすみません…たくさん質問してしまったので回答にすごく時間がかかると思います、すみません…ぜひ教えていただきたいのでよろしくお願いいたします。


dim bf,10 ;弾丸の有無フラグで0なら無効、1なら有効を意味
dim bx,10 ;弾丸の横軸で0〜800の値を管理
dim by,10 ;弾丸の縦軸で0〜600の値を管理

dim fight ;自機の残機数
dim blast ;自機の爆発カウンタ

;自機の初期化
x=(800-60)/2
y=(600-60)-16
fight=3
blast=0

if(blast==0){
stick key,%11111 ; キー入力
if key&1 : mx=limit( mx-msp, 0, wx ) ; 左移動
if key&4 : mx=limit( mx+msp, 0, wx ) ; 右移動
if key&2 : my=limit( my-msp, 0, wy ) ; 上移動
if key&8 : my=limit( my+msp, 0, wy ) ; 下移動
if key&16:gosub *TamaBirth ;自機弾
pos mx-ms,my-ms:color 255,255,255:gmode 4,0,0,256
color
mes "自"
gosub *TamaDraw
}
else:if(blast>1){
blast-- ;自機の左下のカウンタが減る
color $FF,$00,$00:pos mx,my
if(blast\10<5):mes "※"
}
else(fight){ ;残機数
fight-- ;残機数--
blast=0 ;自機の爆発カウンタ
mx=(600-50)/2 ;自機の誕生
my=(400-50)-16
}

;弾丸の発生
*tamabirth
if(tamaTrigg):tamaTrigg--:return ;弾丸の縦軸(y)から 8 ドット引く
foreach bf ;弾丸の縦軸(y)が画面外に外れたかチェック
if(bf(cnt)==0){ ;画面外に外れた場合は、弾丸の有無フラグに 0 をセット
bf(cnt)=1 ;弾丸の有無フラグに1をセット
bx(cnt)=mx ;弾丸の横軸に自機のxをセット
by(cnt)=my ;弾丸の縦軸に自機のyをセット
break
}
loop
tamaTrigg=8 ;弾の発射間隔
return ;次の繰り返しへジャンプ(TamaDrawのcontinue)

;弾丸の描画
*tamadraw
foreach bf ;foreach p1 変数の要素数だけ取り出す,ループの対象となる変数
if bf(cnt){ ;tamaF 配列から弾丸情報が有効である場所を探す
by(cnt)-=8:if(by(cnt)<-60):bf(cnt)=0:continue
pos bx(cnt),by(cnt) ;弾丸の描画位置を設定(pos)
color 0,0,0:font "HG明朝E",30:mes "・"
}
loop
return  

*meter
msg=""
repeat fight
msg+="自"
loop
x(3)=780:y(3)=(400-20)
font MSGOTHIC,20,1
color $00,$FF,$00:pos x(3),y(3):mes msg
font MSGOTHIC,50
return

;アイテムのフラグとタイマー
itmf=1:itmt=-1
;アイテムの座標
itx=0:ity=300
;アイテム出現
if itmf{
if itmt=30*60{ ;30秒経過したら右から左へ
itx=itx+2 ;x軸に2ずつ移
itmsp=1 ;移動スピード
color mes"◆"
if itx>=wx{ ;画面外に出たらアイテムを消す
itmf=0
}
}
}



んさーぷの熊

リンク

2020/10/23(Fri) 01:26:21|NO.91673

USB元に戻りそうなら良かったです。
バックアップ大事ですよね・・。

ところで、今までスクリプトを見てきて思ったのですが、
ねこさんもしかして、何も分からない所から、いろんなところのプログラムを自力で解読しつつ、
変更したり繋げたりして作ってますか?

なんとなくそんな印象を受けたのですが、違ったらすみません。

hspにしろ何にしろ、最初から大掛かりなものは中々作れないです。
簡単なことから、一つ一つ自分の手で進めていって、理解を深めていくのがいいと思います。
だんだんパターンも掴めてきます。

本当に見当違いであればごめんなさい!

しかし、卒業に必要なのであれば、
そんな悠長なことを言っている時間はありませんね・・・。

本題に戻ります。
>>30秒経過したらアイテム(◆)が真ん中あたり〜ことができるというプログラム

自弾や残機については、何も作ってませんが、取り敢えずここだけ作りました。

あと、私には他人の手本になるようなプログラムは書けません。(今更)
一応動きはしますが、私の力不足もあり、汚いです。
役に立ちますかね・・・。

ここからダウンロードできると思います。
http://whitecats.dip.jp/up/download/1603371035/attach/1603371035.zip
合言葉hsp

流石にこうなってくると、(自弾のことも言っておられたので)敵を個別の変数で管理していたねこさんのスクリプトでは、
多分厳しいので、配列にした方に追加実装しました。

もう、かなり私にとっては難しいことをやっています。

まず最初に、今まで敵を管理していたenm_なんちゃらの配列で、アイテムも管理しています。
アイテムも敵も、発生して、移動して、自機とのみ衝突判定をして、特定の画像を表示するので、同じ扱いにしました。
衝突判定時に、自機がダメージを受けるか、無敵になるかの違いなので。

特定の時間にイベントを起こす(この場合はアイテムの出現)方法として、
「何フレーム目に、どの敵が、どこに、どっちに動きながら現れるか」という表を、
timeTableという名前の配列で作りました。
これを処理する部分を、timerサブルーチンに突っ込みました。

最初からいる敵も、0フレーム目で出現するように予定を組んでいます。

私の作ったのでは、30秒待つのが面倒だったので、確認しやすい様に8秒とかに設定してあるはずです。
8*fpsみたいに書いてあるところを、直していただければそれで動きます。


あと、載せていただいたスクリプトの
爆発カウンタblastというのは、コメントに「自機の左下のカウンタが減る」と書いてありますが、
爆発アニメーションの時間の様です。1ずつ減っていくので、アニメーション自体にも使われています。
if(blast\10<5):mes "※"
と書かれていますが、参考にされたと思われるサイトにある、
if(blast\10<5):mes "※":else:mes "*"
のままでアニメーションするはずです。

あまりスクリプトを書く時間が無い+私の頭が追いつかないので、
時期弾とかは遅くなるかもしれません。
ねこさん自身で何とか出来ませんか・・・。



ねこ

リンク

2020/10/24(Sat) 00:00:54|NO.91678

USBの中身はすべて消えてしまいました(大学4年間の勉強内容も)が、卒論の内容は何とか思い出して書けました…

>>ところで、今までスクリプトを見てきて思ったのですが、…
そうですね、教科書やネットで調べて自分が作りたい内容の資料を集めています…
ただそれだけではだめなので工夫店を5つ加えることが条件になっていまして、今回一番最初に貼り付けてあるプログラムの内容以外に2つ何とか自力で考え工夫点を入れました。
しかしHSPの内容をなんとなくでしか理解しないまま作り続けてしまった結果、んさーぷの熊さんに迷惑をかけてしまいました…本当にすみません。ここまでたくさん親身になって考えて教えてくださり本当にありがとうございました。

>>まず最初に、今まで敵を管理していたenm_なんちゃらの配列で、アイテムも管理しています。
アイテムのプログラムありがとうございます。
実は時間がないのもそうですが先週先生に「配列を使ったほうがよかったが時間がないかこのまま進めよう」と言われて配列で作ったほうがよかったことを知りました…。それだけ配列がどういうものかあまり理解していなかったのです。この文章を書いていて本当に情けないですが時間もないのでなんとか進め続けます。昨日の夜からんさーぷの熊さんが作ってくださったプログラムの解読真っ最中です。頑張ります!

>>あと、載せていただいたスクリプトの…
本当ですね。間違えて削除してしまいました。すみません…。

毎回細かく説明してくださりありがとうございます。
自機弾も考えてみます。



ねこ

リンク

2020/10/24(Sat) 00:58:07|NO.91679

何度も質問してしまいすみません。
お聞きしたいのですが、配列を使わずアイテムの出現を書くことは可能なんでしょうか?
まだ追加しなければならないプログラムがあるのでできれば今の理解度に合わせて配列を使わず書きたいと思っています。
今、んさーぷの熊さんが配列で書いてくださったものをこれから配列が使えるようになるかも知れないとおもいながら理解しようと解読中ですがどうしても配列を完全に理解できないこともあるかもしれません。配列を使わずできるか考え中ですが、その時のために配列で書く以外のことが可能か知りたいです。
焦って文章がおかしいかもしれません…
よろしくお願いいたします。



んさーぷの熊

リンク

2020/10/24(Sat) 15:53:26|NO.91681

>>USBの中身はすべて消えてしまいました(大学4年間の勉強内容も)が、卒論の内容は何とか思い出して書けました…
うわあ・・消えてしまいましたか・・・

>>工夫店を5つ加えることが条件になっていまして、今回一番最初に貼り付けてあるプログラムの内容以外に2つ何とか自力で考え工夫点を入れました。
そういう課題でしたか。配列を使わないほうにアイテムを実装したほうがわかりやすかったですね。

>>昨日の夜からんさーぷの熊さんが作ってくださったプログラムの解読真っ最中です。
すみません、分かりづらいほうに書いてしまって・・・。

>>んさーぷの熊さんに迷惑をかけてしまいました…
いや、そんなに迷惑かかってないので、お気になさらずー
こちらこそ、うまい説明も出来ず、すみません。

>>お聞きしたいのですが、配列を使わずアイテムの出現を書くことは可能なんでしょうか?
可能です。書いてみました。下のリンク「item(非配列).hsp」

>>まだ追加しなければならないプログラムがあるのでできれば今の理解度に合わせて配列を使わず書きたいと思っています。
どんなプログラムも配列なしで書けるわけではありません。
理屈上は可能な場合でも、現実的でない長さになったりしますし。

例えば、自機弾の実装は、配列なしでは厳しいと思います。
あれは、同時に大量の弾丸情報を管理しないといけませんから、配列なしで書こうとすると、
弾丸一つ一つに処理を書くことになります。

アイテムは、出すのが一つだけなので、まだ楽です。
逆に言えば自機弾が同時にいくつも存在することのない仕様なら、なんとかならなくも無いと思いますが。

自機弾や残機(item.hsp)と配列を使わないアイテム(item(非配列).hsp)のスクリプトを書いてみました。
http://whitecats.dip.jp/up/download/1603521386/attach/1603521386.zip
非配列のほうは、確か、確認のためにアイテムの出現を3秒後にしたままです。
相変わらず汚いですが、何かの参考になれば・・・。



ねこ

リンク

2020/10/26(Mon) 03:11:25|NO.91688

んさーぷの熊さん

回答していただきありがとうございます。
返信が遅くなり申し訳ありません。

>すみません、分かりづらいほうに書いてしまって・・・。
配列の知識不足を伝えていなかった私のミスです。今は時間に余裕がないですが卒論を終えたら配列での書き方も勉強し直してみます。プログラムを考えてくださりありがとうございます。

>可能です。書いてみました。下のリンク「item(非配列).hsp」
アイテムの非配列のプログラムを作ってくださりありがとうございます。

>例えば、自機弾の実装は、配列なしでは厳しいと思います。
そうなんですか…弾は出ますが当たり判定ができていないので、この場合当たり判定のみを配列で書けばよいのでしょうか?

非配列で送ってくださった10行目のmfs=30と60行目〜62行目のアイテム取得をした自機のプログラムで、mfsは自機の大きさだと思ったのですが数字を変換しても自機の大きさが変わらなかったので何を表しているのか教えていただきたいのと、61行目の「if mi :…mes "自"」のプログラムは今は文字に置き換えていますが、もともと「celput 5」だったものを無敵の時は「clput 6」の画像に置き換える場合下記のプログラムの書き方でよいのでしょうか?

pos mx-mfs/2,my-mfs/2
if mi : color 255,255,255:gmode 4,0,0,256
celput 6

長時間お付き合いいただいてすみません。
再度ご教授よろしくお願いいたします。



んさーぷの熊

リンク

2020/10/26(Mon) 17:50:58|NO.91691

>>弾は出ますが当たり判定ができていないので、この場合当たり判定のみを配列で書けばよいのでしょうか?
えっ、弾出るんですか。
配列なしで書くのは、描画も厳しいと思ったのですが・・・
配列なしで自機弾情報をどう管理しているのかが私には分からないので、
当たり判定も分かりません。
ただ、座標などの管理に配列を使ってないのでしたら、判定にも必要ないと思いますが。


>>mfsは自機の大きさだと思ったのですが数字を変換しても自機の大きさが変わらなかったので
確認しました。すみません私のミスですね。
mfsは自機の大きさのつもりで作ったのですが、
mes "自" の前に font"MS ゴシック",mfs を入れないといけませんでした。

>>もともと「celput 5」だったものを無敵の時は「clput 6」の画像に置き換える場合下記のプログラムの書き方でよいのでしょうか?
if mi〜というのは、色を変更しているだけです。
このif文は、mes "自"とはつながってません。改行した時点で終わりです。
なので、miが0なら黒、それ以外なら赤が指定された状態で、mes "自"が実行され、文字色が変わります。

celputはcolor関係ないので、単純に、
if mi :celput 6(無敵時):else:celput 5(通常時)
とすれば、画像が切り替わります。
透明色を抜く部分は、if文の外に書く。

color 255,255,255:gmode 4,0,0,256 pos mx-mfs/2,my-mfs/2 if mi :celput 6:else:celput 5



ねこ

リンク

2020/10/27(Tue) 00:41:31|NO.91696

んさーぷの熊さん

回答していただきありがとうございます。

>>えっ、弾出るんですか。
下記のサイトを参考に書いたらできたのですが当たり判定はまだうまくいっていません…
https://blog.goo.ne.jp/masaki_goo_2006/e/380943b8a9f0ecaea0f7f4fb034e6e75

こちらのURLはんさーぷの熊さんのように白猫アップローダーを使いました。合言葉はhspです。弾がでるプログラムを追加しました。
http://whitecats.dip.jp/up/download/1603724880/attach/1603724880.hsp

>>mes "自" の前に font"MS ゴシック",mfs を入れないといけませんでした。
なるほど!ありがとうございます。

>>if mi〜というのは、色を変更しているだけです。
プログラムありがとうございます。if elseで分ければよかったんですね。

上記のURLを確認していただいて私の作るプログラムでも非配列で弾丸の当たり判定をかけそうでしたら教えていただきたいです。
よろしくお願いいたします。



んさーぷの熊

リンク

2020/10/27(Tue) 18:06:52|NO.91698

ねこさんのスクリプトは配列を使っていますよ。

if bf(cnt){ ;tamaF 配列から弾丸情報が有効である場所を探す
自分で配列と書かれているじゃあありませんか笑

配列を使った当たり判定は、前にアップロードしたitem.hspに書いてあるものが使えます。
敵側は配列で管理してないので、分けて書く必要があるのと、2点間の距離を取得する自作関数を使っているので、
そこを置き換えて作れませんか。


//敵機と自機弾の衝突判定 foreach bf //自機弾の数繰り返す if ( bf(cnt) ) { //有効な自機弾なら dist=abs(cx-bx(cnt))+abs(cy-by(cnt)) ; 敵との距離を簡易的に求める if dist<(敵と弾の衝突判定円半径を足したやつ) { //衝突していたら cf=0 : ct=5*60 } } } loop
って感じで、全部の敵で書けば動くと思います多分。

私のほうでも書けたら上げます、遅くなるかもしれません。

あと、自機弾処理の部分のコメントを確認したら、勘違いしていると思われる箇所があったので、訂正しました。

;弾丸の発生
*tamabirth
if(tamaTrigg):tamaTrigg--:return ;長押し中の次の発射までのカウントダウン
foreach bf ;弾丸の数繰り返す
if(bf(cnt)==0){ ;無効な弾丸(使ってないのでそこに新しく作れる)の場合
bf(cnt)=1 ;弾丸の有無フラグに1をセット
bx(cnt)=mx ;弾丸の横軸に自機のxをセット
by(cnt)=my ;弾丸の縦軸に自機のyをセット
break ;一つ作ったのでループから出る
}
loop
tamaTrigg=8 ;弾の発射間隔
return ;メインループに戻る


;弾丸の描画
*tamadraw
foreach bf ;foreach p1 変数の要素数だけ取り出す,ループの対象となる変数
if bf(cnt){ ;tamaF 配列から弾丸情報が有効である場所を探す
by(cnt)-=8:if(by(cnt)<-60):bf(cnt)=0:continue ;弾丸Y座標から8引く、画面外に出たら弾丸を無効にする
pos bx(cnt),by(cnt) ;弾丸の描画位置を設定(pos)
color 0,0,0:font "HG明朝E",30:mes "・"
}
loop
return

ちなみにこれだと弾丸の描画位置がずれるので、中心座標引いてやるといいかもしれないです。



ねこ

リンク

2020/10/28(Wed) 23:35:52|NO.91705

んさーぷの熊さん

>>if bf(cnt){ ;tamaF 配列から弾丸情報が有効である場所を探す
本当ですね、配列使ってました…すみません…。

んさーぷの熊さんが書いてくださったものを見て弾の当たり判定書けました!ありがとうございます。
無事自機から撃たれた弾に敵が当たったら消えました。

弾のプログラム内容を説明修正していただきありがとうございます。

もしご存じでしたらお聞きしたいのですが、画面上に敵が1匹もいなくなった瞬間ゲームクリアの画面にしのたいのですがその場合どう書けばよいのでしょうか。資料を探したのですがうまく見つけられず…。
もし教えていただけるのでしたらご教授いただきたいです。
それから制限時間なのですが2分からスタートして「1:59,1:58,1:57…」とだんだん減っていく表示にしたいです。お忙しいかと思いますがぜひ教えていただきたいです。
よろしくお願いいたします。



んさーぷの熊

リンク

2020/10/29(Thu) 21:28:22|NO.91713

ゲームクリアの画面を、ゲームオーバーと同じようにgotoで飛ばすようにするのであれば、
敵の生存フラグが全て0になったところで飛べばいいと思います。
if cf==0 and ef==0 and kf==0 : goto *clear

カウントダウンの表示は、秒でやるだけなら、制限時間秒数-経過秒数
mes "残り "+(120-(counter/fps))+"秒"
分、秒だと、(制限時間秒数-経過秒数)/60、(制限時間秒数-経過秒数)\60
mes "残り "+((120-(counter/fps))/60)+"分"+((120-(counter/fps))\60)+"秒"
って感じですかね。(動作確認してません)
文字列式と一緒に書いてるので、数式部分は括弧で括って先に数式として計算させないと、
文字列を引いたり割ったりしようとしてエラーになります。



ねこ

リンク

2020/11/2(Mon) 01:39:14|NO.91725

んさーぷの熊さん

回答遅くなってしまいすみません。
何分何秒の表示について考えていましたが60秒からスタートしてしまいうまくいかなかったので120秒の表示にすることにしました。

画面から敵がすべて消えた時の動作もうまくいきました。ありがとうございます。
ゼミの進捗状況が全体的によくないこともあって卒論の期限が延びました。なんとかあと一つ工夫点を入れて完成するので9割は終わりました。今週中には終わりそうです。
ここまでたくさん時間をかけて丁寧に教えてくださりほんとうにありがとうございました。感謝してもしきれません。
本当にありがとうございました。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.91598への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

ONION software Copyright 1997-2018(c) All rights reserved.