「ウソザナ」 TEST10

マップ移動時のモンスターとのバトル処理を作ってみました。
今回もいくつかのモジュールスクリプトに手が入っています。


適当なフォルダに次のファイルを用意し、HSPでxana_test10.hspを実行してみて下さい。

  • common.hsp (ここからゲット)
  • xana_test10.hsp (↓からゲット)テストスクリプト
  • xana_screen.hsp (↓からゲット)画面表示用モジュール
  • xana_menu.hsp (ここからゲット)メニュー用モジュール
  • xana_my.hsp (↓からゲット)自キャラ用モジュール
  • xana_mon.hsp (↓からゲット)モンスター用モジュール
  • Xana_tile060227-4.PNGDENZI部屋さんのところからゲット) ※XANADU風タイル(自キャラ)をbmp保存して下さい
  • Xana_tile081213-2.PNGDENZI部屋さんのところからゲット) ※XANADU風タイル(敵キャラ)をbmp保存して下さい
  • Xana_tile091129-2.PNGDENZI部屋さんのところからゲット) ※XANADU風タイル(ステータス、他)をbmp保存して下さい
  • Xana_tile081213-1.PNGDENZI部屋さんのところからゲット) ※XANADU風タイル(マップ)をbmp保存して下さい


うまく起動するとこんな画面でモンスターとバトルすることができます。


テスト方法

  • 矢印キー で上下左右に移動します。
  • ESCキー でシステムメニューを表示し、終了選択できます。


モンスターにぶつかると攻撃します。HPを0にすると画面からモンスターが消えます。
モンスターからも攻撃を受けますが、自分のHPはマイナスでも動きます^^;
攻撃を受けたときのタイルが無いので、白い円でダメージ表現しています(白黒反転ができるといいのですが)

^^;
モンスターの行動パターンはランダムです。
戦闘画面からは外に出られません。

バトル処理の課題はまだまだたくさん残っています。

  • 倒した後のITEMBOX処理
  • モンスター行動パターン 攻撃型(自分に向かってくる),逃避型(逃げていく)
  • 攻撃/防御/経験値計算
  • 魔法攻撃
  • 戦闘画面外移動(マップ画面復帰時)の処理


ウソザナ完成は、まだまだ、まだまだ先です。^^;

xana_test10.hsp

;
; プログラム  :「ウソザナ」を作ってみる TEST10
;
; 作成     :ふじぽん
;
; Copyright   :http://d.hatena.ne.jp/fujiponXP
;
; 利用素材   :
;
;     □ドット絵   :DENZI部屋(http://www3.wind.ne.jp/DENZI/diary/)
;
;                     タイトル  :XANADU風タイル(自キャラ)
;                     更新日    :2006年02月28日
;                     ファイル名:Xana_tile060227-4.png  ※BMP形式で利用します。
;
;                     タイトル  :XANADU風タイル(敵キャラ)
;                     更新日    :2008年12月22日
;                     ファイル名:Xana_tile081213-2.png  ※BMP形式で利用します。
;
;                     タイトル  :XANADU風タイル(ステータス)
;                     更新日    :2007年04月01日
;                     ファイル名:Xana_tile070401-3.png  ※BMP形式で利用します。
;
;                     タイトル  :XANADU風タイル(マップ)
;                     更新日    :2008年12月22日
;                     ファイル名:Xana_tile081213-1.png  ※BMP形式で利用します。
;
; 変更履歴
;  ver.1.0 2009/11/21 新規作成
;  ver.1.1 2009/11/22 TEST3(自・敵移動)+TEST4(ステータス表示)
;  ver.1.2 2009/12/09 TEST6 ニセマップスクロール
;  ver.1.3 2009/12/13 TEST6(マップスクロール)+TEST1(自移動)
;  ver.1.4 2009/12/20 これまでのモジュール(自キャラ、モンスタ、画面、メニュー、共通)を組み合わせてみる
;  ver.1.5 2009/12/26 バトル処理を作ってみる
;

; ライセンスに関する表示
#include "common.hsp"
about_lisence

; 乱数発生の初期化
randomize

; 定数
#const	global	cx				32												; キャラクターサイズX
#const	global	cy				32												; キャラクターサイズY
#const	global	wtime			50												; 描画待ち時間(ms)
#const	global	HO_LEFT			0												; 方向 左
#const	global	HO_RIGHT		1												; 方向 右
#const	global	HO_UP			2												; 方向 上
#const	global	HO_DOWN			3												; 方向 下
#const	global	sid_main		0												; 描画用
#const	global	sid_monload		11												; モンスター読み込み用
#const	global	sid_moncopy		12												; モンスターgcopy用

; モジュール読込
#include "xana_menu.hsp"
#include "xana_screen.hsp"
#include "xana_my.hsp"
#include "xana_mon.hsp"

; 画面生成
newmod scr, m_screen, "Xana_tile091129-2.bmp", 9, 9								; 画面表示用
m_scName		scr, "Fujipon"
m_scTitle		scr, "UsoXanaFighter"
m_scHitPoints	scr, 1250
m_scGold		scr, 12500
m_scFood		scr, 7845
m_scExpAt		scr, 1000
m_scExpMg		scr, 0
m_scWepon		scr, "Dagger"
m_scMagic		scr, "Needle"
m_scWear 		scr, "Cloth"
m_scShield		scr, "Gloves"
m_scItem 		scr, "Spectacles"

celload "Xana_tile081213-1.bmp",1: celdiv 1,cx,cy								; マップチップ

newmod menu, m_menu																; メニュー

; マップ変数定義
dim MapData,9,9
dim MapAction,9,9

MapData(0,0)=  1,  1,  1,  1,  1,  1,  1,  1,  1
MapData(0,1)=  0,  0,  0,  0,  0,  0,  0,  0,  1
MapData(0,2)=  0,  0,  0,  0,  0,  0,  0,  0,  1
MapData(0,3)=  0,  0,  0,  0,  0,  0,  0,  0,  1
MapData(0,4)=  0,  0,  0,  0,  0,  0,  0,  0,  1
MapData(0,5)=  0,  0,  0,  0,  0,  0,  0,  0,  1
MapData(0,6)=  0,  0,  0,  0,  0,  0,  0,  0,  1
MapData(0,7)=  0,  0,  0,  0,  0,  0,  0,  0,  1
MapData(0,8)=  0,  0,  0,  0,  0,  0,  0,  0,  1

; 0=自由移動 1:移動不可 5:落下
MapAction(0,0)=1,1,1,1,1,1,1,1,1
MapAction(0,1)=1,0,0,0,0,0,0,0,1
MapAction(0,2)=1,0,0,0,0,0,0,0,1
MapAction(0,3)=1,0,0,0,0,0,0,0,1
MapAction(0,4)=1,0,0,0,0,0,0,0,1
MapAction(0,5)=1,0,0,0,0,0,0,0,1
MapAction(0,6)=1,0,0,0,0,0,0,0,1
MapAction(0,7)=1,0,0,0,0,0,0,0,1
MapAction(0,8)=1,1,1,1,1,1,1,1,1

; マップ描画
gsel sid_main
for i,0,9
	for j,0,9
		pos j*cx+16,i*cy+16
		celput 1,MapData(j,i)
	next
next

; 装備
;  服   0:ノーマル赤 1:ノーマル白 2:レーザーアーマー 3:ハーフプレート 4:フルプレート
;  頭   0:なし 1:フルヘルム 2:プレートヘルム 3:赤髪 4:白髪 5:茶髪
;  盾   0:なし 1:赤小 2:赤大 3:黒小 4:黒大
;  武器 0:なし 1:剣 2:槍 3:杖 4:斧 5:弓 6:鈍器
dim eq   , 4: eq.0    = 2, 3, 1, 1
dim eqmax, 4: eqmax.0 = 5, 6, 5, 7

; 変数設定
eqpos = 0																		; 装備種類

; 自キャラ生成
newmod my, charactor, "Xana_tile060227-4.bmp", sid_main, 16, 16									
m_myEquip my, eq.0, eq.1, eq.2, eq.3											; 装備
m_myPos my, cx, cy, HO_RIGHT
m_myHpset my.cnt, 1250

; モンスター生成
m_monPicset "Xana_tile081213-2.bmp"												; モンスター用
newmod mon, monster, 0, 16, %1110, 16, 16										; Bat
m_monPos mon.0, 1*cx, 4*cy, HO_RIGHT

	; Bat
	dim p_max, p_hp, p_st, p_df, p_style
	;         Grp1 Grp2 Grp3 Grp4
	m_max   =   8,   9,   9,   9
	m_hp    = 100, 100, 100, 100
	m_st    =  99,  99,  99,  99
	m_df    =  50,  50,  50,  50
	m_style =   2,   2,   2,   2
	n=1
	dim m_grpx
	dim m_grpy
	;         0, 1, 2, 3, 4, 5, 6, 7, 8
	m_grpx  = 4, 5, 3, 4, 4, 3, 5, 3, 5
	m_grpy  = 4, 4, 4, 3, 5, 3, 3, 5, 5

	m_scMonName	scr, "Skeleton Knight"
	repeat m_max(n)
		newmod mongrp, monster, cnt, 166, %0111, 16, 16										; Mummy
		m_monPos mongrp.cnt, m_grpx(cnt)*cx, m_grpy(cnt)*cy, HO_RIGHT
		m_monHpset mongrp.cnt, 150
	loop

*start

	; スクリーン表示
	gsel sid_main
	m_scDraw scr, 1

	; 描画
	redraw 1
	m_mydisp my
	foreach mongrp
		m_mondisp mongrp.cnt
		m_scMonHP scr, cnt, m_monHp(mongrp.cnt)
	loop
	await wtime/2
	redraw 0

	; キー入力
	stick key,255
	if key&128 : gosub *menu_open												; システムメニュー

	; ターン処理
	switch turn
		case 0
			my_turn																; 自キャラ
			swbreak
		case 1
			mon_turn															; モンスター
			swbreak
	swend
	turn = (turn+1)\2

	goto *start

; 自キャラ
#deffunc my_turn

	ret = m_myFall(my.0, MapAction)												; 落下判定
	if ret = 0 : ret = m_myWalk(my.0, key, MapAction)							; 移動処理
	if ret {
		check_x = m_myNX(my.0)
		check_y = m_myNY(my.0)

		; モンスターとの衝突チェック
		foreach mongrp
			if m_monHitcheck(mongrp.cnt, check_x, check_y) {					; 攻撃判定
				ret = 0
				dmg = rnd(20)
				m_monDamage mongrp.cnt, dmg
				m_scMonHP scr, cnt, m_monHp(mongrp.cnt)
				m_scMes scr, strf("HIT-%d", dmg)
				break
			}
		loop
	}
	if ret : m_myWalkcommit my.0												; 移動確定
	return

; モンスター
#deffunc mon_turn

	foreach mongrp: i=cnt
		if m_monHp(mongrp.i) > 0 {
			ret = m_monFall(mongrp.i, MapAction)								; 落下判定
			if ret = 0 : ret = m_monWalk(mongrp.i, MapAction)					; 移動処理
			if ret {
				check_x = m_monNX(mongrp.i)
				check_y = m_monNY(mongrp.i)

				; 自キャラとの衝突チェック
				if m_myHitcheck(my.0, check_x, check_y)	{						; 攻撃判定
					ret = 0
					dmg = rnd(20)
					m_myDamage my.0, dmg
					m_scHitPoints scr, m_myHp(my.0)
					m_scMes scr, strf("DMG-%d", dmg)
				}

				; モンスター同士の衝突チェック
				foreach mongrp
					if i!=cnt {
						if m_monHitcheck(mongrp.cnt, check_x, check_y) {
							ret = 0
							m_monTurn mongrp.i
							break
						}
					}
				loop
			}
			if ret : m_monWalkcommit mongrp.i									; 移動確定
		} else {
			; 消去処理
			m_monErase mongrp.i
			m_scMonHP scr, i, m_monHp(mongrp.i)
			delmod mongrp.i
		}
	loop
	return

; メイン操作不可、ダイアログ表示
*menu_open
	gsel 0: ws_set WS_DISABLED
*menu_main
	sdim menustr
	menustr(0)="システムメニュー"
	menustr(1)="ゲームに戻る"
	menustr(2)="終了する"
	ret = m_menuDisp(menu, menustr, length(menustr))
	if ret=0 or ret=1: goto *menu_close
	if ret=2 : end
	goto *menu_main

; メイン操作不可解除、ダイアログ非表示
*menu_close
	gsel 0,1: ws_reset WS_DISABLED
	return

xana_screen.hsp

;
; モジュール定義:「ウソザナ」画面表示用
; 作成     :ふじぽん
;
; モジュール名 :m_xana_screen
;
; モジュール変数:メッセージ表示Y位置mespos, 表示情報数値配列v_int, 表示情報文字列配列v_str
;
; Copyright   :http://d.hatena.ne.jp/fujiponXP
;
; 変更履歴
;  ver.1.0 2009/11/21 新規作成
;  ver.1.1 2009/12/06 オリジナル画像読込用SID, 表示サイズmapsize をモジュール変数として組み込み
;  ver.1.2 2009/12/20 SYSMENUリセット追加, モンスター体力表示修正
;
#module	m_screen mespos, v_int, v_str, sid_load, mapsizex, mapsizey

	;マクロ定義
	#define	C_BLACK		  0,  0,  0
	#define	C_GLAY		120,120,120
	#define	C_RED		255,  0,  0
	#define	C_BLUE		  0,  0,255
	#define	C_WHITE		255,255,255
	#define C_FONT_SIZE	11

	; 変数初期化
	#modinit	str chipfile, int px, int py
		dim  v_int, 28, 4											; 位置x, 色r,g,b
		sdim v_str, 28												; 表示文字列

		; 変数設定
		mespos = 0
		sid_load = ginfo(25)
		mapsizex = px
		mapsizey = py

		; 画面設定
		screen sid_main, cx * (mapsizex + 7), cy * (mapsizey + 1), screen_fixedsize
		ws_reset WS_SYSMENU
		title "ウソザナ"
		buffer sid_load: picload chipfile

		;マップ枠描画
		gsel sid_main
		repeat ginfo_sy/16: y=cnt
			repeat ginfo_sx/16: x=cnt
				pos x*16,y*16: gcopy sid_load, 64, 0, 16, 16
			loop
		loop
		color C_BLACK : boxf 16 - 2, 16 - 2, cx * mapsizex + 16 + 2, cy * mapsizey + 16 + 2 
		color C_BLUE  : boxf 16    , 16    , cx * mapsizex + 16    , cy * mapsizey + 16

		; ステータス欄
		color C_BLACK: boxf (mapsizex*2+2)*16-2, 2, (mapsizex*2+13)*16+13, 19*16+13
		color C_GLAY : boxf (mapsizex*2+2)*16  , 4, (mapsizex*2+13)*16+11, 19*16+11

		; メッセージ欄
		color   0, 0, 0: boxf (mapsizex*2+2)*16+4, 7*32+4, (mapsizex*2+13)*16+8, 19*16+8
		color 255, 0, 0: boxf (mapsizex*2+2)*16+6, 7*32+6, (mapsizex*2+13)*16+6, 19*16+6
		color   0, 0, 0: boxf (mapsizex*2+2)*16+8, 7*32+8, (mapsizex*2+13)*16+4, 19*16+4

		; フォント設定
		font "Georgia", C_FONT_SIZE, font_bold

		m_ValueSet thismod,  2, 0, C_BLACK, "Hit Points"
		m_ValueSet thismod,  4, 0, C_BLACK, "Gold"
		m_ValueSet thismod,  6, 0, C_BLACK, "Food"
		m_ValueSet thismod,  8, 0, C_BLACK, "Experience"
		m_ValueSet thismod, 11, 0, C_BLACK, "Equipment"

		return

	; 表示情報セット
	#modfunc m_ValueSet int py, int px, int pr, int pg, int pb, str pv
		v_int.py.0 = px												; 表示X位置
		v_int.py.1 = pr												; 赤色 
		v_int.py.2 = pg												; 緑色 
		v_int.py.3 = pb												; 青色
		v_str.py   = pv												; 文字列
		return

	; 表示 flg(0:通常 1:戦闘)
	#modfunc	m_scDraw	int flg
		redraw 0
		color C_GLAY
		boxf 20 * 16, 4, 30 * 16 + 27, 12 * 19 - 1
		repeat 17
			n = cnt + (cnt > 5) * 11 * flg
			m_scPrint v_int.n.1, v_int.n.2, v_int.n.3, v_int.n.0, cnt, v_str.n
		loop
		redraw 1
		return

	; メッセージ表示
	#modfunc	m_scMes	str p1
		gsel sid_main
		redraw 1
		if msgpos > 4 {
			x = (mapsizex + 1) * 32 + 10: y = 7 * 32 + 10
			repeat 14
				pos x, y
				gmode 1
				gcopy sid_main, x, y + 1, 10 * 16 + 7, 5 * 16 -6
				await 10
			loop
			msgpos = 4
		}
		m_scPrint C_WHITE, 1, 18 + msgpos, p1
		msgpos += 1
		await 10
		redraw 0

		return

	; 文字列表示
	#deffunc	m_scPrint	int pr, int pg, int pb, int px, int py, str ps
		x = px * C_FONT_SIZE + 10 * 32 + 4
		y = py * (C_FONT_SIZE+2) + 4

		; 影表示
		s = ps
		if (pr + pb + pg) > 0 {
			color C_BLACK
			repeat strlen(s)
				pos x + 2 + cnt * (C_FONT_SIZE+1), y + 1: mes strmid(s, cnt, 1)
			loop
		}

		; 文字表示
		color pr, pg, pb
		repeat strlen(s)
			c = strmid(s, cnt, 1)
			pos x + 0 + cnt * (C_FONT_SIZE+1), y: mes c
			pos x + 1 + cnt * (C_FONT_SIZE+1), y: mes c
		loop
		return

	; ボス画面
	#modfunc	m_scBossScr
		; 塗り潰し
		for i,0,(mapsizey+1)*2,1
			for j,0,(mapsizex+7)*2,1
				pos j*16, i*16: gcopy sid_scrload, 32, 0, 16, 16
			next
		next
		; 背景
		pos cx, 2*cy: gcopy sid_mapload, 0, 14*cy, 14*cx, 7*cy

		color 120,120,120: boxf cx, 16, cx+5*cx, 16+cy
		color 120,120,120: boxf cx+9*cx, 16, cx+14*cx, 16+cy
		
		return

	; 名前
	#modfunc	m_scName	str ps
		m_ValueSet thismod,  0, 0, C_RED, ps
		return

	; 称号
	#modfunc	m_scTitle	str ps
		m_ValueSet thismod,  1, 0, C_WHITE, ps
		return

	; 体力
	#modfunc	m_scHitPoints	int p1
		m_ValueSet thismod,  3, 5, C_WHITE, strf("%07d", p1)
		return

	; 所持金
	#modfunc	m_scGold	int p1
		m_ValueSet thismod,  5, 5, C_WHITE, strf("%07d", p1)
		return

	; 食料
	#modfunc	m_scFood	int p1
		m_ValueSet thismod,  7, 5, C_WHITE, strf("%07d", p1)
		return

	; 攻撃経験値
	#modfunc	m_scExpAt	int p1
		m_ValueSet thismod,  9, 5, C_WHITE, strf("%07d", p1)
		return

	; 魔法経験値
	#modfunc	m_scExpMg	int p1
		m_ValueSet thismod, 10, 5, C_WHITE, strf("%07d", p1)
		return

	; 武器
	#modfunc	m_scWepon	str ps
		m_ValueSet thismod, 12, 0, C_RED, ps
		return

	; 魔法
	#modfunc	m_scMagic	str ps
		m_ValueSet thismod, 13, 0, C_RED, ps
		return

	; 装備
	#modfunc	m_scWear	str ps
		m_ValueSet thismod, 14, 0, C_RED, ps
		return

	; 盾
	#modfunc	m_scShield	str ps
		m_ValueSet thismod, 15, 0, C_RED, ps
		return

	; 道具
	#modfunc	m_scItem	str ps
		m_ValueSet thismod, 16, 0, C_RED, ps
		return

	; モンスター名
	#modfunc	m_scMonName	str ps
		for i, 17, 28, 1
			if i = 18 {
				m_ValueSet thismod, i, 0, C_BLACK, ps
			} else {
				m_ValueSet thismod, i, 0, C_BLACK, ""
			}
		next
		return

	; モンスター体力
	#modfunc	m_scMonHP	int p1, int p2
		if p2 > 0 {
			m_ValueSet thismod, 19 + p1, 5, C_WHITE, strf("%07d", p2)
		} else {
			m_ValueSet thismod, 19 + p1, 5, C_RED, strf("DEAD")
		}	
		return

#global

xana_my.hsp

;
; モジュール定義:「ウソザナ」自キャラ用
; 作成     :ふじぽん
;
; モジュール名 :charactor
;
; モジュール変数:
;                x , y , ho , pt               現在情報(位置,方向,パターン)
;                ox, oy, oho, opt              旧情報(位置,方向,パターン)
;                nx, ny                        移動計算用
;                sid_load, sid_copy, sid_draw  SID(画像読込用,gcopy用,描画用)
;                basex, basey                  描画基本座標(左上)
;
; Copyright   :http://d.hatena.ne.jp/fujiponXP
;
; 変更履歴
;  ver.1.0 2009/11/08 新規作成
;  ver.1.1 2009/11/14 当たり判定(タイル)実装
;  ver.1.2 2009/11/21 描画位置変更 
;  ver.1.3 2009/11/22 画像書換え方法変更(TEST5対策)
;  ver.1.4 2009/12/13 描画位置変更,移動範囲制限(TEST8対策)
;  ver.1.5 2009/12/19 描画SID保持,描画位置指定,移動判定実装
;  ver.1.5 2009/12/23 ダメージ処理追加, パラメータ設定追加
;
#module charactor x, y, ho, pt, ox, oy, oho, opt, nx, ny, sid_load, sid_copy, sid_draw, basex, basey

	; 初期設定
	#modinit str fname, int p_draw, int p_basex, int p_basey

		; 変数初期化
		sid_draw = p_draw														; 描画用SID
		basex = p_basex
		basey = p_basey
		x = 0: y = 0: ho = 0: pt = 0: ox = -1

		; 画像セット
		sid_load = ginfo(25): buffer sid_load: picload fname					; オリジナル画像用SID
		sid_copy = ginfo(25): buffer sid_copy, 11*cx, cy						; gcopy用SID
		gsel sid_copy: pos 8*cx, 0: gcopy sid_load, 2*cx, 5*cy, cx, cy

		return

	; 位置設定
	#modfunc m_myPos int p1, int p2, int p3
		x = p1
		y = p2
		nx = p1
		ny = p2
		ho = p3
		return

	; パラメータ設定
	#modfunc m_myHpset int p_hp
		hp = p_hp
		return

	; 装備
	#modfunc m_myEquip int p1, int p2, int p3, int p4

		gsel sid_copy: boxf 0,0,9*cx,cy
		pos 0   ,0: gcopy sid_load, 2*cx, p1*cy, 8*cx, cy						; 体
		pos 9*cx,0: gcopy sid_load, (3+(p1=1 | p1=4))*cx, 5*cy, cx, cy			; 死亡

		color 0, 133, 111: gmode 4, 8*cx, cy,255
		if p2 > 0 : pos 0, 0: gcopy sid_load,  2*cx, (p2+12)*cy					; 頭
		if p3 > 0 : pos 0, 0: gcopy sid_load, 12*cx, (p3- 1)*cy					; 盾
		if p4 > 0 : pos 0, 0: gcopy sid_load, 12*cx, (p4+ 3)*cy					; 武器

		return

	; 描画
	#modfunc m_myDisp

		; 表示変更の確認
		if (ox=x)*(oy=y)*(opt=pt)*(oho=ho)*(damage=0) : return

		; 退避画像復元
		if ox > -1 {
			gsel sid_draw: gmode 0, cx, cy
			pos ox+basex, oy+basey: gcopy sid_copy, 10*cx, 0
		}
	
		; 描画前画像退避
		gsel sid_copy: gmode 0, cx, cy
		pos 10*cx, 0: gcopy sid_draw, x+basex, y+basey

		; 描画
		gsel sid_draw: color 0, 133, 111: gmode 4, cx, cy,255
		pos x+basex, y+basey: gcopy sid_copy, (ho*2+pt)*cx, 0
		color 255,255,255: if damage>1 : circle x+basex, y+basey, x+basex+cx, y+basey+cy, 0: damage=2
		damage = limit(damage - 1, 0, 10)

		; 現情報退避
		ox = x: oy = y: opt = pt: oho = ho
		return

	; 移動計算
	#modcfunc m_myWalk int k, array p_check
		key = k: dx = 0: dy = 0
		if key&1 :dx = -4: ho = HO_LEFT : key=0									; 左移動
		if key&4 :dx =  4: ho = HO_RIGHT: key=0									; 右移動
		if key&2 :dy = -4: ho = HO_UP   : key=0									; 上移動
		if key&8 :dy =  4: ho = HO_DOWN : key=0									; 下移動

		if (dx=0) and (dy=0) : nx = x: ny = y: return 0
		nx = x + dx: ny = y + dy
		pt = (pt + 1) \ 2

		; 判定位置算出
		x1 = nx      : y1 = ny													; 左上座標
		x2 = x1+cx-1 : y2 = y1													; 右上座標
		x3 = x1      : y3 = y1+cy-1												; 左下座標
		x4 = x1+cx-1 : y4 = y1+cy-1												; 右下座標

		; 左移動判定(MapActionのx1,y1またはx3,y3が1は移動不可)
		if ho=HO_LEFT  : if p_check(x1/cx,y1/cy)=1 or p_check(x3/cx,y3/cy)=1 : return 0

		; 右移動判定(MapActionのx2,y2またはx4,y4が1は移動不可)
		if ho=HO_RIGHT : if p_check(x2/cx,y2/cy)=1 or p_check(x4/cx,y4/cy)=1 : return 0

		; 上移動判定(MapActionのx1,y1またはx2,y2が1は移動不可)
		if ho=HO_UP    : if p_check(x1/cx,y1/cy)=1 or p_check(x2/cx,y2/cy)=1 : return 0

		; 下移動判定(MapActionのx3,y3またはx4,y4が1は移動不可)
		if ho=HO_DOWN  : if p_check(x3/cx,y3/cy)=1 or p_check(x4/cx,y4/cy)=1 : return 0

		return 1

	; 落下処理( 0=落下なし 1=落下 )
	#modcfunc m_myFall array p_check

		; 判定位置算出
		x1 = x       : y1 = y													; 左上座標
		x2 = x1+cx-1 : y2 = y1													; 右上座標
		x3 = x1      : y3 = y1+cx-1												; 左下座標
		x4 = x1+cx-1 : y4 = y1+cx-1												; 右下座標

		; 落下判定(MapActionのx3,y3またはx4,y4が5の場合)
		if p_check(x3/cx,(y3+1)/cx)=5 or p_check(x4/cx,(y4+1)/cx)=5 {
			ny = y+4
			return 1
		}
		return 0

	; 当たり判定
	#modcfunc m_myHitcheck int px, int py
		ret = (abs(x - px) < cx) & (abs(y - py) < cy)
		return ret

	; ダメージセット
	#modfunc m_myDamage int p1
		damage = p1
		hp -= p1
		return

	; 位置確定
	#modfunc m_myWalkcommit
		x = nx: y = ny
		return

	; 位置x
	#modcfunc m_myX
		return x

	; 位置y
	#modcfunc m_myY
		return y

	; 位置nx
	#modcfunc m_myNX
		return nx

	; 位置ny
	#modcfunc m_myNY
		return ny

	; 方向ho
	#modcfunc m_myHo
		return ho

	; HP
	#modcfunc m_myHp
		return hp

#global

xana_mon.hsp

;
; モジュール定義:「ウソザナ」モンスター用
; 作成     :ふじぽん
;
; モジュール名 :monster
;
; モジュール変数:
;                no               キャラno
;                sp               種類
;                type             タイプ(%1000=浮遊 %0100=上下 %0010=左右 %0001=ランダム %0000=静止)
;                x , y , ho , pt  現在情報(位置,方向,パターン)
;                ox, oy, oho, opt 旧情報(位置,方向,パターン)
;                nx, ny           移動計算用
;                basex, basey     描画基本座標(左上)
;                damage           ダメージ(0=なし 1=あり)
;
; Copyright   :http://d.hatena.ne.jp/fujiponXP
;
; 変更履歴
;  ver.1.0 2009/11/13 新規作成
;  ver.1.1 2009/11/14 当たり判定(タイル)実装
;  ver.1.2 2009/11/21 描画位置変更, 移動範囲変更
;  ver.1.3 2009/11/22 画像書換え方法変更(TEST5対策)
;  ver.1.4 2009/12/20 落下処理追加, 移動判定処理追加, 方向反転処理追加
;  ver.1.5 2009/12/23 ダメージ処理追加, タイル分割修正, 非表示処理追加, パラメータ設定追加
;

#module monster no, sp, type, x, y, ho, pt, ox, oy, opt, oho, nx, ny, basex, basey, damage, hp

	; 画像セット
	#deffunc m_monPicset str fname
		buffer sid_monload: picload fname										; オリジナル画像読込み用
		buffer sid_moncopy, 5*cx, 20*cy											; gcopy用(20体分)
		return

	; 変数初期化
	#modinit int pno, int psp, int p_type, int p_basex, int p_basey 
		no = pno: sp = psp: ox = -1: type = p_type
		basex = p_basex: basey = p_basey
		gsel sid_moncopy
		pos 0     ,no*cy: gcopy sid_monload, (sp\15)*2*cx, (sp/15)*cy, 2*cx, cy				; 左向き
		pos 4*cx-1,no*cy: gzoom -2*cx, cy, sid_monload, (sp\15)*2*cx, (sp/15)*cy, 2*cx, cy	; 右向き

		return

	; 位置設定
	#modfunc m_monPos int p1, int p2, int p3
		x = p1: y = p2: nx = p1 :ny = p2: ho = p3
		return

	; パラメータ設定
	#modfunc m_monHpset int p_hp
		hp = p_hp
		return

	; 描画
	#modfunc m_monDisp

		; 表示変更の確認
		if (ox=x)*(oy=y)*(opt=pt)*(oho=ho)*(odamage=damage) : return

		; 退避画像復元
		if ox > -1 {
			gsel sid_main: gmode 0, cx, cy
			pos ox+basex, oy+basey: gcopy sid_moncopy, 4*cx, no*cy
		}
	
		; 描画前画像退避
		gsel sid_moncopy: gmode 0, cx, cy
		pos 4*cx, no*cy: gcopy sid_main, x+basex, y+basey

		; 画像描画
		gsel sid_main: color 0, 143, 122: gmode 4, cx, cy, 255
		pos x+basex, y+basey: gcopy sid_moncopy, ((ho\2)*2+pt)*cx, no*cy

		; ダメージ描画
		if damage {
			color 255,255,255
			circle x+basex, y+basey, x+basex+cx, y+basey+cy, 0
			damage = 0
		}

		; 現情報退避
		ox = x: oy = y: opt = pt: oho = ho: odamage = damage
		return

	; 非表示
	#modfunc m_monErase

		; 退避画像復元
		gsel sid_main: gmode 0, cx, cy
		pos ox+basex, oy+basey: gcopy sid_moncopy, 4*cx, no*cy

	return

	; 移動計算(ret=0 移動無 ret=1 移動有)
	#modcfunc m_monWalk array p_check
		nx = x: ny = y
		pt = (pt + 1) \ 2
		if (type & %1000) = 0 and (rnd(30)=1) : m_monTurn thismod				; 歩行タイプ 1/30で方向変換
		if (type & %0111) = 0 : return 0										; 静止タイプ 移動なし
		if (type & %1000) = 0 and (rnd(3)=0) : return 0							; 歩行タイプ 1/ 3で移動なし

		nx = x + ((ho=HO_RIGHT) - (ho=HO_LEFT)) * 4
		ny = y + ((ho=HO_DOWN ) - (ho=HO_UP  )) * 4

		; 判定位置算出
		x1 = nx      : y1 = ny													; 左上座標
		x2 = x1+cx-1 : y2 = y1													; 右上座標
		x3 = x1      : y3 = y1+cy-1												; 左下座標
		x4 = x1+cx-1 : y4 = y1+cy-1												; 右下座標

		ret = 1
		; 左移動判定(MapActionのx1,y1またはx3,y3が1は移動不可)
		if ho=HO_LEFT  and (p_check(x1/cx,y1/cy)=1 or p_check(x3/cx,y3/cy)=1) : ret = 0

		; 右移動判定(MapActionのx2,y2またはx4,y4が1は移動不可)
		if ho=HO_RIGHT and (p_check(x2/cx,y2/cy)=1 or p_check(x4/cx,y4/cy)=1) : ret = 0

		; 上移動判定(MapActionのx1,y1またはx2,y2が1は移動不可)
		if ho=HO_UP    and (p_check(x1/cx,y1/cy)=1 or p_check(x2/cx,y2/cy)=1) : ret = 0

		; 下移動判定(MapActionのx3,y3またはx4,y4が1は移動不可)
		if ho=HO_DOWN  and (p_check(x3/cx,y3/cy)=1 or p_check(x4/cx,y4/cy)=1) : ret = 0

		; 衝突時の方向転換
		if ret = 0 : m_monTurn thismod

		return ret

	; 落下処理( 0=落下なし 1=落下 )
	#modcfunc m_monFall array p_check

		; 飛行タイプなら落下なし
		if type & %1000 : return 0

		; 判定位置算出
		x1 = x       : y1 = y													; 左上座標
		x2 = x1+cx-1 : y2 = y1													; 右上座標
		x3 = x1      : y3 = y1+cx-1												; 左下座標
		x4 = x1+cx-1 : y4 = y1+cx-1												; 右下座標

		; 落下判定(MapActionのx3,y3またはx4,y4が5の場合)
		if p_check(x3/cx,(y3+1)/cx)=5 or p_check(x4/cx,(y4+1)/cx)=5 {
			ny = y+4
			return 1
		}
		return 0

	; 方向転換 反転
	#modfunc m_monTurn

		; 上下左右タイプ
		if type & %0110 {
			switch ho
				case HO_LEFT
					ho = HO_RIGHT
					swbreak
				case HO_UP
					ho = HO_DOWN
					swbreak
				case HO_RIGHT
					ho = HO_LEFT
					swbreak
				case HO_DOWN
					ho = HO_UP
					swbreak
			swend
		}

		; ランダムタイプ
		if type & %0001 {
			switch ho
				case HO_LEFT
					ho = HO_UP
					swbreak
				case HO_UP
					ho = HO_RIGHT
					swbreak
				case HO_RIGHT
					ho = HO_DOWN
					swbreak
				case HO_DOWN
					ho = HO_LEFT
					swbreak
			swend
		}

		; 静止タイプ
		if (type & %0111)=0 : ho = rnd(3)

		return ret

	; 当たり判定
	#modcfunc m_monHitcheck int px, int py
		return (abs(x - px) < cx) & (abs(y - py) < cy)

	; ダメージセット
	#modfunc m_monDamage int p1
		damage = p1
		hp -= p1
		return

	; 位置確定
	#modfunc m_monWalkcommit
		x = nx: y = ny
		return

	; 位置x
	#modcfunc m_monX
		return x

	; 位置y
	#modcfunc m_monY
		return y

	; 位置nx
	#modcfunc m_monNX
		return nx

	; 位置ny
	#modcfunc m_monNY
		return ny

	; 方向ho
	#modcfunc m_monHo
		return ho

	; HP
	#modcfunc m_monHp
		return hp

#global