//デバッグ用
var DBG_PRT = false;//値の表示
var DBG_PTY = false;//全パーティメンバーをセット
var DBG_ITM = false;//全アイテムをセット
var DBG_CHANGE = false;//マップ切り替えの場所が判る
var dbgFlg = 0;

//定数
var FNT_SIZ = 36;//フォントの大きさ

//処理ごとのインデックス【制作中】
var IDX_INIT		=  0;//初期化
var IDX_TITLE		=  1;//タイトル
var IDX_MOVE		=  2;//移動シーン
var IDX_CHANGE		=  3;//場所変更
var IDX_TALK		=  4;//会話
var IDX_ITEM		=  5;//道具入手の処理
var IDX_GOLD		=  6;//お金入手の処理
var IDX_JOIN		=  7;//仲間になるイベント
var IDX_INN			=  8;//宿屋
var IDX_STAY		=  9;//泊まる演出
var IDX_SHOP		= 10;//店の処理
var IDX_BUY			= 11;//購入
var IDX_BUYNUM		= 12;//購入個数
var IDX_SELL		= 13;//売却
var IDX_SELLNUM		= 14;//売却個数
var IDX_EVENT		= 15;//各種のイベント
var IDX_MENU_TOP	= 16;//メニュー　トップ画面
var IDX_MENU_STS	= 17;//メニュー　能力値
var IDX_MENU_ITM	= 18;//メニュー　アイテム
var IDX_MENU_EQU	= 19;//メニュー　装備品選択画面
var IDX_MENU_USE	= 20;//メニュー　消費アイテムを使う
var IDX_MENU_MAYOKE	= 21;//メニュー　魔除け効果の演出
var IDX_MENU_DEGUCHI= 22;//メニュー　出口へ移動する演出
var IDX_BTL_INIT	= 30;//戦闘　初期化
var IDX_BTL_START	= 31;//戦闘　開始
var IDX_BTL_TURN	= 32;//戦闘　行動するキャラを決める
var IDX_BTL_CMD		= 33;//戦闘　コマンド入力
var IDX_BTL_SELEMY	= 34;//戦闘　敵選択
var IDX_BTL_ATTACK	= 35;//戦闘　物理攻撃
var IDX_BTL_VIORDE	= 36;//戦闘　勝敗判定
var IDX_BTL_WIN		= 37;//戦闘　勝利
var IDX_BTL_LOSE	= 38;//戦闘　敗北

//色の定義
var COL_POIA = [3, 6, 3];//毒状態で歩く時のアルファ値(÷10して使う)
var COL_RECA = [0, 0, 0, 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 0];//回復演出のアルファ値(÷10して使う)

//最大値の定義
var MAX_GOLD = 99999;
var MAX_ITM = 99;

//変数の宣言
var idx = 0;//┬プログラムの進行を管理
var tmr = 0;//┘
var dcnt = 0;//描画(主にアニメーション)用のカウンター
var gpv = 0;//諸々汎用　その場限りで使う変数
var inp = 0;//入力汎用　その場限りで使う変数

//所持金
var gold;

//プレイヤーキャラの移動用
var XP = [ 0,  0, -1,  1];//各向き（上下左右）の座標変化値
var YP = [-1,  1,  0,  0];
var FACE_DIR = [1, 0, 3, 2];//会話時などにプレイヤー側に向かせる
var PLWF = 4;//何フレームで１マス動くか
var plWalk;//移動処理のフラグ（カウンター）
var steps;//敵エンカウント歩数の管理
var mayoke;//魔除けの歩数カウント
var map_no;//プレイヤーがどのマップにいるか
var worldX, worldY;//プレイヤーのワールドマップ上の座標（町やダンジョンの出入りで使用）

var MENU_TOP = ["能力/装備", "道具", "セーブ", "ロード"];//メニュー画面の項目
var BTL_CMD = ["攻撃", "スキル", "道具", "防御", "撤退"];//戦闘コマンド　【開発メモ】「魔法」がこのゲームでは「スキル」

var selTtl;		//タイトル画面項目選択
var selMenu;	//メニュートップ画面項目選択
var selChr;		//メニュー能力画面　キャラ選択
var selEq;		//メニュー能力画面　装備品選択
var selItm;		//メニュー道具画面
var selItmPage;	//　〃
var selAns;		//はい、いいえを選ぶ
var selShp;		//店の処理用　どの商品を買うか
var selNum;		//店の処理用　それをいくつ買うか
var effRec;		//メニューでの回復演出用
var numOfPty;	//パーティメンバーが何人いるか

//ここから下は初期化不要の変数
var talkNum;	//表示する会話データの番号
var talkNxt;	//会話データが次の文章に続くか
var talkDat;	//表示するメッセージ
var shopNum;	//店番号を管理する
var itemNum;	//購入処理で使う
var price;		//購入処理で使う

//フラグ管理
var FLG_MAX = 2000;//フラグの総数
var flg = [];
function initFlg() {//フラグの初期化
 for(var i = 0; i < FLG_MAX; i++) flg[i] = 0;
}

//入手アイテム管理　※ITM_MAX は ohq_item.js に記述
var ITM_PER = 8;//メニューで何個ずつアイテムを表示するか
var itf = [];//一度手に入れているかのフラグ
var itm = [];//持っている数
function initItm() {//フラグの初期化
 for(var i = 0; i < ITM_MAX; i++) {
  itf[i] = 0;
  itm[i] = 0;
 }
}
function getItm(n, val) {//手に入れる処理
 itf[n] = 1;//【開発メモ】一度手に入れたかのフラグを管理
 itm[n] += val;
 if(itm[n] > 99) {itm[n] = 99; return 1;}//上限値もあるので関数とする
 return 0;
}

function itmName(n) {//アイテムの名称を返す
 return ITEM_DATA[n*5];
}

function itmClass(n) {//アイテムの種類を返す
 return ITEM_DATA[n*5+1];
}

function itmPrice(n) {//アイテムの値段を返す
 return ITEM_DATA[n*5+2];
}

function itmPara1(n) {//アイテムのパラメータを返す
 return ITEM_DATA[n*5+3];
}

function itmAtc(cno) {//cnoキャラの装備の攻撃力増加値を返す
 var val = ITEM_DATA[sts[cno].equip[0]*5+3];
 if(sts[cno].equip[0] == 0) val = 100;//装備無しの時は100(x1)
 return val;
}

function itmDef(cno) {//cnoキャラの装備の防御力増加値を返す
 var val = ITEM_DATA[sts[cno].equip[1]*5+3];
 if(sts[cno].equip[1] == 0) val = 100;//装備無しの時は100(x1)
 return val;
}

function canEq(cno,ino) {//cnoのキャラ(今回は絵の番号)がinoのアイテムを装備できるか返す
 var i;
 var eq = parseInt(ITEM_DATA[ino*5+4]/Math.pow(10,3-obj[cno].p));
 if( eq&1 == 1 ) return true; else return false;
}

//マップデータの管理
var mapdata = [];
var mapname = "";
var mapW, mapH;
var mapAtt = [0, 0, 0, 0, 0];//マップの属性　範囲外は何番のチップにするかなど
var bgmBak = -1;//それまで流していたＢＧＭの番号

function setMap() {//マップデータをセットする
 var mtop = 0;
 var loop = 0;
 while(true) {//データの頭出し
  mapname = MAPDATA[mtop];
  mapW = MAPDATA[mtop+1];
  mapH = MAPDATA[mtop+2];
  if(loop == map_no) break;
  loop++;
  mtop = mtop + 8 + mapW*mapH;
 }
 for(var i = 0; i < mapW*mapH; i++) mapdata[i] = MAPDATA[mtop+3+i];
 for(var i = 0; i < 5; i++) mapAtt[i] = MAPDATA[mtop+3+mapW*mapH+i];
 if(bgmBak != mapAtt[2]) {//ＢＧＭの番号が変化した場合
  bgmBak = mapAtt[2];
  stopBgm();//一旦停止する
  if(bgmBak >= 0) playBgm(bgmBak);//出力
 }
}

function chipNo(x, y) {//マップチップの値を返す
 if(x < 0 || x >= mapW || y < 0 || y >= mapH) return mapAtt[0];
 return mapdata[x+y*mapW];
}

function chkWall(cn, dir) {//キャラクターの上下左右が壁か調べる
 var x = obj[cn].x + XP[dir];
 var y = obj[cn].y + YP[dir];
 if( WALL[chipNo(x,y)]&1 == 1 ) return true;//壁
 return false;
}

function drawChip(cn, dx, dy) {//マップチップの表示
//【開発メモ】↓本来こうしたいが、ＢＧに筋が表示されてしまうので、下の４行で対応
// if(cn == 0) return;
 if(cn == 0) {
  if(mapAtt[1] >= 0) fRect(dx, dy, CHIP_SIZE, CHIP_SIZE, COL_MARGIN[mapAtt[1]]);
  return;
 }
 var sx = 1+(CHIP_SIZE+2)*(cn%10);
 var sy = 1+(CHIP_SIZE+2)*(toInt(cn/10));
 drawImgTS(IMG_MAPCHIP, sx, sy, CHIP_SIZE, CHIP_SIZE, dx, dy, CHIP_SIZE, CHIP_SIZE);
}

function drawMS(cn, dx, dy) {//マップシンボルの表示
 var sx = 100*cn;
 var sy = 0;
 drawImgTS(IMG_MAPSYMBOL, sx, sy, 100, 100, dx, dy, 100, 100);
}

function drawChr(cn, dx, dy, dir, wlk) {//キャラクターの表示
 var sx = 100*cn+2;
 var sy = 72*dir;
 if(wlk == true) sx += 48*(toInt(dcnt/4)%2);//歩行アニメ
 drawImgTS(IMG_HUMAN, sx, sy, 48, 72, dx, dy, 48, 72);
}

function drawFur(n, x, y) {//家具類の表示
 var sx = 96*(n%4);
 var sy = 96*toInt(n/4);
 drawImgTS(IMG_FURNITURE, sx+2, sy+2, 92, 92, x-22, y-44, 92, 92);
}

//各キャラのステータス(能力)を管理
var PTY_MAX = 4;//パーティメンバーを最大何人管理するか
var EMY_MAX = 3;//敵キャラを最大何体扱うか
var EMY_TOP = PTY_MAX;//戦闘処理中に使う敵ステータスの添え字の開始番号

//ステータスを管理するクラス【開発メモ】将来的に戦闘時の敵の能力も管理する
function Sts() {
 this.name = "";//名前
 this.mh   = 0;	//体力値　最大
 this.hp   = 0;	//体力値
 this.mm   = 0;	//魔力　最大
 this.mp   = 0;	//魔力
 this.str  = 0;	//腕力
 this.def  = 0;	//防御力
 this.itl  = 0;	//知力
 this.mde  = 0;	//魔法防御
 this.agi  = 0;	//素早さ
 this.equip = [0, 0, 0];//装備品
 this.gen  = 0;	//性別
 this.img = 0;//敵の画像番号
 this.poison = 0;//毒状態を管理
 this.battle = 0;//戦闘の行動順番を管理
}

var sts = [];
function initSts() {//ステータスクラスの初期化
 for(var i = 0; i < PTY_MAX+EMY_MAX; i++) sts[i] = new Sts();
}

function setSts(no, _name, _mh, _hp, _mm, _mp, _st, _de, _it, _md, _ag, _e0, _e1, _e2, _ge, _im) {
 sts[no].name = _name;
 sts[no].mh   = _mh;
 sts[no].hp   = _hp;
 sts[no].mm   = _mm;
 sts[no].mp   = _mp;
 sts[no].str  = _st;
 sts[no].def  = _de;
 sts[no].itl  = _it;
 sts[no].mde  = _md;
 sts[no].agi  = _ag;
 sts[no].equip[0] = _e0;
 sts[no].equip[1] = _e1;
 sts[no].equip[2] = _e2;
 sts[no].gen  = _ge;
 sts[no].img  = _im;
 sts[no].poison = 0;
 sts[no].battle = 0;
}

function setChrSts(no, typ) {//ohq_status.jsで定義してあるパラメータをセットする
 typ *= 15;
 setSts( no,
  CHR_STATUS[typ+0],
  CHR_STATUS[typ+1],
  CHR_STATUS[typ+2],
  CHR_STATUS[typ+3],
  CHR_STATUS[typ+4],
  CHR_STATUS[typ+5],
  CHR_STATUS[typ+6],
  CHR_STATUS[typ+7],
  CHR_STATUS[typ+8],
  CHR_STATUS[typ+9],
  CHR_STATUS[typ+10],
  CHR_STATUS[typ+11],
  CHR_STATUS[typ+12],
  CHR_STATUS[typ+13],
  CHR_STATUS[typ+14] );
}

function clrSts(no) {//ステータスをクリアする（そのキャラが存在しない状態）
 setSts(no, "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

//オブジェクトの管理
var OBJ_MAX = 100;//最大いくつのオブジェを管理するか			【開発メモ】0～9の10個はパーティメンバー用
var objMax;//各マップに配置されたオブジェの数					【開発メモ】マップシンボルやNPCは配列10番から配置する
var objNum;//プレイヤーが載った（接した）オブジェクト番号

//Var0.0.5からオブジェクト管理をクラス化
function Obj() {
 this.type	= 0;//タイプ　マップシンボルなのか人間なのかなど【開発メモ】値は ohq_mapdata.js で定義している
 this.x		= 0;//┬マップチップ上の座標
 this.y		= 0;//┘
 this.cx	= 0;//┬キャンバスに表示するための座標
 this.cy	= 0;//┘
 this.p		= 0;//画像の番号
 this.d1	= 0;//各種データ【開発メモ】プレイヤーキャラとＮＰＣの向きは objD1 で管理
 this.d2	= 0;
 this.d3	= 0;
 this.d4	= 0;
 this.d5	= 0;
 this.flg	= 0;//フラグ
}

obj = [];
function initObj() {//オブジェクトクラスの初期化
 for(var i = 0; i < OBJ_MAX; i++) obj[i] = new Obj();
}

function clrObj(n) {//オブジェクトを消す
 obj[n].type = 0;//※この値が0なら存在しないものとする
}

function clrObjAll() {//全てのオブジェクトが配置されていない状態にする
 for(var i = 10; i < OBJ_MAX; i++) clrObj(i);
}

function initLeader() {//パーティメンバー先頭キャラの初期化
 setChrSts(0, 0);//勇者のパラメータをセット
 obj[0].type = OBJ_PTY;
 obj[0].x = 60;
 obj[0].y = 63;
 obj[0].p = sts[0].img;
 obj[0].d1 = 1;//向き　0上,1下,2左,3右

//★★★店のデバッグ
/*
map_no = 2;
obj[0].x = 4;
obj[0].y = 9;
worldX = 60;
worldY = 63;

//★★★王様のデバッグ
map_no = 8;
obj[0].x = 7;
obj[0].y = 7;
worldX = 60;
worldY = 63;

//★★★教会デバッグ
map_no = 9;
obj[0].x = 7;
obj[0].y = 5;
worldX = 60;
worldY = 10;
*/
 obj[0].cx = obj[0].x*CHIP_SIZE;
 obj[0].cy = obj[0].y*CHIP_SIZE;
 numOfPty = 1;
}

function joinPty(stsNo) {//パーティメンバーを加える
 var n = numOfPty;
 setChrSts(n, stsNo);
 obj[n].type = OBJ_PTY;
 obj[n].x = obj[0].x + XP[obj[0].d1];
 obj[n].y = obj[0].y + YP[obj[0].d1];
 obj[n].cx = obj[n].x*CHIP_SIZE;
 obj[n].cy = obj[n].y*CHIP_SIZE;
 obj[n].p = sts[n].img;
 obj[n].d1 = FACE_DIR[obj[0].d1];
 numOfPty++;//パーティのメンバー数を増やす
}

function walkPty() {//２人目からのパーティメンバーをぞろぞろ歩かせる
 var i, xp, yp;
 for(i = 1; i < 10; i++) {
  if(obj[i].type == OBJ_PTY) {
   xp = obj[i-1].x - obj[i].x;//列の前にいるキャラが何マス離れたか
   yp = obj[i-1].y - obj[i].y;//
   if(Math.abs(xp) >= 2 || Math.abs(yp) >= 2 || xp*yp != 0) {// 横に２マス or 縦に２マス o r斜め に離れた
     obj[i].x = obj[i-1].x - XP[obj[i-1].d1];//すぐ後ろの座標とする
     obj[i].y = obj[i-1].y - YP[obj[i-1].d1];
   }
   //キャンバス上の座標を計算し、必要なら動かす
   xp = obj[i].x*CHIP_SIZE - obj[i].cx;//あるべき位置と現在の位置の差
   yp = obj[i].y*CHIP_SIZE - obj[i].cy;
   var spd = CHIP_SIZE/PLWF;
   if(yp < 0) {obj[i].d1 = 0; obj[i].cy -= spd;}
   if(yp > 0) {obj[i].d1 = 1; obj[i].cy += spd;}
   if(xp < 0) {obj[i].d1 = 2; obj[i].cx -= spd;}
   if(xp > 0) {obj[i].d1 = 3; obj[i].cx += spd;}
  }
 }
}

function gatherPty(dir) {//パーティ全員を先頭キャラの位置にする
 var i;
 for(i = 0; i < 10; i++) {
  obj[i].x  = obj[0].x;
  obj[i].y  = obj[0].y;
  obj[i].cx = obj[i].x*CHIP_SIZE;
  obj[i].cy = obj[i].y*CHIP_SIZE;
  obj[i].d1 = dir;
 }
}

function walkNpc() {//ＮＰＣを歩かせる
 var i, r, xp, yp;
 var spd = CHIP_SIZE/8;//【開発メモ】CHIP_SIZEが８の倍数である必要がある
 for(i = 10; i < OBJ_MAX; i++) {
  r = rnd(1000);
  if(obj[i].type == OBJ_NPC) {
   //キャンバス上の座標を計算し、必要なら動かす
   xp = obj[i].x*CHIP_SIZE - obj[i].cx;//あるべき位置と現在の位置の差
   yp = obj[i].y*CHIP_SIZE - obj[i].cy;
   if(obj[i].d2 == _WALK && xp == 0 && yp == 0) {//歩くキャラが停止中
    if(r < 50) {//ランダムに向きを変える
     obj[i].d1 = r%4;
     continue;
    }
    else if(r < 100) {//歩く
     if(chipNo(obj[i].x, obj[i].y) == chipNo(obj[i].x+XP[obj[i].d1], obj[i].y+YP[obj[i].d1])) {//向いている先が今いる場所と同じチップ
      if(chkObj(i, obj[i].d1) == -1) {//進む先にオブジェが無い
       obj[i].x += XP[obj[i].d1];
       obj[i].y += YP[obj[i].d1];
       continue;
      }
     }
    }
   }
   if(yp < 0) {obj[i].d1 = 0; obj[i].cy -= spd;}
   if(yp > 0) {obj[i].d1 = 1; obj[i].cy += spd;}
   if(xp < 0) {obj[i].d1 = 2; obj[i].cx -= spd;}
   if(xp > 0) {obj[i].d1 = 3; obj[i].cx += spd;}
  }
 }
}

function setObj() {//オブジェクトデータをセットする
 var pos = 0;
 var loop = 0;
 while(true) {//データの頭出し
  if(isNaN(OBJDATA[pos]) == true) {
   if(loop == map_no) break;
   loop++;
  }
  pos++;
 }
 pos++
 objMax = 10;
 while(true) {
  if(isNaN(OBJDATA[pos]) == true) break;
console.log("オブジェ配置"+objMax+" type="+OBJDATA[pos+0]+"("+OBJDATA[pos+2]+","+OBJDATA[pos+3]+")");//★★★デバッグ
  obj[objMax].type = OBJDATA[pos+0];
  obj[objMax].p  = OBJDATA[pos+1];
  obj[objMax].x  = OBJDATA[pos+2];
  obj[objMax].y  = OBJDATA[pos+3];
  obj[objMax].cx = obj[objMax].x*CHIP_SIZE;
  obj[objMax].cy = obj[objMax].y*CHIP_SIZE;
  obj[objMax].d1 = OBJDATA[pos+4];
  obj[objMax].d2 = OBJDATA[pos+5];
  obj[objMax].d3 = OBJDATA[pos+6];
  obj[objMax].d4 = OBJDATA[pos+7];
  obj[objMax].d5 = OBJDATA[pos+8];
  obj[objMax].flg = OBJDATA[pos+9];

  //宝箱（入手して空の場合）
  if(obj[objMax].type == OBJ_TBOX) {
   if(obj[objMax].d3 == _ITEM || obj[objMax].d3 == _GOLD) {
    if(flg[obj[objMax].flg] != 0) obj[objMax].d1 = 1;//宝箱を開いた絵にする
   }
  }
  //配置しないＮＰＣ
  if(obj[objMax].type == OBJ_NPC) {
   if(obj[objMax].d3 == _JOIN) {
    if(flg[obj[objMax].flg] != 0) clrObj(objMax);//仲間になったキャラは出現させない
   }
  }
  pos += 10;
  objMax++;
 }
}

function chkSw() {//プレイヤーのいる場所にスイッチがあるか？
 var ret = -1;
 for(var i = 10; i < objMax; i++) {
  if(obj[i].type == OBJ_SW && obj[i].x == obj[0].x && obj[i].y == obj[0].y) {ret = i; break;}
 }
 return ret;
}

function chkObj(n, dir) {//目の前にオブジェクトがあるか？　【開発メモ】プレイヤーの移動、及び、ＮＰＣの移動で使う関数
 var ret = -1, st = 0;
 var x = obj[n].x+XP[dir];
 var y = obj[n].y+YP[dir];
 if(n == 0) {//プレイヤーの場合
  st = 10;//パーティメンバーがいるかをチェックしない
  if(CN_TABLE <= chipNo(x,y) && chipNo(x,y) < CN_TABLE+CN_TAB_NUM) {//調べようとしているものがテーブルの場合、その１マス先を調べる
   x += XP[dir];
   y += YP[dir];
  }
 }
 for(var i = st; i < objMax; i++) {
//【開発中】現状パーティメンバー、ＮＰＣ、宝箱、家具を判定
  if(obj[i].type == OBJ_PTY || obj[i].type == OBJ_NPC || obj[i].type == OBJ_TBOX || obj[i].type == OBJ_FUR) {
   if(obj[i].x == x && obj[i].y == y) {ret = i; break;}
  }
 }
 return ret;
}

function drawObj() {//オブジェクトを描画する
 var i, j, n, x, y;
 //表示順番をソート処理で決める
 var sortN = [], sortY = [];
 for(i = 0; i < objMax; i++) {
  sortN[i] = i;
  sortY[i] = obj[i].cy;
  if(obj[i].type == OBJ_PTY) sortY[i] -= i;//パーティメンバーが同じマスにいる時、先頭の勇者が上に表示されるようにする
  if(obj[i].type == OBJ_FUR) sortY[i] -= 10;//家具と人間が同じ位置にいる場合、家具を下にする
  if(obj[i].type == OBJ_SW ) sortY[i] -= 1000;//スイッチは強制的に“下側”に表示
 }
 for(i = 0; i < objMax-1; i++) {//バブルソートで並び替える
  for(j = 0; j < objMax-1-i; j++) {
   if(sortY[j] > sortY[j+1]) {
    n = sortN[j]; sortN[j] = sortN[j+1]; sortN[j+1] = n;
    y = sortY[j]; sortY[j] = sortY[j+1]; sortY[j+1] = y;
   }
  }
 }

 for(i = 0; i < objMax; i++) {//表示処理
  n = sortN[i];
  if(obj[n].type == 0) continue;
  x = obj[n].cx-obj[0].cx+(7*CHIP_SIZE);//プレイヤーキャラとの相対座標
  y = obj[n].cy-obj[0].cy+(7*CHIP_SIZE);
  if(obj[n].type == OBJ_PTY || obj[n].type == OBJ_NPC) {
   if(idx > IDX_BTL_INIT) continue;//戦闘中は表示しない
   y -= 32;//足元の位置
   if(-96 < x && x < 720 && -96 < y && y < 720) drawChr(obj[n].p, x, y, obj[n].d1, true);
   if(n == 0 && mayoke > 0) {//魔除けの演出
    fCir(x+24, y+36, 36, "rgba(255,255,64,0.5)");
   }
   if(n < 10) {//毒の演出
    if(poison[n] > 0) {
     fCir(x+24, y+36, 36, "rgba(255,0,0,"+(COL_POIA[3-poison[n]]/10)+")");
     poison[n]--;
    }
   }
  }
  if(obj[n].type == OBJ_SW) {
   if(obj[n].p >= 0) {//【開発メモ】今のところスイッチはマップシンボルのみ
    x -= ( 100-CHIP_SIZE )/2;//画像のセンタリング
    y -= ( 100-CHIP_SIZE )/2;
    if(-96 < x && x < 720 && -96 < y && y < 720) drawMS(obj[n].p, x, y);
   }
   else {
    if(DBG_CHANGE) sRect(x, y, 48, 48, "red");//★★★デバッグ
   }
  }
  if(obj[n].type == OBJ_TBOX) {
   if(-96 < x && x < 720 && -96 < y && y < 720) drawFur(obj[n].p+obj[n].d1, x, y);//宝箱の表示
  }
  if(obj[n].type == OBJ_FUR) {
   if(-96 < x && x < 720 && -96 < y && y < 720) drawFur(obj[n].p, x, y);//家具の表示
  }
 }
}

//マップ（ＢＧ）の描画
var mapL, mapT, ofsX, ofsY;
function drawBG() {
 var x, y;
//【開発メモ】↓本来こうしたいが、ＢＧに筋が表示されてしまうので、drawChipにて対応
// if(mapAtt[1] >= 0) {//範囲外の色が設定されている場合
//  fRect(0, 0, 720, 720, COL_MARGIN[mapAtt[1]]);//全体を塗り潰す
// }
 mapL = toInt(obj[0].cx/CHIP_SIZE)-7;
 mapT = toInt(obj[0].cy/CHIP_SIZE)-7;
 ofsX = -(obj[0].cx%CHIP_SIZE);
 ofsY = -(obj[0].cy%CHIP_SIZE);
 for(y = -1; y < 16; y++) {
  for(x = -1; x < 16; x++) drawChip(chipNo(mapL+x,mapT+y), x*CHIP_SIZE+ofsX, y*CHIP_SIZE+ofsY);
 }
}

function drawFG() {
 var c, x, y;
 for(y = 0; y < 17; y++) {
  for(x = -1; x < 16; x++) {
   c = chipNo(mapL+x,mapT+y);
   //フォアとして描画するチップ（屋根のパーツや隠し通路など）
   if(WALL[c] == 2) drawChip(c, x*CHIP_SIZE+ofsX, y*CHIP_SIZE+ofsY);
   //上下に並べて表示するチップ
   if(WALL[c] == 3) {
    if(c == CN_CANDLE-1) c += toInt(dcnt/5)%3;//蜀台のアニメーション
    drawChip(c+1, x*CHIP_SIZE+ofsX, (y-1)*CHIP_SIZE+ofsY);
   }
  }
 }
}

//戦闘用　戦闘開始時に初期値をセットする
var btlBG;		//背景の番号
var btlAct;		//誰が（行動するキャラ）
var btlTgt;		//誰を（ターゲット）
var btlCmd;		//コマンド
var selEmy;		//攻撃する敵を選ぶ
var mpShake = [];//ダメージを受けた時、パラメータ表示部を揺らす
var emyXP = [], emyYP = [];//敵表示用
var dmg = [];


function drawArrow(x, y) {//矢印の表示
 fTri(x, y+12, x-12,y-12, x+12,y-12, "black");
 fTri(x, y+10, x-10,y-10, x+10,y-10, "white");
}

function drawEmy(p, x, y) {//敵の表示
 var sx = 300*(p%3)+720;
 var sy = 360*parseInt(p/3);
 drawImgTS(IMG_BTL, sx+1, sy+1, 300-2, 360-2, x-150, y-360, 300-2, 360-2);
}

function drawBBar( txt ) {//戦闘画面上
 drawMenu(360, 30, 720, 60);
 fText(txt, 360, 30, FNT_SIZ, "white");
}

function drawBBG( dy ) {//戦闘背景
 var sx = 0;
 var sy = btlBG*360;
 drawImgTS(IMG_BTL, sx, sy, 720, 360, 0, dy, 720, 360);
}

//戦闘メッセージ
var btlMSG = [];//文字列
var btlMST = [];//時間管理(表示位置、透明度)
function clrBtlMsg() {
 for(var i=0; i<5; i++) { btlMSG[i] = ""; btlMST[i] = 0; }
}

function setBtlMsg(txt) {
 for(var i=0; i<5; i++) {
  if(btlMST[i] == 0) {
   btlMSG[i] = txt;
   btlMST[i] = 50;
   for(var j=0; j<5; j++) {//既にセットされていたメッセージを追い出す
    if(j != i && btlMST[j] > 10) btlMST[j] = 10;
   }
   break;
  }
 }
}

function drawBtlMsg() {
 for(var i=0; i<5; i++) {
  if(btlMST[i] > 0) {
   var a = 1.0;//アルファ値
   var y = 360;
   if(btlMST[i] < 10) { y = 360-(10-btlMST[i])*10; a = btlMST[i]/10; }
   if(btlMST[i] > 40) { y = 360+(btlMST[i]-40)*5; a = (50-btlMST[i])/10; }
   fText(btlMSG[i], 360, y+2, FNT_SIZ*0.9, "rgba(0,0,0,"+a+")");
   fText(btlMSG[i], 360, y, FNT_SIZ*0.9, "rgba(255,255,255,"+a+")");
   btlMST[i]--;
  }
 }
}

function drawBTL() {//戦闘画面
 var i, x, y;
 drawBBG(60);
 fRect(0, 420, 720, 300, "rgba(0,0,0,0.5)");
 for(i=0; i<EMY_MAX; i++) {
  x = 120+240*i;	//┬敵の足元の中心の位置
  y = 420;			//┘
  if(sts[EMY_TOP+i].hp > 0) drawEmy(sts[EMY_TOP+i].img, x+emyXP[i], y+emyYP[i]);
 }
 drawBtlMsg();
 miniPara(480);

//for(i=0; i<PTY_MAX+EMY_MAX; i++) fText(i+":"+sts[i].hp+"/"+sts[i].mh+" "+sts[i].battle, 360, 120+40*i, 20, "red");//★★★
}

//メニュー画面の描画用
function drawMenu(x, y, w, h) {
 fRect(x-w/2, y-h/2, w, h, "rgba(0,0,0,0.5)");
 sRect(x-w/2, y-h/2, w, h, "white");
}

function selBar(x, y, w, h) {
 fRect(x-w/2, y-h/2, w, h, "rgba(255,255,255,0.4)");
}

//所持金の加算
function getGld(val) {
  gold += val;
  if(gold > MAX_GOLD) gold = MAX_GOLD;
}

//所持金の表示
var GOLD = "gold";
function drawGold(typ) {
 var x = 360;//基本値
 var y = 100;
 var w = 360;
 var h =  60;
 var ofs = 0;
 if(typ == 0) {//メニュー
  drawMenu(x, y, w, h);
 }
 if(typ == 1) {//宿屋
  x = 180;
  y = 120;
  h = 160;
  ofs = 40;
  drawMenu(x, y, w, h);
  fText("宿泊代 " + gpv + GOLD, x, y+ofs, FNT_SIZ, "white");
 }
 if(typ == 2) {//店
  y = 40;
  drawMenu(x, y, w, h);
 }
 fText("所持金 " + gold + GOLD, x, y-ofs, FNT_SIZ, "white");
}

//はい、いいえを選ぶ処理
function inputYN(typ) {
 var x = 620;
 var y = 120;
 var w = 160;
 var h = 160;
 var ANS0 = "はい";
 var ANS1 = "いいえ";
 if(typ == 1) { ANS0 = "買う"; ANS1 = "売る"; }
 drawMenu(x, y, w, h);
 drawBtn(ANS0, x, y-40, 80, 60, FNT_SIZ, (selAns==0)?"-cyan":"-silver", 10); if(btn_on[10] == 1) selAns = 0;
 drawBtn(ANS1, x, y+40, 80, 60, FNT_SIZ, (selAns==1)?"-cyan":"-silver", 11); if(btn_on[11] == 1) selAns = 1;
 if(inkey == 38 || vkey == 38) selAns = 0;
 if(inkey == 40 || vkey == 40) selAns = 1;
}

//アイテムのメニュー画面
function drawItemMenu( cap ) {
 var c, i, col, nam;
 var x = 360;
 var y = 320;
 var w = 660;
 var h = 448;
 drawMenu(x, y-270, 400, 60);
 fText(cap, x, y-270, FNT_SIZ, "white");
 if(idx == IDX_MENU_ITM || idx == IDX_SELL) {
  drawBtn("←", x-150, y-270, 80, 80, FNT_SIZ, "-white", 22);
  drawBtn("→", x+150, y-270, 80, 80, FNT_SIZ, "-white", 23);
 }
 drawMenu(x, y, w, h);
 y = y - h/2 + 28;
 for(i = 1; i <= ITM_PER; i++) {
  if(selItm == i) selBar(x, y, 260, 40);
  c = selItmPage*ITM_PER + i;
  col = (selItm==i)?"cyan":"white";
  nam = itmName(0);
  if(itf[c] > 0) {
   nam = itmName(c);
   if(idx == IDX_MENU_EQU) {
    if(canEq(selChr,c) == false) col = (selItm==i)?"teal":"gray";//装備できないキャラの文字の色
   }
   fText(itm[c]+"ｺ", x+180, y, FNT_SIZ*0.8, col);
  }
  drawBtn(nam, x, y, 240, 40, FNT_SIZ, "-"+col, 10+i);
  y += 56;
 }
}

//メッセージを一定時間表示する処理
var imStr = "";
var imCol = "";
var imTim = 0;
function iMessage(s, c, t) {
 imStr = s;
 imCol = c;
 imTim = t;
}

function iMessageDraw() {
 if(imTim == 0) return;
 var x = 360, y = 360;
 var w = 40+mTextWidth(imStr);
 var h = 40+FNT_SIZ;
 drawMenu(x, y, w, h);
 fText(imStr, x, y, FNT_SIZ, imCol);
 imTim--;
}

//ヴァーチャルキーの表示と入力判定
var vkey = 0;
function virtualKey() {
 vkey = 0;
 if(winW > winH) {
  fRect(720, 0, 240, 720, "#048");
  drawBtn("↑", 840,  90, 240-2, 180-2, 40, "white", 0); if(btn_on[0] > 0) vkey = 38;
  drawBtn("↓", 840, 630, 240-2, 180-2, 40, "white", 1); if(btn_on[1] > 0) vkey = 40;
  drawBtn("←", 780, 360, 120-2, 360-2, 40, "white", 2); if(btn_on[2] > 0) vkey = 37;
  drawBtn("→", 900, 360, 120-2, 360-2, 40, "white", 3); if(btn_on[3] > 0) vkey = 39;
  drawCBtn("[SPC]", 624, 624, 72, 40, "white", 4); if(btn_on[4] > 0) vkey = 32;
 }
 else {
  fRect(0, 720, 720, 240, "#408");
  drawBtn("↑", 360, 780, 360-2, 120-2, 40, "white", 0 ); if( btn_on[0] > 0 ) vkey = 38;
  drawBtn("↓", 360, 900, 360-2, 120-2, 40, "white", 1 ); if( btn_on[1] > 0 ) vkey = 40;
  drawBtn("←",  90, 840, 180-2, 240-2, 40, "white", 2 ); if( btn_on[2] > 0 ) vkey = 37;
  drawBtn("→", 630, 840, 180-2, 240-2, 40, "white", 3 ); if( btn_on[3] > 0 ) vkey = 39;
  drawCBtn("[SPC]", 360, 624, 72, 40, "white", 4); if(btn_on[4] > 0) vkey = 32;
 }
}

function escapeKey() {
 if(winW > winH) {
  drawBtn("[Esc]", 100, 624, 128, 112, 40, "yellow", 6); if(btn_on[6] > 0) vkey = 27;
 }
 else {
  drawBtn("[Esc]", 100, 624, 128, 112, 40, "yellow", 6); if(btn_on[6] > 0) vkey = 27;
 }
}

//ブラウザのサイズが変化した時（スマホなら縦持ち⇔横持ち）
//CWIDTH,CHEIGHT,SCALE,winW,winH変数はシステムで定義されている
function resizeCanvas() {
 var cw, ch;
 if(winW < winH) {//縦長の画面
  CWIDTH = 720;
  CHEIGHT = 960;
  cw = winW;
  ch = winW*CHEIGHT/CWIDTH;
  if(winW/winH > CWIDTH/CHEIGHT) {//縦長ではあるが（正方形に近く）上２行の値では高さが入らない場合
   ch = winH;
   cw = winH*CWIDTH/CHEIGHT;
  }
 }
 else {
  CWIDTH = 960;
  CHEIGHT = 720;
  cw = winH*CWIDTH/CHEIGHT;
  ch = winH;
  if(winW/winH < CWIDTH/CHEIGHT) {//横長ではあるが（正方形に近く）上２行の値では幅が入らない場合
   cw = winW;
   ch = winW*CHEIGHT/CWIDTH;
  }
 }
 cw = toInt(cw);
 ch = toInt(ch);
 SCALE = cw / CWIDTH;
 canvas.width = cw;
 canvas.height = ch;
 bg.scale(SCALE,SCALE);
 bg.textAlign = "center";
 bg.textBaseline = "middle";
}

//パーティメンバーの簡易パラメータ表示
function miniPara( mY ) {
 var i, x, y;
 for(i = 0; i < numOfPty; i++) {
  y = mY;
  x = 90+180*i;
  if(mpShake[i] > 0) {
   mpShake[i]--;
   x = x + (rnd(5)-2)*2;
   y = y + (rnd(5)-2)*2;
  }
  drawMenu(x, y, 180, 120);
  drawChr(obj[i].p, x-76, y-56, _DirD, false);
  if(sts[i].poison > 0) fText("毒", x+20, y-30, FNT_SIZ*0.8, "red");
  fText("H" + sts[i].hp + "/" + sts[i].mh, x, y+10, FNT_SIZ*0.75, "white");
  fText("M" + sts[i].mp + "/" + sts[i].mm, x, y+42, FNT_SIZ*0.75, "white");
  fText("", 0, 0, FNT_SIZ, "white");//【仮】文字サイズを通常の大きさに戻しておく→iMessageDraw()用
  if(idx == IDX_MENU_USE) {
   if(selChr == i) selBar(x, y, 180, 120);
  }
  if(idx == IDX_BTL_CMD) {
//★★★制作中
  }
 }
}

//クリックでパーティメンバーを選ぶ関数
function selPtyClick( mY ) {
 var i, x, y = mY;
 for(i = 0; i < numOfPty; i++) {
  x = 90+180*i;
  drawBtn("", x, y, 172, 112, FNT_SIZ, "-white", 30+i);
  if(btn_on[30+i] > 1) selChr = i;
 }
}

//左右キーでパーティメンバーを選ぶ関数
function selPtyLRKey() {
 if(key[37] == 1 || key[37] > 10 || btn_on[2] == 1 || btn_on[2] > 10 || btn_on[22] == 1 || btn_on[22] > 10) {selEq = -1; selChr--; if(selChr < 0) selChr = numOfPty-1;}
 if(key[39] == 1 || key[39] > 10 || btn_on[3] == 1 || btn_on[3] > 10 || btn_on[23] == 1 || btn_on[23] > 10) {selEq = -1; selChr++; if(selChr > numOfPty-1) selChr = 0;}
}

var MSG_NONEED = "使う必要はありません";

function useItem(who, ino) {//who番のキャラにinoのアイテムを使う処理

 var rec = 0;//回復量
 var flg = false;//使ったかのフラグ

 if(itmClass(ino) == 1) {//体力回復
  if(sts[who].hp < sts[who].mh) {
   if(sts[who].hp == 0) {
    iMessage("復活させる必要があります", "white", 30);
   }
   else {
    rec = toInt(sts[who].mh*itmPara1(ino)/100);//回復薬の回復量はアイテムのパラメータ１
    stsUD(who, STS_HP, rec);
    iMessage("HP +" + rec, "cyan", 30);
    flg = true;
   }
  }
  else {
   iMessage(MSG_NONEED, "white", 30);
  }
 }

 if(itmClass(ino) == 2) {//魔法回復
  if(sts[who].mp < sts[who].mm) {
   if(sts[who].hp == 0) {
    iMessage("復活させる必要があります", "white", 30);
   }
   else {
    rec = toInt(sts[who].mm*itmPara1(ino)/100);//回復薬の回復量はアイテムのパラメータ１
    stsUD(who, STS_MP, rec);
    iMessage("MP +" + rec, "cyan", 30);
    flg = true;
   }
  }
  else {
   iMessage(MSG_NONEED, "white", 30);
  }
 }

 if(itmClass(ino) == 3) {//毒消し
  if(sts[who].poison > 0) {
   sts[who].poison = 0;
   iMessage("毒が消えました", "cyan", 30);
   flg = true;
  }
  else {
   iMessage(MSG_NONEED, "white", 30);
  }
 }

 if(itmClass(ino) == 4) {//完全に復活させる
  if(sts[who].hp < sts[who].mh || sts[who].mp < sts[who].mm || sts[who].poison > 0) {
   recPty(who);
   iMessage("完全回復しました", "cyan", 30);
   flg = true;
  }
  else {
   iMessage(MSG_NONEED, "white", 30);
  }
 }
 
 if(flg == true) itm[ino]--;//使ったら数を減らす
 return flg;

}

//パーティメンバーのステータスを変化させる関数
var STS_MH = 0;//体力最大値
var STS_HP = 1;//体力
var STS_MM = 2;//魔力最大値
var STS_MP = 3;//魔力
var STS_ST = 4;//腕力 strength
var STS_DE = 5;//防御力 defense
var STS_IN = 6;//知力 intelligence
var STS_MD = 7;//魔法防御 magic defense
var STS_AG = 8;//素早さ agility

function stsUD(no, para, val) {
 switch(para) {
  case STS_MH: sts[no].mh += val; if(sts[no].mh > 9999) sts[no].mh = 9999; break;
  case STS_HP: sts[no].hp += val; if(sts[no].hp > sts[no].mh) sts[no].hp = sts[no].mh; break;
  case STS_MM: sts[no].mm += val; if(sts[no].mm > 9999) sts[no].mm = 9999; break;
  case STS_MP: sts[no].mp += val; if(sts[no].mp > sts[no].mm) sts[no].mp = sts[no].mm; break;
  case STS_ST: sts[no].str+= val; if(sts[no].str > 999) sts[no].str = 999; break;
  case STS_DE: sts[no].def+= val; if(sts[no].def > 999) sts[no].def = 999; break;
  case STS_IN: sts[no].itl+= val; if(sts[no].itl > 999) sts[no].itl = 999; break;
  case STS_MD: sts[no].mde+= val; if(sts[no].mde > 999) sts[no].mde = 999; break;
  case STS_AG: sts[no].agi+= val; if(sts[no].agi > 999) sts[no].agi = 999; break;
 }
}

//パーティメンバーを回復させる関数
function recPty(no) {
 var sn = no;
 var en = no+1;
 if(no == -1) {sn = 0; en = numOfPty;}//引数-1で全員
 for(var i=sn; i<en; i++) {
  sts[i].hp = sts[i].mh;
  sts[i].mp = sts[i].mm;
  sts[i].poison = 0;
 }
}

//歩行時の毒の処理
var poison = new Array(10);
function poisonProc() {
 for(var i = 0; i < 10; i++) {
  if(obj[i].type == OBJ_PTY) {//メンバーが存在し
   if(sts[i].poison > 0) {//毒状態なら
    sts[i].poison--;
    if(sts[i].hp > 1) sts[i].hp--;
    poison[i] = 3;
   }
  }
 }
}

function setPoison(no, val) {//毒状態にする関数
 var sn = no;
 var en = no+1;
 if(no == -1) {sn = 0; en = numOfPty;}//引数-1で全員
 for(var i=sn; i<en; i++) {
  if(sts[i].hp > 0) {
   sts[i].poison = val;
   poison[i] = 3;
  }
 }
}

//初期化が必要な変数
function initVariable() {
 gold		= 100;
 plWalk		= 0;
 steps		= 0;
 mayoke		= 0;
 map_no		= 0;
 selTtl		= 0;
 selMenu	= 0;
 selChr		= 0;
 selEq		= 0;
 selItm		= 1;
 selItmPage	= 0;
 selAns		= 0;
 selShp		= 0;
 selNum		= 0;
 effRec		= 0;
 numOfPty	= 0;
 bgmBak		= -1;
 for(var i = 0; i < 10; i++) poison[i] = 0;
}

//メイン処理　※メインループはWWSシステムが担っている
function mainProc() {
 var c, i, n;
 var x, y, w, h;
 var col;//色汎用

 tmr++;
 dcnt++;

 switch(idx) {
  case IDX_INIT://初期化処理
  resizeCanvas();
  initVariable();
  initFlg();
  initItm();
if( DBG_ITM ) {//★★★デバッグ
 gold = toInt(MAX_GOLD/2);
 for(i=0;i<ITM_MAX;i++)getItm(i,99);
}
  initObj();
  initSts();
  idx = IDX_TITLE;
  break;

  case IDX_TITLE://タイトル画面
  fRect(0, 0, 720, 720, "white");
  drawImg(IMG_TITLE, 60, 40);
  virtualKey();
  if(inkey == 38 || vkey == 38) selTtl = 0;
  if(inkey == 40 || vkey == 40) selTtl = 1;
  drawBtn("ＢＧＭあり", 360, 380, 240, 60, FNT_SIZ, (selTtl==0)?"-cyan":"-gray", 10); if(btn_on[10] == 1) selTtl = 0;
  drawBtn("ＢＧＭ無し", 360, 480, 240, 60, FNT_SIZ, (selTtl==1)?"-cyan":"-gray", 11); if(btn_on[11] == 1) selTtl = 1;
  if(key[32] == 1 || btn_on[4] == 1 || btn_on[10] > 1 || btn_on[11] > 1) {
   if(selTtl == 0) SOUND_ON = true;
   if(selTtl == 1) SOUND_ON = false;
   initLeader();
if( DBG_PTY ) {//★★★デバッグ
joinPty(1); sts[1].hp = toInt(sts[1].mh*0.5); sts[1].mp = toInt(sts[1].mm*0.5); sts[1].poison = 100;
joinPty(2); sts[2].hp = toInt(sts[2].mh*0.1); sts[2].mp = toInt(sts[2].mm*0.5);
joinPty(3); sts[3].hp = toInt(sts[3].mh*0.0); sts[3].mp = toInt(sts[3].mm*0.0); sts[3].poison = 100;
}
   setMap();
   setObj();
   idx = IDX_MOVE;
  }
  break;

  case IDX_MOVE://プレイヤーキャラの移動
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  walkPty();//パーティメンバーをぞろぞろ引き連れて歩く処理
  walkNpc();
  if(plWalk == 0) {//停止中
   obj[0].cx = obj[0].x*CHIP_SIZE;
   obj[0].cy = obj[0].y*CHIP_SIZE;
   if(     inkey == 38 || vkey == 38) {obj[0].d1 = 0; if(chkWall(0,obj[0].d1) == false && chkObj(0,obj[0].d1) == -1) {obj[0].y--; plWalk = 1;} }
   else if(inkey == 40 || vkey == 40) {obj[0].d1 = 1; if(chkWall(0,obj[0].d1) == false && chkObj(0,obj[0].d1) == -1) {obj[0].y++; plWalk = 1;} }
   else if(inkey == 37 || vkey == 37) {obj[0].d1 = 2; if(chkWall(0,obj[0].d1) == false && chkObj(0,obj[0].d1) == -1) {obj[0].x--; plWalk = 1;} }
   else if(inkey == 39 || vkey == 39) {obj[0].d1 = 3; if(chkWall(0,obj[0].d1) == false && chkObj(0,obj[0].d1) == -1) {obj[0].x++; plWalk = 1;} }
   else if(key[32] == 1 || btn_on[4] == 1) {//【制作中】調べる、メニューを開く
    objNum = chkObj(0,obj[0].d1);
    if(objNum >= 10) {//目の前に何かある
     if(obj[objNum].type == OBJ_NPC) {
      obj[objNum].d1 = FACE_DIR[obj[0].d1];//プレイヤーの方に向かせる
      if(obj[objNum].d3 == _TALK) {
       talkNum = obj[objNum].d4;
       idx = IDX_TALK;
       tmr = 0;
       break;
      }
      if(obj[objNum].d3 == _JOIN) {//仲間になるイベント
       talkNum = obj[objNum].d4;
       selAns = 0;
       idx = IDX_JOIN;
       tmr = 0;
       break;
      }
      if(obj[objNum].d3 == _INN) {//宿屋
       talkNum = obj[objNum].d4;
       gpv = obj[objNum].d5 * numOfPty;//宿泊料
       selAns = 0;
       idx = IDX_INN;
       tmr = 0;
       break;
      }
      if(obj[objNum].d3 == _SHOP) {//店
       talkNum = obj[objNum].d4;
       shopNum = obj[objNum].d5;
       selAns = 0;
       idx = IDX_SHOP;
       tmr = 0;
       break;
      }
      if(obj[objNum].d3 == _EVNT) {//各種のイベント
       talkNum = obj[objNum].d4;
       selAns = 0;
       idx = IDX_EVENT;
       tmr = 0;
       break;
      }
     }
     else if(obj[objNum].type == OBJ_TBOX) {
      if(flg[obj[objNum].flg] == 0) {//まだ開けていない
       obj[objNum].d1 = 1;//宝箱を開いた絵にする
       gpv = obj[objNum].d4;//中身（アイテムの番号）もしくは金額
       if(obj[objNum].d3 == _ITEM) {
        idx = IDX_ITEM;
        break;
       }
       if(obj[objNum].d3 == _GOLD) {
        idx = IDX_GOLD;
        break;
       }
      }
     }
    }
    //イベントが無ければメニューを開く
    idx = IDX_MENU_TOP;
   }
  }
  else {//移動中
   obj[0].cx = (obj[0].x-XP[obj[0].d1])*CHIP_SIZE + toInt(XP[obj[0].d1]*CHIP_SIZE*plWalk/PLWF);
   obj[0].cy = (obj[0].y-YP[obj[0].d1])*CHIP_SIZE + toInt(YP[obj[0].d1]*CHIP_SIZE*plWalk/PLWF);
   plWalk++;
   if(plWalk >= PLWF) {//移動終了
    steps++;//エンカウント用歩数のカウント
    if(mayoke > 0) {
     steps = 0;//敵を出さなくする
     mayoke--;
     if(mayoke == 0) iMessage("魔除けの効果が切れた", "white", 30);
    }
    poisonProc();//毒状態だった時の処理
    plWalk = 0;
    objNum = chkSw();
    if(objNum >= 10) {//町やダンジョンに入る
     idx = IDX_CHANGE;
     tmr = 0;
     break;
    }
    if(obj[0].x < 0 || obj[0].x >= mapW || obj[0].y < 0 || obj[0].y >= mapH) {//ワールドマップに戻る
     objNum = 0;//ワールドマップに戻るフラグとして使用
     idx = IDX_CHANGE;
     tmr = 0;
     break;
    }
    if(mapAtt[3] >= 0) {//敵が出現するマップ
     if(steps > 10 && rnd(100) < steps-10) {//エンカウント　★★★仮実装
      idx = IDX_BTL_INIT;
      tmr = 0;
     }
    }
   }
  }
  break;

  case IDX_CHANGE://マップ切り替え
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  if(tmr == 1) {
   obj[0].cx = obj[0].x*CHIP_SIZE;
   obj[0].cy = obj[0].y*CHIP_SIZE;
   walkPty();//パーティメンバーをぞろぞろ引き連れて歩く処理
   if(map_no == 0) {worldX = obj[0].x; worldY = obj[0].y;}//ワールドマップから町などに入る時は、ワールドマップ上の位置を記憶
  }
  if(tmr <= 20) fRect(0, 0, CHIP_SIZE*15, CHIP_SIZE*15, "rgba(0,0,0,"+0.05*tmr+")");
  if(tmr >  20) fRect(0, 0, CHIP_SIZE*15, CHIP_SIZE*15, "rgba(0,0,0,"+0.05*(40-tmr)+")");
  if(tmr == 20) {
   if(objNum == 0) {//ワールドマップに戻る
    obj[0].x = worldX;
    obj[0].y = worldY+1;
    obj[0].d1 = 1;
    map_no = 0;
   }
   else {//町やダンジョンへ、及び、階層移動
    if(     obj[objNum].d1 < -20) map_no += (obj[objNum].d1+20);//配列前方に定義してあるマップへ移動
    else if(obj[objNum].d1 < -10) map_no -= (obj[objNum].d1+10);//配列後方に定義してあるマップへ移動
    else map_no = obj[objNum].d1;
    obj[0].x  = obj[objNum].d2;
    obj[0].y  = obj[objNum].d3;
    obj[0].d1 = obj[objNum].d4;
   }
   obj[0].cx = obj[0].x*CHIP_SIZE;
   obj[0].cy = obj[0].y*CHIP_SIZE;
   gatherPty(obj[0].d1);
   clrObjAll();
   setObj();
   setMap();
  }
  if(tmr == 40) {
   steps = 0;//敵エンカウント歩数をリセット
   idx = IDX_MOVE;
  }
  break;

  case IDX_ITEM://道具入手処理
  case IDX_GOLD://お金入手処理
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  x = 360;
  y = 440;
  w = 680;
  h = 180;
  drawMenu(x, y, w, h);
  if(idx == IDX_ITEM) {
   if(itm[gpv] == 99) {
    fMessage(itmName(gpv)+"が入っているが、\nこれ以上は持てない。", x-w/2+20, y-h/2+30, 60, FNT_SIZ, "white");
    if(key[32] == 1 || btn_on[4] == 1) {
     obj[objNum].d1 = 0;//宝箱を閉じた絵にする
     idx = IDX_MOVE;
    }
   }
   else {
    fMessage("入手アイテム　"+itmName(gpv), x-w/2+20, y-h/2+30, 60, FNT_SIZ, "white");
    if(key[32] == 1 || btn_on[4] == 1) {
     getItm(gpv, 1);
     flg[obj[objNum].flg] = 1;
     idx = IDX_MOVE;
    }
   }
  }
  if(idx == IDX_GOLD) {
   fMessage("入手金額　"+gpv+GOLD, x-w/2+20, y-h/2+30, 60, FNT_SIZ, "white");
   if(key[32] == 1 || btn_on[4] == 1) {
    getGld(gpv);
    flg[obj[objNum].flg] = 1;
    idx = IDX_MOVE;
   }
  }
  break;

  case IDX_TALK://会話
  case IDX_JOIN://仲間になる
  case IDX_INN://宿屋
  case IDX_SHOP://店
  case IDX_EVENT://各種のイベント
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  x = 360;
  y = 440;
  w = 680;
  h = 180;
  drawMenu(x, y, w, h);
  if(tmr <= 0) break;//メッセージ表示時のワンクッション
  if(tmr == 1) {//表示するメッセージを調べ、次の文章に続く場合はフラグを立てる
   talkDat = TALK_DATA[talkNum];
   talkNxt = 0;
   if(talkDat.slice(-5) == "#NEXT") {
    talkDat = talkDat.substring(0,talkDat.length-5);
    talkNxt = 1;
   }
  }
  if(tmr%20 >= 10) {
   if(talkNxt == 1) fText("▼", x+w/2-24, y+h/2-24, FNT_SIZ*0.8, "white");
  }
  fMessage(talkDat, x-w/2+20, y-h/2+30, 60, FNT_SIZ, "white");

  if(talkNxt == 1) {//次のメッセージがある場合
   if(key[32] == 1 || btn_on[4] == 1) {
    talkNum++;
    tmr = -2;
   }
   break;
  }

  if(idx == IDX_TALK) {//会話だけの処理
   if(key[32] == 1 || btn_on[4] == 1) idx = IDX_MOVE;
  }
  if(idx == IDX_INN) drawGold(1);//宿屋では所持金を表示
  if(idx == IDX_JOIN || idx == IDX_INN || idx == IDX_EVENT) {//はい、いいえを選ぶ処理
   inputYN(0);//選択肢
   if(key[32] == 1 || btn_on[4] == 1 || btn_on[10] > 1 || btn_on[11] > 1) {

    if(idx == IDX_JOIN) {
     if(selAns == 0) {//仲間にする
      joinPty(obj[objNum].d5);//誰が仲間になるか（ステータスの番号）
      flg[obj[objNum].flg] = 1;//フラグを立てる
      clrObj(objNum);
      talkNum++;
      idx = IDX_TALK;
      tmr = -2;
     }
     else {
      idx = IDX_MOVE;
     }
    }

    if(idx == IDX_INN) {
     if(selAns == 0) {//泊まる
      if(gold < gpv) {//宿泊料が足りない
       talkNum = TN_SHORTAGE;
       idx = IDX_TALK;
       tmr = -2;
      }
      else {
       idx = IDX_STAY;
       tmr = 0;
      }
     }
     else {
      idx = IDX_MOVE;
     }
    }

    if(idx == IDX_EVENT) {//各種のイベントの処理
     if(selAns == 0) {//はいを選んだ場合
      if(obj[objNum].d5 == EV_POISON) {//毒を浴びる
       setPoison(-1, 50);
       talkNum++;
       idx = IDX_TALK;
       tmr = -2;
      }
     }
     else {
      idx = IDX_MOVE;
     }
    }

   }
  }

  if(idx == IDX_SHOP) {//買う、売るを選ぶ処理
   escapeKey();
   inputYN(1);//選択肢
   if(key[32] == 1 || btn_on[4] == 1 || btn_on[10] > 1 || btn_on[11] > 1) {
    if(selAns == 0) {
     idx = IDX_BUY;
     selShp = 0;
    }
    else {
     idx = IDX_SELL;
     tmr = 0;//画面切り替え直後に道具を選ばないようにする
    }
   }
   if(key[27] == 1 || btn_on[6] == 1) idx = IDX_MOVE;
  }

  break;

  case IDX_STAY://泊まる演出
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  if(tmr == 40) {
   gold -= gpv;
   gatherPty(_DirD);//位置を揃え
   recPty(-1);//全メンバー完全回復
  }
  if(tmr < 40) {
   fRect(0, 0, CHIP_SIZE*15, CHIP_SIZE*15, "rgba(0,0,0,"+0.025*tmr+")");
  }
  else if(tmr < 80) {
   fRect(0, 0, CHIP_SIZE*15, CHIP_SIZE*15, "rgba(0,0,0,"+0.025*(80-tmr)+")");
  }
  else {
   talkNum = TN_RECALL;
   idx = IDX_TALK;
   tmr = 0;
  }
  break;

  case IDX_BUY://購入
  case IDX_BUYNUM://購入個数
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  drawGold(2);
  x = 360;
  y = 310;
  w = 660;
  h = 448;
  drawMenu(x, y, w, h);
  y = y+toInt(-h/2+h/16);
  n = 8;//その店で何品売られているか
  for(i=0; i<8; i++) {
   col = (selShp==i)?"cyan":"white";
   c = SHOP_LIST[shopNum*8+i];
   if(c == 0) { n = i; break; }
   if(selShp == i) selBar(x, y, 480, 40);
   fText(itmPrice(c)+GOLD, x+120, y, FNT_SIZ*0.9, col);
   drawBtn(itmName(c), x-120, y, 280, 40, FNT_SIZ, "-"+col, 10+i);
   y += toInt(h/8);
  }
  if(idx == IDX_BUY) {
   escapeKey();
   if(key[38] == 1 || key[38] > 10 || btn_on[0] == 1 || btn_on[0] > 10) {selShp--; if(selShp < 0) selShp = n-1;}
   if(key[40] == 1 || key[40] > 10 || btn_on[1] == 1 || btn_on[1] > 10) {selShp++; if(selShp > n-1) selShp = 0;}

   inp = 0;
   for(i=0; i<n; i++) {
    if(btn_on[10+i] > 1) selShp = i;//項目を押したか
    if(btn_on[10+i] > 3) inp = 1;//長押ししたか
   }
   if(inp == 1 || key[32] == 1 || btn_on[4] == 1) {
    itemNum = SHOP_LIST[shopNum*8+selShp];//買おうとしている商品
    if(itm[itemNum] == MAX_ITM) {
     iMessage("これ以上持つことはできません", "yellow", 30);
    }
    else if(gold < itmPrice(itemNum)) {
     iMessage("お金が足りません", "yellow", 30);
    }
    else {
     idx = IDX_BUYNUM;
     selNum = 1;
     n = parseInt(gold/itmPrice(itemNum));//所持金で何個まで買えるか
     if(n+itm[itemNum] > MAX_ITM) n = MAX_ITM-itm[itemNum];//但し最大所持数を超えない
     gpv = 1; if(n > 1) gpv = n;
     break;//画面遷移直後に購入してしまわないように
    }
   }
   if(key[27] == 1 || btn_on[6] == 1) idx = IDX_MOVE;
  }
  if(idx == IDX_BUYNUM) {
   fRect(0, 0, 720, 720, "rgba(0,0,0,0.6)");
   escapeKey();//ESCの表示が暗くならないよう、ここに
   x = 360;
   y = 310;
   w = 712;
   h = 240;
   drawMenu(x, y, w, h);
   fText(itmName(itemNum) + "は" + itm[itemNum] + "コ持っています", x, y-80, FNT_SIZ, "white");
   fText("いくつ買いますか？", x, y, FNT_SIZ, "white");
   price = itmPrice(itemNum)*selNum;
   fText(selNum, x-160, y+80, FNT_SIZ, "white");
   fText((price)+GOLD, x+160, y+80, FNT_SIZ, "white");
   drawBtn("←", x-160-100, y+80, 80, 80, FNT_SIZ, "-white", 22);
   drawBtn("→", x-160+100, y+80, 80, 80, FNT_SIZ, "-white", 23);
   if(key[37] == 1 || key[37] > 10 || btn_on[2] == 1 || btn_on[2] > 10 || btn_on[22] == 1 || btn_on[22] > 10) {selNum--; if(selNum < 1) selNum = gpv;}
   if(key[39] == 1 || key[39] > 10 || btn_on[3] == 1 || btn_on[3] > 10 || btn_on[23] == 1 || btn_on[23] > 10) {selNum++; if(selNum > gpv) selNum = 1;}
   if(key[32] == 1 || btn_on[4] == 1) {
    getItm(itemNum, selNum);
    gold -= price;
    iMessage(itmName(itemNum)+"を買いました", "white", 30);
    idx = IDX_BUY;
   }
   if(key[27] == 1 || btn_on[6] == 1) idx = IDX_BUY;
  }
  break;

  case IDX_MENU_TOP://メニュートップ画面
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  escapeKey();
  drawGold(0);
  x = 360;
  y = 320;
  w = 480;
  h = 320;
  drawMenu(x, y, w, h);
  for(i = 0; i < 4; i++) {
   x = 240+240*(i%2);
   y = 240+160*toInt(i/2);
   if(selMenu == i) selBar(x, y, 180, 50);
   drawBtn(MENU_TOP[i], x, y, 160, 60, FNT_SIZ, (selMenu==i)?"-cyan":"-white", 10+i);
  }
//【制作中】仮のメニュー項目選択
  if(key[38] == 1 || btn_on[0] == 1) if(selMenu >= 2) selMenu -= 2;
  if(key[40] == 1 || btn_on[1] == 1) if(selMenu <= 1) selMenu += 2;
  if(key[37] == 1 || btn_on[2] == 1) selMenu -= selMenu%2;
  if(key[39] == 1 || btn_on[3] == 1) selMenu += (selMenu+1)%2;

  inp = 0;
  for(i = 0; i < 4; i++) {
   if(btn_on[10+i] > 1) selMenu = i;//項目を押したか
   if(btn_on[10+i] > 3) inp = 1;//長押ししたか
  }
  if(inp == 1 || key[32] == 1 || btn_on[4] == 1) {
   if(selMenu == 0) {
    idx = IDX_MENU_STS;
    selEq = -1;
    tmr = 0;//画面切り替え直後に装備を選ばないようにする
   }
   if(selMenu == 1) {
    idx = IDX_MENU_ITM;
    tmr = 0;//画面切り替え直後に道具を選ばないようにする
   }
  }
  if(key[27] == 1 || btn_on[6] == 1) idx = IDX_MOVE;
  break;

  case IDX_MENU_STS://メニュー能力画面
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  escapeKey();
  x = 360;
  y = 320;
  w = 660;
  h = 448;
  drawMenu(x, y-270, 400, 60);
  fText(sts[selChr].name, x, y-270, FNT_SIZ, "white");
  if(numOfPty >= 2) {//パーティメンバーが２人以上いる時
   drawBtn("←", x-150, y-270, 80, 80, FNT_SIZ, "-white", 22);
   drawBtn("→", x+150, y-270, 80, 80, FNT_SIZ, "-white", 23);
  }
  drawMenu(x, y, w, h);
  y = 144;
  drawChr(obj[selChr].p, x-180-24, y-36, _DirD, false);
  if(sts[selChr].poison > 0) fText("毒"+sts[selChr].poison, x-260, y, FNT_SIZ, "red");
  y = 220;
  for(i = 0; i < 3; i++) {
   if(selEq == i) selBar(x-180, y+45, 260, 40);
   fText(ITEM_EQ[i], x-180, y, FNT_SIZ*0.8, "lime");
   drawBtn(itmName(sts[selChr].equip[i]), x-180, y+45, 240, 60, FNT_SIZ, (selEq==i)?"-cyan":"-white", 10+i);
   y += 115;
  }
  x = 380;
  y = 140;
  fText("ＨＰ",     x, y, FNT_SIZ*0.9, "white"); fText(sts[selChr].mh+"/"+sts[selChr].hp, x+128, y, FNT_SIZ*0.9, "white"); y += 60;
  fText("ＭＰ",     x, y, FNT_SIZ*0.9, "white"); fText(sts[selChr].mm+"/"+sts[selChr].mp, x+128, y, FNT_SIZ*0.9, "white"); y += 60;
  fText("攻撃力",   x, y, FNT_SIZ*0.9, "white"); fText(sts[selChr].str, x+128, y, FNT_SIZ, "white"); fText("x"+(itmAtc(selChr)/100), x+230, y, FNT_SIZ*0.9, (selEq==0)?"cyan":"white"); y += 60;
  fText("防御力",   x, y, FNT_SIZ*0.9, "white"); fText(sts[selChr].def, x+128, y, FNT_SIZ, "white"); fText("x"+(itmDef(selChr)/100), x+230, y, FNT_SIZ*0.9, (selEq==1)?"cyan":"white"); y += 60;
  fText("知力",     x, y, FNT_SIZ*0.9, "white"); fText(sts[selChr].itl, x+128, y, FNT_SIZ, "white"); y += 60;
  fText("魔法防御", x, y, FNT_SIZ*0.9, "white"); fText(sts[selChr].mde, x+128, y, FNT_SIZ, "white"); y += 60;
  fText("素早さ",   x, y, FNT_SIZ*0.9, "white"); fText(sts[selChr].mde, x+128, y, FNT_SIZ, "white");

  selPtyLRKey();//左右キーでパーティメンバーを選ぶ

  //装備品の選択
  if(key[38] == 1 || btn_on[0] == 1) { selEq--; if(selEq < 0) selEq = 0; }
  if(key[40] == 1 || btn_on[1] == 1) { selEq++; if(selEq > 2) selEq = 2; }

  inp = 0;
  if(tmr > 5 && imTim == 0) {//【重要】画面押しっぱなしで装備処理が連続して入ることを防ぐ
   for(i = 0; i < 3; i++) {
    if(btn_on[10+i] > 1) selEq = i;//項目を押したか
    if(btn_on[10+i] > 3) inp = 1;//長押ししたか
   }
  }

  if(inp == 1 || key[32] == 1 || btn_on[4] == 1) {
   if(selEq == 0) { selItmPage = 1 + sts[selChr].gen*2; selItm = 1; idx = IDX_MENU_EQU; tmr = 0; break; }//武器
   if(selEq == 1) { selItmPage = 2 + sts[selChr].gen*2; selItm = 1; idx = IDX_MENU_EQU; tmr = 0; break; }//防具
   if(selEq == 2) { selItmPage = 5;                     selItm = 1; idx = IDX_MENU_EQU; tmr = 0; break; }//アクセサリー
  }
  if(key[27] == 1 || btn_on[6] == 1) idx = IDX_MENU_TOP;//戻る
  break;

  case IDX_MENU_ITM://メニュー　アイテム画面
  case IDX_MENU_EQU://メニュー　装備品選択画面
  case IDX_SELL://売却
  case IDX_SELLNUM://売却個数
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  if(idx != IDX_SELLNUM) escapeKey();
  drawItemMenu(ITEM_CLAS[selItmPage]);

  if(idx == IDX_SELLNUM) {//売却個数を選んで売る
   fRect(0, 0, 720, 720, "rgba(0,0,0,0.6)");
   escapeKey();//ESCの表示が暗くならないよう、ここに
   x = 360;
   y = 310;
   w = 712;
   h = 240;
   drawMenu(x, y, w, h);
   fText(itmName(itemNum), x-160, y-80, FNT_SIZ, "white");
   fText("所持金 " + gold + GOLD, x+160, y-80, FNT_SIZ, "white");
   fText("いくつ売りますか？", x, y, FNT_SIZ, "white");
   price = toInt(itmPrice(itemNum)*selNum/2);//【メモ】売却価格は購入価格の半分で
   fText(selNum, x-160, y+80, FNT_SIZ, "white");
   fText((price)+GOLD, x+160, y+80, FNT_SIZ, "white");
   drawBtn("←", x-160-100, y+80, 80, 80, FNT_SIZ, "-white", 22);
   drawBtn("→", x-160+100, y+80, 80, 80, FNT_SIZ, "-white", 23);
   if(key[37] == 1 || key[37] > 10 || btn_on[2] == 1 || btn_on[2] > 10 || btn_on[22] == 1 || btn_on[22] > 10) {selNum--; if(selNum < 1) selNum = gpv;}
   if(key[39] == 1 || key[39] > 10 || btn_on[3] == 1 || btn_on[3] > 10 || btn_on[23] == 1 || btn_on[23] > 10) {selNum++; if(selNum > gpv) selNum = 1;}
   if(key[32] == 1 || btn_on[4] == 1) {
    itm[itemNum] -= selNum;
    getGld(price);
    iMessage(itmName(itemNum)+"を売りました", "white", 30);
    idx = IDX_SELL;
   }
   if(key[27] == 1 || btn_on[6] == 1) idx = IDX_SELL;
   break;
  }

  if(key[38] == 1 || key[38] > 10 || btn_on[0] == 1 || btn_on[0] > 10) {selItm--; if(selItm < 1) selItm = ITM_PER;}
  if(key[40] == 1 || key[40] > 10 || btn_on[1] == 1 || btn_on[1] > 10) {selItm++; if(selItm > ITM_PER) selItm = 1;}

  inp = 0;
  if(tmr > 5) {//【重要】画面切り替え直後に選んでしまうのを防ぐ
   for(i = 1; i <= ITM_PER; i++) {
    if(btn_on[10+i] > 1) selItm = i;//項目を押したか
    if(btn_on[10+i] > 3) inp = 1;//項目を長押ししたか
   }
  }

  if(idx == IDX_MENU_ITM || idx == IDX_SELL) {//アイテム選択
   if(key[37] == 1 || key[37] > 10 || btn_on[2] == 1 || btn_on[2] > 10 || btn_on[22] == 1 || btn_on[22] > 10) {selItmPage--; if(selItmPage < 0) selItmPage = 5;}
   if(key[39] == 1 || key[39] > 10 || btn_on[3] == 1 || btn_on[3] > 10 || btn_on[23] == 1 || btn_on[23] > 10) {selItmPage++; if(selItmPage > 5) selItmPage = 0;}
  }

  if(idx == IDX_MENU_ITM) {//アイテム一覧
   if(inp == 1 || key[32] == 1 || btn_on[4] == 1) {
    if(selItmPage == 0) {//消費アイテムを使う？
     c = selItmPage*ITM_PER + selItm;//選んでいるアイテムの番号
     if(itm[c] > 0) {
      if(itmClass(c) == 10) {//魔除け
       if(mayoke > 0) {
        iMessage("魔除け効果が残っています", "white", 30);
       }
       else {
        itm[c]--;
        idx = IDX_MENU_MAYOKE;
        tmr = 0;
        break;
       }
      }
      else if(itmClass(c) == 11) {//出口へ
iMessage("★★★制作中", "white", 30);
      }
      else {
       idx = IDX_MENU_USE;
       tmr = 0;
      }
     }
    }
   }
   if(key[27] == 1 || btn_on[6] == 1) idx = IDX_MENU_TOP;
  }

  if(idx == IDX_MENU_EQU) {//装備選択
   if(inp == 1 || key[32] == 1 || btn_on[4] == 1) {
    c = selItmPage*ITM_PER + selItm;//選んでいるアイテムの番号
    if(itm[c] > 0) {
     if(canEq(selChr,c) == true) {
      iMessage("装備しました", "lime", 30);
      getItm(sts[selChr].equip[selEq], 1);
      sts[selChr].equip[selEq] = c;
      itm[c]--;
      idx = IDX_MENU_STS;
     }
     if(canEq(selChr,c) == false) {
      iMessage("装備できません", "yellow", 30);
     }
    }
   }
   if(key[27] == 1 || btn_on[6] == 1) idx = IDX_MENU_STS;
  }

  if(idx == IDX_SELL) {//売却
   if(inp == 1 || key[32] == 1 || btn_on[4] == 1) {
    if(selItmPage < 6) {//売ってよいもの
     itemNum = selItmPage*ITM_PER + selItm;//選んでいるアイテムの番号
     gpv = itm[itemNum];
     if(gpv > 0) {
      idx = IDX_SELLNUM;
      tmr = 0;
      selNum = 1;
     }
    }
    else {//重要アイテムは売れない
     iMessage("重要品は売れません", "yellow", 30);
    }
   }
   if(key[27] == 1 || btn_on[6] == 1) idx = IDX_MOVE;
  }
  break;

  case IDX_MENU_USE://メニュー　消費アイテムを使う
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  escapeKey();
  drawItemMenu("誰が使いますか？");
  y = 480;
  miniPara(y);
  if(effRec > 0) {
   x = 90+180*selChr;
   w = 180;
   h = 120;
   fRect(x-w/2, y-h/2, w, h, "rgba(64,192,255,"+(COL_RECA[toInt(effRec/2)]/10)+")");
   effRec--;
   if(effRec == 0) {
    idx = IDX_MENU_ITM;
    tmr = 0;//画面切り替え直後に道具を選ばないようにする
   }
   break;//演出中は連続して使えないように
  }
  selPtyClick(y);//クリックでパーティメンバーを選ぶ
  selPtyLRKey();//左右キーでパーティメンバーを選ぶ

  inp = 0;
  if(tmr > 5) {//画面押しっぱなしで選んでしまわないように
   for(i = 0; i < numOfPty; i++) { if(btn_on[30+i] > 3) inp = 1; }//項目を長押ししたか
  }

  if(inp == 1 || key[32] == 1 || btn_on[4] == 1) {//アイテムを使う
   if(useItem(selChr, selItm) == true) effRec = 30;//使った場合は回復演出を行う
   break;
  }

  if(key[27] == 1 || btn_on[6] == 1) idx = IDX_MENU_ITM;
  break;

  case IDX_MENU_MAYOKE://メニュー　魔除け効果の演出
  drawBG();
  drawObj();
  drawFG();
  col = 0.5; if(tmr > 80) col = 0.5*(100-tmr)/20;
  fCir(360, 360, tmr*6, "rgba(255,255,64,"+col+")");
  if(tmr ==  40) iMessage("爽やかな香りが広がり", "white", 40);
  if(tmr ==  80) iMessage("しばらく敵が出なくなった", "white", 40);
  if(tmr == 100) {
   mayoke = 200;
   idx = IDX_MOVE;
   tmr = 0;
  }
  virtualKey();
  break;

  case IDX_MENU_DEGUCHI://メニュー　出口に移動する演出　★★★制作中
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  break;

  case IDX_BTL_INIT://戦闘　初期化　★★★仮実装
  if(tmr == 2) {//パーティの座標をマス目の位置に合わせる
   obj[0].cx = obj[0].x*CHIP_SIZE;
   obj[0].cy = obj[0].y*CHIP_SIZE;
   walkPty();//パーティメンバーをぞろぞろ引き連れて歩く処理
  }
  if(tmr == 10) {//戦闘用の変数
   steps = 0;//エンカウント歩数をリセット
   clrBtlMsg();
   for(i=0; i<PTY_MAX+EMY_MAX; i++) {
    sts[i].battle = 0;
    dmg[i] = 0;
   }
   for(i=0; i<PTY_MAX; i++) mpShake[i] = 0;
   for(i=0; i<EMY_MAX; i++) { emyXP[i] = 0; emyYP[i] = 0; }
   btlBG = mapAtt[4];//戦闘背景
   btlAct = 0;
   btlTgt = 0;
   btlCmd = 0;
   selEmy = 0;

   setChrSts(EMY_TOP+0, 10+rnd(3));//★★★仮
   setChrSts(EMY_TOP+1, 10+rnd(3));//★★★仮
   setChrSts(EMY_TOP+2, 10+rnd(3));//★★★仮

  }
  if(tmr < 20) {
   if(tmr%2 == 1) {
    drawBG();
    drawObj();
    drawFG();
    virtualKey();
   }
   else {
    fRect(0, 0, 720, 720, "black");
   }
  }
  else {
   y = -360+30*(tmr-20);
   drawBBG(y);
  }
  if(tmr == 31) stopBgm();
  if(tmr == 32) playBgm(2);
  if(tmr == 33) {//戦闘開始へ
   idx = IDX_BTL_START;
   tmr = 0;
   setBtlMsg("敵が現れた！");//★★★
  }
  break;

  case IDX_BTL_START://戦闘　開始
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  drawBBar("");
  drawBTL();
  if(tmr == 30) {
   idx = IDX_BTL_TURN;
   tmr = 0;
  }
  break;

  case IDX_BTL_TURN://戦闘　行動するキャラを決める
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  drawBBar("");
  drawBTL();
  for(i=0; i<PTY_MAX+EMY_MAX; i++) {
   if(sts[i].hp > 0) {
    sts[i].battle = sts[i].battle + 100 + sts[i].agi;
    if(sts[i].battle > 1000) {
     sts[i].battle = 0;
     if(i < PTY_MAX) {//プレイヤーの行動
      btlAct = i;
      idx = IDX_BTL_CMD;
     }
     else {//敵の行動
      btlAct = i;
      btlTgt = rnd(PTY_MAX);
      while(sts[btlTgt].hp == 0) {
       btlTgt--;
       if(btlTgt < 0) btlTgt = PTY_MAX-1;
      }
      idx = IDX_BTL_ATTACK;
      tmr = 0;
     }
     break;
    }
   }
  }
  break;

  case IDX_BTL_CMD://戦闘　コマンド入力
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  drawBBar("コマンド選択");
  drawBTL();
  drawArrow(38+180*btlAct, 415+(toInt(tmr/5)%3)*4);
  x = 640;
  y = 120;
  if(key[38] == 1 || key[38] > 10 || btn_on[0] == 1 || btn_on[0] > 10) {btlCmd--; if(btlCmd < 0) btlCmd = 4;}
  if(key[40] == 1 || key[40] > 10 || btn_on[1] == 1 || btn_on[1] > 10) {btlCmd++; if(btlCmd > 4) btlCmd = 0;}
  for(i=0; i<5; i++) {
   var siz = FNT_SIZ;
   if(i == 1) siz *= 0.9;//スキルの文字の大きさ
   drawBtn(BTL_CMD[i], x, y, 120, 60, siz, (btlCmd==i)?"cyan":"white", 10+i);
   y += 60;
  }
  inp = 0;
  for(i=0; i<5; i++) {
   if(btn_on[10+i] > 1) btlCmd = i;//項目を押したか
   if(btn_on[10+i] > 3) inp = 1;//長押ししたか
  }
  if(inp == 1 || key[32] == 1 || btn_on[4] == 1) {
   if(btlCmd == 0) {//攻撃
    if(sts[EMY_TOP+selEmy].hp == 0) {
     for(i=0; i<EMY_MAX; i++) if(sts[EMY_TOP+i].hp > 0) { selEmy = i; break; }
    }
    idx = IDX_BTL_SELEMY;
    tmr = 0;
   }
   if(btlCmd == 1) {//魔法→このゲームではスキル　★★★開発中
    iMessage("開発中", "pink", 10);
   }
   if(btlCmd == 2) {//道具　★★★開発中
    iMessage("開発中", "lime", 10);
   }
   if(btlCmd == 3) {//防御　★★★開発中
    iMessage("開発中", "gold", 10);
   }
   if(btlCmd == 4) {//撤退　★★★仮
    clrSts(EMY_TOP+0);
    clrSts(EMY_TOP+1);
    clrSts(EMY_TOP+2);
    stopBgm();//一旦停止する
    if(bgmBak >= 0) playBgm(bgmBak);//移動画面のＢＧＭを出力
    idx = IDX_MOVE;
   }
  }
  break;

  case IDX_BTL_SELEMY://戦闘　敵を選択
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  drawBBar("相手を選んで下さい");
  drawBTL();
  for(i=0; i<EMY_MAX; i++) {
   x = 120+240*i;	//┬敵の足元の中心の位置
   y = 420;			//┘
   drawBtn("", x, y-190, 200, 280, FNT_SIZ, (selEmy==i)?"-cyan":"-white", 10+i);
   if(i == selEmy) {
    fText(sts[selEmy+EMY_TOP].name, x, y-280, FNT_SIZ*0.8, "white");
    drawArrow(x, y-320+(toInt(tmr/5)%3)*4);
   }
  }
  if(tmr < 5) break;//タップが連続して入らないように
  if(key[37] == 1 || key[37] > 10 || btn_on[2] == 1 || btn_on[2] > 10) {
   while(true) { selEmy--; if(selEmy < 0) selEmy = EMY_MAX-1; if(sts[selEmy+EMY_TOP].hp > 0) break; }
  }
  if(key[39] == 1 || key[39] > 10 || btn_on[3] == 1 || btn_on[3] > 10) {
   while(true) { selEmy++; if(selEmy > EMY_MAX-1) selEmy = 0; if(sts[selEmy+EMY_TOP].hp > 0) break; }
  }
  inp = 0;
  for(i=0; i<EMY_MAX; i++) {
   if(btn_on[10+i] > 1) if(sts[i+EMY_TOP].hp > 0) selEmy = i;//項目を押したか
   if(btn_on[10+i] > 3) if(sts[i+EMY_TOP].hp > 0) inp = 1;//長押ししたか
  }
  if(inp == 1 || key[32] == 1 || btn_on[4] == 1) {
   btlTgt = selEmy + EMY_TOP;
   idx = IDX_BTL_ATTACK;
   tmr = 0;
  }
  break;

  case IDX_BTL_ATTACK://戦闘　物理攻撃
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  drawBBar("【開発中】物理攻撃の処理");//★★★開発中
  drawBTL();
  //敵、プレイヤー共通の処理
  if(tmr ==  1) setBtlMsg(sts[btlAct].name+"の攻撃！");
  if(tmr == 40) {//ダメージの計算
   var offense = toInt(sts[btlAct].str*itmAtc(btlAct)/100);//攻撃力　武器加算
console.log("offense="+offense);//★★★開発中
   var defence = toInt(sts[btlTgt].def*itmDef(btlTgt)/100);//防御力　防具加算
console.log("defence="+defence);//★★★開発中
   dmg[btlTgt] = offense - defence;
   if(dmg[btlTgt] < 0) dmg[btlTgt] = 0;
   dmg[btlTgt] += rnd(2);
  }
  if(tmr == 41) setBtlMsg(sts[btlTgt].name+"は" + dmg[btlTgt] + "のダメージを受けた");
  if(tmr == 51) {
   sts[btlTgt].hp -= dmg[btlTgt];
   if(sts[btlTgt].hp < 0) sts[btlTgt].hp = 0;
  }
  if(tmr == 61) {
   if(sts[btlTgt].hp == 0) {
    if(btlAct < PTY_MAX)
     setBtlMsg(sts[btlTgt].name+"を倒した！");
    else
     setBtlMsg(sts[btlTgt].name+"は倒れた...");
   }
  }
  if(tmr == 81) idx = IDX_BTL_VIORDE;//勝敗判定へ
  //以下、個別の処理
  if(btlAct < PTY_MAX) {//プレイヤー→敵を攻撃
   if(15 <= tmr && tmr < 35) {//ダメージ演出
    emyXP[btlTgt-EMY_TOP] = (rnd(5)-2)*2;
    emyYP[btlTgt-EMY_TOP] = (rnd(5)-2)*2;
   }
   if(tmr == 35) {
    emyXP[btlTgt-EMY_TOP] = 0;
    emyYP[btlTgt-EMY_TOP] = 0;
   }
  }
  else {//敵→プレイヤーを攻撃
   if(tmr <= 4) emyYP[btlAct-EMY_TOP] = tmr*8;//敵の動き
   if(tmr == 15) mpShake[btlTgt] = 20;//ダメージ演出
   if(tmr == 35) {
    emyYP[btlAct-EMY_TOP] = 0;
   }
  }
  break;

  case IDX_BTL_VIORDE://戦闘　勝敗判定
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  drawBBar("【開発中】勝敗判定");//★★★開発中
  drawBTL();
  c = 0; for(i=0; i<PTY_MAX; i++) c += sts[i].hp;
  if(c == 0) { idx = IDX_BTL_LOSE; tmr = 0; break; }
  c = 0; for(i=0; i<EMY_MAX; i++) c += sts[EMY_TOP+i].hp;
  if(c == 0) { idx = IDX_BTL_WIN; tmr = 0; break; }
  idx = IDX_BTL_TURN;
  break;

  case IDX_BTL_WIN://戦闘　勝利
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  drawBBar("【開発中】ＷＩＮ！");
  drawBTL();
  if(tmr == 1) stopBgm();
  if(tmr == 2) playSE(0);
  if(tmr == 20) {
   if(numOfPty == 1)
    setBtlMsg(sts[0].name + "は勝利した！");
   else
    setBtlMsg(sts[0].name + "達は勝利した！");
  }
  if(tmr == 80) {
   if(bgmBak >= 0) playBgm(bgmBak);//移動画面のＢＧＭを出力
   idx = IDX_MOVE;//★★★開発中　レベルアップの処理を作る
  }
  break;

  case IDX_BTL_LOSE://戦闘　敗北
  drawBG();
  drawObj();
  drawFG();
  virtualKey();
  drawBBar("【開発中】ＬＯＳＥ");
  drawBTL();
  if(tmr == 1) stopBgm();
  if(tmr == 2) playSE(1);
  if(tmr == 40) {
   if(numOfPty == 1)
    setBtlMsg(sts[0].name + "は負けてしまった...");
   else
    setBtlMsg(sts[0].name + "達は負けてしまった...");
  }
  if(tmr == 160) {
   if(bgmBak >= 0) playBgm(bgmBak);//移動画面のＢＧＭを出力
   recPty(-1);//全メンバー完全回復
   gold = toInt(gold/2);//所持金半分に
   idx = IDX_MOVE;//★★★開発中
  }
  break;

 }

 iMessageDraw();

//★★★デバッグ　フラグの値を表示する
if( DBG_PRT ) {//★★★デバッグ

if(idx==IDX_MENU_TOP) {
 if(inkey == 65) {dbgFlg-=20; if(dbgFlg<0)dbgFlg=FLG_MAX-20; }
 if(inkey == 90) {dbgFlg+=20; if(dbgFlg>=FLG_MAX-20)dbgFlg=0; }
 fRect(20, 20, 680, 100, "rgba(0,0,0,0.5)");
 for(y=0;y<5;y++){
  fText((dbgFlg+y*20)%FLG_MAX, 40, 30+20*y, 14, "lime");
  for(x=0;x<20;x++){
  i=(dbgFlg+x+y*20)%FLG_MAX;
  fText(flg[i],70+32*x,30+20*y,12,(flg[i]==1)?"red":"white");
  }
 }
} else {
 fText( mapname, 100, 30, 24, "white" );
 fText( "X="+obj[0].x+" Y="+obj[0].y+" D="+obj[0].d1+" map_no="+map_no, 400, 30, 24, "white" );
 fText( ""+idx+":"+tmr, 100, 60, 24, "cyan" );
 fText( "inkey="+inkey+" vkey="+vkey, 400, 90, 24, "yellow" );
 fText( "CX="+obj[0].cx+" CY="+obj[0].cy+" plWalk="+plWalk+" steps="+steps, 400, 60, 24, "white" );
 fText( "bgmBak="+bgmBak+" BGM番号="+mapAtt[2]+" 敵セット="+mapAtt[3], 400, 120, 24, "cyan" );
// fText( "key[32]="+key[32]+" btn_on[4]="+btn_on[4], 400, 150, 24, "pink" );
 if( plWalk == 0 ) fText( chkObj(0,obj[0].d1), 680, 30, 24, "yellow" );
}

}

 //ブラウザのサイズが変化したか？（スマホなら持ち方を変えたか　縦持ち⇔横持ち）
 w = window.innerWidth;
 h = window.innerHeight;
 if(winW != w || winH != h) {
  winW = w;
  winH = h;
  resizeCanvas();
 }

}


//【メモ】メイン処理と描画処理を分ける場合、描画処理をここに記載
function drawProc() {}
