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

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

ここ数日、先日作りかけていた回転しながらレーザーを撃つ敵のスプリクトを作っていたんですが、どうも上手くいかないので
後回しにして、自機を追っかけながら3方向自機狙い弾を撃ってくる敵のスプリクトを作ってみました。
敵画像、弾画像ともにgrotate命令で回転させています。
こんな感じ
0603.jpg
スプリクトはコチラ↓
*************************************
;初期設定
#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 "stg12.gif";画像をバッファ3に読み込み
buffer 4 ; ウィンドウ4をバッファ画面として用意
picload "s396.jpg" ;背景画像をバッファ4に読み込み
buffer 5 ; ウィンドウ4をバッファ画面として用意
picload "bomb.gif" ;ボム画像をバッファ5に読み込み
ssp=485 ;スクロール速度
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=40 ;自機弾の数
dim tx,tmx ;自機弾のX座標の配列変数
dim ty,tmx ;自機弾のY座標の配列変数
dim tf,tmx ;自機弾が画面にあるか無いかを調べる配列変数
dim txv,tmx;自機弾のx軸移動量
dim tyv,tmx;自機弾のy軸移動量

emx=50;敵の数
dim ex,emx : dim ey,emx;敵の初期位置
dim dx,emx : dim dy,emx;敵の移動量
dim ef,emx;敵のフラグ
dim em,emx;敵の種類
dim et,emx;敵出現からの時間
dim enm,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;敵弾のフラグ
dim etxp,emt;敵弾画像のx軸の座標
dim etyp,emt;敵弾画像のy軸の座標
dim etxs,emt;敵弾画像のx軸の大きさ
dim etys,emt;敵弾画像のy軸の大きさ
dim etr,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;バッファ画面(ウィンドウ3)より自機画像をコピー

;自機弾発射処理
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以下の時){}内の命令を行う
th=th+1;一回で撃てる弾数の為の変数
tf(cnt)=1 ;tf(cnt)に1を代入。画面に弾があると言う事
st=0 ;連射の為の処理
shottime=2 ;連射の為の処理
ts=10 ;自機弾の速さ
if th=1 :tx(cnt)=px : ty(cnt)=py-12 : r=double(4.712) : txv(cnt)=cos(r)*ts : tyv(cnt)=sin(r)*ts;直進弾
if th=2 :tx(cnt)=px-6 : ty(cnt)=py-12 : r=double(4.61) : txv(cnt)=cos(r)*ts : tyv(cnt)=sin(r)*ts;左弾
if th=3 :tx(cnt)=px+6 : ty(cnt)=py-12 : r=double(4.813) : txv(cnt)=cos(r)*ts : tyv(cnt)=sin(r)*ts : th=0;右弾
}

if tf(cnt)=1{ ;画面に弾があるとき、{}内の命令を行う
tx(cnt)=tx(cnt)+txv(cnt) : ty(cnt)=ty(cnt)+tyv(cnt) ;自機弾の移動量
pos tx(cnt),ty(cnt) ;自機弾の座標指定
gcopy 3,96,0,32,32 ;バッファ画面(ウィンドウ3)より自機弾画像をコピー
if ty(cnt)<-32 : tf(cnt)=0 : st=0 ;画面から自機弾が消えたら弾を消す
}
loop
ck_joystick ky,2048 ;Zキーのチェック
if ky&2048 { ;Zキーが押されていた時はmove(自機移動速度)を2にして連射速度を上げる。そうでなければmoveを4にする
move=2 : shottime=0 }else{
move=4
}

;ボム処理
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フレーム過ぎたらボムが効かなくなる
}


;敵移動処理
repeat emx ;repeat〜loop間をemx回繰り返す
ent=cnt
et(cnt)++ ;敵出現時間を+
if ef(cnt)<1 : continue ;ef(cnt)が1以下(敵が画面にいない)ならばrepeatに戻る
if enm(cnt)=5 : gosub *em05 ;敵の名前が4の時*em04へ移動
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) ;敵弾の座標指定
gmode 2,16,16
grotate 3,etxp(cnt),etyp(cnt),etr(cnt),etxs(cnt),etys(cnt) ;バッファ画面(ウィンドウ3)より敵弾画像をコピー
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
if etxs(cnt)=16 : ddx=(etx(cnt))-(px+16) : if ddx<0 : ddx=-ddx ;自機と弾の中心座標の差の絶対値を求める
if etys(cnt)=16 : ddy=(ety(cnt))-(py+16) : if ddy<0 : ddy=-ddy
if (abs(ddx<3))&(abs(ddy<3)) { ;x軸とy軸の差が3以下の時、ゲームオーバー
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+"-"
;fps表示
fp++
time=gettime(6)
if time!=time2{
fpc=fp
fp=0}
pos 0,462
mes " Fps "+fpc
time2=time

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=176 : by=-64 : gosub *eb05
if gtime=17 : bx=208 : by=-64 : gosub *eb05
if gtime=33 : bx=240 : by=-64 : gosub *eb05
if gtime=49 : bx=272 : by=-64 : gosub *eb05
if gtime=65 : bx=303 : by=-64 : gosub *eb05
if gtime=101 : bx=464 : by=-64 : gosub *eb05
if gtime=117 : bx=432 : by=-64 : gosub *eb05
if gtime=133 : bx=400 : by=-64 : gosub *eb05
if gtime=149 : bx=368 : by=-64 : gosub *eb05
if gtime=165 : bx=336 : by=-64 : gosub *eb05
if gtime=200 : gtime=0
return

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

*em05;敵移動処理
if gtime¥15=0 : gosub *tekitama7
er=atan(py+16-ey(cnt), px+16-ex(cnt));自機と敵との角度計算
dx(cnt)=cos(er)*eds : dy(cnt)=sin(er)*eds;敵の移動量計算
ex(cnt)=ex(cnt)+dx(cnt) ;敵の移動量決定
ey(cnt)=ey(cnt)+dy(cnt) ;敵の移動量決定
if ey(cnt)>480 : ef(cnt)=0 ;画面から消えたら敵の存在を無しにする
pos ex(cnt),ey(cnt) : gmode 2 : grotate 3,96,64,atan(ex(cnt)-(px+16),(py+16)-ey(cnt)),32,32
;自機に向かって画像を回転させて敵画像を表示
;自機と敵との当り判定
if (abs(px+16-ex(cnt))<16)&(abs(py+16-ey(cnt))<16) {
gend=1
}

;自機弾と敵との当り判定
repeat tmx ;repeat〜loop間をtmx回繰り返す
if tf(cnt)<1 : continue ;tf(cnt)が1以下(弾が画面にいない)ならばrepeatに戻る
if (abs(tx(cnt)+16-ex(ent))<16)&(abs(ty(cnt)+16-ey(ent))<16) { ;自機弾と敵のx軸とy軸の座標差を求め(敵と自機弾全て)、どちらも32以下であれば{}}内の命令を行う
tf(cnt)=0 ;弾が当った時は弾の存在を消す
ef(ent)- ;弾が当った時は敵の存在を消す
sc+200
if ef(ent)=0 : gosub *bomb3
}
loop
;ボム処理
if bombcnt!-1 {
ef(cnt)-
if ef(cnt)=0 : gosub *bomb3
}
return

*tekitama7;狙い系(回転的用)
repeat emt
if etf(cnt)>0 : continue ;etfが0(敵弾が画面に無い時)、emn(cnt)が1(敵の名前が1の時)の場合if{}内の命令を行う
eh=eh+1 : etf(cnt)=1 ;弾数の為の処理。弾の存在を有にする
etx(cnt)=double(ex(ent)) : ety(cnt)=double(ey(ent)) ;弾の初期座標
ds=4 ;敵弾の速さ
etxp(cnt)=128 : etyp(cnt)=48;コピー座標指定
etxs(cnt)=16 : etys(cnt)=16;コピー大きさ指定
if eh=1 :r=atan(py+16-ety(cnt), px+16-etx(cnt)) :etr(cnt)=r: etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=2 :r=atan(py+16-ety(cnt), px+106-etx(cnt)) :etr(cnt)=r: etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds
if eh=3 :r=atan(py+16-ety(cnt), px-74-etx(cnt)) :etr(cnt)=r: etxv(cnt)=cos(r)*ds : etyv(cnt)=sin(r)*ds :eh=0 :break
loop
return

*bomb3
bbmx(ent)=ex(ent)-16 : bbmy(ent)=ey(ent)-16
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;escが押されたら強制終了
goto *gameover
************************************
HSP3.0使用 CK_JOYFORCE.DLL使用 画像は↓を使用
stg12.gif  s396.jpg  bomb.gif
コレを実行すると、左右から5匹づつ回転する敵が出てきて自機狙い3方向弾を延々と撃ってきます。

そう言えば、ちょっと前にエラー31が出て悩んでますって書いていたんですが、筆者は実数と整数とを同じように考えていたのですが
どうも、分けて考えないといけないようです。
最初に整数で計算した変数に実数を代入しようとしたりするとエラーになるみたい。
その場合は、double命令やint命令で整数なり実数なりに変更してやれば、エラーは出なくなりました^^
PR
この記事にコメントする
お名前
タイトル
メールアドレス
URL
コメント
パスワード   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
この記事へのトラックバック
この記事にトラックバックする:
Twitter
カレンダー
03 2024/04 05
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
最新コメント
[04/20 kt.]
[04/19 うぇむ]
[11/24 kt.]
[11/21 NONAME]
[11/24 kt.]
プロフィール
HN:
kt.
性別:
男性
自己紹介:
プログラミング経験は昔ファミリーベーシックでちょっとさわったくらい。
好きなSTGは、怒首領蜂大往生、エスプガルーダ(2)等の弾幕STGやら雷電シリーズなんかの非弾幕、バトルガレッガ、グラディウスシリーズ、R-TYPE等、STGなら何でも好きです。
音楽がカッコイイSTGが特に好きで、並木学氏は最高!
ブログ内検索
忍者ブログ [PR]