まったくのプログラミング素人の筆者がC++/HSPを使用してSTG(シューティングゲーム)を作っていく過程を書くブログでしたが最近は脱線気味。プログラミング以外にも、ゲーム関連の記事、日々の戯言など。
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
さー次は敵を作ろう!と思ってとりあえず敵を作ってみた。

これもDOGA-L2を使用して書いてるんですが、凄いソフトだなーと感心してしまう。
ほんと簡単に作成出来て、色んな人が使ってるのも納得って感じ。
んで敵の生成なんですが、ここでつまづいた。本に載ってるスプリクトや色んな解説サイトなんかを見てみても
敵の生成はランダムで行ってるんですよね。でも、ランダムで敵が出てくるのってどうよ?って思う訳です。
出来れば、自分の思うような順番で敵を生成したい!と思い色々と考えたんですがまったく良いアイデアも浮かばず
どうすんだ?と思っていたら、これまた遊々窓々さんのサイトで素晴らしいスプリクトを発見。
ここのStarshipって言うスプリクトにすべての答えが書いてあった!
具体的にどうしたかと言うのが↓このスプリクト(とりあえず敵しか出ません)
*************************************
;初期設定
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg2.gif";画像をバッファに読み込み
screen 0,480,640,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
emx=12;敵の数
dim ex,emx : dim ey,emx;敵の初期位置
dim dx,emx : dim dy,emx;敵の移動量
dim ef,emx;敵のフラグ
dim em,emx;敵の種類
*main
redraw 0 ;仮想画面を指定
color 0,0,0 ;色に黒を指定
boxf 0,0,480,640 ;仮想画面を黒で塗りつぶす
gosub *men ;*men(タイムテーブル)へ移動
;敵移動処理
repeat emx ;repeat〜loop間をemx回繰り返す
if ef(cnt)<1 : continue ;ef(cnt)が1以下(敵が画面にいない)ならばrepeatに戻る
if enm(cnt)=1 : gosub *em01 ;enm(cnt)(敵の名前)が1ならば*em01へ移動
if enm(cnt)=2 : gosub *em02
loop
redraw 1 ;メイン画面を更新
await 1 ;これを入れないとパソコンが固まる
gtime=gtime+1 ;タイムテーブルの為の変数
goto *main ;*mainに戻る
*men ;タイムテーブル
if gtime=0 : bx=0 : by=-64 : gosub *eb01;gtimeが0の時、bxに0をbyに-64を代入し*eb01に移動
if gtime=1 : bx=416 : by=-64 : gosub *eb01
if gtime=50 : bx=80 : by=-64 : gosub *eb01
if gtime=51 : bx=336 : by=-64 : gosub *eb01
if gtime=100 : bx=160 : by=-64 : gosub *eb01
if gtime=101 : bx=256 : by=-64 : gosub *eb01
if gtime=150 : bx=0 : by=-64 : gosub *eb02
if gtime=151 : bx=415 : by=-64 : gosub *eb02
if gtime=200 : bx=0 : by=-64 : gosub *eb02
if gtime=201 : bx=415 : by=-64 : gosub *eb02
if gtime=250 : bx=0 : by=-64 : gosub *eb02
if gtime=251 : bx=415 : by=-64 : gosub *eb02
return
*eb01
repeat emx ;repeat〜loop間をemx回繰り返す
if ef(cnt)>0 : continue ;ef(cnt)が0以上(すでに敵が画面にいる)ならばrepeatに戻る
enm(cnt)=1 ;敵の名前
ef(cnt)=1 ;敵の有無(1=有)
ex(cnt)=bx : ey(cnt)=by ;敵生成位置決定
dx(cnt)=0 : dy(cnt)=2 ;移動方向
break ;repeat〜loop間のループから、強制的に抜け出す
loop
return
*eb02
repeat emx
if ef(cnt)>0 : continue
enm(cnt)=2 ;敵の名前
ef(cnt)=1 ;敵の有無(1=有)
ex(cnt)=bx : ey(cnt)=by ;敵生成位置決定
dx(cnt)=3 : dy(cnt)=1 ;移動方向
break ;repeat〜loop間のループから、強制的に抜け出す
loop
return
*em01
ex(cnt)=ex(cnt)+dx(cnt) : ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if ey(cnt)>640 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : gcopy 1,0,64,64,64 ;敵1の表示
return
*em02
ex(cnt)=ex(cnt)+dx(cnt) ;敵の移動量決定
if(ex(cnt)<1)|(ex(cnt)>415) :dx(cnt)=-dx(cnt) ;画面の端まで行ったら反転させる
ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if ey(cnt)>640 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : gcopy 1,0,128,64,64 ;敵2の表示
return
*************************************
HSP3.0使用 画像は上の画像を使用
動かすとこんな感じ

まずgtimeという変数を使って時間の概念を導入する。gtimeはメインループ1回ごとに1増えていく。
例えばgtimeが10の時に敵1を任意の場所へ表示、gtimeが20の時に敵2を任意の場所へ表示・・・
と言った感じで1面分の敵を全て書いてしまえば(タイムテーブルと言うらしい)思い通りに敵を出現できる。
いやー、この遊々窓々さんのスプリクト見た時は、おお!と感動してしまいました。(こんな事でと思われるかもしれませんが(汗))
簡単にスプリクトの説明をすると、まずタイムテーブルを読みに行って、そこで敵の座標などを決定。
んで敵の数だけ生成を行って、移動させて表示。
って文章だと簡単だけど、こんなの思いつきませんって(笑)
まだ、敵のアルゴリズムやアニメーションなど全然出来てませんが、すげーレベルアップしたような気になりました^^
これもDOGA-L2を使用して書いてるんですが、凄いソフトだなーと感心してしまう。
ほんと簡単に作成出来て、色んな人が使ってるのも納得って感じ。
んで敵の生成なんですが、ここでつまづいた。本に載ってるスプリクトや色んな解説サイトなんかを見てみても
敵の生成はランダムで行ってるんですよね。でも、ランダムで敵が出てくるのってどうよ?って思う訳です。
出来れば、自分の思うような順番で敵を生成したい!と思い色々と考えたんですがまったく良いアイデアも浮かばず
どうすんだ?と思っていたら、これまた遊々窓々さんのサイトで素晴らしいスプリクトを発見。
ここのStarshipって言うスプリクトにすべての答えが書いてあった!
具体的にどうしたかと言うのが↓このスプリクト(とりあえず敵しか出ません)
*************************************
;初期設定
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg2.gif";画像をバッファに読み込み
screen 0,480,640,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
emx=12;敵の数
dim ex,emx : dim ey,emx;敵の初期位置
dim dx,emx : dim dy,emx;敵の移動量
dim ef,emx;敵のフラグ
dim em,emx;敵の種類
*main
redraw 0 ;仮想画面を指定
color 0,0,0 ;色に黒を指定
boxf 0,0,480,640 ;仮想画面を黒で塗りつぶす
gosub *men ;*men(タイムテーブル)へ移動
;敵移動処理
repeat emx ;repeat〜loop間をemx回繰り返す
if ef(cnt)<1 : continue ;ef(cnt)が1以下(敵が画面にいない)ならばrepeatに戻る
if enm(cnt)=1 : gosub *em01 ;enm(cnt)(敵の名前)が1ならば*em01へ移動
if enm(cnt)=2 : gosub *em02
loop
redraw 1 ;メイン画面を更新
await 1 ;これを入れないとパソコンが固まる
gtime=gtime+1 ;タイムテーブルの為の変数
goto *main ;*mainに戻る
*men ;タイムテーブル
if gtime=0 : bx=0 : by=-64 : gosub *eb01;gtimeが0の時、bxに0をbyに-64を代入し*eb01に移動
if gtime=1 : bx=416 : by=-64 : gosub *eb01
if gtime=50 : bx=80 : by=-64 : gosub *eb01
if gtime=51 : bx=336 : by=-64 : gosub *eb01
if gtime=100 : bx=160 : by=-64 : gosub *eb01
if gtime=101 : bx=256 : by=-64 : gosub *eb01
if gtime=150 : bx=0 : by=-64 : gosub *eb02
if gtime=151 : bx=415 : by=-64 : gosub *eb02
if gtime=200 : bx=0 : by=-64 : gosub *eb02
if gtime=201 : bx=415 : by=-64 : gosub *eb02
if gtime=250 : bx=0 : by=-64 : gosub *eb02
if gtime=251 : bx=415 : by=-64 : gosub *eb02
return
*eb01
repeat emx ;repeat〜loop間をemx回繰り返す
if ef(cnt)>0 : continue ;ef(cnt)が0以上(すでに敵が画面にいる)ならばrepeatに戻る
enm(cnt)=1 ;敵の名前
ef(cnt)=1 ;敵の有無(1=有)
ex(cnt)=bx : ey(cnt)=by ;敵生成位置決定
dx(cnt)=0 : dy(cnt)=2 ;移動方向
break ;repeat〜loop間のループから、強制的に抜け出す
loop
return
*eb02
repeat emx
if ef(cnt)>0 : continue
enm(cnt)=2 ;敵の名前
ef(cnt)=1 ;敵の有無(1=有)
ex(cnt)=bx : ey(cnt)=by ;敵生成位置決定
dx(cnt)=3 : dy(cnt)=1 ;移動方向
break ;repeat〜loop間のループから、強制的に抜け出す
loop
return
*em01
ex(cnt)=ex(cnt)+dx(cnt) : ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if ey(cnt)>640 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : gcopy 1,0,64,64,64 ;敵1の表示
return
*em02
ex(cnt)=ex(cnt)+dx(cnt) ;敵の移動量決定
if(ex(cnt)<1)|(ex(cnt)>415) :dx(cnt)=-dx(cnt) ;画面の端まで行ったら反転させる
ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if ey(cnt)>640 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : gcopy 1,0,128,64,64 ;敵2の表示
return
*************************************
HSP3.0使用 画像は上の画像を使用
動かすとこんな感じ
まずgtimeという変数を使って時間の概念を導入する。gtimeはメインループ1回ごとに1増えていく。
例えばgtimeが10の時に敵1を任意の場所へ表示、gtimeが20の時に敵2を任意の場所へ表示・・・
と言った感じで1面分の敵を全て書いてしまえば(タイムテーブルと言うらしい)思い通りに敵を出現できる。
いやー、この遊々窓々さんのスプリクト見た時は、おお!と感動してしまいました。(こんな事でと思われるかもしれませんが(汗))
簡単にスプリクトの説明をすると、まずタイムテーブルを読みに行って、そこで敵の座標などを決定。
んで敵の数だけ生成を行って、移動させて表示。
って文章だと簡単だけど、こんなの思いつきませんって(笑)
まだ、敵のアルゴリズムやアニメーションなど全然出来てませんが、すげーレベルアップしたような気になりました^^
PR
昨日作ったスプリクトで弾は発射されるようになったけど連射が上手く出来なかった。
上手く出来なかったってのは、連射はするんだけど連射速度が速すぎて10発撃ってるはずなのに
連射が早すぎて殆ど一発にしか見えなかった。
で、色々といじくってみたけど上手くいかず、どうしたもんかとネットを検索していると
遊々窓々さんと言うサイトを発見。ここのHSP講座を見てやっと上手く連射出来るようになった^^
ちゅうか、ここのHSP講座すげーわかりやすい!ソースも公開しておられるし、筆者のような初心者は必見の内容です。
で連射はどうするかと言うと、今までは一回のループで全発発射していたので、処理が早すぎて
おかしな事になっていたので、弾の発射処理を3回のループに1回行うように(5回に1回でも10回に1回でも連射速度によって変えればOK)
すれば自分の思う連射速度に調整出来る。んで、Zキーを押してる時だけ弾の発射処理を行うようにすれば・・・

おお!無事、ボタンを押してる間だけ連射されてる!
このスプリクトで言えば、shottimeの数値を変えるだけで、連射速度も自由自在。
で、昨日のスプリクトのままだと透明化処理が出来なくて、これまたおかしな事になってたんだけど
これも、gcopyのまえにgmode 2と記述すれば0番の黒い色を勝手に透明化処理してくれてる。いやー良い感じです。
連射出来るようになったスプリクトはコレ↓昨日のスプリクトの自機弾発射処理の部分を差し替えるだけでOK
*************************************
;自機弾発射処理
shottime-- ;連射為の処理
ck_joystick ky,2048 ;Zキーのチェック
if ky&2048 : if shottime<0: st=1 ;Zキーが押されていて、かつshottimeが0以下の時、stに1を代入
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)=0 : if st=1{ ;tf(cnt)が0の時=画面に弾がない時、かつstが1の時(Zキーを押している時){}内の命令を行う
tx(cnt)=px ;tx(cnt)(弾のx座標)にpx(自機のx座標)の値を代入
ty(cnt)=py-40 ;ty(cnt)(弾のy座標)にpy(自機のy座標)より40引いた値を代入。(弾と自機が重ならないようにする為)
tf(cnt)=1 ;tf(cnt)に1を代入。つまり画面に弾があると言う事
st=0 ;連射の為の処理
shottime=3 ;連射の為の処理
}
ty(cnt)-=10 : if ty(cnt)<-64 : tf(cnt)=0 :ty(cnt)=-64: st=0;弾を進めて画面から出たら弾を消す
if tf(cnt)=1{ ;画面に弾があるとき、{}内の命令を行う
pos tx(cnt),ty(cnt) ;自機弾の座標指定
gmode 2 ;透明化処理の為の命令
gcopy 1,192,0,64,64 ;;バッファ画面(ウィンドウ1)より自機弾画像をコピー
}
loop
*************************************
上手く出来なかったってのは、連射はするんだけど連射速度が速すぎて10発撃ってるはずなのに
連射が早すぎて殆ど一発にしか見えなかった。
で、色々といじくってみたけど上手くいかず、どうしたもんかとネットを検索していると
遊々窓々さんと言うサイトを発見。ここのHSP講座を見てやっと上手く連射出来るようになった^^
ちゅうか、ここのHSP講座すげーわかりやすい!ソースも公開しておられるし、筆者のような初心者は必見の内容です。
で連射はどうするかと言うと、今までは一回のループで全発発射していたので、処理が早すぎて
おかしな事になっていたので、弾の発射処理を3回のループに1回行うように(5回に1回でも10回に1回でも連射速度によって変えればOK)
すれば自分の思う連射速度に調整出来る。んで、Zキーを押してる時だけ弾の発射処理を行うようにすれば・・・
おお!無事、ボタンを押してる間だけ連射されてる!
このスプリクトで言えば、shottimeの数値を変えるだけで、連射速度も自由自在。
で、昨日のスプリクトのままだと透明化処理が出来なくて、これまたおかしな事になってたんだけど
これも、gcopyのまえにgmode 2と記述すれば0番の黒い色を勝手に透明化処理してくれてる。いやー良い感じです。
連射出来るようになったスプリクトはコレ↓昨日のスプリクトの自機弾発射処理の部分を差し替えるだけでOK
*************************************
;自機弾発射処理
shottime-- ;連射為の処理
ck_joystick ky,2048 ;Zキーのチェック
if ky&2048 : if shottime<0: st=1 ;Zキーが押されていて、かつshottimeが0以下の時、stに1を代入
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)=0 : if st=1{ ;tf(cnt)が0の時=画面に弾がない時、かつstが1の時(Zキーを押している時){}内の命令を行う
tx(cnt)=px ;tx(cnt)(弾のx座標)にpx(自機のx座標)の値を代入
ty(cnt)=py-40 ;ty(cnt)(弾のy座標)にpy(自機のy座標)より40引いた値を代入。(弾と自機が重ならないようにする為)
tf(cnt)=1 ;tf(cnt)に1を代入。つまり画面に弾があると言う事
st=0 ;連射の為の処理
shottime=3 ;連射の為の処理
}
ty(cnt)-=10 : if ty(cnt)<-64 : tf(cnt)=0 :ty(cnt)=-64: st=0;弾を進めて画面から出たら弾を消す
if tf(cnt)=1{ ;画面に弾があるとき、{}内の命令を行う
pos tx(cnt),ty(cnt) ;自機弾の座標指定
gmode 2 ;透明化処理の為の命令
gcopy 1,192,0,64,64 ;;バッファ画面(ウィンドウ1)より自機弾画像をコピー
}
loop
*************************************
自機も動くようになったし次は弾を撃てるようにしようと思い、まず弾の画像を書いてみた。

とりあえずエスプガルーダ2の画面見ながら書きました^^;
で、これを発射させる訳ですが、仮に自機の弾を画面上に3発発射させたいとします。
すると、少なくみても弾1発につきX軸用とY軸用の変数を用意しなければならず
3発発射となると2×3で6個の変数を用意しなければなりません。
今時のSTGなど、それこそ死ぬ程弾を撃てる訳で、いちいち弾の数だけ変数を用意していては話になりません。
そこで登場してくるのが配列変数です。これはdim tx,3なんて感じで表記すれば
いちいちtx1,tx2,tx3などと変数を用意しなくても、tx(1),tx(2),tx(3)と用意してくれます。
しかも、dim tx,3の3の部分には変数を使用する事が出来るので、仮にtmx=3としてdim tx,tmx
dim ty,tmxなんて書き方をすれば、一気に変数を沢山用意出来るんです。いやー考えた人エラい。
その配列変数を使って自機弾を撃てるようにしたスプリクトがコレ↓大きい文字が今回変更した部分です。
*************************************
;初期設定
#include "CK_JOYFORCE.AS"
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg1.gif" ;画像をバッファに読み込み
screen 0,480,640,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
px=224:py=576;自機の初期位置
tmx=10 ;自機弾の数
dim tx,tmx ;自機弾のX座標の配列変数
dim ty,tmx ;自機弾のY座標の配列変数
dim tf,tmx ;自機弾が画面にあるか無いかを調べる配列変数
color 0,0,0;色に黒を指定
boxf 0,0,480,640;画面を黒で塗りつぶす
;メインループ
*main
redraw 0;仮想画面を指定
color 0,0,0;色に黒を指定
boxf 0,0,480,640;仮想画面を黒で塗りつぶす
;自機移動処理
pk=0
ck_joystick ky,15;キーボードのチェック
if ky&1 :px-=8 :pk=64 :if px<0 :px=0;カーソルキー左(←)を押した時pxより-8を引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=8 :pk=128 :if px>416 :px=416
if ky&2 :py-=8 :if py<0 :py=0
if ky&8 :py+=8 :if py>576 :py=576
pos px,py;自機の座標指定
gcopy 1,pk,0,64,64;バッファ画面(ウィンドウ1)より自機画像をコピー
;自機弾発射処理
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)=0 { ;tf(cnt)が0の時=画面に弾がない時、{}内の命令を行う
if ky&2048 { ;zキーを押した時、{}内の命令を行う
tx(cnt)=px ;tx(cnt)(弾のx座標)にpx(自機のx座標)の値を代入
ty(cnt)=py-40 ;ty(cnt)(弾のy座標)にpy(自機のy座標)より40引いた値を代入。(弾と自機が重ならないようにする為)
tf(cnt)=1 ;tf(cnt)に1を代入。つまり画面に弾があると言う事
ky=0 ;キーを一回押した時に2発弾が出たりしないようにキー入力をリセット
}
} ty(cnt)-=10 : if ty(cnt)<0 : tf(cnt)=0 ;弾を進めて画面から出たら弾を消す
if tf(cnt)=1{ ;画面に弾があるとき、{}内の命令を行う
pos tx(cnt),ty(cnt) ;自機弾の座標指定
gcopy 1,192,0,64,64 ;バッファ画面(ウィンドウ1)より自機弾画像をコピー
}
loop
redraw 1;メイン画面を更新
await 1 ;これを入れないとパソコンが固まる
goto *main;*mainに戻る
*************************************
hsp3,0使用 画像は上の画像を使用 CK_JOYFORCE.DLL使用
弾発射部分について間単に説明すると、まず画面上に弾があるかないかを弾のかずだけ判断して
弾がない時は、キー入力のチェックをする。キーが押されていれば弾の座標を決めて
画面に弾がある事を宣言し、弾を10ドット進める。この時弾が画面の一番上まできてたら(tyが0以下になったら)
弾の存在を消す(tf=0にする)
また、画面に弾がある時は座標決定などを飛ばして弾を進める。
これらの作業を弾一個づつ分繰り返す。(今回の場合はtmxが10なので10回)
ちなみに(cnt)ってのはリピート回数が入ります。1回目なら1、10回目なら10。
いやー凄いです配列変数。こんな短い命令で簡単に弾を制御してくれてます。
コレを使えば100発だって1000発だって簡単に発射させる事が出来ますね。(tmxの数を変えればよいだけ)
例えば、この発射処理を配列変数を使わずにやろうとすると自機発射処理の部分を
10回書かなければならないって事ですのし(100発なら100回)変数も30個用意しなければならず
やってられないです。
で上記スプリクトを実行してみると・・・

無事、弾が発射されました^^
でも、このスプリクトだと連射しないんですよね・・・高橋名人ばりに自分で連射しなければならず、やってられません。
連射出来るようにしようと試みてみたんですが、どうも上手くいきませんでした。
もうちょっと調べてみよう。
それとwait命令はawait命令の方が機種依存率が低くなるみたいです。
とりあえずエスプガルーダ2の画面見ながら書きました^^;
で、これを発射させる訳ですが、仮に自機の弾を画面上に3発発射させたいとします。
すると、少なくみても弾1発につきX軸用とY軸用の変数を用意しなければならず
3発発射となると2×3で6個の変数を用意しなければなりません。
今時のSTGなど、それこそ死ぬ程弾を撃てる訳で、いちいち弾の数だけ変数を用意していては話になりません。
そこで登場してくるのが配列変数です。これはdim tx,3なんて感じで表記すれば
いちいちtx1,tx2,tx3などと変数を用意しなくても、tx(1),tx(2),tx(3)と用意してくれます。
しかも、dim tx,3の3の部分には変数を使用する事が出来るので、仮にtmx=3としてdim tx,tmx
dim ty,tmxなんて書き方をすれば、一気に変数を沢山用意出来るんです。いやー考えた人エラい。
その配列変数を使って自機弾を撃てるようにしたスプリクトがコレ↓大きい文字が今回変更した部分です。
*************************************
;初期設定
#include "CK_JOYFORCE.AS"
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg1.gif" ;画像をバッファに読み込み
screen 0,480,640,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
px=224:py=576;自機の初期位置
tmx=10 ;自機弾の数
dim tx,tmx ;自機弾のX座標の配列変数
dim ty,tmx ;自機弾のY座標の配列変数
dim tf,tmx ;自機弾が画面にあるか無いかを調べる配列変数
color 0,0,0;色に黒を指定
boxf 0,0,480,640;画面を黒で塗りつぶす
;メインループ
*main
redraw 0;仮想画面を指定
color 0,0,0;色に黒を指定
boxf 0,0,480,640;仮想画面を黒で塗りつぶす
;自機移動処理
pk=0
ck_joystick ky,15;キーボードのチェック
if ky&1 :px-=8 :pk=64 :if px<0 :px=0;カーソルキー左(←)を押した時pxより-8を引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=8 :pk=128 :if px>416 :px=416
if ky&2 :py-=8 :if py<0 :py=0
if ky&8 :py+=8 :if py>576 :py=576
pos px,py;自機の座標指定
gcopy 1,pk,0,64,64;バッファ画面(ウィンドウ1)より自機画像をコピー
;自機弾発射処理
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)=0 { ;tf(cnt)が0の時=画面に弾がない時、{}内の命令を行う
if ky&2048 { ;zキーを押した時、{}内の命令を行う
tx(cnt)=px ;tx(cnt)(弾のx座標)にpx(自機のx座標)の値を代入
ty(cnt)=py-40 ;ty(cnt)(弾のy座標)にpy(自機のy座標)より40引いた値を代入。(弾と自機が重ならないようにする為)
tf(cnt)=1 ;tf(cnt)に1を代入。つまり画面に弾があると言う事
ky=0 ;キーを一回押した時に2発弾が出たりしないようにキー入力をリセット
}
} ty(cnt)-=10 : if ty(cnt)<0 : tf(cnt)=0 ;弾を進めて画面から出たら弾を消す
if tf(cnt)=1{ ;画面に弾があるとき、{}内の命令を行う
pos tx(cnt),ty(cnt) ;自機弾の座標指定
gcopy 1,192,0,64,64 ;バッファ画面(ウィンドウ1)より自機弾画像をコピー
}
loop
redraw 1;メイン画面を更新
await 1 ;これを入れないとパソコンが固まる
goto *main;*mainに戻る
*************************************
hsp3,0使用 画像は上の画像を使用 CK_JOYFORCE.DLL使用
弾発射部分について間単に説明すると、まず画面上に弾があるかないかを弾のかずだけ判断して
弾がない時は、キー入力のチェックをする。キーが押されていれば弾の座標を決めて
画面に弾がある事を宣言し、弾を10ドット進める。この時弾が画面の一番上まできてたら(tyが0以下になったら)
弾の存在を消す(tf=0にする)
また、画面に弾がある時は座標決定などを飛ばして弾を進める。
これらの作業を弾一個づつ分繰り返す。(今回の場合はtmxが10なので10回)
ちなみに(cnt)ってのはリピート回数が入ります。1回目なら1、10回目なら10。
いやー凄いです配列変数。こんな短い命令で簡単に弾を制御してくれてます。
コレを使えば100発だって1000発だって簡単に発射させる事が出来ますね。(tmxの数を変えればよいだけ)
例えば、この発射処理を配列変数を使わずにやろうとすると自機発射処理の部分を
10回書かなければならないって事ですのし(100発なら100回)変数も30個用意しなければならず
やってられないです。
で上記スプリクトを実行してみると・・・
無事、弾が発射されました^^
でも、このスプリクトだと連射しないんですよね・・・高橋名人ばりに自分で連射しなければならず、やってられません。
連射出来るようにしようと試みてみたんですが、どうも上手くいきませんでした。
もうちょっと調べてみよう。
それとwait命令はawait命令の方が機種依存率が低くなるみたいです。
とりあえず動くようになった自機。でもキーボードでしか操作出来ないのは
シューティングゲームとしては話になりません。
でもHSPの基本命令にはジョイスティックに対応した命令がないんですよね。
しかし外部プラグインを導入する事によってジョイスティック対応にする事ができる。
色々探してみるとジョイスティック対応プラグインも数種類ある事が判明。
その中で使いやすいと言うか、初心者でもわかりやすかったのがCYBER STATION 200Xさんで公開している
CK_JOYFORCE DLLでした。
このプラグインだと、stick命令をck_joystickと書き換えるだけでジョイスティックに対応出来て超簡単。
後はプログラムの最初に#include "CK_JOYFORCE.AS"と記述すればOK。
これだけでジョイスティックに対応出来るなんて、開発者の人に感謝ですね^^
それと昨日のスプリクトでは、左を押しても右を押しても傾かなかったので傾くようにしてみた。
まず、自機の表示はgcopy 1,0,0,64,64で行っています。
この命令の意味はバッファ1のx軸0、y軸0から縦横64×64の画像をコピーと言う意味です。
なので、キーを押している時にx軸をずらす事が出来れば傾く事が出来そう。
早速実行してみる。まず、自機の傾きの変数をpkとして、初期数は0。
で、キー入力判断の部分 if ky&1 :px-=8 :if px<0 :px=0の所にpk=64
if ky&4 :px+=8 :if px>416 :px=416の所にpk=128を足してみた。
これで左を押している時はpkに64、右を押している時はpkに128が入力される事になる
そして、gcopy 1,0,0,64,64をgcopy 1,pk,0,64,64に書き換えれば自機が傾くはず。
上記部分を書き換えたスプリクトがコレ↓太字が書き換えた部分
*************************************
;初期設定
#include "CK_JOYFORCE.AS"
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg.gif";画像をバッファに読み込み
screen 0,480,640,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
px=224:py=576;自機の初期位置
color 0,0,0;色に黒を指定
boxf 0,0,480,640;画面を黒で塗りつぶす
;メインループ
*main
redraw 0;仮想画面を指定
color 0,0,0;色に黒を指定
boxf 0,0,480,640;仮想画面を黒で塗りつぶす
pk=0 ;自機の傾きの為の変数
ck_joystick ky,15;キーボードのチェック
if ky&1 :px-=8 :pk=64 :if px<0 :px=0;カーソルキー左(←)を押した時pxより-8を引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=8 :pk=128 :if px>416 :px=416
if ky&2 :py-=8 :if py<0 :py=0
if ky&8 :py+=8 :if py>576 :py=576
pos px,py;自機の座標指定
gcopy 1,pk,0,64,64;バッファ画面(ウィンドウ1)より自機画像をコピー
redraw 1;メイン画面を更新
wait 1;これを入れないとパソコンが固まる
goto *main;*mainに戻る
*************************************
HSP3.0使用 画像は4月27日の自機画像を使用 CK_JOYFORCE.DLL使用
実行してみると・・・

ちゃんと傾いて動いてくれました!
シューティングゲームとしては話になりません。
でもHSPの基本命令にはジョイスティックに対応した命令がないんですよね。
しかし外部プラグインを導入する事によってジョイスティック対応にする事ができる。
色々探してみるとジョイスティック対応プラグインも数種類ある事が判明。
その中で使いやすいと言うか、初心者でもわかりやすかったのがCYBER STATION 200Xさんで公開している
CK_JOYFORCE DLLでした。
このプラグインだと、stick命令をck_joystickと書き換えるだけでジョイスティックに対応出来て超簡単。
後はプログラムの最初に#include "CK_JOYFORCE.AS"と記述すればOK。
これだけでジョイスティックに対応出来るなんて、開発者の人に感謝ですね^^
それと昨日のスプリクトでは、左を押しても右を押しても傾かなかったので傾くようにしてみた。
まず、自機の表示はgcopy 1,0,0,64,64で行っています。
この命令の意味はバッファ1のx軸0、y軸0から縦横64×64の画像をコピーと言う意味です。
なので、キーを押している時にx軸をずらす事が出来れば傾く事が出来そう。
早速実行してみる。まず、自機の傾きの変数をpkとして、初期数は0。
で、キー入力判断の部分 if ky&1 :px-=8 :if px<0 :px=0の所にpk=64
if ky&4 :px+=8 :if px>416 :px=416の所にpk=128を足してみた。
これで左を押している時はpkに64、右を押している時はpkに128が入力される事になる
そして、gcopy 1,0,0,64,64をgcopy 1,pk,0,64,64に書き換えれば自機が傾くはず。
上記部分を書き換えたスプリクトがコレ↓太字が書き換えた部分
*************************************
;初期設定
#include "CK_JOYFORCE.AS"
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg.gif";画像をバッファに読み込み
screen 0,480,640,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
px=224:py=576;自機の初期位置
color 0,0,0;色に黒を指定
boxf 0,0,480,640;画面を黒で塗りつぶす
;メインループ
*main
redraw 0;仮想画面を指定
color 0,0,0;色に黒を指定
boxf 0,0,480,640;仮想画面を黒で塗りつぶす
pk=0 ;自機の傾きの為の変数
ck_joystick ky,15;キーボードのチェック
if ky&1 :px-=8 :pk=64 :if px<0 :px=0;カーソルキー左(←)を押した時pxより-8を引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=8 :pk=128 :if px>416 :px=416
if ky&2 :py-=8 :if py<0 :py=0
if ky&8 :py+=8 :if py>576 :py=576
pos px,py;自機の座標指定
gcopy 1,pk,0,64,64;バッファ画面(ウィンドウ1)より自機画像をコピー
redraw 1;メイン画面を更新
wait 1;これを入れないとパソコンが固まる
goto *main;*mainに戻る
*************************************
HSP3.0使用 画像は4月27日の自機画像を使用 CK_JOYFORCE.DLL使用
実行してみると・・・
ちゃんと傾いて動いてくれました!
昨日作った自機が気に入らなかったので、もう一度作りなおしてみた。

64×64ドットで書いています。
怒首領蜂などの画面は240×320ドットで自機は32×32ドットだと思うのですが(多分)
240×320ドットで作っていくとパソコンで見ると画面がとても小さくなってしまうので
480×640ドットで作っていこうと思っているので、自機のサイズを64×64にしました。
で、とりあえず自機をキーボードで動かせる所まで作ってみた。
そのスプリクトがコレ↓
**************************************************
;初期設定
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg.gif";画像をバッファに読み込み
screen 0,480,640,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
px=224:py=576;自機の初期位置
color 0,0,0;色に黒を指定
boxf 0,0,480,640;画面を黒で塗りつぶす
;メインループ
*main
redraw 0;仮想画面を指定
color 0,0,0;色に黒を指定
boxf 0,0,480,640;仮想画面を黒で塗りつぶす
stick ky,15;キーボードのチェック
if ky&1 :px-=8 :if px<0 :px=0;カーソルキー左(←)を押した時pxより-8を引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=8 :if px>416 :px=416
if ky&2 :py-=8 :if py<0 :py=0
if ky&8 :py+=8 :if py>576 :py=576
pos px,py;自機の座標指定
gcopy 1,0,0,64,64;バッファ画面(ウィンドウ1)より自機画像を仮想画面にコピー
redraw 1;仮想画面をメイン画面に更新
wait 1;これを入れないとパソコンが固まる
goto *main;*mainに戻る
**************************************************
HSP3.0使用 画像は上の自機画像を使用
上記スプリクトを実行した画面がコレ↓

スプリクトは殆ど本に載ってたのを写したような感じ。
それでも自機が表示されて自在に動くと嬉しい^^まだ傾いたりはしないけど。
簡単に説明すると、まず使用する画像をメモリに読み込んで
(こうしないと、いちいちHDDから読み込むので実行速度が非常に遅くなる)
使用するメイン画面の大きさを決める。自機の初期位置を宣言する。
で、まず仮想画面にキーボードでの入力の結果、移動した自機を表示して
メイン画面を書き換える。コレを延々と繰り返して動いているようにみせるって感じ。
なんかゲームってもっと同時に色んな事してるんかなーと思ってたけど
基本的には一つ一つの動作を高速で延々と繰り返していくんだって事がわかった。
でも、コレに弾やら敵やら当り判定やらが加わってくるとややこしいんだろなー。
64×64ドットで書いています。
怒首領蜂などの画面は240×320ドットで自機は32×32ドットだと思うのですが(多分)
240×320ドットで作っていくとパソコンで見ると画面がとても小さくなってしまうので
480×640ドットで作っていこうと思っているので、自機のサイズを64×64にしました。
で、とりあえず自機をキーボードで動かせる所まで作ってみた。
そのスプリクトがコレ↓
**************************************************
;初期設定
buffer 1 ;ウィンドウ1をバッファ画面として用意
picload "stg.gif";画像をバッファに読み込み
screen 0,480,640,0,0,0;メイン画面(ウィンドウ0を480*640で用意)
px=224:py=576;自機の初期位置
color 0,0,0;色に黒を指定
boxf 0,0,480,640;画面を黒で塗りつぶす
;メインループ
*main
redraw 0;仮想画面を指定
color 0,0,0;色に黒を指定
boxf 0,0,480,640;仮想画面を黒で塗りつぶす
stick ky,15;キーボードのチェック
if ky&1 :px-=8 :if px<0 :px=0;カーソルキー左(←)を押した時pxより-8を引く:画面からはみ出さないようにpxが0以下にならないようにする
if ky&4 :px+=8 :if px>416 :px=416
if ky&2 :py-=8 :if py<0 :py=0
if ky&8 :py+=8 :if py>576 :py=576
pos px,py;自機の座標指定
gcopy 1,0,0,64,64;バッファ画面(ウィンドウ1)より自機画像を仮想画面にコピー
redraw 1;仮想画面をメイン画面に更新
wait 1;これを入れないとパソコンが固まる
goto *main;*mainに戻る
**************************************************
HSP3.0使用 画像は上の自機画像を使用
上記スプリクトを実行した画面がコレ↓
スプリクトは殆ど本に載ってたのを写したような感じ。
それでも自機が表示されて自在に動くと嬉しい^^まだ傾いたりはしないけど。
簡単に説明すると、まず使用する画像をメモリに読み込んで
(こうしないと、いちいちHDDから読み込むので実行速度が非常に遅くなる)
使用するメイン画面の大きさを決める。自機の初期位置を宣言する。
で、まず仮想画面にキーボードでの入力の結果、移動した自機を表示して
メイン画面を書き換える。コレを延々と繰り返して動いているようにみせるって感じ。
なんかゲームってもっと同時に色んな事してるんかなーと思ってたけど
基本的には一つ一つの動作を高速で延々と繰り返していくんだって事がわかった。
でも、コレに弾やら敵やら当り判定やらが加わってくるとややこしいんだろなー。
カレンダー
| 02 | 2026/03 | 04 |
| 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 |
リンク
カテゴリー
最新記事
(04/04)
(12/26)
(12/25)
(11/17)
(10/11)
プロフィール
HN:
kt.
性別:
男性
自己紹介:
プログラミング経験は昔ファミリーベーシックでちょっとさわったくらい。
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!
ブログ内検索
最古記事