1MAP_STG キャラをグラフィックにする


2018年 5月12日
 
 
 キャラをグラフィックにする。

 座標と当たり判定をすっきりさせ、さらにグラを回転させて向きを表現する。

 それからスマホ向けにマウスカーソルでは無くて「照準」のグラを用意する。
 スマホではカーソル表示は無いため。


 
 
 グラフィック

 自機

 ショット

 敵

 照準

 使用する場合は「名前をつけて画像を保存」でダウンロードして下さい。

 
 
 ソース

; 企画第一弾 : 1画面防衛シューティングを作ろう
; var.0.003

#include "hsp3dish.as" ; HSPdishの宣言


	randomize	; 乱数の初期化

	pai=3.141593
	pai2=pai*2

	rad45=0.7853982		; ラジアンで45度
	rad90=1.5707965		; ラジアンで90度


	wx=640	; 画面の大きさx
	wy=360	; 画面の大きさy

	gmode 2

	jw=1 : jo=20 : jo2=jo/2	; 自機
	 celload "jiki_1.png",jw
	  celdiv jw,jo,jo,jo2,jo2

	sw=2 : so=6 : so2=so/2	; ショット
	 celload "shot_1.png",sw
	  celdiv sw,so,so,so2,so2

	ew=3 : eo=20 : eo2=eo/2	; 敵
	 celload "ene_1.png",ew
	  celdiv ew,eo,eo,eo2,eo2

	cw=4 : co=24 : co2=co/2	; カーソル
	 celload "csr_1.png",cw
	  celdiv cw,co,co,co2,co2

; 自機 ----------
	jx=wx/2	; プレイヤーの座標x
	jy=wy/2	; プレイヤーの座標y

	jx1=jx-jo2 ; 自機左座標
	jx2=jx+jo2 ; 自機右座標
	jy1=jy-jo2 ; 自機上座標
	jy2=jy+jo2 ; 自機下座標

; SHOT ----------
	sb=20			; ショット最大数
	 dim sf,sb		; ショット発射フラグ
	 ddim sx,sb		; ショット座標x
	 ddim sy,sb		; ショット座標y
	 ddim sdx,sb	; ショット移動量x
	 ddim sdy,sb	; ショット移動量y
	ssp=20.0		; スピード

	sc=0			; 出現カウント
	scb=1			; 発射間隔(フレーム)

; ENEMY ----------
	eb=40			; 敵最大数
	 dim ef,eb		; 出現フラグ
	 ddim ex,eb		; 敵座標x
	 ddim ey,eb		; 敵座標y
	 ddim edx,eb	; 敵移動量x
	 ddim edy,eb	; 敵移動量y
	 ddim er,eb		; 向き
	esp=3.0			; 敵スピード

	ec=0			; 出現カウント
	ecb=4			; 出現間隔(フレーム)

	scr=0		; スコア
	hiscr=0		; ハイスコア


*main

	mainf=0 ; ゲームフラグ

	repeat ; メインループ ----------------------------------

	 switch mainf
	  case 0 ; タイトル ----------
	   stick k : if k=0 : swbreak ; ボタンでゲーム再開
	   mainf=1
	  swbreak ; ----------

	  case 1 ; ゲーム ----------

; 自機 ----------
	   x=mousex : y=mousey	; マウスの座標

; SHOT ----------
	   repeat 1 ; 発射
	    if sc>0 : sc- : break ; ウエイト中

	    repeat sb
	     if sf(cnt)>0 : continue ; 使用中

	     sf(cnt)=1 ; 使用フラグon
		 sx(cnt)=double(jx) : sy(cnt)=double(jy) ; 初期座標

		 xn=double(x-jx)		; 自機とマウスの距離x
		 yn=double(y-jy)		; 自機とマウスの距離y

		 rad=atan(xn,yn)		; 距離xyから角度を求める

	 	 sdx(cnt)=sin(rad)*ssp	; 角度とスピードから移動量xを求める
	 	 sdy(cnt)=cos(rad)*ssp	; 角度とスピードから移動量yを求める

		 break
		loop
		sc=scb ; 発射ウエイト
	   loop

	   repeat sb : scn=cnt ; ショット移動処理
		if sf(scn)=0 : continue ; 無し

		sx(scn)+=sdx(scn) ; xの移動
		sy(scn)+=sdy(scn) ; yの移動

		sx1=int(sx(scn))-so2 ; ショット左座標
		sx2=int(sx(scn))+so2 ; ショット右座標
		sy1=int(sy(scn))-so2 ; ショット上座標
		sy2=int(sy(scn))+so2 ; ショット下座標

		repeat eb ; 敵との当たり判定
		 if ef(cnt)=0 : continue

		 ex1=int(ex(cnt))-eo2 ; 敵左座標
		 ex2=int(ex(cnt))+eo2 ; 敵右座標
		 ey1=int(ey(cnt))-eo2 ; 敵上座標
		 ey2=int(ey(cnt))+eo2 ; 敵下座標

		 if sx1<ex2 and ex1<sx2 and sy1<ey2 and ey1<sy2 {
			ef(cnt)=0 : sf(scn)=0 ; 当たった敵とショットを消す
			scr+ ; スコア
			if hiscr<scr : hiscr=scr ; ハイスコアの更新
			break
		 }
		loop

		if sf(scn)=1 : if sx2<0 or wx<sx1 or sy2<0 or wy<sy1 : sf(scn)=0 ; 場外でフラグ off
	   loop


; ENEMY ----------

	   repeat 1 ; 敵出現
	    if ec>0 : ec- : break ; ウエイト中

		repeat eb ; フラグ確認
		 if ef(cnt)>0 : continue ; 使用中
		 ef(cnt)=1 ; 使用フラグon

		 r=rnd(4) ; 出現方向
		  if r=0 : exs=rnd(wx)-eo2 : eys=0-eo2	; 上
		  if r=1 : exs=rnd(wx)-eo2 : eys=wy+eo2	; 下
		  if r=2 : exs=-eo2	  : eys=rnd(wy)-eo2	; 左
		  if r=3 : exs=wx+eo2 : eys=rnd(wy)-eo2	; 右

		  ex(cnt)=double(exs)	; 初期位置x
		  ey(cnt)=double(eys)	; 初期位置y

		  xn=double(jx-exs)	; 敵と自機の距離x
		  yn=double(jy-eys)	; 敵と自機の距離y

		  rad=atan(xn,yn) 	; 距離xyから角度を求める

		  edx(cnt)=sin(rad)*esp	; 角度とスピードから移動量xを求める
		  edy(cnt)=cos(rad)*esp	; 角度とスピードから移動量yを求める

		  er(cnt)=-rad+pai	; 向き

		  ec=ecb ; 出現ウエイト

		  break ; 登録終わり
		loop
	   loop

	   repeat eb ; 敵移動処理
		if ef(cnt)=0 : continue ; 無し

		ex(cnt)+=edx(cnt) : ey(cnt)+=edy(cnt) ; 移動

		ex1=int(ex(cnt))-eo2 ; 敵左座標
		ex2=int(ex(cnt))+eo2 ; 敵右座標
		ey1=int(ey(cnt))-eo2 ; 敵上座標
		ey2=int(ey(cnt))+eo2 ; 敵下座標

		if jx1<ex2 and ex1<jx2 and jy1<ey2 and ey1<jy2 {
			mainf=2 : break ; 自機と当たりで GAME OVER
		}

		if ex2<0 or wx<ex1 or ey2<0 or wy<ey1 : ef(cnt)=0 ; 枠外でフラグ off
	   loop
	  swbreak ; ----------

	  case 2 ; gameover ----------
	   stick k : if k=0 : swbreak ; ボタンでゲーム再開

	  repeat eb
	    ef(cnt)=0 ; 敵リセット
	   loop

	   repeat sb
	    sf(cnt)=0 ; ショットリセット
	   loop

	   scr=0 ; スコアリセット

	   mainf=0 ; ゲーム再開
	  swbreak ; ----------
	 swend


	 redraw 0 ; 表示 ====================
	  color 1,1,1 : boxf : color 255,255,255 ; 画面クリア

	  pos jx,jy : celput jw ; 自機

	  repeat sb ; ショット
	   if sf(cnt)=0 : continue ; 無い
	   pos sx(cnt),sy(cnt) : celput sw ; ショット
	  loop

	  repeat eb ; 敵
	   if ef(cnt)=0 : continue ; 無い
	   pos ex(cnt),ey(cnt) : celput ew,,,,er(cnt) ; 敵
	  loop

	  pos x,y : celput cw

	  switch mainf
	   case 0 ; タイトル
	    pos wx/2-120,wy/2-50 : mes "1画面防衛シューティング"
	    pos wx/2-43,wy/2+30 : mes "var.0.003"
	   swbreak

	   case 1 ; ゲーム
	   swbreak

	   case 2 ; gameover
	    pos wx/2-43,wy/2+50 : mes "GAME OVER"
	   swbreak
	  swend

	  pos wx-300,5 : mes "SCORE "+scr
	  pos wx-150,5 : mes "HI SCORE "+hiscr
	 redraw 1 ; ====================


	 await 1000/15	; ウエイト、FPS 15

	loop ; --------------------------------------------------

end ; 終わり

 
 

プログラム解説

初期設定

pai=3.141593
pai2=pai*2

rad45=0.7853982 ; ラジアンで45度
rad90=1.5707965 ; ラジアンで90度

 円周率。
 円周率の値は決まっているため、ラジアン用に 45度、90度、180度(1π)、360度(2π)を用意する。

 ゲームプログラムの時は大体書いてる。
 
 
gmode 2
 表示モード、これを書かないとブラウザで PNGの透明を抜いてくれない。
 
 
jw=1 : jo=20 : jo2=jo/2 ; 自機
 celload “jiki_1.png”,jw
  celdiv jw,jo,jo,jo2,jo2

jw=1 : 自機のグラフィックバッファNo.
jo=20 : 大きさ、今回はグラの縦と横の大きさが同じとして扱う。
jo2=jo/2 : 半分の大きさ。

celload “jiki_1.png”,jw
 グラを読み込む命令。
 jwバッファに jiki_1.pngを読み込む。

celdiv jw,jo,jo,jo2,jo2
 読み込んだグラフィックバッファの設定。
 jw=設定するバッファNo.。
 jo,joは番号振りの区切りの大きさ(今回は 1枚絵のため関係無い)
 jo2,jo2=表示の中点座標、jo2はグラの大きさの半分のため posで設定した座標にグラの中心点が来るように表示される。
 つまり前回は posの座標がキャラの左上座標だったが、今回は posの座標がキャラの中心点になる。

 それから今回はグラの回転表示を行うが、その再の中心点になる。
 
 
jx1=jx-jo2 ; 自機左座標
jx2=jx+jo2 ; 自機右座標
jy1=jy-jo2 ; 自機上座標
jy2=jy+jo2 ; 自機下座標

 当たり判定用の 4辺端座標。
 ショットと敵もそうだが、今回はあらかじめ計算しておく事で判定時の計算を省き、高速化するのとソースを見やすくする。

 たぶんこの程度のプログラムなら速度に影響は無い。
 jx,jyは中点座標になるため、4辺端はそこからそれぞれ半分の大きさの距離となる。
 
 
ddim er,eb ; 向き
 今回は敵のみ向きに従って回転表示を行う、その回転値。

 
 
メインルーチン

sx1,sx2,sy1,sy2、ex1,ex2,ey1,ey2
 今回はこれらショットや敵の当たり判定用の 4辺座標をあらかじめ用意しておく事で、見た目にもスッキリしたと思う。

 合わせて場外判定のソースも分かりやすくなった。
 
 
er(cnt)=-rad+pai ; 向き
 これで敵が自機の方を向く角度を設定できるが、なぜそうなるのかは自分は理解してない。
 rad(角度)値を -にして pai(3.141593)を足すとうまく行ったというだけの思考錯誤の産物。

 そもそも celput(グラ表示)のラジアンの値も独自のような気もするし

 つまりプログラム的には真上が 0で、時計周り(右回り)に真下までが π(パイ(3,141593))で、そこから真上が 2π(6.28・・・)という仕様らしい。

 これはグラフィックが普通上向きだから 0が正位置なら合理的なんだと思う。

 今回用意した敵のグラも正位置で上向きだし。
 ←0でこの向き

 
 
表示

pos ex(cnt),ey(cnt) : celput ew,,,,er(cnt) ; 敵
 celput が HSPdish用のグラフィック表示命令になります。
 先に設定した posの座標に表示します。
 ew=グラのバッファNo.
 er=回転表示角度。

 間の,,,,には、その画像バッファの何番目の画像を表示するか(celdivで区切った)と、xとyの拡大縮小表示率が設定できます。

 
 
 今回ショットの大きさを 6ドットにし、当たり判定もその大きさで計算してるので、前回よりエイム(狙う)要素が増したと思います。
 
 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です