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


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0310
PCAPRPGのバグを直したい。13未解決


PCAP

リンク

2017/3/10(Fri) 20:38:35|NO.78470

一部のモンスターで逃げることができなくなってしまいました。


randomize buffer 1 picload "ver.1.bmp" screen 0,480,336 h="name" cls 4 color 255,255,255 pos 150,100 mes"名前を入力してください。 pos 170,180 input h button"Let'go",*aa stop *aa cls 4 color 100,255,0 pos 150,100 font"MS 明朝",40 mes h +"の冒険" pos 170,180 color 255,255,255 font"MS 明朝",20 mes"バージョン を入力 ve="" pos 197,200 input ve button"go",*START stop *START mmload ve +".wav",0,1 mmplay 0 notesel datenote noteload ve +".txt" cls 4 color 255,255,255 mes datenote button"go",*STARTB stop *STARTB cls gmode 2 gosub *SETMAP MESSAGE="" MHP=100 ;主人公のデータ MLEVEL=1 MAT=1 MDF=3 EXP=0 ;/■/■/■メインループ/■/■/■ *DRAWLOOP1 redraw 0 color 0,0,0 :boxf 0,0,479,335 ;移動ルーチン MDX=0 :MDY=0 ;カーソルキーに応じて移動量MDX,MDYを取得 stick KY,15,1 if KY=1 :MDX=-1 if KY=4 :MDX=1 if KY=2 :MDY=-1 if KY=8 :MDY=1 if KY=16 :gosub *INVENTORY ;スペースキーが押されたらアイテム一覧表示 MMX=MX+MDX :MMY=MY+MDY ;移動量を足して、移動先の座標を求める S=MAP(MMX,MMY) ;移動先のマップデータを変数Sに代入 if S>=400:gosub *TAKARABAKO ;移動先の物体に応じた処理 if S>=300 & S<=399 :gosub *ENCOUNT if S>=200 and S<=299 :gosub *PUSHSW if S>=100 and S<=199 { ;閉じたドアの処理 SS="A" poke SS,0,'A'+S-(S/100*100) MESSAGE=SS+"と書かれたドアは閉ざされている" } if S=3 :goto *GOAL if S<2 {MX=MMX:MY=MMY} ;移動先が2未満ならそこに移動 if MX<0 :MX=0 ;マップからはみ出さないよう制限 if MX>44 :MX=44 if MY<0 :MY=0 if MY>44 :MY=44 ;画面表示 gosub *DRAWMAP color 255,255,255 :pos 0,288 :mes MESSAGE redraw 1 if MHP<=0 :goto *GAMEOVER await 80 goto *DRAWLOOP1 ;/■/■/■マップ表示/■/■/■ *DRAWMAP color 255,255,255 :boxf 0,0,480,280 SX=MX-5 if SX<0 :SX=0 if SX>34 :SX=34 SY=MY-4 if SY<0 :SY=0 if SY>36 :SY=36 repeat 9 YCNT=cnt repeat 11 XCNT=10-cnt ;ループを逆にする S=MAP(SX+XCNT,SY+YCNT) pos (XCNT+YCNT)*24, (YCNT-XCNT)*12+120 if S<5 :gcopy 1,S*48,0,48,48 ;番号が0〜4の場合 if S>4 { ;番号が100〜499の場合 SS=S/100-1 gcopy 1,SS*48,48,48,48 } if (SX+XCNT=MX) and (SY+YCNT=MY) :gcopy 1,192,0,48,48 loop loop return ;/■/■/■マップ初期化/■/■/■ *SETMAP dim MAP,45,45 bload ve +".map",MAP repeat 45 ;自キャラ位置取得 RCNT=cnt repeat 45 if MAP(cnt,RCNT)=4 {MX=cnt :MY=RCNT :MAP(cnt,RCNT)=0} loop loop sdim MONDATA,128:notesel MONDATA ;モンスターデータ読み込み noteload "monster.txt" sdim ITMDATA,128:notesel ITMDATA ;アイテムデータ読み込み noteload "item.txt" return ;/■/■/■スイッチ発見/■/■/■ *PUSHSW SW=MAP(MMX,MMY)-MAP(MMX,MMY)/100*100 ;下二桁を取得 SS="A" poke SS,0,'a'+SW dialog SS+"のスイッチです。\n押しますか?",2,"RPG" if stat=7 :return MESSAGE="何も起こらない" SW=SW+100 ;ドアの番号を求める repeat 45 ;対応するドアを探す RCNT=cnt repeat 45 if MAP(cnt,RCNT)=SW { MAP(cnt,RCNT)=1 MESSAGE="どこかでギィッという音がした" } loop loop return ;/■/■/■宝箱発見/■/■/■ *TAKARABAKO dialog "宝箱がある\n開けますか?",2,"RPG" if stat=7 :return ITM=MAP(MMX,MMY)-MAP(MMX,MMY)/100*100 ;アイテム番号取得 notesel ITMDATA noteget ITEMNAME,ITM*3 noteget SS,ITM*3+1 :ITEMTYPE=SS noteget SS,ITM*3+2 :ITEMVAL=int(SS) dialog ITEMNAME+"を拾いますか?",2,"RPG" if stat=7 :return if ITEMTYPE="H" { notesel INVENT noteadd ""+ITM,0 LEN=noteinfo(0) if LEN>6 :notedel 6 } if ITEMTYPE="S" { MAT=ITEMVAL } if ITEMTYPE="A" { MDF=ITEMVAL } MESSAGE=ITEMNAME+"を手に入れた" MAP(MMX,MMY)=0 return ;/■/■/■アイテム一覧/■/■/■ *INVENTORY gosub *DRAWMAP redraw 1 color 0,0,0 :boxf 80,40,400,240 color 255,255,255 pos 84,44 mes "レベル"+MLEVEL+" 体力"+MHP+" 攻撃力"+MAT+" 防御力"+MDF NEXP=(MLEVEL*MLEVEL*MLEVEL*246)-EXP pos 84,60 :mes "経験値"+EXP+"(次のレベルに"+NEXP+"必要)" pos 84,90 :mes "セーブ:S、ロード:L" pos 84,120 :mes "アイテム(使う:A〜F、閉じる:スペース)" notesel INVENT :SS=noteinfo(0) ;拾ったアイテムの数を求める repeat SS ;アイテムの数だけループ notesel INVENT :noteget T,cnt :ITM=int(T) ;アイテム番号を取り出す notesel ITMDATA :noteget ITEMNAME,ITM*3 ;対応するデータを探す T="A":poke T,0,cnt+65 ;アルファベットを作る pos 84,cnt*16+136 :mes T+":"+ITEMNAME ;画面に表示 loop *IVKYLOOP KY=0 repeat SS getkey KY,'A'+cnt if KY=1 { notesel INVENT :noteget T,cnt :ITM=int(T) notedel cnt notesel ITMDATA :noteget ITEMNAME,ITM*3 noteget T,ITM*3+2 MHP=MHP+T MAXHP=MLEVEL*30+70 if MHP>MAXHP :MHP=MAXHP MESSAGE=ITEMNAME+"を使った。体力が"+MHP+"に回復した" break } loop if KY=1 :return getkey KY,'S' ;サブルーチン*DATASAVEを呼び出す if KY=1 {gosub *DATASAVE :return} getkey KY,'L' ;サブルーチン*DATALOADを呼び出す if KY=1 {gosub *DATALOAD :return} stick KY ;アイテム一覧を閉じる if KY=16 :return wait 5 goto *IVKYLOOP ;/■/■/■データのセーブ/■/■/■ *DATASAVE dim SDATA,7 SDATA(0)=MHP :SDATA(1)=MLEVEL :SDATA(2)=MAT SDATA(3)=MDF :SDATA(4)=EXP SDATA(5)=MX :SDATA(6)=MY bsave "save1.dat",SDATA notesel INVENT notesave "save2.dat" bsave "save3.dat",MAP MESSAGE="データをセーブした" return ;/■/■/■データのロード/■/■/■ *DATALOAD dim SDATA,7 bload "save1.dat",SDATA MHP=SDATA(0) :MLEVEL=SDATA(1) :MAT=SDATA(2) MDF=SDATA(3) :EXP=SDATA(4) MX=SDATA(5) :MY=SDATA(6) notesel INVENT noteload "save2.dat" bload "save3.dat",MAP MESSAGE="データをロードした" return ;/■/■/■怪しい気配発見/■/■/■ *ENCOUNT dialog "怪しげな気配がある\n踏み込みますか?",2,"RPG" if stat=7 :return ENCT=MAP(MMX,MMY)-MAP(MMX,MMY)/100*100 ;モンスター番号取得 buffer 2 :picload "monster"+ENCT+".bmp" gsel 0 notesel MONDATA noteget SS,ENCT*6 :ENAME=SS noteget SS,ENCT*6+1 :EHP=int(SS) noteget SS,ENCT*6+2 :ELEVEL=int(SS) noteget SS,ENCT*6+3 :EAT=int(SS) noteget SS,ENCT*6+4 :EDF=int(SS) noteget SS,ENCT*6+5 :ETMR=int(SS) gosub *BATTLESTART return ;/■/■/■モンスターとの戦闘/■/■/■ *BATTLESTART gosub *DRAWMAP redraw 1 pos 80,40 :gcopy 2,0,0,320,220 color 255,255,255 :pos 0,288 :mes ENAME+"が現れた" wait 100 ETM=0 *BATTLE ;戦闘 color 0,0,0:boxf 0,288,479,335 color 255,0,0 :pos 0,288 :mes "どうする(攻撃A、防御D、逃げるE)?" color 255,255,255 DICENUM=MLEVEL*2 gosub *DICE *KYLOOP getkey KY,'A' if KY=1 :goto *ATTACK getkey KY,'D' if KY=1 :goto *DEFENCE getkey KY,'E' if KY=1 :goto *ESCAPE wait 5 goto *KYLOOP *ATTACK CMAT=DICEVAL+MAT CMDF=MDF goto *ENEMY *DEFENCE CMAT=0 CMDF=DICEVAL+MDF *ENEMY DICENUM=ELEVEL*2 gosub *DICE R=rnd(10) if R<ETMR { ETM=ETM+DICEVAL+EAT :CEAT=0 } else { CEAT=DICEVAL+EAT+ETM :ETM=0 } CEDF=EDF ;ダメージ判定 MDAMAGE=CEAT-CMDF :if MDAMAGE<0 :MDAMAGE=0 EDAMAGE=CMAT-CEDF :if EDAMAGE<0 :EDAMAGE=0 MHP=MHP-MDAMAGE :if MHP<0 :MHP=0 EHP=EHP-EDAMAGE :if EHP<0 :EHP=0 color 0,0,0:boxf 0,288,479,335 color 255,255,255 :pos 0,288 mes h +"あの攻撃が敵に" +EDAMAGE+"のダメージを与えた!" wait 50 if (ETM>0) and (EHP>0) { mes "敵は力をためている" } else :mes "敵から"+MDAMAGE+"のダメージを受けた" wait 100 color 0,0,0:boxf 0,288,479,335 color 255,255,255 :pos 0,288 :mes "自分の体力"+MHP+"、敵の体力"+EHP wait 100 if (EHP<=0) and (MHP>0) :goto *BKATI if MHP<=0 :goto *BMAKE goto *BATTLE *ESCAPE MESSAGE= h +"は命からがら逃げ出した" return *BKATI GEXP=ELEVEL*ELEVEL*ELEVEL*49 ;獲得経験値計算 R=rnd(GEXP/5)-(GEXP/8) GEXP=GEXP+R EXP=EXP+GEXP NEXP=(MLEVEL*MLEVEL*MLEVEL*246)-EXP color 0,0,0:boxf 0,288,479,335 color 255,255,255 :pos 0,288 :mes ENAME+"を倒した" mes "経験値"+GEXP+"を得た(次のレベルアップに"+NEXP+"必要)" MAP(MMX,MMY)=0 if NEXP<=0 { wait 100 color 0,0,0:boxf 0,288,479,335 color 255,255,255 :pos 0,288 :mes "レベルアップ!" MLEVEL=MLEVEL+1 } MESSAGE="" wait 200 return *BMAKE color 0,0,0:boxf 0,288,479,335 color 255,255,255 :pos 0,288 :mes h +"は敵に敗れた" MESSAGE="" wait 200 return ;/■/■/■サイコロ投げ/■/■/■ *DICE DICEVAL=0 repeat DICENUM R=rnd(6) DICEVAL=DICEVAL+R+1 loop return ;/■/■/■ゲームクリアー/■/■/■ *GOAL redraw 1 color 0,200,255 :font "MS ゴシック",30,1 pos 140,140 :mes "STAGECLEAR" wait 400 END ;/■/■/■ゲームオーバー/■/■/■ *GAMEOVER color 255,0,0 :font "MS ゴシック",30,1 pos 160,160 :mes "GAMEOVER" wait 200 sysfont dialog "REPLAY?",2,"GAMEOVER" if stat=6 : goto *START end

monster.txtという名前のファイルを作成し、下を入力。

梅干し野郎 10 1 1 0 0 摂理の目 10 3 1 1 3 ベニテングダケ 10 3 8 12 3 カニ魔王 10 4 5 1 5 Word魔獣 10 5 6 10 2 いなべっちぃ 1000 100 40 1 2 1


item.txtという名前のファイルを作成し、下を入力。

栄養ドリンク H 500 薬草1000 H 1000 石の剣 S 12 妖刀ムラマサ S 18 草薙の剣 S 45 作業員のツナギ A 10 甲冑 A 20 鎧LV4 A 30 鎧LV5 A 40
ver.1という名前のファイルを作成し、下を入力。

2xxx年。 地球が侵略され、人類は火星へ避難した。 残された地球を救うため選ばれた勇者・・・・・・・・・・・・ それこそが君だああああああああああっ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 大魔王いなべっちぃを倒し 地球を救えっ!!!!!!!!!!!!!!!!!!!!!!!!!!! :すとーりー作成:ドアホ☆
ver.1という名前で、BGMファイルを作成。

ver.1という名前で、
240*90pixel 一つのブロック5*2個の比
上面下面が上の角と下の角が120°のひし形のブロック背景は黒
の絵を作製してください。bmp形式で。
(12歳から始めるワクワクゲームプログラミング教室という本を持っている方は、
そのCDに入っているサンプル画像から取ってくると良いと思う。)

最初のとは別に下のソースコードで作ったプログラムで ver.1.map というファイルを作製してください。

#pack "rpgmaps.bmp" onexit *EDITOWARI sdim FNAME,512 buffer 2:picload "rpgmaps.bmp" screen 5,240,96,12,10,20:title "パーツ" ;パーツウィンドウ初期化 gosub *SELPARTS screen 4,200,96,12,10,150:title "ツール" ;ツールウィンドウ初期化 cls 1 gosub *SETTOOL screen 0,480,480,0,260,20 ;メインウィンドウ初期化 cls 1 gmode 2 dim MAP,45,45 :MAP(3,3)=4 MAPX=0 :MAPY=0 :VIEWX=0 :VIEWY=0 PARTS=0 gosub *DRAWMAP ;/■/■/■エディターメイン/■/■/■ *EDITMAIN wait 5 stick KY,271,1 if KY&256 :goto *MSBTN if KY&1 :VIEWX=VIEWX-1 if KY&2 :VIEWY=VIEWY-1 if KY&4 :VIEWX=VIEWX+1 if KY&8 :VIEWY=VIEWY+1 if VIEWX<0 :VIEWX=0 if VIEWY<0 :VIEWY=0 if VIEWX>15 :VIEWX=15 if VIEWY>15 :VIEWY=15 gosub *DRAWMAP goto *EDITMAIN *MSBTN ACTWIN = ginfo(2) if ACTWIN=5 { PARTS=mousey/48*5+mousex/48 gosub *SELPARTS } if ACTWIN=0 { X=mousex/16 :Y=mousey/16 if (X+VIEWX)<0 or (X+VIEWX)>44 or (Y+VIEWY)<0 or (Y+VIEWY)>44 :goto *EDITMAIN if PARTS<5 :MAP(X+VIEWX,Y+VIEWY)=PARTS if PARTS>4 :goto *SETNUM } goto *EDITMAIN ;/■/■/■数値入力/■/■/■ *SETNUM gsel 4 cls 1 if PARTS=5 {mes "閉じたドア(100〜199)":NUM=100} if PARTS=6 {mes "ドアスイッチ(200〜299)":NUM=200} if PARTS=7 {mes "モンスター(300〜399)":NUM=300} if PARTS=8 {mes "宝箱(400〜499)":NUM=400} input NUM,,,5 button goto "OK",*SETNUMEND button goto "CANCEL",*SETNUMEND2 *SETNUM1 wait 5 goto *SETNUM1 *SETNUMEND NUM=int(NUM) if (NUM<(PARTS-4)*100) or NUM>((PARTS-4)*100+99) :goto *SETNUM MAP(X+VIEWX,Y+VIEWY)=NUM *SETNUMEND2 cls 1 gosub *SETTOOL goto *EDITMAIN ;/■/■/■パーツ選択/■/■/■ *SELPARTS gsel 5 :X=(PARTS\5)*48: Y=(PARTS/5)*48 gmode 0 pos 0,0:gzoom 240,96,2,0,0,80,32 color 255,255,255 boxf X,Y,X+47,Y+3 boxf X,Y+44,X+47,Y+47 return ;/■/■/■ツール表示/■/■/■ *SETTOOL gsel 4 button goto "マップロード",*MAPLOAD button goto "マップセーブ",*MAPSAVE return *MAPLOAD dialog "map",16 if stat=0 :goto *EDITMAIN FNAME=refstr:bload FNAME,MAP goto *EDITMAIN *MAPSAVE dialog "map",17 if stat=0 :goto *EDITMAIN FNAME=getpath(refstr,1) bsave FNAME+".map",MAP goto *EDITMAIN ;/■/■/■マップ表示/■/■/■ *DRAWMAP gsel 0 :redraw 0 color 0,0,0: boxf 0,0,480,480 repeat 30 RCNT=cnt repeat 30 S=MAP(VIEWX+cnt,VIEWY+RCNT) pos cnt*16, RCNT*16 if S<5: gcopy 2,S*16,0,16,16 if S>5 { S1=S/100 gcopy 2,(S1-1)*16,16,16,16 S2=S-S1*100 ;下二桁だけを取り出す SS="A" if S1=1 :poke SS,0,'A'+S2 ;ドア if S1=2 :poke SS,0,'a'+S2 ;スイッチ if S1=3 :SS=str(S2) ;怪物 if S1=4 :SS=str(S2) ;宝箱 font "MS ゴシック",16,1 color 255,255,255 :mes SS } loop loop redraw 1 title "マップエディター(" +VIEWX + ":" +VIEWY+")-("+(VIEWX+29)+":"+(VIEWY+29)+")" return *DRAWMAP3D gsel 0 redraw 0 color 0,0,0: boxf 0,0,480,260 repeat 9 RCNT=cnt repeat 9 LCNT=9-cnt S=MAP(VIEWX+LCNT,VIEWY+RCNT) pos (LCNT+RCNT)*24, (RCNT-LCNT)*12+110 if S<5: gcopy 2,S*48,0,48,48 loop loop redraw 1 return ;/■/■/■エディタ終了/■/■/■ *EDITOWARI dialog "終了しますか?",3 if stat!=6 :goto *EDITMAIN END
bmp形式で、monster1.bmp〜monster5.bmpをなんかの画像またはイラストで作製してください。

こんなに大変かとは思いますが、どうにかよろしくお願いします!!!!!!!!!!



この記事に返信する


PCAP

リンク

2017/3/10(Fri) 20:55:06|NO.78473

ゲームのバージョンはver.1と入力してください。
教えてほしいのは、バグの解決方法です。



スペース

リンク

2017/3/11(Sat) 17:24:36|NO.78481

正直、これはデバッグする気が失せます。
画像の用意が非常に面倒なので、
一式をアップローダーにアップロードすることをお勧めします。



PCAP

リンク

2017/3/12(Sun) 12:13:08|NO.78497

>一式をアップローダーにアップロードすることをお勧めします。

こんな感じですか?

https://srv19.bitsend.jp/filesgroup/7ae051e7e3272096758d60f4618ba424.html



IBS

リンク

2017/3/12(Sun) 12:19:25|NO.78499




PCAP

リンク

2017/3/12(Sun) 19:35:56|NO.78501

名前間違えた!!!!!!!!
こっちはラジオだ!!!!!!!!!!!!



PCAP

リンク

2017/3/12(Sun) 19:36:29|NO.78502

マスコットも違う!!!!!!!!!!!!!!!!!!!!!!!!!11



PCAP

リンク

2017/3/12(Sun) 19:37:43|NO.78503

上のハイパーリンクは本物です。



PCAP

リンク

2017/3/13(Mon) 17:21:13|NO.78516

どうにかどなたかお願いします!!!!!!!



Taddi

リンク

2017/3/14(Tue) 00:02:02|NO.78520

12歳から始めるHSP3.0ワクワクゲームプログラミング教室の
サンプルスクリプトですね。

ざっとしか見ていないので見当違いであったら申し訳ないのですが、
サンプルそのものにミスがあるような気がします。

77行目の S=MAP(MMX,MMY) でマップの侵入可否を判断する値をSに代入しているのですが、
79行目の gosub *ENCOUNT から、
289行目の gosub *BATTLESTART に飛んだ先で 
106行目の gosub *DRAWMAP を呼び出しています。
この *DRAWMAP 内で、S=MAP(SX+XCNT,SY+YCNT) と、Sの値を上書きしているのが
問題になっているのではないでしょうか。
結果として、
89行目の if S<2 {MX=MMX:MY=MMY} 移動先が2未満ならそこに移動で
Sが想定外の数字となり、侵入不可のところに移動してしまうことで
「逃げられない」という、はまった状態になっていると思います。

実際に、*ENCOUNTルーティンを抜けた後の、
86行目あたり if S=3 :goto *GOAL の前に S=MAP(MMX,MMY) を加えてみてください。
たぶん逃げられるようになると思います。

こういったバグは、変数の中身をチェックしながら対処するしかありません。
今回は、変数Sに狙いをつけてdialog S を怪しそうなところに記述しては実行を繰り返しました。
デバッグ作業は慣れと忍耐が要求される作業です。

それにしてもサンプルとはいえ、gotoからgosubそして、その先でreturnって
デバッグ泣かせの難しいサンプルですね。
12歳でこれを理解できたら、
なかなかのものだと思うのですが…。



沢渡

リンク

2017/3/14(Tue) 13:37:32|NO.78525

あー、なるほど。本来なら逃げた場合はモンスターのいるマスの手前で立ち止まったままの筈なのに、
if S<2 {MX=MMX:MY=MMY} でモンスターのいるマスにハマり込んでしまい、
逃げた次の瞬間に再びモンスターに遭遇してしまうと。やっと解読できました。

だったらむしろ、*DRAWMAP内で変数Sの使い回しをせず、別の変数を用いるのも良いかもしれませんね。



PCAP

リンク

2017/3/14(Tue) 19:07:41|NO.78530

ありがとうございます。 やってみます。



PCAP

リンク

2017/3/14(Tue) 19:14:03|NO.78532

>12歳でこれを理解できたら、なかなかのものだと思うのですが…。
僕は13歳ですが・・・内容は理解できましたが、細かい命令がよくわかりません。



PCAP

リンク

2017/3/14(Tue) 19:21:17|NO.78533

ありがとうがございます。
逃げられるようになりました。



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