忍者ブログ
まったくのプログラミング素人の筆者がC++/HSPを使用してSTG(シューティングゲーム)を作っていく過程を書くブログでしたが最近は脱線気味。プログラミング以外にも、ゲーム関連の記事、日々の戯言など。
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

先日作った弾幕サンプルを利用して、ゲームっぽく弾幕を撃たせてみた。
5211.jpg
こんな感じなんですが、まぁゲームとしては殆ど成り立ってませんが弾幕ゲーっぽくて良い感じです^^

ついでに、開始時のフルスクリーン選択、ボム処理、Zボタンを押している時の自機のスピードダウンなんかを追加
フルスクリーンはchgdisp命令で解像度を変更してbgscrとgsel命令で一番手前に画面を持ってくれば出来ました。

スプリクトはコチラ↓
*************************************
;初期設定
#include "CK_JOYFORCE.AS"
dialog "fullscreenで起動しますか?「はい」を選択した場合、画面解像度を640×480に変更します。",2
if stat=6:fullscreen=0
if stat=7:fullscreen=1
if fullscreen=0 : chgdisp 1,640,480 : mouse -1 ;ディスプレイ解像度を640×480に。マウスを表示しない
*start
buffer 3 ;ウィンドウ3をバッファ画面として用意
picload "stg8.gif";画像をバッファ3に読み込み
buffer 4 ; ウィンドウ4をバッファ画面として用意
picload "s399.jpg" ;背景画像をバッファ4に読み込み
buffer 5 ; ウィンドウ4をバッファ画面として用意
picload "bomb.gif" ;ボム画像をバッファ5に読み込み
ssp=482 ;スクロール速度
wxs=320 :wys=480 ;ゲーム画面の座標設定
screen 2,640,480,1;メイン画面(ウィンドウ2を480*640で用意)
bgscr 2,640,480,2 : gsel 2,1 ;メイン画面を初期化して枠のないウィンドウを作成。メイン画面をアクティブに
gtime=0 ;フレーム数
px=304:py=448;自機の初期位置
tmx=10 ;自機弾の数
dim tx,tmx ;自機弾のX座標の配列変数
dim ty,tmx ;自機弾のY座標の配列変数
dim tf,tmx ;自機弾が画面にあるか無いかを調べる配列変数

emx=50;敵の数
dim ex,emx : dim ey,emx;敵の初期位置
dim dx,emx : dim dy,emx;敵の移動量
dim ef,emx;敵のフラグ
dim em,emx;敵の種類
dim et,emx;敵出現からの時間
dim bbmx,emx;ボムで爆破時の爆発のx座標
dim bbmy,emx;ボムで爆破時の爆発のy座標
dim bbmc,emx;ボムカウント

emt=2000;敵の弾
dim etx,emt : dim ety,emt ;敵弾の位置、移動量
dim etxv,emt; etxv 敵弾x方向運動量
dim etyv,emt; etyv 敵弾y方向運動量
dim etf,emt;敵弾のフラグ

sc=0;スコア
gend=0;ゲームオーバー処理の為の変数
bombcnt=-1;ボム処理の為の変数(-1でボムを撃っていない)
nbomb=30;ボムの数

*main
redraw 0 ;仮想画面を指定
color 0,0,0 ;色に黒を指定

;スクロール処理
gmode 1 ; ノーマルコピーモード
scr=(scr+ssp)¥wys ; コピー元座標を算出
pos 160,scr :gcopy 4,0,0,wxs,wys-scr ;
if scr!0 { pos 160,0 ; 背景画像をコピー
gcopy 4,0,wys-scr,wxs,scr ;
} ;

;面データ読み込み
gosub *men ;*men(タイムテーブル)へ移動

;自機移動処理
pk=0 ;自機の傾きの為の変数
ck_joystick ky,15;キーボードのチェック
if ky&1 :px-=move :pk=32 :if px<160 :px=160;カーソルキー左(←)を押した時pxよりmoveを引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=move :pk=64 :if px>448 :px=448
if ky&2 :py-=move :if py<0 :py=0
if ky&8 :py+=move :if py>448 :py=448
gmode 2 ;透明化処理の為の命令
pos px,py;自機の座標指定
gcopy 3,pk,0,32,32;バッファ画面(ウィンドウ1)より自機画像をコピー

;自機弾発射処理
shottime-- ;連射為の処理
if shottime<0: st=1 ;shottimeが0以下の時、stに1を代入
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)=0 : if st=1{ ;tf(cnt)が0の時=画面に弾がない時、かつstが1の時(shottimeが0以下の時){}内の命令を行う
tx(cnt)=px ;tx(cnt)(弾のx座標)にpx(自機のx座標)の値を代入
ty(cnt)=py-20 ;ty(cnt)(弾のy座標)にpy(自機のy座標)より20引いた値を代入。(弾と自機が重ならないようにする為)
tf(cnt)=1 ;tf(cnt)に1を代入。画面に弾があると言う事
st=0 ;連射の為の処理
shottime=3 ;連射の為の処理
}
ty(cnt)-=12 : if ty(cnt)<-32 : tf(cnt)=0 :ty(cnt)=-32: st=0;弾を進めて画面から出たら弾を消す
if tf(cnt)=1{ ;画面に弾があるとき、{}内の命令を行う
pos tx(cnt),ty(cnt) ;自機弾の座標指定
gcopy 3,96,0,32,32 ;バッファ画面(ウィンドウ1)より自機弾画像をコピー
}
loop
ck_joystick ky,2048 ;Zキーのチェック
if ky&2048 { ;Zキーが押されていた時はmove(自機移動速度)を1にする。そうでなければmoveを3にする
move=1 }else{
move=3
}

;ボム処理
ck_joystick ky,4096 ;Xキーのチェック
if ky&4096 { ;Xキーが押された時は{}内の命令を行う
if (bombcnt=-1)&(nbomb>0) { ;ボムが画面に出てなく、ボム数が0以上の時
nbomb=nbomb-1 ;ボム数を1減らす
bombcnt=0:bombp=17 ;ボムの存在を有にする。ボムアニメの為に変数を用意。
bpx=px-152 : bpy=py-400;ボムの座標指定
}
}
if bombcnt!-1 { ;ボムが画面に有る時。!は-1以外の時という事
repeat emt ;弾の存在を調べ画面に弾がある時は、弾の存在を消す(etf(cnt)=0)
if etf(cnt)<1 : continue
etf(cnt)=0
loop
bombcnt=bombcnt+1 ;ボムの効いている時間処理
if bombcnt=20 { bombcnt=-1 } ;20フレーム過ぎたらボムが効かなくなる
}
if bombcnt!-1 {
repeat emx ;敵の存在を調べ、敵がいる時は敵体力から1を引く(ef(cnt)-)
if ef(cnt)<1 : continue
ef(cnt)-
if ef(cnt)=0 : bbmx(cnt)=ex(cnt)+8 : bbmy(cnt)=ey(cnt)+8 :bbmc(cnt)=17
;敵体力が0になったら爆発させる
loop
}

;敵移動処理
repeat emx ;repeat〜loop間をemx回繰り返す
ent=cnt
et(cnt)++ ;敵出現時間を+
if ef(cnt)<1 : continue ;ef(cnt)が1以下(敵が画面にいない)ならばrepeatに戻る
if enm(cnt)=3 : gosub *em03 ;敵の名前が3の時*em03へ移動
loop

;敵弾発射処理
repeat emt ;repeat〜loop間をemt回繰り返す
if etf(cnt)=1 { ;etf(cnt)が1(敵弾が画面にあるなら){}内の命令を行う
etx(cnt)=etx(cnt)+etxv(cnt) ;敵弾x座標に敵弾移動速度をプラス
ety(cnt)=ety(cnt)+etyv(cnt) ;敵弾y座標に敵弾移動速度をプラス
pos etx(cnt),ety(cnt) ;敵弾の座標指定
gcopy 3,96,48,16,16 ;バッファ画面(ウィンドウ1)より敵弾画像をコピー
if etx(cnt)>480 : etf(cnt)=0 ;敵弾x座標が480以上になったら弾の存在を消す
if etx(cnt)<152 : etf(cnt)=0
if ety(cnt)>480 : etf(cnt)=0
if ety(cnt)<-16 : etf(cnt)=0
}
loop

;敵弾当り判定
repeat emt ;emt回繰り返す
if etf(cnt)=0 : continue
ddx=(etx(cnt)+8)-(px+16) : if ddx<0 : ddx=-ddx ;自機と弾の中心座標の差の絶対値を求める
ddy=(ety(cnt)+8)-(py+16) : if ddy<0 : ddy=-ddy
if (ddx<2)&(ddy<2) { ;x軸とy軸の差が2以下の時、ゲームオーバー
gend=1 ;1にするとゲームオーバー
}
loop

;爆風とボムのアニメ処理
if bombp>0 { ;ボムのアニメ処理変数が0以上の時{}内の命令を行う
bombp- : pos bpx,bpy
gcopy 5,320*(16-bombp),0,320,480
}
repeat emx ;敵のアニメ処理変数が0以上の時{}内の命令を行う
if bbmc(cnt)>0 {
bbmc(cnt)- : pos bbmx(cnt),bbmy(cnt)
gcopy 3,128+48*(16-bbmc(cnt)),0,48,48
}
loop


color 0,0,0 ;色に黒を指定
boxf 0,0,160,480 ;画面右側を黒で塗りつぶす
boxf 480,0,640,480 ;画面左側を黒で塗りつぶす

;スコア表示
font msmincho,18,3 ;フォントをMS明朝に、大きさを18に、イタリック体太字に指定
color 255,255,255 ;色に白を指定
pos 0,0
mes"Escで終了"
pos 496,0
mes"SCORE-"+sc+"-"
pos 496,462
mes"BOMB-"+nbomb+"-"
if gend=1 : gosub *gameover ;gendが1(ゲームオーバーの時)*gameoverに移動
redraw 1 ;メイン画面を更新
await 16 ;これを入れないとパソコンが固まる
gtime=gtime+1 ;タイムテーブルの為の変数
getkey syuryo,27:if syuryo=1:end ;Escキーのチェック。押されたら終了
goto *main ;*mainに戻る

;サブルーチン
*men ;タイムテーブル

if gtime=1 : bx=170 : by=-64 : gosub *eb03
if gtime=126 : bx=406 : by=-64 : gosub *eb03
if gtime=376 : bx=170 : by=-64 : gosub *eb03
if gtime=500 : bx=406 : by=-64 : gosub *eb03

if gtime=1000 : gtime=0
return

*eb03;敵発生処理
repeat emx
if ef(cnt)>0 : continue ;画面に敵がいなければrepeatに戻る
enm(cnt)=3 ;敵の名前
ef(cnt)=30 ;敵の体力
ex(cnt)=bx : ey(cnt)=by ;敵生成位置決定
dx(cnt)=0 : dy(cnt)=1 ;移動方向
et(cnt)=0 ;敵弾生成時間をリセット
break ;repeat〜loop間のループから、強制的に抜け出す
loop
return


*em03;敵移動処理
if et(cnt)>200 : if gtime¥20=0 : gosub *tekitama3 ;敵生成時間が200以上の時かつgtimeを20で割った余りが0の時*tekitama3へ移動
ex(cnt)=ex(cnt)+dx(cnt) ;敵の移動量決定
ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if et(cnt)>180 : dy(cnt)=0
if et(cnt)>500 : dy(cnt)=1
if ey(cnt)>480 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : gcopy 3,0,96,64,64 ;敵3の表示

;敵と自機との当り判定
ddx=(ex(cnt)+32)-(px+16) : if ddx<0 : ddx=-ddx
ddy=(ey(cnt)+32)-(py+16) : if ddy<0 : ddy=-ddy
if (abs(ddx<32))&(abs(ddy<32)) {
gend=1
}

;自機弾と敵との当り判定
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)<1 : continue ;tf(cnt)が1以下(弾が画面にいない)ならばrepeatに戻る

ddx=(ex(ent)+32)-(tx(cnt)+16) : if ddx<0 : ddx=-ddx
ddy=(ey(ent)+32)-(ty(cnt)+16) : if ddy<0 : ddy=-ddy
if (abs(ddx<32))&(abs(ddy<32)) { ;自機弾と敵のx軸とy軸の座標差を求め(敵と自機弾全て)、どちらも32以下であれば{}}内の命令を行う
tf(cnt)=0 ;弾が当った時は弾の存在を消す
ef(ent)- ;弾が当った時は敵の存在を消す
sc+1000
pos ex(ent),ey(ent)
gcopy 3,192,96,64,64
if ef(ent)=0 : gosub *bomb1
}
loop
return

*tekitama3;敵弾発生処理
edx=ex(ent)+28 : edy=ey(ent)+32
repeat emt
if etf(cnt)>0 : continue ;etfが0(敵弾が画面に無い時)、emn(cnt)が1(敵の名前が1の時)の場合if{}内の命令を行う
eh=eh+1 : etf(cnt)=1 ;弾数の為の処理。弾の存在を有にする
etx(cnt)=double(edx) : ety(cnt)=double(edy) ;弾の初期座標
ds=3 ;敵弾の速さ
r=double(r+0.1) ;弾の角度を実数で計算
etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds ;弾の移動量を角度より計算
if eh>62 : eh=0 :break ;63発弾を撃った時点でrepeatを抜ける
loop
return

*bomb1;敵爆破処理
bbmx(ent)=ex(ent)+8 : bbmy(ent)=ey(ent)+8 ;爆風の座標指定
bbmc(ent)=17 ;爆風アニメの為の変数
return

*gameover
color rnd(255),rnd(255),rnd(255) ;色指定
pos 280,228
mes "Game Over"
pos 230,248
mes"Press X to Continue"
redraw 1
wait 1
ck_joystick ky ;Xキーのチェック。押されたら*startに戻る
if ky=4096 :goto *start
getkey syuryo,27:if syuryo=1:end
goto *gameover
*************************************
HSP3.0使用、CK_JOYFORCE.DLL使用、画像は↓を使用
bomb.gif  s399.jpg  stg8.gif

このスプリクトでは、Zキーを押していないときに弾を発射させて、Zボタンを押した時は自機のスピードを遅くしています。
CAVEシューっぽいですね(汗)
Xキーでボム発射。ボム処理はまだまだですね・・・もっと派手派手にしたいんですが研究中です。
ちなみに、敵移動処理のif gtime¥20=0の20や、敵弾発生処理のr=double(r+0.1)やif eh>62の0.1、62などの数字を弄ると色んな弾幕が撃てます。
5212.jpg
こんな事も出来ますよ^^
しかし、筆者の開発マシンはP4/1.7Gのノートなのですが、全体的に処理が重いです。
色んなHSPサイトを見てみてもDirectXを使った方が速度は速くなるようなので、DirectXを使うようにしようか迷ってます。
PR
この記事にコメントする
お名前
タイトル
メールアドレス
URL
コメント
パスワード   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
初めまして
こんにちは。
ここのスクリプトを参考にHSPでSTG作ってる者です。
いつも有難う御座います。

質問があるのですが、ここのスクリプトと、2006年5月19日の弾幕スクリプトでは断然こちらの方が軽いのですが、なぜでしょうか?

最近HSP言語を始めたばかりなので、ソースを見ても大した違いが判らないです。

宜しければ教えてもらえると有難いです。
GIL 2008/07/29(Tue)11:09:32 編集
無題
GILさん>
はじめまして。
私の環境では、どちらもそれ程変わらないので良くわかりませんが、多分、画面全体での敵弾の総数が19日のスクリプトよりも21日のスクリプトの方が少ないからではないかな?と思います。
どちらも、やっている事にかわりはありませんので。
STG作製頑張って下さいね。
kt. 2008/07/30(Wed)00:16:43 編集
この記事へのトラックバック
この記事にトラックバックする:
カウンター
ゲーマータグ
Twitter
携帯百景
カレンダー
06 2017/07 08
S M T W T F S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
最新コメント
[11/24 kt.]
[11/24 kt.]
[11/24 NONAME]
[11/23 NONAME]
[10/05 tejas]
プロフィール
HN:
kt.
HP:
性別:
男性
自己紹介:
STG大好きな40歳。
プログラミング経験は昔ファミリーベーシックでちょっとさわったくらい。
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!
ブログ内検索
アクセス解析
忍者ブログ [PR]