« [改造記]画面描写(es_copy) | トップページ | [改造記]スプライトを使う準備 »

[改造記]解剖記のスクリプトを改造しよう

実はここまでの所さえ理解できていれば、DirectX対応に改造することは可能です。ただし、もちろんスプライトの機能は使えません^^;

というわけで「解剖記」のサンプルスクリプトを改造しちゃいましょう。当然スプライトの機能は使いません。否、まだ使えないでしょって^^;

 

; シューティングゲームサンプルv2.1
; by たかのん
; HSP v2.5 で作成されています
; 敵と自機の距離によって画面に倍数が表示されます。
; この倍数は、距離が近いほど大きくなります。

; v1.1との違い
; 画面描写をDirectXに対応
; ただし、スプライトの機能は使ってません

; ジョイスティックに対応


;■ DirectX 初期化&チェック
#include "hspdxfix.as"
#include "hspjsis.as"

es_ini : es_screen 640,480,8,0
if stat=1 : goto *dxerr1
if stat=2 : goto *dxerr2
goto *gamesetting

*dxerr1
dialog "DirectXの初期化に失敗しました。",1    : end
*dxerr2
dialog "スクリーンの初期化に失敗しました。",1 : end
*dxerr3
es_bye : wait 100
dialog "VRAMの容量が不足しています。",1       : end


*gamesetting
cls 4
highscore=5000
randomize
move=5 ;自機の移動速度を指定
smax=50 ;星の最大数
emax=50 ;敵の最大数
tmax=200 ;敵弾最大数
wmax=3 ;自機弾最大数
imax=10 ;倍数表示最大数
vmax=10 ;情報表示最大数
bmax=10 ;爆風最大数
cmax=50 ;カスリ効果最大数
level=1 ;難易度


;■ バッファへ画像の読みこみ
buffer 2,640,480,1
pos 0,0
picload "sample2.bmp",1

es_buffer 0,0
if stat=1 : goto *dxerr3
;↑オフスクリーンバッファへの転送と成否判定


;■ 効果音とBGMの読みこみ
sndload "Int01.mid",0,1
sndload "dmg.wav",1,0
sndload "exp.wav",2,0
sndload "shot.wav",3,0
sndload "kin.wav",4,0
snd 0


;■ 配列定義
*gamestart
dim sx,smax ;星のx軸座標
dim sy,smax ;星のy軸座標
dim sc,smax ;星の色
dim ss,smax ;星の移動速度

dim ex,emax ;敵x軸座標
dim ey,emax ;敵y軸座標
dim ef,emax ;敵固さ・生死
dim en,emax ;敵種類
dim exv,emax ;敵x方向運動量
dim eyv,emax ;敵y方向運動量
dim et,emax ;敵出現からの時間

dim tx,tmax ;敵弾x軸座標
dim ty,tmax ;敵弾y軸座標
dim tf,tmax ;敵弾on/off
dim txv,tmax ;敵弾x方向運動量
dim tyv,tmax ;敵弾y方向運動量

dim wx,wmax ;自機弾のx軸座標
dim wy,wmax ;自機弾のy軸座標
dim wf,wmax ;自機弾のOn/Off
dim wyv,wmax ;自機弾のy軸移動距離

dim ix,imax ;倍数x軸座標
dim iy,imax ;倍数y軸座標
dim iff,imax ;倍数表示時間
dim iv,imax ;倍数フォントサイズ
dim in,imax ;元得点

dim bx,bmax ;爆風x軸座標
dim by,bmax ;爆風y軸座標
dim bf,bmax ;爆風表示時間


 dim cx,cmax ;カスリ効果x軸座標
dim cy,cmax ;カスリ効果y軸座標
dim cxv,cmax ;カスリ効果x方向移動距離
dim cyv,cmax ;カスリ効果y方向移動距離
dim cf,cmax ;カスリ効果表示時間


;■ 星の準備
repeat smax
rnd sx.cnt,640
rnd sy.cnt,480
rnd sc.cnt,10
ss.cnt=10-sc.cnt
sc.cnt=sc.cnt*5
loop

;■ 平方根の準備
dim calc,900
repeat 900
temp=cnt : calc.cnt=temp*temp
loop

;■ スタート前準備
mx=295 : my=400 ;自機の初期位置を指定
mf=8 ;自機の初期シールドを指定
gameovertime=0
score=0
frame=0
highdst=0
gsel 0

es_cls
es_sync
wait 100

;■ メインルーチン
*main

es_cls bgcolor,0,0 : bgcolor=0
gosub *message ;ゲーム情報
gosub *haikei ;星の描写
gosub *jikimove ;自機移動
gosub *weapon ;自機弾
if frame\(25-level)=0 : gosub *enemyborn ;敵生成
gosub *enemymove ;敵移動
gosub *tekitamamove ;敵弾移動
if pat&128>0 : gosub *pausegame ;ポーズ
getkey returntop,123 : if returntop=1 : end ;強制終了(F12)
if mf<1 : mxv=0 : myv=0 : gameovertime++ : gosub *bomb
if gameovertime>100 : goto *gameover

await 0
es_sync 30
frame++
level=frame/500+1
if level>20 : level=20
goto *main


;■ 自機移動
*jikimove
if mf>0 : stick pat,79 : jstick 79

if stat!0 : pat=stat
;↑ジョイスティック入力判定
shottime--
if mf>0 : if (pat&64>0)&(shottime<0) : shot=1
xv=(pat>>2&1)-(pat&1)
yv=(pat>>3&1)-(pat>>1&1)
if mf>0 : mx=xv*move+mx : my=yv*move+my
if mx<0 : mx=0
if mx>590 : mx=590
if my<0 : my=0
if my>430 : my=430
pos mx,my

gmode 1,50,50 : es_copy 0,xv*50+50,0
return


;■ 背景描写
*haikei
repeat smax
sy.cnt=sy.cnt+ss.cnt
if sy.cnt>480 : sy.cnt=0 : rnd sx.cnt,640

pos sx.cnt,sy.cnt
gmode 1,5,5 : es_copy 0,400,sc.cnt
loop
return


;■ 自機弾発射
*weapon
repeat wmax
if (shot=1)&(wf.cnt<1) {
wf.cnt=1
wx.cnt=mx+12
wy.cnt=my
shot=0
shottime=1
; snd 3
;↑効果音がうるさいので切ってあります^^;
}
if wf.cnt<1 : continue
wy.cnt=wy.cnt-40
if wy.cnt<-50 : wf.cnt=0
pos wx.cnt,wy.cnt

gmode 1,25,50
es_copy 0,150,0
loop
return


;■ 敵生成
*enemyborn
rnd temp,7
if temp=0 : return
repeat emax
if ef.cnt>0 : continue
if temp=1 : en.cnt=1
if temp=2 : en.cnt=1
if temp=3 : en.cnt=1
if temp=4 : en.cnt=2
if temp=5 : en.cnt=2
if temp=6 : en.cnt=3
ef.cnt=en.cnt ; 固さ
rnd ex.cnt,640 ; 初期出現位置x軸
ey.cnt=-50 ; 初期出現位置y軸
exv.cnt=0 ; 初期移動量x軸
eyv.cnt=10 ; 初期移動量y軸
et.cnt=0
break
loop
return


;■ 敵移動
*enemymove
repeat emax
et.cnt++
if ef.cnt<1 : continue
if en.cnt=1 : gosub *enemy1
if en.cnt=2 : gosub *enemy2
if en.cnt=3 : gosub *enemy3
if ef.cnt<1 : continue
ent=cnt
repeat wmax
if wf.cnt<1 : continue
ddx=(ex.ent+25)-(wx.cnt+12)
if ddx<0 : ddx=-ddx
ddy=(ey.ent+25)-(wy.cnt+25)
if ddy<0 : ddy=-ddy
if (ddx<20)&(ddy<40) {
ef.ent-- : wf.cnt=0
if ef.ent>0 {
pos wx.cnt,wy.cnt

gmode 1,25,25
es_copy 0,175,25
snd 4
score++
}
else {
pos ex.ent,ey.ent

gmode 1,50,50
es_copy 0,200,0
snd 2
gosub *messageborn
}
}
loop
loop
return

;■ 敵1
*enemy1
dx=mx-ex.cnt
dy=my-ey.cnt
if dy<350 {
if dx<0 {
exv.cnt=exv.cnt-1
if exv.cnt<-25 : exv.cnt=-25
}
else {
exv.cnt=exv.cnt+1
if exv.cnt>25 : exv.cnt=25
}
}
if dx<0 : dx=-dx
if dx<50 : gosub *tamaborn
eyv.cnt=4
ex.cnt=ex.cnt+exv.cnt
ey.cnt=ey.cnt+eyv.cnt
if ex.cnt<-50 : ef.cnt=0
if ex.cnt>640 : ef.cnt=0
if ey.cnt<-50 : ef.cnt=0
if ey.cnt>480 : ef.cnt=0
pos ex.cnt,ey.cnt

gmode 1,50,50 : es_copy 0,250,0
return


;■ 敵2
*enemy2
dx=mx-ex.cnt
if et.cnt<2 {
if dx<0 {
exv.cnt=-6
}
else {
exv.cnt=6
}
}
if et.cnt>25 : eyv.cnt-- : if eyv.cnt<-10 : eyv.cnt=-10
if ey.cnt>200 : gosub *tamaborn
ex.cnt=ex.cnt+exv.cnt
ey.cnt=ey.cnt+eyv.cnt
if ex.cnt<-50 : ef.cnt=0
if ex.cnt>640 : ef.cnt=0
if ey.cnt<-50 : ef.cnt=0
if ey.cnt>480 : ef.cnt=0
pos ex.cnt,ey.cnt

gmode 1,50,50 : es_copy 0,300,0
return


■ 敵3
*enemy3
dx=mx-ex.cnt
if et.cnt<2 {
if dx<0 {
exv.cnt=-3
}
else {
exv.cnt=3
}
}
if ey.cnt>200 : eyv.cnt--
if et.cnt>20 : if ey.cnt<50 : eyv.cnt++
if ey.cnt>200 : gosub *tamaborn
if et.cnt>20 : if ey.cnt<50 : gosub *tamaborn
ex.cnt=ex.cnt+exv.cnt
ey.cnt=ey.cnt+eyv.cnt
if ex.cnt<-50 : ef.cnt=0
if ex.cnt>640 : ef.cnt=0
if ey.cnt<-50 : ef.cnt=0
if ey.cnt>480 : ef.cnt=0
pos ex.cnt,ey.cnt

gmode 1,50,50 : es_copy 0,350,0
return


;■ 弾生成
*tamaborn
if frame\(8-(level/4))>0 : return
dx=mx-ex.cnt : px=dx : if dx<0 : dx=0-dx
dy=my-ey.cnt : py=dy : if dy<0 : dy=0-dy
dst=(dx*dx)+(dy*dy)
edx=ex.cnt+12 : edy=ey.cnt+12
repeat 900
if dst<calc.cnt : dst=cnt : break
loop
repeat tmax
if tf.cnt>0 : continue
tf.cnt=1
tx.cnt=edx : ty.cnt=edy
rnd ds,8 : ds=level/5+3+ds
txv.cnt=px*ds/dst
tyv.cnt=py*ds/dst
break
loop
return


;■ 敵弾移動 & 当り判定
*tekitamamove
repeat tmax
if tf.cnt<1 : continue
tx.cnt=tx.cnt+txv.cnt
ty.cnt=ty.cnt+tyv.cnt
if tx.cnt>640 : tf.cnt=0 : continue
if tx.cnt<-25 : tf.cnt=0 : continue
if ty.cnt>480 : tf.cnt=0 : continue
if ty.cnt<-25 : tf.cnt=0 : continue
dx=(mx+25)-(tx.cnt+12) : if dx<0 : dx=-dx
dy=(my+25)-(ty.cnt+12) : if dy<0 : dy=-dy
if (dx<5)&(dy<5) {
repeat tmax : tf.cnt-- : loop
pos tx.cnt,ty.cnt

gmode 1,25,25 : es_copy 0,175,25
bgcolor=128
snd 1
mf--
}
if (dx<30)&(dy<30) {
score++

ent=cnt
repeat cmax
if cf.cnt>0 : continue
cx.cnt=tx.ent+10
cy.cnt=ty.ent+10
rnd cxv.cnt,3 : cxv.cnt-1
rnd cyv.cnt,3 : cyv.cnt-1
cf.cnt=10
break
loop

}
pos tx.cnt,ty.cnt

gmode 1,25,25
es_copy 0,175,0
loop
return


;■ 倍率表示
*messageborn
dmy=my-ey.ent : if dmy<0 : dmy=-dmy
dstv=480-dmy/50
if highdst<dstv : highdst=dstv
dstlevel=level
dstcore=dstv*dstlevel
score=en.ent*100*dstcore+score
repeat imax
if iff.cnt>0 : continue
ix.cnt=ex.ent
iy.cnt=ey.ent
iv.cnt=dstv
iff.cnt=40
in.cnt=en.ent*100
il.cnt=dstlevel
break
loop
return

;■ ゲーム情報
*message

repeat cmax
if cf.cnt<1 : continue
cx.cnt=cx.cnt+cxv.cnt
cy.cnt=cy.cnt+cyv.cnt
gmode 1,5,5
cw=10-cf.cnt*5
pos cx.cnt,cy.cnt
es_copy 0,405,cw
cf.cnt--
loop

repeat imax
if iff.cnt<1 : continue
rnd icr,8 : icr=icr*32+31
rnd icg,8 : icg=icg*32+31
rnd icb,8 : icb=icb*32+31
color icr,icg,icb
font "Impact",iv.cnt*5+12
pos ix.cnt,iy.cnt

es_fmes ""+in.cnt+" x "+iv.cnt
iy.cnt++
iff.cnt--
loop

font "MSゴシック",12,3
if highscore<score : highscore=score
color 0,255,255
pos 10,10

es_fmes "HIGHSCORE "+highscore

color 255,255,255
pos 10,30

es_fmes "SCORE "+score

color 0,255,0
pos 10,50

es_fmes "HIGH DISTANCE "+highdst

color 255,255,0
pos 10,70

es_fmes "LEVEL "+level

color 255,255,255
pos 10,460

es_fmes "SHIELD "
if mf<1 : return
repeat mf
color 255,cnt*32,0
pos cnt*10+60,460

es_fmes "■"
loop
return


;■ 自機爆風
*bomb
repeat bmax
bf.cnt--
if bf.cnt<1 {
rnd bf.cnt,10 : bf.cnt=bf.cnt+10
rnd bx.cnt,50 : bx.cnt=25-bx.cnt+mx
rnd by.cnt,50 : by.cnt=25-by.cnt+my
}
pos bx.cnt,by.cnt

gmode 1,50,50 : es_copy 0,200,0
rnd dbx,10 : dbx=dbx-5
bx.cnt=bx.cnt+dbx
by.cnt=by.cnt+10
loop
rnd effect,10
if effect=0 : snd 1 : bgcolor=128
if effect=1 : snd 2 : bgcolor=255
return


;■ ポーズ処理
*pausegame
es_cls
gosub *message ;ゲーム情報
font "MSゴシック",40,3
rnd icr,8 : icr=icr*32+31
rnd icg,8 : icg=icg*32+31
rnd icb,8 : icb=icb*32+31
color icr,icg,icb
pos 250,200

es_fmes "PAUSE"
stick pat : stick pat,79 : jstick 79 : if stat!0 : pat=stat
if pat&128>0 : return
getkey returntop,123 : if returntop=1 : end ; 強制終了(F12)
es_sync 30
await 0
goto *pausegame


;■ ゲームオーバー
*gameover
es_cls
gosub *message ;ゲーム情報
font "MSゴシック",40,3
rnd icr,8 : icr=icr*32+31
rnd icg,8 : icg=icg*32+31
rnd icb,8 : icb=icb*32+31
color icr,icg,icb
pos 200,200

es_fmes "GAME OVER"
pos 30,250
es_fmes "PUSH RETURN TO RESTART"
stick pat : stick pat,79 : jstick 79 : if stat!0 : pat=stat
if pat&32>0 : goto *gamestart
getkey returntop,123 : if returntop=1 : end ; 強制終了(F12)
es_sync 30
await 0
goto *gameover

hspdxfix.dll対応にする際に変更を加えた箇所はこの色になってます。大きく異なるのは基本設定の部分と、ポーズ&ゲームオーバーの処理です。その瞬間の画面のまま静止させるのが面倒だったので、ポーズ&ゲームオーバーのルーチンはその部分だけでループさせてます。画面上には文字しか表示されないです。もしやるとしたら、敵や自機などの表示だけをさせるルーチンを用意しましょう。試しに作ってみましたがやっぱり面倒でしたes_getbufを使って画面全部をbufferに保存して表示する・・・というやり方も試してみたんですが、こちらはうまくいかなかったです^^;

後はmes命令が全部es_fmesに変わってます。この命令は単純に置き換えできるので、エディタの置換機能で一気に変更しちゃいましょう。gcopyの部分も単純置換できるかな?

後は、カスリ効果を視認できるようにしたのと倍率表示を派手にしたのが変更点。もちろん改造元のスクリプトでやらかしてた部分(無駄な計算や、動かす前に表示しちゃってた事)も直してます^^;

« [改造記]画面描写(es_copy) | トップページ | [改造記]スプライトを使う準備 »

3.改造記」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/67538/57445622

この記事へのトラックバック一覧です: [改造記]解剖記のスクリプトを改造しよう:

« [改造記]画面描写(es_copy) | トップページ | [改造記]スプライトを使う準備 »