したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | |
レス数が900を超えています。1000を超えると投稿できなくなるよ。

【初心者歓迎】プチコンなんでも相談室【質問専用スレ】

1プチコンまとめWiki管理人★:2012/08/25(土) 15:52:47 ID:???
こちらは【初心者歓迎】の【質問専用スレッド】です。
プチコンで分からない事があったら、こちらで質問してください。
知識のある方は、よろしければ質問への回答のご協力をお願いします。
雑談その他は【プチコン総合スレッド】へお願いします。

★これは2ちゃんねるによく似た見た目の掲示板ですが、
ここは2ちゃんねるではなく、プチコンまとめWikiの一部です。お気軽に書き込んでください。
また、不適切な書き込み・他人が不快になる書き込みは削除する場合があります。

★マナーを守って楽しく書き込みましょう!
・質問前に、自分で出来る事は最大限試してみて下さい。きっと上達につながります。
・質問内容はなるべく詳しく書きましょう。
 ×プログラムを書いたんですが動きません
 ○上記のように命令を書いたんですが、「Syntax Error」というエラーが出てしまいます
・質問者も回答者も気持ちよく話を締められるように、解決したら一言お礼をお願いします。
 (質問者からの返答がなく、解決したのかもよく分からない状態になるのは良くないことです)

702名無しさん:2015/03/15(日) 15:35:12 ID:MNK4RpLw
さて、これで一応マウスカーソルは動くのですが、快適には使えないように感じませんか。
それは、なぜなのでしょうか。考えてみると、
本物のタッチパッドは、指を早く動かすとマウスカーソルはもっと大きく動きませんか。
なるほど!本物はそんな工夫をしていたんだなぁと、改めて気づいた気分です。

今のプログラムは単純にタッチ移動量をそのまま使っているので、
何かしら工夫して、数値をそれっぽく加工してあげると良さそうですよね。
次はそこを、自分で考えてやってみてはどうでしょう。

また、先のプログラムにも、説明のために冗長なところがあったりするので
プログラムの流れを見ながら、もっと無駄がなく効率的に動作させるには
どう書けばいいか、とか頭の体操に考えてみるのもいいかも知れませんね。
書き写しミスあればご容赦ください

703名無しさん:2015/03/15(日) 16:03:23 ID:akAEgO3.
なるほど、そういうことか。
わかりやすいかいせつどうもありがとうございました

704名無しさん:2015/03/19(木) 15:14:22 ID:daMam8RI
ホント初心者的な質問なんですが、
NEXTの使い方が良く分かりません。
誰か教えてくださる方よろしくお願いします。

705名無しさん:2015/03/19(木) 18:18:55 ID:MNK4RpLw
NEXT の意味を日本語で解説すると、
「ここまでを、繰り返してください」という意味だと説明できると思います。

NEXTは、FORの対になる命令です。
このように、何かの対になる命令というのは他にもあって、

IF の対が ENDIF
WHILE の対が WEND
REPEAT の対が UNTIL
などの組み合わせがあります。

これらを日本語で例えるとするならば、
様々なカッコみたいなものと考えるのはいかがでしょうか。
"【"の記号を見たら、次に"】"の記号が出てくるまでは
ひとまとまり、みたいに考えますよね。
その途中に"』"の記号が出てきても、
最初の"【"の対になる記号とは違うから、まだ区切りではないと思いますよね。

ですから、最初に出てくる命令と、その対になる命令がある場合は、
2つをセットで覚えると良いでしょう。

FOR命令は、「FOR」の文字に続いて、どれだけ繰り返すのか、などの
繰り返すための条件を指定して書きます。
そして、繰り返したい命令をいくつでも書いて、
「ここに書いたまでの命令を、繰り返すんですよ」という
目印のように書くのが、NEXTです。

706名無しさん:2015/03/20(金) 12:06:36 ID:xZF8KTkw
>>704が気になったので、試しに
GOTO @JP
FOR I=0 TO 10
@JP
NEXT
て書いてみたらエラーにならなかった

普通はエラーになるんだがなぁ

707706:2015/03/20(金) 12:23:55 ID:xZF8KTkw
更にいろいろ試してみた
GOTO @JP
PRINT "START"
FOR I=0 TO 2
PRINT "FOR";
@JP
PRINT "JP";I
NEXT

結果↓
JP0
FORJP1
FORJP2

GOTO @JP
PRINT "START"
FOR I=0 TO -2 '←ループを殺してみた
PRINT "FOR";
@JP
PRINT "JP";I
NEXT

結果↓
JP0


これバグじゃないか?

708名無しさん:2015/03/20(金) 14:43:45 ID:MNK4RpLw
プチコン3号は、中間コードのような仕組みで動いており、
実行前にソースコードから変換されます。
その過程でFOR命令は IF/INC/GOTO の組み合わせに再構築されているのではないか
と推測している方がいらっしゃいました。
GOTOでFORループ内部へ飛び込んでも、逆に飛び出してもエラーになりません。

709706:2015/03/20(金) 15:46:05 ID:xZF8KTkw
てことは

FOR I=0 TO 10 STEP 2
NEXT



I=0                        'FORの初期化相当
@LOOP                     'NEXTのジャンプ先
IF I<=10 THEN I=I+2 ELSE @LOOPEND 'FORのループ実体
GOTO @LOOP                 'NEXTの本体
@LOOPEND                  'FORの終了先

は等価ということ?インデントが崩れてたらごめんなさい

710709:2015/03/20(金) 16:05:42 ID:xZF8KTkw
ああ、更にごめんなさい
解釈されるかどうかだわ

711名無しの厨房:2015/03/20(金) 19:08:46 ID:3XUkIQmg
XSCREEN4を使わずにスプライトかBGを上画面と下画面に同時に表示させる方法はありますか?

712名無しさん:2015/03/20(金) 20:36:51 ID:daMam8RI
705>>分かり易いご返答ありがとうございました。

713名無しさん:2015/03/21(土) 05:07:55 ID:MNK4RpLw
>>709
そう推測されています。


>>711
XSCREEN 2または3で、上下画面が繋がったような動作をさせるには
そういう風に見えるように工夫してプログラムを作る必要があります。

上下画面共に同じ内容のスプライトやBGを用意するなどが必要になるので
XSCREEN 4よりも使えるスプライト数や重ねられるBG枚数が減ったと
感じることになると思います。

714名無しさん:2015/03/23(月) 08:07:37 ID:K6FrvEHw
BGANIMの"XY"の線形補完を連続使用したときの挙動、おかしくないですか?
バージョンは「プチコン3号 v3.1.0」です。
何かご存知の方いましたら教えてください。

----------------------詳細-----------------------
>>689 さんのコメを参考に
十字キー上下左右でマップ移動できるようなコードを作ったんですが、
何度か移動していると、BGの座標が時々ぶっとぶのです。。。
これといって、こったつくりにはしてないので、
コーディングミスの可能性は低いかなぁとおもっているんですが。。。

サンプルプログラム公開ID(KK34PRP)
該当記述→10行目
BGANIM 1,0,-15,BGX,BGY

715名無しさん:2015/03/23(月) 18:40:09 ID:MNK4RpLw
プチコン3号のバグっぽいですね。
「極めて頻繁にBGANIM命令を発行すると、瞬間的にBGの位置がリセットされる」っぽいです。
公式に報告を出しておきました。

あなたのプログラムの場合、とりあえずこの症状を回避するには、
9行目に「VSYNC」と書いてください。
(もし、それでも解消できなければ、要再調査...)

716名無しさん:2015/03/23(月) 19:29:33 ID:K6FrvEHw
>>715さん
回答ありがとうございます。(いつも回答ご苦労様です。)
いずれ、同期を取るためにVSYNCは使用しようと思っていました。
解決策の提示から、公式への報告までご丁寧にありがとうございます。

717sora_suke:2015/03/24(火) 08:46:59 ID:qw98NVmA
アクションゲームでブロックに乗ったとき、下、横から当たった時の
処理がうまく作れませんちなみにブロックはBGで表示させるタイプです

718名無しさん:2015/03/24(火) 16:33:49 ID:MNK4RpLw
現時点の、処理がうまく作れていない状態のプログラムを示して
(文字で書き写す、写真をどこかに上げてURLを貼る、公開キーを出すなど)
その上で質問してくださった方が回答しやすいですので
どうぞご検討ください。

719名無しさん:2015/03/25(水) 00:08:19 ID:MNK4RpLw
他には、こんな方法もあります。

音声を使ってプチコンからPCへ転送する仕組みが作られて公開されていたはずなので、
それを探して使用し、PCからプログラムのソースコードを投稿する。

パソコンが無く、携帯電話やスマートフォンしかなくても、
プログラムをQRコードに変換してプチコンの画面上に表示するプログラムもあるので、
その方法で転送し、携帯電話機からソースコードを投稿する。

・・・うん、やっぱり初心者向けの方法じゃないな。

720mikan:2015/03/27(金) 15:48:31 ID:fK1UWblk
今三号のサンプルプログラムGAME5VSを触って 攻撃のビープ音のあとに 少し時間差で実際に剣の攻撃が行われるように改造を行いたいのですが 276行目に WAIT 24 という風に付け足すと 目的の音のあとに攻撃が行われるという動作にはなるのですが 画面全体が止まってしまうためカクカクした動きになってしまいます 次に VSNYC 24 としてみたり FOR NEXT で空ループをはさんでみたりしても やはり画面全体が止まってしまってうまく行きません。 スプライトのアニメを表示する行を挟んでみたら そのアニメが終わるまで 攻撃のアニメが動かないかなと試してもみたのですが 実際には 挟んでみたアニメが途中で止まるような感じになり これもうまく行きませんでした。
勉強不足で申し訳ないのですが 画面全体の動きを止めることなく 特定のイベントの動作のタイミングを制御するよい方法があるなら教えていただけると嬉しいです。

721名無しさん:2015/03/27(金) 21:49:16 ID:MNK4RpLw
他の人が作った高度なプログラムを読み解くのは、大変な労力が要るものです。
だからこそ勉強になる面があります。見てみましょう。

まず、あなたが言った276行目の付近は、
(262行)@PUNCH というサブルーチンの中だというのは分かりますか。
(263)最初に変数PCHを見ていますね。ひとまず(270)ENDIFまで読み飛ばす
(272)次にDMGを見ています。
変数名から察するに、ダメージを食らっている動作の最中なのかどうかを
見ているものと思われます。食らいモーション中は攻撃できないようにする処理だろう
(273)変数BTを見ています。変数名と、ANDを使うことと、32という数値の使い方から
ボタン操作を見ていると推測できます。Bボタンを押してなければRETURN
(274)変数PCHを操作しています。最初の条件に出てきた変数ですね。
同じサブルーチン内で判定に使う変数をセットする・・・この変数は重要そうです。
(275)音を鳴らし
(276)スプライトを変える。
この行を無効(コメントアウト)にして実行してみると、人間が腕を振りません。
人間の見た目だけを操作していて、剣の操作はしていないようです。
(261)このルーチンは攻撃に関する処理のはずなのに、剣を操作していない。
これは重要なポイントになりそうですね。

(264)変数PCHで判断されるIFの中身を見てみます。
(265)変数Xを設定しています。ここを無効にすると攻撃の時に
一歩踏み込む動作をしなくなります。同時に攻撃終了時に戻る動作も。なるほど。
(266)スプライトの見た目を変える。無効にしてみると人物が
攻撃モーションのまま戻らなくなります。見た目を戻す処理ですね。
(276)で変えた見た目を、この行で戻すまでがセットのようです。
(267)PCHを減らしています。
(268)PCHの値を整えています。
PCHで判断されるIFの中で、PCHを変更しています。
(269)RETURNですから、この@PUNCHサブルーチン自体を戻らせています。ENDIFを待たずに。
変数PCHで判断したIFの中に入ると、これ以降の他の処理をせずに
@PUNCHサブルーチンが終わるのですね。

722名無しさん:2015/03/27(金) 21:50:30 ID:MNK4RpLw
プチコンでは、0がFALSEで0以外がTRUEの扱いになるのは知っていますか。
PCHは減らされて、ゼロ未満にならないようになっています。
(274)でPCHに設定されていたPCHMAXを虫眼鏡マークのボタンから検索してみると、
(92)数値は9に設定され、他に書き換わることは無いようです。

PCHは9から始まり、(263)のIFをTRUE扱いになり、(267)で1ずつ減り、(269)他の処理はしない。
0になると(263)でIFを通らなくなり、他の処理をする。
こういう動きをしていそうだ、ということが分かってきましたね。

このことから、変数PCHはタイマー的な役割も兼ねたフラグの変数だと分かります。
質問には「よい方法を」とありましたが、これがその答えとなります。

時間を決めて、何かをさせたい場合。この場合は「動作を止める」という動作をさせたいわけですが、

●1、その時間を計るための変数を用意して、
●2、その数値を変化させ、
●3、数値が範囲内にある場合だけ、
●4、特別な処理を行う。(攻撃の処理を行わせずに戻るという処理をさせる、など)

こういう手順で動作させることが、ご質問の「よい方法」だと思います。

723名無しさん:2015/03/27(金) 21:51:23 ID:MNK4RpLw
さて、では実際に考えてみましょう。
(274)を無効にしてみると、剣が前に出ず、攻撃できなくなりました。
変数PCHに値を設定させることが、攻撃が出ることに繋がるのですね。
この動作を遅らせるようなプログラムにしてみましょう。

●1、時間を計るための変数として、「PCHWAIT」を使用することにします。
「PCH=PCHMAX」の替わりに「PCHWAIT=24」をおきます。
●2、変数PCHWAITを変化させるために、
「@PUNCH」の下に処理を書き加えていきます。
変数PCHWAITの数値は、例にならって減らすようにしましょう。「PCHWAIT=PCHWAIT-1」
●3、変数PCHWAITの数値が範囲内にあるかどうかを判断するために、
これまた例にならって、「IF PCHWAIT THEN」とENDIFで囲います。
例にならうなら、ついでに「IF PCHWAIT<0 THEN PCHWAIT=0」も書きます。
このへんはコピー&ペーストを利用して書き換えてもいいですね。
●4、この場合に行う「特別な処理」とは、
『変数PCHに値を設定する』こと、ですね。
「IF PCHWAIT==0 THEN PCH=PCHMAX」

最後に、これまた例にならってRETURNを入れて、出来上がりです。
でも、実際に実行して試してみると、何かおかしいです。
人物が攻撃モーションのまま戻らなかったりもします。
なぜでしょう。分かりますか。

724名無しさん:2015/03/27(金) 21:52:23 ID:nsfMp0Nc
人物の攻撃モーションの見た目を設定する命令は、見てきましたよね。
それをもう一度見てみると、変えるスプライト番号の指定は「変数N」になっています。
変数で指定している理由とは・・・。
このサブルーチンは、実は、人間が操作するキャラクターの制御と、
コンピューターが操作するキャラクターの制御を、同時にやっていたんですね。
さっき用意したPCHWAIT変数は1つしか無いのに、両方のキャラクターの制御の時に
弄くられてしまっていたので、変なことになってしまったのです。

でも、元々あった変数「PCH」の書き方をなるべく手本にして書いたのに、
なぜPCHは大丈夫だったのでしょうか。
「PCH」を検索して変数の行方を探ってみると、180行目付近でSPVAR命令との関連が見えてきます。
スプライトが個別に持っている変数と入れ替えて一時的に受け皿のように使うための
変数だったのです。

またまた例にならって、さっき作ったPCHWAIT変数も、同じような扱いになるように
すれば良さそうですね。
考えてみてください。

725名無しさん:2015/03/27(金) 21:53:26 ID:MNK4RpLw
考え方のヒントを出します。SPVAR命令のヘルプを読むことと、
ここで使われている、先頭の文字がVの変数の役割を、変数名で検索して探って考えてみましょう。

さて、それで上手く動きますが、細かいことで言えば、まだあるかも知れません。
ボタンを押すとすぐに人物が攻撃動作の絵になり、剣の動きだけが遅れる感じですが、
攻撃動作の絵自体も遅らせたいとか。
あるいは、攻撃待ちの間にもジャンプや移動ができるのは、自分が思ってるのと違うとか。

しかし、ここまで出来れば、きっとあとは、大きな苦労はしないでできますよね。
他の人の作ったプログラムを見るのにも、少しは慣れたことでしょうし。

726mikan:2015/03/27(金) 23:39:14 ID:fK1UWblk
お忙しい中、わかりやすく丁寧な解説を本当にありがとうございます!
先生の一行一行の解説が本当に宝の言葉に感じます。これだけの示唆に富むありがたい文章を、わざわざご回答いただき本当に感謝の気持ちで胸がいっぱいになりました。
勉強不足でプチコンで0以外がtrueになることも理解していませんでした。動作の確認を予測するために、わざと行をコメントアウトの状態にしてプログラムを確認する方法があることに、目から鱗がおちる思いがしました。今までは数字を大きくしたり小さくしたり変更して、その数字の役割みたいなものを予想していました。自分で触っていたプログラムはこんな感じになっていました(キーKK8NDZM) どうしてこのように タイミングを変更したプログラムを作りたいと思ったかと申しますと ハドソンさまの作られたゲームのシステムの中で 盾の操作がとても楽しいゲームがあったのです。参考動画https://www.youtube.com/watch?v=JYSxdJYwTy0&amp;feature=youtube_gdata_player
そんな盾の楽しいゲームの防御?を再現できたらと思ってサンプルを触っていたのでした! 今は音のあとに攻撃が遅れて動作するようにして 防御を任意に行えるような形を目指しているのですが 行く行くは 攻撃前にモーションのかわりになんらかのエフェクトを追加して そのタイミングにうまくボタンを押したら 防御ができるような シューティングゲームのボムのプログラムを研究して 少しの瞬間だけ攻撃を防げる盾のような動きをするスプライトを追加できるように 先生に解説していただいた文章を研究して頑張りたいと思います!
本当に本当に丁寧な解説ありがとうございます。

727名無しさん:2015/03/28(土) 00:13:52 ID:K6FrvEHw
だれかオラに知恵をかしてくれ!

[やりたい事]
可読性の高いデコーダーを作りたい

[背景]
プチコン3号ではCASEやSWITCH文に相当する命令が無く、
IF,ELSEで記述する場合、ネストが恐ろしいことになってしまい、
コードの可読性が落ちてしまいます。
バージョン310からELSEIFが使えるようになったので
以下のようにコーディングをしてみましたが、
ELSEIF(?)THENの後は改行を入れなければ
構文解析がうまくいかないようです(カッコの対応付けがおかしい?)。
----------ダメなコード例----------
IF (A==1)THEN ANS=XXX
ELSEIF(A==2)THEN ANS=YYY
ELSEIF(A==3)THEN ANS=ZZZ
ELSE ANS=0
ENDIF
------------------------------

自分の尺度で語って恐縮なんですが、
改行を入れてと1条件のデコードを2行にするのはNGで
1行1条件のデコードを行いたいというのがあります。
また、ELSEIFを使用しないで、IFを使用した以下のようなコードもNGです。
理由は条件分岐の実行回数が増えるため、
プログラムが重くなってしまうからです。。。
----------重いコード例----------
RESULT=0
IF (A==1)THEN RESULT=XXX
IF (A==2)THEN RESULT=YYY
IF (A==3)THEN RESULT=ZZZ
------------------------------

いい案が思いついた方、よろしくお願いします。

728名無しさん:2015/03/28(土) 04:33:21 ID:hbYUR6ZU
>>727
気になって調べた。マニュアルと先達は偉大
-----------------
ON A GOTO @END,@a1,@a2,@a3
@a1 ANS=XXX:GOTO @END
@a2 ANS=YYY:GOTO @END
@a3 ANS=ZZZ:GOTO @END
@END

729名無しさん:2015/03/28(土) 08:31:32 ID:MNK4RpLw
>>726
「ゼロ以外はTRUEになる」のは、厳密に正確ではない部分もあると思いますので、
もし期待と違う動作をした時には疑ってみてください。

一部をコメントアウトにして動作確認してみる方法も、
数字を変えて動作確認してみる方法も、どちらも大切ですね。
たとえば「SPCHR N,略」という命令があったとしたら、
「SPCHR N+100,」と書き換えて試してみるとか、
「N=100:SPCHR N,」とか。色々な書き方で試してみると、
理解が深まることもあると思います。

挙げられていたゲームは知らないので、動画を見ても説明を読んでも
いまいちピンと来なかったのですが、
また何か質問があれば答えられる事もあるかも知れません。
(今回の、ヒントもらったけど分かりませんでした!とかでも)
さらに要素を追加すると、今回の部分が邪魔になってくるかも知れませんし、
SPVERを使う今の方法だと、これ以上の機能の追加は厳しそうなので
他の方法にする必要も出てきそうですね。

・・・他の人が作った高度なプログラムは、読み解くのも大変なら
高度な改造を施すのは、もっと大変な面があります。
「うん、一通りある程度、勉強になったな!」と思ったら、そこで切り上げて
自分で最初から作った方が簡単かも知れませんよ、というのもアドバイスです。

730名無しさん:2015/03/28(土) 08:32:41 ID:MNK4RpLw
>>727
「ELSEIF THENで改行が無いと」とおっしゃっているのは、
プチコン3号の構文解析の仕様のせいだと思います。

「ダメなコード例」を順番に見てみると、
1行目のIF THEN は、THENの後が空白ではなく命令が書かれているので、
ブロック型のIF文の書き方ではないと判断されていると思います。
その次のうちにIF文は終わり、と判断されてしまった後で、
2行目で、IF文が無いのに急にELSEIFが出てきて、ダメだと言われます。
THEN(とELSE)の後に何も書かれないまま改行になるかどうか、が
プチコン3号の構文解析がブロックとみなすかどうかの条件だと思います。

判断に使いたい条件が==(完全一致)だけならば、
>>728 のような方法で良いと思います。
プチコン3号では、ラベルと同じ行に命令を書けるようになったので、
ある程度スッキリ書けますね。

こんな工夫した書き方もあります。
REPEAT IF !CHKLABEL("@CASE_"+STR$(A)) GOTO @DEFAULT ELSE GOTO "@CASE_"+STR$(A)
  @CASE_1:  ANS=XXX  BREAK
  @CASE_2:  '2の場合は3と同じ結果にする例
  @CASE_3:  ANS=ZZZ  BREAK
  @DEFAULT:  ANS=0
UNTIL 1
見た目優先の書き方ですね、処理が軽いかどうかは分かりません。
また、もっと柔軟な条件式を使いたい場合は、
こんなような書き方ではきっと無理だと思います。

731名無しさん:2015/03/28(土) 09:00:13 ID:MNK4RpLw
確かプチコンmkIIの時は、ラベル名をいっぱい書き連ねたON GOTOよりも
GOTO "@"+STR$() の方が早かったと思います。
ただし3号では中間言語化されてる方式にと、条件が大きく変わってますよね。
速度を比べてみるのもいいかも知れません。

732名無しさん:2015/03/28(土) 10:49:30 ID:K6FrvEHw
>>728
まずはありがとうございます。確かに格段に見やすく、且つ処理が軽そうです。
ただ・・・気になるのは、ラベル(センシティビティリスト相当)を2回書くというところですね。
ラベル列挙の場合その行が長くなってしまって後々ラベルが
100個 200個・・・って多くなったときにコーディングミスしてしまいそうです。

>>730
かなり最適解に近づいたと思います。
「REPEAT BREAK UNTIL文」を「GOTO @END」にしても動きそうですね。
また、自分がBASIC言語あんまり触ってなくてビックリしてるだけかもしれませんが、
ラベルってこんなにふんだんに使うものなんでしょうか。。?

>>731
mk2つかった事なかったんですが、インタプリタだったんですね。

他にもこんな風に描くともっとスッキリしてて、且つ処理も軽そう!
っていうのがあったらヨロシクおねがします。

733名無しさん:2015/03/28(土) 11:53:51 ID:MNK4RpLw
ラベルをふんだんに使うと言うか、
プチコン3号でswitch的な書き方をする時に、ラベルを多く使う以外に適当な方法が無い
ってのが正しいんじゃないかなーと。
(と言うかC言語でもcaseはラベル扱いだった気が)

プチコン3号でも呼び名だけは「インタプリタ」となってますね。
ま、細かい事はどうでもいいんでしょう、普通は無理に区別する必要が無いことですし。

そんなわけで、「様々な書き方を試してみた結果
 IF文を泥臭く書いた方が早かった!」ということもあり得るので、
本当に速さを気にするなら、つど速度比較のテストをお勧めします。

734名無しさん:2015/03/28(土) 14:01:18 ID:K6FrvEHw
>>733
やっぱそういう言語仕様なんですね。。
私がソフトウェアに疎い人間なんでカルチャーショックだっただけかも。。。
(本職ではverilogやVHDL,といったHDLという言語を使ってます。
verilogのCASE文では直値が列挙される形になっているので違和感を覚えてました。)

735名無しさん:2015/03/29(日) 00:24:00 ID:hbYUR6ZU
100万ループしてみたので報告
--------------------
テスト内容
ループごとに乱数に対応した文字を追加していくプログラム。乱数は0-3と150-153の2種類で試した。
ループ回数は100万回
対象はON(0-3)、IF(0-3)(150-153)、CHKLABEL(0-3)(150-153)、ON+DEF(IF)(150-153)の6パターン
ON(150-153)は現実的じゃないので、代わりにON+DEF手法で調べた
ON+DEFとは外部関数CHKNUMでONで調べる乱数を0-3に修正する方法

処理時間はMAINCNTの差で計測
MAINCNTは実行からのフレーム数を数えるシステム変数(fromマニュアル)
環境は旧3DS、テスト回数は1。
--------------------
結果
処理抜きループ:389
ON:746(0-3)
IF:1055(0-3)1128(150-153)
ON+DEF(IF):2139(150-153)
>>730CHKLABELそのまま:4646
>>730CHKLABEL修正:3397(0-3)
>>730CHKLABEL修正:3784(150-153)
------------------------
単純なONは高速。IFの半分程度の時間で終わった。文字列検索は時間がかかるようだ
しかし任意の数を想定した(150-153)の場合IFが最も速度が早くなった
ON+DEFを使った変換はスタックが増えるせいか6倍程度時間が掛かった
一時文字列(>>730の"@"+STR$)をあらかじめ文字列変数に代入するよう修正すると早くなった
その場合処理時間はONの9倍程度掛かり、文字列が増えると時間も伸びた

ONは条件さえ整えれば高速に動作する。任意の条件だと速度が落ちる
IFは汎用性が高く処理速度も良好。しかし保守は大変
CHKLABELは保守が楽だが相応に処理速度は遅い(IFの5倍)ラベルの文字列が長くなるとより遅くなる

736名無しさん:2015/03/29(日) 00:24:42 ID:hbYUR6ZU
使用したコード
--------------------
@START
RTIME=MAINCNT
TIME=0
TEXT$=""
WHILE TIME<1000000
INC TIME
処理
WEND
PRINT MAINCNT-RTIME
---------------------
処理内容(ON〜GOTOの場合)
I=RND(4,4)
ON I GOTO @0,@1,@2,@3
@0:INC TEXT$+"X":GOTO @END
@1:INC TEXT$+"Y":GOTO @END
@2:INC TEXT$+"A":GOTO @END
@3:INC TEXT$+"B":GOTO @END
@END
----------------------
ON+DEFに使用した外部関数CHKNUM
DEF CHKNUM(NUM)
IF NUM==150 THEN RETURN 0
IF NUM==151 THEN RETURN 1
IF NUM==152 THEN RETURN 2
IF NUM==153 THEN RETURN 3
END

737名無しさん:2015/03/30(月) 00:40:17 ID:MNK4RpLw
「デコーダーを作りたい」という部分がピンと来ていないままなのですが、
仮に、例にあるような、「特定の数値(A)が別の特定の数値(ANS)に対応する」
というだけだとしたら、配列を使うのが、多分これが一番早いと思います。

DIM TBL[ length ]
TBL[1]=XXX
TBL[2]=YYY
TBL[3]=ZZZ
IF A<LEN(TBL) THEN ANS=TBL[A] ELSE ANS=0
配列へのセットは、DATAで書いてREADで行ってもいいし。

でも、こんな単純なデータ置換じゃないからこそ、
switch文をという事だったんでしょうけど。とにかく思いついたので言ってみました。

テストの結果だと、文字列演算がネックの1つになっている印象ですかね。
プチコン3号では文字列の扱いは、内部では配列の管理と共通する部分が
あるような感じだったので、そのあたりを意識すると何か改善のヒントに繋がるかも?
そんな意味では「INC TEXT$+"ほげ"」を連発するようなプログラムの、
流れとか構造自体を何か変えることができれば良いかも知れないですけどね。

738:2015/03/30(月) 17:47:00 ID:TpJ2jeE.
すみません。なぜかセーブが出来なくなってしまいました。セーブ方法は、
save"[名前].txt"です。昨日はこれでできたんですが・・・。
エラーはIllegal function call(SAVE)です。「関数の呼び方が間違っている」です。
これであってるんでしょうか?違ったら返信してください。

739:2015/03/30(月) 17:55:14 ID:TpJ2jeE.
あ、文字数少なくしたらできました。

740名無しさん:2015/03/30(月) 20:51:36 ID:K6FrvEHw
>>735->>736
CHKNUMの使いどころが微妙にわかっていないのでアレですが、
ON+DEFの場合、CHKNUMの中でIFの実行が乱発されるので重くなってるとかないですか?
ON+GOTOは普通に早そうです。。。

>>737
それですわ!ついに解にたどり着いた感。
なるほど。配列の引数をそのまま使って、
それぞれの引数に応じた値を格納しておけばよかったんですねー。
これでIFを連呼する必要なくなりました!

741名無しさん:2015/03/30(月) 21:19:53 ID:K6FrvEHw
>>738
SAVEでエラーでると、すごいこまりますよね。
データ保存したいのにエラーで最初から実行しなおし・・・。
コード汚いですが、以下のようなプログラムでエラー回避しています。

INPUT "ファイルメイ:",FILENAME$
UNKNOWN_STR=0
FOR I=0 TO LEN(FILENAME$)-1
CHKSTR$=MID$(FILENAME$,I,1) '1文字だけ取り出して
SCODE = ASC(CHKSTR$) 'アスキーコードに変換して
IF( (SCODE==45) OR
(SCODE==46) OR
(SCODE>=48 AND SCODE<=57 ) OR
(SCODE>=64 AND SCODE<=90 ) OR
(SCODE==95) OR
(SCODE>=97 AND SCODE<=122) )THEN
'OKの場合の処理(必要なし?)
 ELSE
'NGの場合の処理
PRINT "NG →" + CHKSTR$
UNKNOWN_STR=1
ENDIF
NEXT

IF(LEN(FILENAME$)==0 OR LEN(FILENAME$)>14 OR UNKNOWN_STR==1)THEN
'ファイル名が不正な場合の処理
ELSE
SAVE "TXT:"+FILENAME$, TXTDATA$
ENDIF

742名無しさん:2015/03/31(火) 04:52:46 ID:MNK4RpLw
>>740
なんと本当に数値の対応(だけ)だったのですか。
まさかとは思ったが念のため言ってよかった。。。
「CHKNUMの中でIFの実行が乱発」と言うか、そのCHKNUMの使い方だったら
単純に150を引き算すればいいだけでは・・・と思ってしまうので、
後は、テストコードではなく実際に目的の動作をするプログラムと
実際に扱いたいデータを使って、動作テストや速度テストをやるといいと思います。
これ以上の細かいアドバイスをする場合は、
こっちも、それらを知らないと答えにくいと思います。

743名無しさん:2015/03/31(火) 08:15:57 ID:Iv/KyL5Y
>>740
問題解決したようでよかったです。
なのであとは蛇足になりますが
CHKNUMは処理内部のONに
ON CHKNUM(I) GOTO @0,@1,@2,@3
といった感じで使用しました。
質問については
確かに重くはなりますが、適合すればすぐRETURNしているのでIFで総当たりするよりは処理時間は若干短くなると思います。ELSEIFを使うようなものです。
IFの2倍以上時間が掛かったのはIFとONで実質2回比較しているのに加えて、DEF関数を呼び出す時間のせいですね。
DEFは100万回呼び出して定数値返すだけで750フレーム掛かったので
今回のテストの条件ではDEFの影響の方が大きかったと思います。

744名無しさん:2015/04/02(木) 21:50:55 ID:K6FrvEHw
[ローカル通信での同期について]
リアルタイムにPVPをするようなプログラムの場合、
親機と子機で格納されるデータが異なってしまいます。
おそらく、ローカル通信による情報の取りこぼし結果
ではないかとおもっていますが、うまく同期をとる方法、
ご存知の方いましたらよろしくおねがいします。
-----------------------------
[バージョン] プチコン3号v3.1.0
[サンプル公開ID] VK23QJ4P
-----------------------------
余談ですが、「みんなで守ってナイト」という市販のゲームでも
同様の現象が起きてしまうのを思い出しました。
プチコンうんぬんというより、3DSの仕様なのかも。と思っています。

745名無しさん:2015/04/03(金) 03:38:03 ID:VcJS5JHY
試してみましたが、動きにズレなど特に起こりませんでしたよ。
確実に症状が出る条件や操作方法などありませんか?

746名無しさん:2015/04/03(金) 18:05:04 ID:K6FrvEHw
>>745
確実に症状が出る条件を突き止めるのは難しいですが、
ふたりで1〜2戦しているとほぼ確実に出てしまいます。
上下左右に十字キーをおしつつYボタン操作、Bボタン操作。
等と、常に何かのボタンを絶えず押し続けているような状態。
が一番近いかと思います。

症状として最もわかりやすいシチュエーションとして、
片方は勝利し、ゲーム終了しているのに
もう片方は、まだゲーム終了していない状態になってしまう
ということが挙げられます。
(座標のズレやHPの表示ではわずかの差であるため、
なかなかわかりにくいです。)

747名無しさん:2015/04/03(金) 22:54:17 ID:jOwmrvXY
なるほど手元でも発症しました。
こんな検証コードを書いてみました。

ACLS
BGFILL 0,0,0,24,1,1
SPSET 0,0
MPSTART 2,"HOGE"
@LOOP
VSYNC
B=BUTTON(0,0)
IF B AND 4 THEN DEC X,20
IF B AND 8 THEN INC X,20
SPOFS 0,X,0
GOTO @LOOP

十字ボタン左右でイチゴを左右に動かすだけですが、
位置がズレたり、また位置が合ったり。
注目点は、毎フレームSPOFSを、変数Xの値に基づいて行っているので、
イチゴの位置のズレは、変数の値がズレている事を指すという点です。

これ自体は、プチコン上でのプログラムからでは、
どうしようもない事なのでしょうが、
機械語で動いている、プチコンのシステム側では、
これ以上の工夫はできないのでしょうか。難しい事だろうとは想像できますが、
バグだらけの有様見てると、これもバグかも知れないし。
公式サイトから意見を送ってみても良いと思います。

748名無しさん:2015/04/03(金) 22:56:27 ID:jOwmrvXY
次に、送信側に「MPSET 0,X」を書き加えて、
受信側はBUTTONとINC/DECを無効にした上で「X=MPGET(0,0)」としてみました。
これは、当然ながら、イチゴの位置は一致しました。
そして、受信側のイチゴの動きがカクカクになったのも想定内ですが、
送信側のイチゴの動きも少し鈍くなったように感じました。気のせい?

そこで、これらの問題点を解決する試みとして、
送信側は「B=BUTTON()」としました。
通信上のボタン情報ではなくて、直に手元側のボタン情報を取得することで、
送信側のイチゴの動きの鈍さが改善されたような気がします。

受信側では、「B=BUTTON(0,0)」とINC/DECをそのまま復活させ、
ボタン情報を受け取るようにした上で、
「IF B==0 THEN X=MPGET(0,0)」と書き加えました。
ボタン情報を参照することで、動き出しの素早さや、動き途中のなめらかさを
確保した上で、ボタンを離している時はMPGETで正確な値を得る、
両方の方式の良いところを得ようという作戦です。

これによって、目標だった、動きのなめらかさと変数の値の正確性の点は成功しました。
新たに、受信側のイチゴがときたま一瞬だけ瞬間移動してしまう問題が出ましたが、
この解決方法は・・・どうしたもんでしょう。分かりません。

749名無しさん:2015/04/03(金) 22:59:05 ID:jOwmrvXY
ともかく、通信では、ボタンやスティックといった入力の情報は
全面的には信用せず、参考程度に留めておいて、
重要な判断は、きちんと数値でやりとりして決めた方が良いでしょうね。
さらに、その数値のやりとりも、遅延というのが問題になりそうですね。

たとえば、ほとんど全部の処理を親機だけがやる、とか。
親機は、各子機のボタン状態を取得して、キャラを動かし、当たり判定をして、
子機に結果を通知する。
子機は、通知された結果を元に、キャラを指示通りの位置に表示させるなど
画面を作る。子機はローカルのボタン情報を、キャラの動き出しの反応など
補助の目的だけに使い、当たり判定には口を出さない。など。

・・・なんだか難しいプログラムになっちゃいそうな予感がします!
「ラグ 軽減 プログラムテクニック」とか、それっぽいキーワードで検索して
出てきたページには、『美しくごまかす』と書かれていましたが
(ttp://www.accessgames.co.jp/news/nws_cedec2011_2.html )
その美しいごまかし方を教えて欲しい・・・。
もう少し色んなキーワードで検索してみてもいいかも知れませんね。

サンプルには通信対戦のプログラムは入ってませんでしたっけ。
過去に、ゲームショウだかで展示された対戦格闘ゲームのサンプルを写した動画では
動きがカクカクでした。きっとMPSETだけで確実性を重視していたのでしょうね。
 → youtu.be/wyJyUSDn04E
「子機はローカルのボタン情報を補助の目的に使って、美しくごまかす」
の部分を省くと、きっとこんな風な見た目のゲームになるんだと思います。

750名無しさん:2015/04/03(金) 23:12:36 ID:jOwmrvXY
MPSET/MPGETは整数値のみで、小数点のある数値はダメとのことなので、
注意してくださいね。

751名無しさん:2015/04/03(金) 23:36:39 ID:K6FrvEHw
>>747さんのサンプルコードを併記して公式に報告おくっておきました。

ズレるものはズレるということで・・・しかたないとして。
MPGETという便利そうな関数があるようなので、
ちょっとこの辺使って、親機からデータ引っ張ってこれないか検討してみます。

752名無しさん:2015/04/04(土) 00:00:05 ID:K6FrvEHw
と・・・更新してみたら大量のレスが、読んでから対応考えまふ

753名無しさん:2015/04/04(土) 00:57:31 ID:K6FrvEHw
なるほど。。。参考になります。

とりあえず以下の処理で乗り越えて見ようと思います。
・各自の端末が処理をする。
・ずれは一定かんかくで親機からMPSET,MPGETでとってくる。

MPSET,MPGETは9個までしか変数をもてない点から
変数を送る手立ては何か工夫が必要ですね。

754ヨッキ:2015/04/09(木) 19:06:45 ID:XGIK/ZTk
437のヨッキです。
お礼するの忘れていました。
申し訳ございませんでした。
そして、ありがとうございました。

755名無しさん:2015/04/20(月) 18:33:29 ID:StfxjRhA
3号を使ってシューティングゲームを組みたいと思っていますが、組んでみたところ、
・スケートもびっくりの止まらなさ。
・自機が安地どころか画面外。
・て言うか弾撃たないとシューティングゲームじゃない。
と、問題山積。
プログラムを乗せますので、すごいプログラマの皆様に問題点を指摘、改善策をご指南頂きたいです。

@PLAYING
B=BUTTON(1)
IF B==1 THEN
PCY=PCY-0.5
SPANIM 0,0,-180,PCX,PCY,1
SPSWOW 0
ENDIF
IF B==2 THENPCY=PCY+0.5
SPANIM 0,0,-180,PCX,PCY,1
SPSWOW 0
ENDIF
IF B==4 THEN
PCX=PCX-0.5
SPANIM 0,0,-180,PCX,PCY,1
SPSWOW 0
ENDIF
IF B==8 THEN
PCX=PCX+0.5
SPANIM 0,0,-180,PCX,PCY,1
SPSWOW 0
ENDIF
IF B==256 THEN
SPSWOW 1
SPOFS 0 OUT PCX,PCY
WT=PCY-479
SPANIM 1,0,-30,PCX,WT,3
SPSTART 1
ENDIF
GOTO @PLAYING

0は自機、1は弾です。
PCXとPCYは自機の座標です。
PCYに-479しているのはXSCREEN 4を使って弾が直進するようにするためです。

是非、よろしくお願いいたします。

756名無しさん:2015/04/20(月) 20:22:35 ID:zEjBTUmw
とりあえず「SPSWOW」ではないです。

●なぜ移動が止まらないのか。
3秒間、移動し続けるようにプログラムされているからです。
「SPANIM 0,0,-180,PCX,PCY,1」
の「-180」の意味は、「移動に180フレームかける」という意味になります。
1秒は60フレームなので、180フレームは3秒間です。
▼止まるようにするには
止めるための条件を、例えば「ボタンを離した時」とした場合、
ボタンを離したことを検知して、移動を止めるプログラムを書き加えたり、
現在の「ボタンを押した瞬間、3秒間の移動を開始する」という仕様を止めて
「ボタンを押している間だけ移動させる」というプログラムに
大幅に書き換える。などが考えられます。

●なぜ画面外に移動するのか。
画面外に行かないようにするプログラムが作られていないからです。
何でもかんでも、面倒を見てやるプログラムを作る必要があるんです。
▼画面外に行かないようにするには
まず、スプライト番号0番の自機の位置を知ることから始まります。
たとえば「SPOFS 0 OUT X,Y」と書いたとして、
変数XとYの中身が、自機の位置を指す数値になります。
XSCREEN 4の場合、画面の範囲は、横が0〜319、縦が0〜479です。
変数Xは自機の横の位置、変数Yは縦の位置になっているので、
この数値を0や319の数値と比較するなどして、
「画面外に出て行ってしまっているのか、あるいは出て行ってしまいそうな状況か」
を判断します。そして必要に応じて、「画面の範囲内に押し戻す」ようにすると、
結果として自機は画面の範囲外に行かなくなります。

●なぜ弾が撃てないのか。
発射を「開始する位置」を指定していないからです。
発射ボタンを押すと、弾は現在の位置から移動するようになっています。
▼弾の発射が自機から開始するようするには
弾のスプライトに対して移動させる命令を出す前に、
SPOFS命令を使い、弾の位置を自機と同じ位置や近くの位置に移動させましょう。
あるいは、SPANIM命令自体に、移動する先の位置だけでなく
移動が始まる位置も設定する方法もあります。

757味たむ:2015/05/01(金) 11:59:43 ID:AWRgwqv6
はじめまして、プチコン初心者なんですが、プログラムを学ぶのにおすすめの本やサイトはありませんか?
mkⅡの初心者講座を見てみたのですが、3号には無い命令なども出てきて頭がこんがらがってしまいまして…(^_^;)

758名無しさん:2015/05/02(土) 23:00:07 ID:OcC0RsXo
もともと入っていたマップを作るプログラムのマップ保存と読み込みの
仕組みを教えてください。

759名無しさん:2015/05/02(土) 23:03:14 ID:OcC0RsXo
マークIIのようにマップ用のリソースはないのでしょうか

760名無しさん:2015/05/03(日) 03:32:29 ID:2Y9uFsiU
>>757
そうですね。違うプログラム言語、あるいは 違いがあるプログラム言語の
情報を参考にするには、前提として、何が違うポイントなのかを理解していたり
プログラムの知識全般をある程度知っていたりする必要があると思います。
なので、そうではない場合は、『プチコン3号を解説している』ものを
選んで探したり読むようにすると良いと思います。

その場合で言いますと、
質問の「おすすめの本」は、プチコン3号の公式ガイドブックが
最初に挙げられると思います。この掲示板の下に広告が出ているので
そこをクリックしても良いのではないでしょうか。
↓こちらでためし読みができるようです。
ttp://smileboom.com/special/ptcm3/nindori/2015/03/post.php

それ以外の書籍では、ゲーム情報雑誌「ニンテンドードリーム」や、
プログラム雑誌「日経ソフトウェア」の中で、
プチコン3号の情報やプログラム講座が載っているそうです。
プチコン3号公式サイトのトップページ最下部に、
まとまって紹介されているようですよ。
紙媒体だと、これくらいでしょうか。

次の質問の「おすすめのサイト」は、
公式サイトで、2つの初心者講座を見ることができます。
ttp://smileboom.com/special/ptcm3/beginner/
ttp://smileboom.com/special/ptcm3/nindori/lecturer/
どちらも、今はまだ内容がスカスカですが、のんびり待っても良ければ、
それでもいいかも知れません。

2番目のアドレスの方は、毎週更新する予定だそうですよ。
内容は前述の公式ガイドブックの内容と同じになるみたいです。
本を買わなくても済むかも?
↓こちらも合わせて読むと良いかもしれません
ttp://smileboom.com/special/ptcm3/nindori/2015/03/20151.php

公式が行っている以外のサイトについては、
「プチコン3号 講座」などのキーワードで検索すると良いと思います。
また、この掲示板では過去にあった同様の質問への回答として
>>673  などが寄せられているようですので、参考にしてみてはいかがでしょう。

761名無しさん:2015/05/03(日) 03:37:13 ID:2Y9uFsiU
>>758,759
プチコン3号のファイルは、テキストファイルとバイナリファイルの
2種類しか無いことになっています。画像を保存したファイルも
BGを保存したファイルも、バイナリファイルだという点では同じです。

SYS/SBMAP のプログラムでは、2種類の形式で、作ったマップを
保存することができるようになっていて、
読み込みは、そのうち1種類の形式だけでできるようです。

このプログラムで作られるマップは、

●レイヤー0からレイヤー3までの、4枚のマップを重ねて
作るようになっていますので、4つ分のデータがあることになります。

●さらに、マップ部品の種類毎に、当たり判定などの用途に
応用して使えるような情報を、レイヤー毎に持っています。

それらをふまえて、

保存する形式の1種類目は、
これらのデータを1つのファイルにまとめた形式です。
読み込みができるのは、この形式ですね。
あらかじめ決められた順番でデータが並んでいます。
それについて詳しく知りたい場合は、SYS/SBMAP のプログラムの
中身を読み解いて調べたり、あるいはネット検索で
誰かがどこかで解説したのを見つけられるかもしれません。
(ミーバースで見かけたような?)

もう1つの形式は、
マップ部品の並び順だけを、レイヤー毎に別のファイルにして記録したものです。
ですから、ファイルが4つで1組になっており、
「当たり判定などに使える情報」は含まれていません。
質問にあった「マークIIのようなマップ用のリソース」に近いものと言えます。
この形式のファイルの使い方は、次のようにします。

BGSCREEN 0,64,64  ’BGの広さを調整します
DIM D[64*64]  ’ファイルを読み込む用の配列変数を用意します
LOAD "DAT:MAP_????_L0",D  ’配列変数にファイルを読み込みます
BGLOAD 0,D  ’配列変数の内容をBGにセットします

762味たむ:2015/05/05(火) 12:29:27 ID:AWRgwqv6
>>760
ありがとうございました。これらを参考に勉強してみます。

763名無しさん:2015/05/10(日) 09:50:28 ID:OcC0RsXo
760さんありがとうございます!!
てっきりマップの画像のまま保存するかと思っていました
BGASVEでちがうものに変えてからそれをセーブするのですね

764素人:2015/05/30(土) 13:33:06 ID:CbHczVgk
こんにちは、初心者です!
公式プログラム集のMAZER byこあ/co.aさんのプログラムの最初の6行の
迷路を作っている部分の解釈ですが、横(X)、縦(Y)で30:23でブロック
をおいて迷路ができてますが、数式が複雑で、よくわかりません!
 最初の縦(Y)0行目は、横(X)に一つ目のLOCATEでブロックを一つとばしで
置いて、二つ目のLOCATEで横(X)、縦(Y)で数式で1つとばしで空いてある場所に
ブロックを置いてあるのは、わかりました。
次の縦(Y)からのブロック置いていくプログラム(数式)がよくわかりません!
できれば、わかりやすく、教えてください!

765名無しさん:2015/05/30(土) 19:37:38 ID:Xfsjq2nQ
初代プチコン用のwebページの物ですね?
http://smileboom.com/special/petitcom/pochette-mazer.html

「ブロック置いていくプログラム(数式)」を教えて欲しいという質問ですね。
このプログラムの中でブロックを置く部分と言えば、
  LOCATE X+P%2,Y-(P-1)%2
の部分ですね。
変数Pの値が重要そうなのが、見て分かりますね。
では、変数Pに値を設定している、「P=」な式を見てみると、
  P=I%176<15
  P=P+R*(P<1)
この2つがありますね。これがご質問の要になるに違いありません。

上の式の意味を見てみましょう。
0から190まで1ずつ増える値のIを、176で割った余りの値が、
15未満ならば1、そうでなければ0。という意味ですね。
この式では、変数Pは、0か1の値になります。

この式で決め打ちされている、176と15という数値の意味が気になりますよね。
試しに(プチコン3号で)、
  FOR I=0 TO 190:?I MOD 176<15;:NEXT
を実行してみると、最初と最後が1の連続になり、間に0の連続がある並びになりました。
このことから、この式の意味は、
『迷路の最上段または最下段を作る時は、変数Pの値は1』だろうと読み解きました。

最上段と最下段は、ただの壁で、通路が作られてはいけないという特徴があります。
これは、変数Pの値が1の時は迷路の生成が起こらないように
作られていると考えられますね。

766名無しさん:2015/05/30(土) 19:39:16 ID:Xfsjq2nQ
次に、下の式を見てみましょう。
この式には、変数Rが登場するので、Rに値を設定する式から見たいですが、

その前に、「(P<1)」という部分が気になります。
Pの値は0か1の2種類だけでした。そのPの値が1未満、つまり0かどうかを見ています。
Pの値が0ならば式が成り立ち1に、Pの値が1ならば0になりますね。
つまりこの部分は、『Pの値を反転させている』と解釈できます。
初代プチコンには、論理反転演算子「!」が無かったのですね。

そして、それをRと掛け算しています。
0を掛け算すると、Rの値が何であろうが0になり、
1の場合はRの値がそのまま適用される。すなわちここまでの意味は、
『Pの値が1ならば、Rの値は無効にする。0ならば、Rはそのまま有効にする。』
という意味になりますね。ちょうどIFの条件判断のような動作をさせているのです。
Rはその変数名からランダムつまり迷路生成のキモなのでしょうし、
さっき言った、変数Pの値によって迷路の生成が起こらないようにしている
という動作の部分がここなのでしょうね。

さて では その 有効と無効を切り替えられるRの値について見ましょう。
  R=(RND(2+(Y<3)+L)-L)*(X%30>0)
新たに変数Lが登場しました。これは
  L=X<3
とされていて、Xの値が3未満、つまり0か1か2の時だけ1になります。
Xの値が小さい時だけ・・・? これって、左端の壁かどうかを判別するのと
関係があるのでしょうか。よく見ると、「(X%30>0)」という部分もあり、
迷路全体の広さは横30ブロックですから、これは右端の壁の判別なのかも。
そうなると、「(Y<3)」の部分も気になりますね。

767名無しさん:2015/05/30(土) 19:40:04 ID:Xfsjq2nQ
ここまで書いて力尽きました。ごめんなさい。気力が続きませんでした・・・
ほんのわずかでも参考になれば幸いです。
後日にでも続きが書け・・・ればいいんですけど

768素人:2015/05/31(日) 22:58:23 ID:m0n609bE
765(名無し)さん、わかりやすい解説ありがとうございました。
もう一度、今回の解説を参考にして、プログラムを調べたいと
思いました!大変参考になりました!

769名無しさん:2015/06/03(水) 09:46:28 ID:AWRgwqv6
セーブ時の保存先は必ずデフォルトのフォルダになるのですか?
SAVE命令を使ってセーブするとき、デフォルトで設定してある標準のプロジェクト以外の別のプロジェクトへ保存させることはできませんか?

770名無しさん:2015/06/03(水) 11:21:24 ID:9ITdlX1M
SAVE命令時に、現在のプロジェクトとは別の
ファイル保存先のプロジェクトを指定することが可能なのは
プログラムがスマイルツールとして実行されている時だけだと思います。

PROJECT命令のヘルプの2ページ目も参考にしてみてください。
とても分かり難いですけど・・・。

要するにプログラムが実行されている時の「現在のプロジェクト」だけを
意識すればいいってことだと思います。
「作品を見る」からだと自動的に切り替えてから実行してるよ、とか。

後は、とりあえずファイルは保存しておいて、後でコピーと削除するとか、
ファンクションキーにPROJECT命令を含む一連の操作の命令を登録して
手間を減らすとか。
ちなみに直接ファイルを複製するのは、プチコン3号のメニューから
手動でのみ許されている操作です。
プログラムで行うには、変数やグラフィックページを介して
間接的に行うしかないでしょう。

771アルカリでんちマン:2015/06/07(日) 19:58:10 ID:hTBb9xQA
三角関数について、猿でも分かるくらいで教えてください。

772アルカリでんちマン:2015/06/09(火) 21:40:01 ID:hTBb9xQA
『SIN=COS+4 としたら、COSを9にすると勝手にSINに13が入る』って予想で正しいでしょうか?

773名無しさん:2015/06/10(水) 15:54:11 ID:AWRgwqv6
>>770さん
ありがとうございました。

774素人:2015/06/12(金) 16:42:26 ID:m0n609bE
768の続きになりますが、宜しくお願いします!

プチコン、プログラムリスト集のMAZER byこあ/co.aさんのプログラムで、
6行目のFOR I=0 TO 2 から 13行目、I=X/57+Y/42:NEXTの解釈なんですが、

最初、I=0 で始まり、X=29の座標になりX/57=0.5087と同じくYの値が、Y=21
にY/42=0.5になり合わさる(足し算)でI=1.009になりNEXTで6行目のFORに
戻り繰り返し(たぶん整数でI=1が代入される)考えでいいと思うんですが、
また、その後、13行目に進み、I=X/57+Y/42:NEXTですが、FOR I=1 と
ここの計算式、この場合I=1.009が合わさり、I=2.009になるのでしょうか?
実際、プログラムI=X/57+Y/42:NEXT:PRINT Iで2.009と表示されプログラム
終了していますが、I=1 か I=2 でFOR文が繰り返しされ13行目のNEXTの前
のI=X+57/+Y/42:NEXTでまた、I=1.009 FOR I=1 か I=2 に戻され13行目の
NEXTの一歩前でまた、I=1.009にな戻されると自分は、解釈してしまうんですが
どうでしょうか?また、プログラム FOR I=O TO 2を3にすると、プログラム
終了しないんですが説明できる方宜しくお願いします!

775名無しさん:2015/06/14(日) 05:41:47 ID:JVIZrV9Y
初代プチコンでは、数値は「32ビット固定小数」でした。
ですから、『たぶん整数でI=1が代入される』ということが
間違っているのですね。小数点以下の値も有効なのです。

おっしゃる通り、『X=29の座標になりX/57=0.5087と
同じくYの値が、Y=21にY/42=0.5になり
合わさる(足し算)でI=1.009に』なります。

そして、NEXTによりFORに戻ると、
省略されたSTEPにより、変数Iに1が加算されます。
その結果が「I=2.009」になります。

TOで指定された数値2よりも0.009だけ大きくなったので、
FORはループの継続をやめ、NEXTの次へ実行が移ります。

776素人:2015/06/15(月) 13:00:09 ID:m0n609bE
774、素人です!775、名無しさん!
大変、ありがたい解説ありがとうございました!

FOR〜NEXT文の使い方、と理屈がこのプログラムでよくわかりました!

自分なりに確認してみました!

1 CLS
2 FOR I=1 TO 10 STEP 2
3 PRINT I
4 NEXT:'PRINT I

そのままRUNと4行目PRINT文実行で目視確認できました!

777ひかり:2015/06/29(月) 18:27:19 ID:/48Jel1A
プチコン3号で電子書籍的なもの(第三回プチコン大喜利の社長賞の「P6姉さんと読書」的なのの、もっと
簡単バージョン。)が作りたいんです!
全くわからんのですが…
ヒントをください!

778名無しさん:2015/07/02(木) 17:03:38 ID:kpdlEBG2
プチコン3号で電子書籍リーダーを作って公開なさっている方が
いらっしゃいますので紹介しておきます。
http://d.hatena.ne.jp/gust_notch/20150326

もし「そうじゃない!」と思われたなら、どこが どう そうじゃないと感じたのか、
もう少し詳しく質問を書いてくだされば答えやすくなると思います。

779名無しさん:2015/07/17(金) 10:57:30 ID:/h8R2fJM
自作したプログラムを使うにはどうすればいいですか?

780名無しさん:2015/07/19(日) 02:02:56 ID:7aHZ34uE
「使う」とは、どういうことを指していますか?
トップメニューの「作品を見る」からプログラムは実行できます。

781名無しさん:2015/07/21(火) 21:40:42 ID:WcMZkQlI
アクションゲームで地面やブロックのBGの当たり判定ってどうやるんですか??
具体的に教えてください

782名無しさん:2015/07/22(水) 12:37:49 ID:7aHZ34uE
もしかして、あなたが質問したいのは、
当たり判定の事だけではなくてアクションゲームの基礎全般のプログラム手法
ではありませんか?

↓このページに丁寧に解説してくださっている方がいらっしゃいます。
https://miiverse.nintendo.net/posts/AYIHAAAEAAA5VHwZFPOzCA

さて、質問の「BGの当たり判定」の事だけで言うと、

プチコン3号では、BGGET命令を使う方法がよく使われます。
BGGET命令は、座標を指定して、特定の位置のBGの状態を取得する命令です。
ピクセル単位の画面上の座標値をそのまま使うこともできるので、
例えばスプライトで表示した主人公の足元のBG、なども簡単に取得できます。

サンプルゲームのジャンプくん(SYS/GAME3JUMP)でも使われている方法では、
BGレイヤーを1枚、当たり判定専用に使用し、
見た目に関係なくゼロ番以外のBGキャラクターがあるかどうかという
簡単な判断で当たり判定ができるようにしています。

もちろん、ゼロかどうかだけではなくて
特定のキャラクター番号であるかどうかを判別すれば、
壊せるブロックかどうかを判断するような事もできるでしょう。

783キジトラ:2015/08/19(水) 11:27:17 ID:pgalHUr6
今横スクロールシューティングを作っているのですが、横スクロールと弾を射つコマンドや方法が分かりません。
どうすれば出来ますか?

784名無しさん:2015/08/20(木) 03:58:33 ID:fq./BWcc
横スクロールシューティングで横スクロールするのは、
背景ですよね。
背景をBGでつくり、BGANIM命令を与えるのが良いと思います。
弾を射つには、
1.ボタンが押されるのを待ち構えるプログラムを作る。
2.弾のスプライトを用意する。
3.弾のスプライトを、自機と同じ位置に移動させる。
4.弾のスプライトにSPANIM命令を与える。
のようにするのが良いと思います。
以下に、ごく基本的なサンプルプログラムを書きます。
ACLS
BGSCREEN 0,1092,15
FOR I=0 TO 200
 BGPUT 0,RND(1092),RND(15),754  ←BGで星空の背景
NEXT
BGANIM 0,"XY",-9000,17472,0  ←背景をゆっくり横移動
SPSET 0,3481  ←自機のスプライトを用意
SPOFS 0,50,100
@LOOP
 B=BUTTON(2)
 IF B AND #A THEN  ←Aボタンが押された事を検出したら
  SPSET 1,1344  ←弾のスプライトを用意
  SPROT 1,90
  SPOFS 0 OUT X,Y  ←自機の位置を得る
  SPOFS 1,X,Y  ←弾の位置を、自機と同じ位置に
  SPANIM 1,"XY",-70,X+500,Y  ←弾をゆっくり横移動
  BEEP 67
 ENDIF
 VSYNC
GOTO @LOOP
書き写しミスあれば許して。
各命令の細かい意味や書き方は「?」で調べてください。
どうしても分からなければまた質問してください。

785名無しさん:2015/08/25(火) 18:17:47 ID:/h8R2fJM
圧縮ツールの作る手順、作り方を教えてください

786名無しさん:2015/08/27(木) 15:13:22 ID:fq./BWcc
ファイル容量を圧縮するなら、プチコンが扱うファイルと、その中身の形式について
調査と理解をすることが、最初の手順ですね。
圧縮したいデータの種類と、それらに適した圧縮方法を考えたり探したりするのが
次の手順だと思います。
自分で考える場合でも、考え方のヒントなどにするために、
インターネットで検索したり図書館で調べたり
データ圧縮の基本的な考え方やプログラム例などを見て理解しておいた方がいいでしょう。
そこまでできれば、あとはプチコンのプログラムとして、それを作り上げます。
このような手順で作ればよいと思います。

787名無しさん:2015/09/03(木) 20:35:31 ID:U4uCfM12
敵を5匹、1匹ずつランダムで動かして自機が触ったら消える用にしたいの
ですがうまくいきません、関係ない敵が止まってしまいます。
どうしたらよろしいのでしょうか?
ACLS
SPSET 100,496
SPCOL 100
DIM X[5]
DIM Y[5]
DIM ED[5]
FOR I=0 TO 4
X[I]=192
Y[I]=112
ED[I]=0
SPSET 0+I,1060
SPOFS 0+I,192,112
SPCOL 0+I
NEXT
@LOOP
GOSUB @MY
GOSUB @TEKI
VSYNC 1
GOTO @LOOP
@MY
B=BUTTON( )
IF B AND 1 THEN PY=PY-1
IF B AND 2 THEN PY=PY+1
IF B AND 4 THEN PX=PX-1
IF B AND 8 THEN PX=PX+1
SPOFS 100,PX,PY
RETURN
@TEKI
FOR I=0 TO 4
IF ED[I]==-1 THEN RETURN
R=RND(4)
IF R==0 THEN VX=0:VY=-4
IF R==1 THEN VX=0:VY=4
IF R==2 THEN VX=-4VY=0
IF R==3 THEN VX=4:VY=0
X[I]=X[I]+VX:Y[I]=Y[I]+VY
SPANIM 0+I,"XY",-16,X[I],Y[I]
IF SPHITSP(100,0+I) THEN GOSUB @ED
NEXT
RETURN
@ED
BEEP 12
ED[I]=-1
SPCLR 0+I
RETURN
GOTO @LOOP

788名無しさん:2015/09/06(日) 12:28:09 ID:fq./BWcc
●原因の箇所
 30行目、「IF ED[I]==-1 THEN RETURN」の行がマズイです。
●結論/解決方法
 RETURN を「CONTINUE」に書き換えましょう。

●解説
この付近のプログラムの動作を、順に見ていきましょう。
「GOSUB @TEKI」の命令で、ラベル@TEKIの行から実行されます。

「FOR I=0 TO 4」で、変数Iの値が、ゼロから始まり4まで1づつ増加しながら
次の行以降のプログラムが繰り返し実行されます。

「IF ED[I]==-1」では、順に
ED[0]の内容が-1なのかどうか、
ED[1]の内容が-1なのかどうか、
ED[2]の内容が-1なのかどうか、・・・を判断されます。

変数Iがゼロの時、つまりED[0]が-1だった場合を考えてみます。
「THEN RETURN」の命令によって、
GOSUBで呼ばれた位置に実行が戻ります。

その先では、「GOTO @LOOP」でループされ、「GOSUB @TEKI」で
再び変数Iがゼロから順に、ED[0]1の内容が-1なので戻り・・・。

変数Iの値がゼロよりも増えないままのループになってしまいました。
「RETURN」命令によって、サブルーチンごと戻ってしまうのが問題です。

「CONTINUE」命令を使うと、それ以降の、FORでループさせる予定の命令を
1度スキップさせることができます。
そして変数Iの値が増えて、FORループが続けられます。

789めがちゃ:2015/09/06(日) 13:59:08 ID:ho3fE5pQ
全くの初心者です。
書籍「プチコン公式活用テクニック」で、
プログラム4-02 スプライトを拡大縮小・回転させるのを、
三角関数を使って、回転軸が中心に変ったように見せかけるテクニックがわかりません。

GCLS
GCIRCLE 128,96,20,15
PNLTYPE "OFF"
SPPAGE 0
SPCLR
X=128:Y=100:PAT=68:PAL=2
SPSET 0,PAT,PAL,0,0,0
SPANIM 0,4,30
@MAIN
D=TCHX
S=TCHY
CLS
①A=RAD((D+225))%360)
②R=8*S/100*SQR(2)
X1=COS(A)*R
Y1=SIN(A)*R
SPANGELE 0,D
SPSCALE 0,S
SPOFS 0,X+X1,Y+Y1
VSYNC 1
GOTO @MAIN

①と②の計算式の意味がわかりません。
①計算処理をする事で、円内からはみだす事なく、
スプライトが回転する事はわかりました。この計算式をしないで、
A=RAD(D)とすると、はみだしてしまいます。
回転角度が135度の時、0度としてXの移動量を計算しているようですが、
なぜ135度なのか意味がわかりません。
スプライトの中心のX座標は135である事が関係しているのかと思い、
表示座標位置を変え、①の式も、変更した位置にあわせたものに修正しましたが、
やはり、スプライトの表示位置に関係なく
この計算式の((D+225))%360)が必要でした。
また、②の計算ですが、
タッチ画面の中央を押した時のYの100座標が拡大率100%としているのは
わかるんですが、8×ルート2の意味がわかりません。
スプライトの長さが16ドットなので、8がでてきたんでしょうか?
すいません、ながながと。わかる方教えてください。

790名無しさん:2015/09/06(日) 16:05:31 ID:U4uCfM12
>>788さん、うまく動きました!ありがとうございます!助かりました!

791名無しさん:2015/09/07(月) 12:57:26 ID:fq./BWcc
>>789
その本は、初代プチコンについて書かれています。
現在は初代プチコンを入手することはできません。
プチコンmkIIが近いですが、プチコンmkIIには
スプライトの回転軸を変えられる命令「SPHOME」が
用意されるようになりましたので、
そのテクニックを使う必要はありません。

さて質問について、私は三角関数は分からないので正しく答えられないと思いますが、

スプライト画像の中心の位置は、
スプライトの左上にある原点から見て、右斜め下45度にあたりますよね。
初代プチコンはスプライトのサイズは必ず16*16ドットでしたから、
縦横比が違う場合などを考慮する必要はありませんし。

そして、三角関数を使って円を描くよくあるプログラムの動作を見てみた時に、
三角関数の角度は通常の(?)角度と90度ズレているのは、なんとなく思っていまして。

その2つの角度を足して、90度+45度=135度だと思うんですけど、
・・・どうですかね? A(^^;

スプライトの大きさが16ドットだから8という数値が出てくるのか、
という部分については、それで正しいと思います。・・・きっとたぶん。

792めがちゃ:2015/09/07(月) 13:52:38 ID:ho3fE5pQ
>>791さん
135度については、なんとなくわかったような気がします。
ありがとうございます。
プチコンのスプライトの座標位置は、左上隅で、その位置辺りを
円の中心座標にし、角度、拡大率に応じて、x、y座標を修正し、あたかも、
スプライトが、スプライトの左隅座標 128,100に常に表示されるよう修正する為に、
①と②のプログラムが必要だったんですね。
確かに、「SPHOME 0,8,8」文を加えると、簡単にスプライトの中心で回転して、
x、y座標のめんどくさい修正が必要なくなりました!ありがとうございます。
ただ、円の中心座標が128,96なので、
スプライトの表示座標も128,100ではなく、128,96にした方が、
円内の調度中心でスプライトが回転するんですが、
これも、初代プチコンの仕様の関係上なんでしょうか・・・
これは、独り言です。

793めがちゃ:2015/09/07(月) 13:57:11 ID:ho3fE5pQ
>>792
スプライトが、スプライトの左隅座標 128,100に常に表示されるよう
↑間違い、
スプライトの中心がスプライトの左隅座標 128,100に常に表示されるよう
です。

794名無しさん:2015/09/08(火) 18:59:59 ID:fq./BWcc
三角関数が分からないなりに自分勝手に考えを続けてみています。
FOR I=0 TO 360
 X=100+COS(RAD(I))*50
 Y=100+SIN(RAD(I))*50
NEXT
↑これは、よくある三角関数を使って円を描くプログラムで、
変数Iの値が、われわれ人間が普段よく使う角度の値として、
ゼロ度から360度まで1度毎に点を打つ、というものですが、

普通、人間がゼロ度から1周、円を描こうと思ったら、
アナログ時計の12時の位置から描き始めますよね。
人間の感覚では「角度がゼロ イコール 12時」ですが、

このプログラムにWAITを入れて観察すると、
描き始められるのは3時の方向からです。
三角関数で角度を扱う時、90度ズレている印象の理由は、これです。
12時から描き始めるようにするには、
「FOR I=0-90 TO 360-90」と、90度ズラしてやることになります。

3時の方向がゼロ度になっていて、時計回りに角度の値が増える。
この事を踏まえて、>>789でいくつか出た数値を当てはめて考えてみると、

「225度」という数値は、スプライトの中心から見て、
左上にある原点の方角、ということに気づきました。
さっきのプログラムで225度を描かせてみると、左上の方角を指します。

SPANGLE命令でゼロ度、つまり傾き無しを指定したい時に、
225度、つまり左上の方角に対しての計算をして欲しいようにするために、
225という数値を決め打ちしていたんだと思います。

795名無しさん:2015/09/08(火) 19:04:13 ID:fq./BWcc
8という数値は、16ドットの半分、8ドットのことで、
「SQR(2)」は、正方形の対角線の長さを計算することに関係があるのだと
google先生が示してくれたので、8*8ドット分の斜めの距離に関することなのでしょう。
これを合わせると、

『中心から見て、原点(角度ゼロの場合は左上)への、角度と距離』を
求める計算式だと言える。
こう結論付けて良いと思います。・・・どうでしょうかね? A(^^;;;

そして「描いた円とスプライトの中心が微妙にズレているのは何故か?」
という疑問ですが、

(1)、とくに理由は無い。あくまでサンプルだから、だいたいで良いだろう。
(2)、人物の足元が円周に触れるようにした。
このあたりを考えてみました。
しかし、このプログラムは「回転軸を中心にする」のが目的なので、
2の理由は無理があります。やはり1か、あるいは
別の目的で作ったプログラムを流用した結果ゴミが残ったとか、
typoや校正ミス/印刷ミスの類なんじゃないでしょうか。
『だって、プチコンの書籍だし。』
↑これで通ってしまう状況・・・。編集者は反省が足りない。

このプログラムの意図を考えると、変数XとYで指定した位置に、
スプライトの中心が来るようにしているはずなので、
「左隅座標に表示される」というのは、ちょっと違うように感じますよ。
でも、使う言葉のチョイスが違っただけで、意図や言いたいことは
違ってないと思うので、問題ないですよね。

796名無しさん:2015/09/08(火) 19:15:18 ID:fq./BWcc
ぎゃあ最初のプログラムでGPSET忘れた

797名無しさん:2015/09/12(土) 23:03:00 ID:OcC0RsXo
初心者です。
アクションゲームを作りたいのですが、BGのデザインをこだわりたくてマリオのはてなブロックみたいに定義番号を変えるアニメーションは実現可能ですか?
可能ならやり方を教えていただけると幸いです。

798名無しさん:2015/09/17(木) 12:49:34 ID:kD3qX4NU
実現可能です。
最もよく使われるであろう方法は、
「グラフィックページ側を書き換える」方法です。
この方法の利点は2つあり、
画面上にはてなブロックがいくつ存在していようとも
1つの処理だけでアニメーションできることと、
当たり判定としてBGタイルの番号を利用している時に
それがコロコロ変わらないのということです。

以下は、特定のBGタイルが
アニメーションパターンとして「ABC」を表示する例を挙げます。

BGPUT 0,9,9,1 'BGタイル定義番号1番を表示
A=1 'アニメーションパターン位置の変数
@LOOP
 GPAGE 0,5 'BGタイル用グラフィックページを操作
 GCOPY A*16,32,A*16+15,47,16,0,1 'BGタイル定義番号1番の画像を書き換える
 INC A
 IF A>3 THEN A=1
 WAIT 15
GOTO @LOOP

799名無しさん:2015/09/17(木) 15:17:44 ID:OcC0RsXo
http://jbbs.shitaraba.net/bbs/lite/read.cgi/computer/43199/1345877567/798ぬおーー!!!
ありがとうございます!
2ヶ月文の悩みを解決しました。
僕が考えていたことはそのブロックをおいた座標を記録してそこにいちいちBGputすることだったのでそんな簡単なやり方があるだなんて感動しました!
ありがとうございます!

800名無しさん:2015/09/17(木) 15:18:30 ID:OcC0RsXo
http://jbbs.shitaraba.net/bbs/lite/read.cgi/computer/43199/1345877567/798ぬおーー!!!
ありがとうございます!
2ヶ月文の悩みを解決しました。
僕が考えていたことはそのブロックをおいた座標を記録してそこにいちいちBGputすることだったのでそんな簡単なやり方があるだなんて感動しました!
ありがとうございます!

801名無しさん:2015/09/22(火) 00:46:19 ID:kAQHhSO2
武器を振って攻撃するアクションゲームを作っています。
武器のスプライトの中心を柄の方にして、SPANIMで回転させて振っているように見せています。
当たりをつける段になって、SPCOLの設定が回転についてこないことを知り、途方にくれています。
どなたか、SPCOLが回転についてくるようになる方法、または当たりのつけ方の参考になるものを教えてください。
よろしくお願いします。


新着レスの表示


名前: E-mail(省略可)

※書き込む際の注意事項はこちら

※画像アップローダーはこちら

(画像を表示できるのは「画像リンクのサムネイル表示」がオンの掲示板に限ります)

掲示板管理者へ連絡 無料レンタル掲示板