これは多少長いですがジャンプアクションゲームのスクリプトです。
#define global ctype iflet(%1,%2,%3) (((0!(%1))*(%2))|((0=(%1))*(%3))) #define global ctype ptmap(%1,%2) ((%1<<16) | %2) #define global ctype _ptX(%1) (((%1>>16)&$FFFF)) #define global ctype _ptY(%1) ((%1&$FFFF)) #define global ctype ptX(%1) (((%1>>16)&$FFFF)*32) #define global ctype ptY(%1) ((%1&$FFFF)*32) #module #defcfunc outSpace str strA mystr = "" myss = 0 sdim strB,100 strC = strA repeat getstr strB,strC,myss,' ' if strsize=0:break mystr += strB myss += strsize loop return mystr #defcfunc eq array p1,int p2,local ret ret=0 foreach p1 if p2=p1(cnt):ret=1:break loop return ret #global #const global blockMax 600 #const scrx 512 #const scry 320 #define softName "(ソフト名)" buffer 5,32*6,32*3 // picload "pattern.bmp" color 0,0,255 boxf 0,0,ginfo_winx,64 color 255,255 boxf 0,65,ginfo_winx,ginfo_winy color 0,128,0 line 31,ginfo_winy,31,65 *start screen 0,scrx,scry title softName gmode 4,,,256 boxf rightBlock = 'a','b','c','d' rightTeki = 'B','C' dim pattern,255 pattern('a') = ptmap(0,2) pattern('b') = ptmap(1,2) pattern('c') = ptmap(2,2) pattern('d') = ptmap(3,2) font msgothic,50 color 255,255,255 pos 10,20 mes softName sysfont pos 210,150 mes "Press Enter" repeat stick k,32 if k&32:break await 17 loop //**********************************ステージ読み込み開始 color:boxf dim blockon,blockMax dim blockx,blockMax dim blocky,blockMax dim blockNum,blockMax sdim mine,1000 mine ={"%backR%:0 %backG%:128 %backB%:255 %stageX%:30 %stageY%:20 $map$ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aa..........................aa aa...........B.....C...D.....a aa...aaaaaaaaaaaaaaaaaaaaa...a aa..Ca...................a...a a...aa.......aaaaa.......aa..a a...a......aaaaaaaaa......a..a a..aaaa.....aaaaaaa.....aaaa.a a.....aa...............aa....a a......aa.............aa.....a a......aa.............aa.....a a.....aa...............aa....a a..aaaa.....aaaaaaa.....aaaa.a a...a......aaaaaaaaa......a..a a...aa.......aaaaa.......aa..a aa...a...................a...a aa...aaaaaaaaaaaaaaaaaaaaa...a aa...........................a aa..A.......................aa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} notesel mine repeat notemax rerm="" noteget rerm,cnt rerm = outSpace(rerm) if yomu_mode=0{ switch peek(rerm,0) case '%' option_name = strmid(rerm,1,instr(rerm,1,"%")) option_value= strmid(rerm,instr(rerm,0,":")+1,iflet(instr(rerm,0,";")!-1,instr(rerm,0,";"),strlen(rerm))) switch option_name case "backR" backR=int(option_value) swbreak case "backG" backG=int(option_value) swbreak case "backB" backB=int(option_value) swbreak case "stageX" stageX=int(option_value) swbreak case "stageY" stageY=int(option_value) swbreak swend case '$' command_name = strmid(rerm,1,instr(rerm,1,"$")) if command_name="map"{ gyou=0 repeat stageY,cnt+1 rerm="" noteget rerm,cnt repeat stageX if eq(rightBlock,peek(rerm,cnt)){ mnt=cnt repeat blockMax if blockon(cnt)=1:continue blockon(cnt)=1 blockx(cnt)=mnt*32 blocky(cnt)=gyou*32 blockNum(cnt)=peek(rerm,mnt) break loop } if peek(rerm,cnt)='A'{ x=cnt*32 y=gyou*32 } loop gyou++ loop yomu_mode=1 } swbreak swend }else{ break } loop //**********************************ステージ読み込み終わり**********************************初期設定 cur = 0 ;コマ数 mode= 0 ;主人公モード 0=停止 1=歩行 2=ジャンプ muki= 0 ;0=左 1=右 jump_vy = 0 ;ジャンプY移動量 jumpflg=0 ;ジャンプフラグ speedmax=5 ;横移動スピードMax jumpmax=15 ;ジャンプY移動Max fallmax=8 ;ジャンプ降下量Max //**********************************初期設定終わり *main redraw 0 color backR,backG,backB:boxf scrollX = limit(x-scrx/2+16,0,stageX*32-scrx) ;スクロール量 scrollY = limit(y-scry/2+16,0,stageY*32-scry) ;↓ color 128,0,128 //**********************************ブロック描画 repeat blockMax if blockon(cnt)=0:continue // dialog "x:"+blockx(cnt)+"\ny:"+blocky(cnt)+"\nscrollX:"+scrollX+"\nscrollY:"+scrollY+"\n\n"+((blockx(cnt)>scrollX)or(blockx(cnt)<(scrollX-32))or(blocky(cnt)>scrollY)or(blocky(cnt)<(scrollY-32))),2 // if stat=7:end if blockx(cnt)>(scrollX+scrx):continue if blockx(cnt)<(scrollX-32):continue if blocky(cnt)>(scrollY+scry):continue if blocky(cnt)<(scrollY-32):continue pos blockx(cnt)-scrollX,blocky(cnt)-scrollY gcopy 5,ptX(pattern(blockNum(cnt))),ptY(pattern(blockNum(cnt))),32,32 loop //**********************************ブロック描画終わり stick key,31 ;キー判定 //**********************************歩・止ってるとき処理 if mode<=1{ xx=x if key&5{ //**********************************移動処理 if key&1:x-=speedmax:mode=1:muki=0 if key&4:x+=speedmax:mode=1:muki=1 }else:mode=0 ;キー左右どっちも押されてなければmode=0(止) //**********************************ジャンプ処理 if key&16{ mode=2 jump_vy=-jumpmax jump_vx=x-xx } }else{ //**********************************ジャンプ中処理 if key&1:jump_vx-=1 if key&4:jump_vx+=1 if jump_vx<0:muki=0 if jump_vx>0:muki=1 jump_vx = limit(jump_vx,-speedmax,speedmax) x+=jump_vx } //**********************************ジャンプ処理 if mode=2{ if jumpflg:jump_vy++ jump_vy = limit(jump_vy,-jumpmax,fallmax) y+=jump_vy jumpflg^=1 ky=0 /* repeat blockMax if blockon(cnt)=0:continue if x<(blockx(cnt)+32):if blockx(cnt)<(x+32):if blocky(cnt)<(y+32):if y<(blocky(cnt)+32){ } loop */ } //**********************************ジャ中処理終わり //**********************************当たり判定全般処理 repeat blockMax if blockon(cnt)=0:continue if x<(blockx(cnt)+32):if blockx(cnt)<(x+32):if blocky(cnt)<(y+32):if y<(blocky(cnt)+32){ if mode=2{ //**********************************天井処理 if jump_vy<0{ if (blocky(cnt)<y)|(y<(blocky(cnt)+32)){ // myx = x+16-iflet(muki=1,1,0) // if (myx>=blockx(cnt))and(myx<=(blockx(cnt)+31))and(y>=blocky(cnt))and(y<=(blocky(cnt)+31)){ if iflet(muki=0,(x<(blockx(cnt)+32))and(blockx(cnt)<(x+16))and(blocky(cnt)<(y+32))and(y<(blocky(cnt)+16)),((x+16)<(blockx(cnt)+32))and(blockx(cnt)<(x+32))and(blocky(cnt)<(y+32))and(y<(blocky(cnt)+16))){ y = blocky(cnt)+32:jump_vy=1 break } } } //**********************************床処理 if jump_vy>0{ if (blocky(cnt)>y)|((y+32)<blocky(cnt)){ myx = x+16-iflet(muki=1,1,0) myy = y+31 // if (myx>=blockx(cnt))and(myx<=(blockx(cnt)+31))and(y>=blocky(cnt))and(y<=(blocky(cnt)+31)){ if iflet(muki=0,(x<(blockx(cnt)+32))and(blockx(cnt)<(x+16))and(blocky(cnt)<(y+32))and(y<(blocky(cnt)+16)),((x+16)<(blockx(cnt)+32))and(blockx(cnt)<(x+32))and(blocky(cnt)<(y+32))and(y<(blocky(cnt)+16))){ y = blocky(cnt)-32:mode=0 break } } } } //**********************************左右壁処理 if x<blockx(cnt){ if (blockx(cnt)-x)<=16:x = blockx(cnt)-17 if mode=2:break }else{ if (x-blockx(cnt))<=16:x = blockx(cnt)+17 if mode=2:break } //**********************************左右壁処理終了 // break } loop //**********************************画面外に出ない処理 x=limit(x,scrollX-16,scrollX+scrx-16) cur++ if cur&8:cur=0 //**********************************描画処理 pos x-scrollX,y-scrollY switch mode case 0 if muki{ buffer 7,32,32 pos 31,0 gzoom -32,32,5,0,0,32,32 gsel 0 gcopy 7,0,0,32,32 }else{ gcopy 5,0,0,32,32 } swbreak case 1 if muki{ buffer 7,32,32 pos 31,0 gzoom -32,32,5,64+(cur<4)*32,0,32,32 gsel 0 gcopy 7,0,0,32,32 }else{ gcopy 5,64+(cur<4)*32,0,32,32 } swbreak case 2 if muki{ buffer 7,32,32 pos 31,0 gzoom -32,32,5,32+(jump_vy>0)*128,0,32,32 gsel 0 gcopy 7,0,0,32,32 }else{ gcopy 5,32+(jump_vy>0)*128,0,32,32 } swbreak swend //**********************************描画処理終わり //デバッグ用 pos 0,0 mes "scrollX:"+scrollX mes "scrollY:"+scrollY mes "x:"+x+" y:"+y mes "mode:"+mode mes "myflag:"+myflag redraw 1 await 17 // await 300 goto *main
このスクリプトでは、ジャンプ(スペースキー)したときにたまに障害物を突き抜けたり、
ジャンプしているときに壁に横から壁にぶつかるとそのまま下にさがっていったりするのですが、
これらの症状はどのようにすれば改善できるでしょうか?
理想としては、ジャンプしたときに上にぶつかるとそのまま下に落ち始め、
床にぶつかるとそのままそこで止まる、
ジャンプしているときに壁に横から壁にぶつかった場合はY方向の進行量に影響を与えることなく
壁の方向に進めないようになる、ということです。
よろしくお願いします。