// RPG16 第16章 選択肢によって分岐 // 2004/07/21 import java.awt.*; import java.awt.event.*; import java.applet.*; import java.io.*; import java.net.URL; import java.util.Random; public class Rpg16 extends Applet implements Runnable,KeyListener{ Image buffer;//イメージバッファ Graphics bufferg;//バックバッファ Random rand = new Random();//乱数 volatile Thread th;//スレッド final int CHIP_SIZE=32;//チップサイズ final int MAX_EVENT_TABLE=100;//イベントテーブルの最大個数 final int KAKUHO_NO=99;//確保イベントNO(キャラが次に着く位置) float FrameTime;//1フレームあたりの時間(秒) long waitTime;//現在時刻保存用 Image chara_image;//キャラチップ画像 MyClass My = new MyClass(168);//自分クラス宣言(チップNO 168) //方向テーブル(上下左右の順) int dir_x[] = {0,0,-1,+1}; int dir_y[] = {-1,+1,0,0}; //キーの状態(離している=0、押し続けている=1、押した瞬間=2) int key_states[] = new int[5];//4方向(上=0,下=1,左=2,右=3)+Zキー=4 //マップデータ int now_map_no;//現在のマップNO short map_data[][] = new short[256][256];//256×256 int map_width,map_height;//マップの横幅、高さ(チップ数) Image map_image;//マップチップ画像 //イベントデータ int event_data[][] = new int[256][256]; //イベントテーブル Event eventtbl[] = new Event[MAX_EVENT_TABLE]; int event_num;//そのマップでのイベントの個数 //ゲーム進行スイッチ boolean game_switch[] = new boolean[128]; //------------ゲーム管理フラグ------------- //0=マップ移動(黒幕下がる) //1=マップ移動(黒幕上がる) //2=イベント中 //3=会話イベント //4=文字が流れている途中 //7=デバッグフラグ //8=テーブル更新予約フラグ //9=ダイアログ中 //10=スクリプトスキップ中 boolean game_flags[] = new boolean[16]; //------------ゲーム管理ウェイト----------- //0=黒い幕の昇降ウェイト //1=会話の流れる文字ウェイト float game_waits[] = new float[8]; //------------ゲーム管理バッファ----------- //0=現在のイベントNO //1=読み込むマップNO //2=移動先X座標 //3=移動先Y座標 //4=移動後向き //5=現在のスクリプトの行 //6=会話中の文字の位置。 //7=現在選択中選択肢 //8=選択肢の数 int game_buffer[] = new int[16]; //------------ゲーム管理文字列----------- //0=現在のスクリプトファイル名 //1=現在の会話内容 //2=分岐1 //3=分岐2 //4=分岐3 String game_strings[] = new String[8]; char game_talks[] = new char[256];//会話内容char配列 //セルテーブル MapCell celltbl[] = { new MapCell(0,true), //平原 new MapCell(1,true), //芝1 new MapCell(2,true), //芝2 new MapCell(3,true), //家 new MapCell(4,false), //木1 new MapCell(5,false), //木2 new MapCell(6,true), //城 new MapCell(7,false), //海 new MapCell(8,true), //塔(上) new MapCell(9,true), //塔(下) new MapCell(10,true), //洞窟 new MapCell(11,false), //岩山 new MapCell(12,true), //宇宙1 new MapCell(13,true), //宇宙2 new MapCell(14,false), //クリスタル new MapCell(15,true), //宇宙の城 new MapCell(16,true), //真っ黒 new MapCell(17,true), //茶色 new MapCell(18,false), //灰色 new MapCell(19,true), //ツボ new MapCell(20,true), //空 new MapCell(21,true), //地面2 new MapCell(22,true), //宝箱 new MapCell(23,true), //青壁 new MapCell(24,true), //黒 new MapCell(25,false), //机 new MapCell(26,true), //川1 new MapCell(27,true), //川2 new MapCell(28,false), //洞窟岩 new MapCell(29,true), //洞窟地面 new MapCell(30,true), //草原1 new MapCell(31,true), //草原2 new MapCell(32,true), //雪地面 new MapCell(33,true), //雪芝1 new MapCell(34,true), //雪芝2 new MapCell(35,true), //雪家 new MapCell(36,false), //雪木 new MapCell(37,true), //雪城 new MapCell(38,false), //雪池 new MapCell(39,true), //雪洞窟 new MapCell(40,true), //雪木 new MapCell(41,true), //雪芝3 new MapCell(42,true), //木の壁 }; //マップデータ構造 MapFile mapfiles[] = { new MapFile(1,"最終決戦",64,64), new MapFile(2,"世界フィールド",64,64), new MapFile(3,"テッペの街",64,32), new MapFile(4,"雪山1",20,15), new MapFile(5,"雪山2",64,64), new MapFile(6,"雪山3",20,15), new MapFile(7,"麓の村",20,15), new MapFile(8,"オアシス村",20,15), new MapFile(9,"ゴーマの神殿",20,15), new MapFile(10,"ハルー博物館",20,15), /* new MapFile(11,"ラストダンジョン1",20,40), new MapFile(12,"ラストダンジョン2",40,20), new MapFile(13,"ラストダンジョン3",20,15), new MapFile(14,"ラストダンジョン4",40,15), new MapFile(15,"ラストダンジョン5",20,15), new MapFile(16,"ラストダンジョン6",20,15), new MapFile(17,"ラストダンジョン7",20,60), new MapFile(18,"ラストダンジョン8",20,15), new MapFile(19,"ラストダンジョン9",20,60), new MapFile(20,"ラストダンジョン10",20,15), new MapFile(21,"Aの塔1階",32,32), new MapFile(22,"Aの塔2階",24,24), new MapFile(23,"Aの塔4階",20,20), new MapFile(24,"Aの塔3階",20,15), new MapFile(25,"スタッフロール",20,15), new MapFile(26,"幻の島",20,15), new MapFile(27,"幻の町",64,32), new MapFile(30,"学校",32,32), new MapFile(32,"アスファル1階",32,32), new MapFile(33,"アスファル2階",32,32), new MapFile(34,"洞窟1",32,32), new MapFile(35,"彼方",50,50), new MapFile(40,"川1",80,15), new MapFile(41,"川2",20,15), new MapFile(42,"川3",80,15), new MapFile(43,"海1",80,15), new MapFile(44,"海2",80,15), new MapFile(50,"宇宙",24,16), new MapFile(51,"魔王の城1階",32,32), new MapFile(52,"魔王の城2階",32,32), new MapFile(60,"サンプル草原",20,15), */ }; final int MAXMAPNUM = 10;//マップの個数 //初期化 public void init(){ System.out.println("init()"); int i; Dimension d = getSize(); MediaTracker mediaT = new MediaTracker(this); //ボール画像ロード chara_image = getImage(getDocumentBase(),"chara_chip.gif"); mediaT.addImage(chara_image,0); //マップチップ画像ロード map_image = getImage(getDocumentBase(),"map_chip.gif"); mediaT.addImage(map_image,0); //ロード待ち try{ mediaT.waitForAll(); }catch(InterruptedException e){} //イベントテーブル初期化 for(i=0;i= 1){ eventtbl[ event_data[x][y] ].x = x; eventtbl[ event_data[x][y] ].y = y; eventtbl[ event_data[x][y] ].px = x*CHIP_SIZE; eventtbl[ event_data[x][y] ].py = y*CHIP_SIZE; //その他初期化 eventtbl[ event_data[x][y] ].sum_move_length = 0.0f; } if(++x == map_width){ ++y; x=0; if(y==map_height)break; //終了条件 } } is.close(); }catch(IOException e){} //------------イベントテーブル更新---------------- Load_Event_Table(); //主人公の初期座標 My.x = game_buffer[2]; My.y = game_buffer[3]; My.moving_dir = game_buffer[4]; My.px = My.x*CHIP_SIZE; My.py = My.y*CHIP_SIZE; //フレーム時間初期化(ロード時間が長いので) waitTime = System.currentTimeMillis(); } //イベントテーブル更新 void Load_Event_Table(){ int i,j,x,y; InputStream is = null; int id; String sid; char line[] = new char[256]; String str=""; int no=0;//イベントNO保存用 int sw=0;//スイッチ int maxno=0; //マップNOから添え字取得 id=1; for(i=0;i",0); //NULLと書いてるものはそのまま実行 if(str.equals("NULL")){;} else{ //数字のものはゲーム進行スイッチにより読み込む sw = Integer.parseInt(str); //条件がマッチしているか? if(game_switch[sw]){ ;//続ける }else{ //この行は破棄 x=0; y++; continue; } } //イベントNO str = Harulib.HaruSplit(sline,"<>",1); no = Integer.parseInt(str); eventtbl[no].no = Integer.parseInt(str); //System.out.println("y="+y+" eventtbl[y].no="+eventtbl[y].no); //スクリプト名 str = Harulib.HaruSplit(sline,"<>",2); eventtbl[no].filename = str; //グラフィックス str = Harulib.HaruSplit(sline,"<>",3); eventtbl[no].gra = Integer.parseInt(str); //System.out.println("y="+y+" eventtbl[y].gra="+eventtbl[y].gra); if(eventtbl[no].gra >= 1){ eventtbl[no].type_of_event = 1; } //動作フラグ str = Harulib.HaruSplit(sline,"<>",4); if(str.equals("true")){ eventtbl[no].move_flag = true; }else{ eventtbl[no].move_flag = false; } //移動タイプ str = Harulib.HaruSplit(sline,"<>",5); eventtbl[no].type_of_move = Integer.parseInt(str); eventtbl[no].speed = 32; //最大値保存 if(maxno < no){ maxno = no; } x=0; y++; } } is.close(); }catch(IOException e){} //イベントの数(最大値) event_num = maxno+1; //KAKUHO_NO番目に入れる eventtbl[KAKUHO_NO].move_flag = true; eventtbl[KAKUHO_NO].type_of_event = 1; } //実行 public void run(){ System.out.println("run()"); Thread thisThread = Thread.currentThread(); try{ //ここがゲームループ while(th == thisThread){ //1フレーム時間計算(秒) FrameTime = ( System.currentTimeMillis()-waitTime ) /1000.0f; waitTime = System.currentTimeMillis(); action();//処理 repaint();//描画 //ちょっと休憩(0.01秒) Thread.sleep(10); } th = null; } catch(Exception e){ } } //描画更新 public void update(Graphics g){ paint(g); } //描画 public void paint(Graphics g){ Dimension d = getSize(); int i; int x,y;//描画位置 //バッファのグラフィックコンテキストを取得する if(bufferg == null){ bufferg = buffer.getGraphics(); } //バッファを描画する bufferg.setColor(Color.white); bufferg.fillRect(0,0,d.width,d.height); //マップ&イベント描画 DispMap(bufferg); //イベント描画 DispEvent(bufferg); //主人公描画 DispMy(bufferg); //エフェクト //黒い幕(マップ移動時) if(game_flags[0] || game_flags[1]){ bufferg.setColor(Color.black); bufferg.fillRect(0,0,d.width,(int)(d.height*game_waits[0])); } //会話(ダイアログ中も表示) if(game_flags[3] || game_flags[9]){ //ウインドウを作る(下1/3) bufferg.setColor(Color.black); bufferg.fillRect(0,2*d.height/3,d.width,d.height/3); //文字 bufferg.setColor(Color.white); //一文字ずつ書いていく x=y=0; for(i=0;i lim_right){ view_x = lim_right; } if(My.py + CHIP_SIZE/2 < lim_top){ view_y = lim_top; } if(My.py + CHIP_SIZE/2 > lim_bottom){ view_y = lim_bottom; } } //マップデータの範囲(主人公から6チップ分) int start_x; int start_y; int end_x; int end_y; start_x = view_x/CHIP_SIZE - 6; start_y = view_y/CHIP_SIZE - 6; end_x = view_x/CHIP_SIZE + 6; end_y = view_y/CHIP_SIZE + 6; //描画位置IJ //世界マップのみ int disp_start_i,disp_i,disp_start_j,disp_j; disp_start_i = start_y; disp_start_j = start_x; //限界 //世界マップ以外 if(now_map_no != 2){ if(start_x < 0){start_x = 0;} if(start_y < 0){start_y = 0;} if(end_x > map_width){end_x = map_width;} if(end_y > map_height){end_y = map_height;} }else{ //ループ //世界マップのみ if(start_x < 0){start_x += map_width;} if(end_x >= map_width){end_x -= map_width;} if(start_y < 0){start_y += map_height;} if(end_y >= map_height){end_y -= map_height;} } //描画位置 int dsp_x; int dsp_y; for(i=start_y,disp_i=disp_start_i; ;i++,disp_i++){ //iがマップ端の場合、0に。(世界マップのみ) if(i == map_height && now_map_no == 2){i = 0;} //終了 if(i == end_y){break;} for(j=start_x,disp_j=disp_start_j; ;j++,disp_j++){ //jがマップ端の場合、0に。 if(j == map_width && now_map_no == 2){j = 0;} //終了 if(j == end_x){break;} //セルデータ取得 cell_data = map_data[j][i]; //セルデータからマップグラフィックスを取得 gra = celltbl[ cell_data ].gra; //マップチップからグラフィックスの位置を取得 x = (gra%16)*CHIP_SIZE; y = (gra/16)*CHIP_SIZE; //マップ描画位置 if(now_map_no == 2){ dsp_x = disp_j*CHIP_SIZE - (view_x - d.width/2); dsp_y = disp_i*CHIP_SIZE - (view_y - d.height/2); }else{ dsp_x = j*CHIP_SIZE - (view_x - d.width/2); dsp_y = i*CHIP_SIZE - (view_y - d.height/2); } bufferg.drawImage(map_image,dsp_x,dsp_y, dsp_x+CHIP_SIZE,dsp_y+CHIP_SIZE,x,y,x+CHIP_SIZE,y+CHIP_SIZE,this); //イベントがある場合はEマークを表示(デバッグ用) if(event_data[j][i] >= 1 && game_flags[7]){ //グラフィックスの位置を取得 x = (13%16)*CHIP_SIZE; y = (13/16)*CHIP_SIZE; bufferg.drawImage(chara_image,dsp_x,dsp_y, dsp_x+CHIP_SIZE,dsp_y+CHIP_SIZE,x,y,x+CHIP_SIZE,y+CHIP_SIZE,this); } } } } //--------------イベント(キャラクター)描画------------------ void DispEvent(Graphics bufferg){ int i; int dsp_x,dsp_y; int x,y; Dimension d = getSize(); //画面中心座標を主人公の位置から取得 int view_x = (int)My.px + CHIP_SIZE/2; int view_y = (int)My.py + CHIP_SIZE/2; //カメラが行ける範囲(マップの端−画面半分) int lim_left = d.width/2; int lim_right = map_width * CHIP_SIZE - d.width/2; int lim_top = d.height/2; int lim_bottom = map_height * CHIP_SIZE - d.height/2; //主人公がマップの端寄りの場合、カメラ固定 //世界マップ以外 if(now_map_no != 2){ if(My.px + CHIP_SIZE/2 < lim_left){ view_x = lim_left; } if(My.px + CHIP_SIZE/2 > lim_right){ view_x = lim_right; } if(My.py + CHIP_SIZE/2 < lim_top){ view_y = lim_top; } if(My.py + CHIP_SIZE/2 > lim_bottom){ view_y = lim_bottom; } } for(i=0;i= 0){ x = (eventtbl[i].gra%16)*CHIP_SIZE; y = (eventtbl[i].gra/16)*CHIP_SIZE; bufferg.drawImage(chara_image,dsp_x,dsp_y, dsp_x+CHIP_SIZE,dsp_y+CHIP_SIZE,x,y,x+CHIP_SIZE,y+CHIP_SIZE,this); } } } //--------------主人公描画------------------ void DispMy(Graphics bufferg){ int i,j,x,y; int cell_data,gra; Dimension d = getSize(); //カメラが行ける範囲(マップの端−画面半分) int lim_left = d.width/2; int lim_right = map_width * CHIP_SIZE - d.width/2; int lim_top = d.height/2; int lim_bottom = map_height * CHIP_SIZE - d.height/2; //描画開始位置 int view_x = d.width/2 - CHIP_SIZE/2; int view_y = d.height/2 - CHIP_SIZE/2; //マップの端に近づいてる時(カメラが行けない範囲) //通常マップ if(now_map_no != 2){ if(My.px + CHIP_SIZE/2 < lim_left){ view_x = (int)My.px; } if(My.px + CHIP_SIZE/2 > lim_right){ view_x += (int)My.px + CHIP_SIZE/2 - lim_right; } if(My.py + CHIP_SIZE/2 < lim_top){ view_y = (int)My.py; } if(My.py + CHIP_SIZE/2 > lim_bottom){ view_y += (int)My.py + CHIP_SIZE/2 - lim_bottom; } } //主人公描画 //チップNO定義 int no = My.chip_no + My.moving_dir*2 + My.anime_no; //チップNOからグラフィックスの位置を取得 x = (no%16)*CHIP_SIZE; y = (no/16)*CHIP_SIZE; //頭 bufferg.drawImage(chara_image,view_x,view_y-32, view_x+CHIP_SIZE,view_y-32+CHIP_SIZE,x,y,x+CHIP_SIZE,y+CHIP_SIZE,this); //胴体 y+=CHIP_SIZE; bufferg.drawImage(chara_image,view_x,view_y, view_x+CHIP_SIZE,view_y+CHIP_SIZE,x,y,x+CHIP_SIZE,y+CHIP_SIZE,this); } //処理 public void action(){ int i; //上下左右キー状態で移動処理 //エフェクト中、イベント中、会話中は受け付けない if(game_flags[0] || game_flags[1] || game_flags[2] || game_flags[3]){;} else{ KeyForMove(); } //Zキー(決定キー)を押した時 if(key_states[4] == 2){ //決定キーのいろんな処理 ZAction(); //キーの状態を押し続けに変更。 key_states[4] = 1; } //上下キーを押した時 for(i=0;i<2;i++){ if(key_states[i] == 2){ //上の場合 if(i==0){ if(game_buffer[7] > 0)game_buffer[7]--; } //下の場合 else if(i==1){ if(game_buffer[7] < game_buffer[8]-1)game_buffer[7]++; } //キーの状態を押し続けに変更。 key_states[i] = 1; } } //移動中の場合 if(My.moving_flag){ MyMoving(); //アニメーション(0.2秒に1回) My.anime_wait += FrameTime; if(My.anime_wait >= 0.2f){ My.anime_no = 1 - My.anime_no; My.anime_wait = 0.0f; } } //イベント移動(エフェクト中、イベント中、会話中は受け付けない) if(game_flags[0] || game_flags[1] || game_flags[2] || game_flags[3]){;} else{ EventMove(); } //会話中の場合、文字が流れていく if(game_flags[3]){ //0.05秒に1文字 game_waits[1] += FrameTime; if(game_waits[1] >= 0.05f){ game_waits[1] = 0.0f; game_buffer[6]++; if(game_buffer[6] > game_strings[1].length()){ game_buffer[6] = game_strings[1].length(); //完了 game_flags[4] = false; } } } //マップ移動開始(幕閉じ) if(game_flags[0]){ //黒い幕が降りてくる(1.1秒) game_waits[0] += FrameTime; if(game_waits[0] >= 1.1f){ game_flags[0] = false; game_flags[1] = true; //マップロード readMapData(game_buffer[1]); } } //マップ移動2(幕開け) else if(game_flags[1]){ //黒い幕が上っていく(1.2秒) game_waits[0] -= FrameTime; if(game_waits[0] <= 0.0f){ game_flags[1] = false; game_waits[0] = 0.0f; } } //イベント中 if(game_flags[2]){ //マップ移動時、会話の時、ダイアログ中は停止中 if(game_flags[0] || game_flags[1] || game_flags[3] || game_flags[9]){;} else{ ActionScript();//スクリプト実行 } } } //イベント移動開始 void EventMove(){ int i; int ran; int dir; int next_x,next_y; boolean ismove; for(i=0;i= map_width || next_y < 0 || next_y >= map_height){ //通行不可 ismove = false; } //障害物 else if(!celltbl[ map_data[next_x][next_y] ].move_flag){ //通行不可 ismove = false; } //イベント else if(event_data[next_x][next_y] >= 1){ //通行不可 ismove = false; } //主人公の位置 else if(next_x == My.x && next_y == My.y){ //通行不可 ismove = false; } //それ以外 else{ //通行可 ismove = true; //移動開始 eventtbl[i].sum_move_length = 0.0f; eventtbl[i].moving_dir = dir; //移動先イベントデータにKAKUHO_NOを入れる event_data[next_x][next_y] = KAKUHO_NO; } eventtbl[i].moving_flag = ismove; } //移動中の時 else{ //その方向に向かって移動 CharaMoving( eventtbl[i] ); } } } } //Zキーの処理 void ZAction(){ //ダイアログ中は決定 if(game_flags[9]){ game_flags[9] = false; System.out.println("Done:Dialog"); } //会話中の時はウインドウを消す(文字が流れ終わった時) else if(game_flags[3] && !game_flags[4]){ game_flags[3] = false; System.out.println("Done:Talk"); } //そうでなくてイベント中でないなら、イベントチェック else if(!game_flags[2]){ //その方向にイベントがあるかチェック //決定ボタンが押されると実行するものを実行 check_event(My.x + dir_x[My.moving_dir] , My.y + dir_y[My.moving_dir],1); } } //キー状態で移動処理 public void KeyForMove(){ int i; int next_x,next_y; boolean ismove; //上下左右キー for(i=0;i<4;i++){ if(key_states[i] == 1){ //現在移動中か? if(!My.moving_flag){ //移動中でないなら移動 My.moving_dir = i; //その方向は通行可能か? next_x = My.x + dir_x[My.moving_dir]; next_y = My.y + dir_y[My.moving_dir]; //世界マップならループさせる if(now_map_no == 2){ if(next_x < 0){next_x += map_width;} if(next_x >= map_width){next_x -= map_width;} if(next_y < 0){next_y += map_height;} if(next_y >= map_height){next_y -= map_height;} } //System.out.println("My next("+next_x+","+next_y+")"); //領域外(通常マップ時) if(next_x < 0 || next_y >= map_width || next_y < 0 || next_y >= map_height){ //通行不可 ismove = false; } //障害物 else if(!celltbl[ map_data[next_x][next_y] ].move_flag){ //通行不可 ismove = false; } //イベントで、通行不可タイプ else if(!eventtbl[ event_data[next_x][next_y] ].move_flag){ //通行不可 ismove = false; } //確保イベント else if(event_data[next_x][next_y] == KAKUHO_NO){ //通行不可 ismove = false; } //それ以外 else{ //通行可 ismove = true; //移動開始 My.sum_move_length = 0.0f; //移動先イベントデータにKAKUHO_NOを入れる(0の時) if(event_data[next_x][next_y] == 0){ event_data[next_x][next_y] = KAKUHO_NO; } } My.moving_flag = ismove; } } } } //自分移動 public void MyMoving(){ //その方向に移動 My.px += FrameTime * My.speed * dir_x[My.moving_dir]; My.py += FrameTime * My.speed * dir_y[My.moving_dir]; //総合距離加算 My.sum_move_length += FrameTime * My.speed; //一定距離動いたか if(My.sum_move_length >= (float)CHIP_SIZE){ //ピッタリの位置にする My.x += dir_x[My.moving_dir]; My.y += dir_y[My.moving_dir]; //世界マップの時 if(My.x < 0){My.x += map_width;} if(My.x >= map_width){My.x -= map_width;} if(My.y < 0){My.y += map_height;} if(My.y >= map_height){My.y -= map_height;} My.px = My.x*CHIP_SIZE; My.py = My.y*CHIP_SIZE; My.moving_flag = false; //この位置の確保イベントを消す(KAKUHO_NOの時) if(event_data[My.x][My.y] == KAKUHO_NO){ event_data[My.x][My.y] = 0; } //イベントチェック //その上に重なると起動するもの。 check_event(My.x,My.y,0); } } //キャラ移動 void CharaMoving(Event event){ int ran; //その方向に移動 event.px += FrameTime * event.speed * dir_x[event.moving_dir]; event.py += FrameTime * event.speed * dir_y[event.moving_dir]; //総合距離加算 event.sum_move_length += FrameTime * event.speed; //一定距離動いたか if(event.sum_move_length >= (float)CHIP_SIZE){ //前の位置のイベントを消す event_data[event.x][event.y] = 0; //ピッタリの位置にする event.x += dir_x[event.moving_dir]; event.y += dir_y[event.moving_dir]; event.px = event.x*CHIP_SIZE; event.py = event.y*CHIP_SIZE; event.moving_flag = false; event_data[event.x][event.y] = event.no; //小休止(ランダム1秒〜3秒) ran=rand.nextInt(); if(ran<0){ran=-ran;} event.sum_move_length = -(ran%3+1); } } //その場所のイベントチェック void check_event(int x,int y,int type){ //領域外の時 if(x < 0 || y < 0 || x >= map_width || y >= map_height)return; //イベントがあった場合(KAKUHO_NOは無視) if(event_data[x][y] != 0 && event_data[x][y] != KAKUHO_NO){ //上に乗った時。それは重なると起動するものか? if(type == 0 && eventtbl[ event_data[x][y] ].type_of_event != 0){ //違う場合は抜ける return; } //決定ボタンを押した時。それは遠くから起動するものか? if(type == 1 && eventtbl[ event_data[x][y] ].type_of_event != 1){ //違う場合は抜ける return; } game_buffer[0] = eventtbl[ event_data[x][y] ].no;//イベントNO記憶 game_flags[2] = true;//イベントフラグセット //スクリプトファイル名決定 game_strings[0] = "eventscript\\"+eventtbl[ game_buffer[0] ].filename+".txt"; } } //スクリプト実行 void ActionScript(){ String filename; int i,x; char line[] = new char[256]; InputStream is = null; filename = game_strings[0]; System.out.println("Script("+filename+"):Load"); //指定の行まで行く int line_num = 0; boolean done_flag=true;//最後まで読みきったか boolean next_flag;//次の行も読み取るか try{ is = new URL(getDocumentBase(),filename).openStream(); Reader r = new BufferedReader(new InputStreamReader(is)); x=0; while((i=r.read()) != -1){ //一行ずつ読み込む line[x++] = (char)i; //System.out.print((char)i); //改行がきた場合 if(i == '\n'){ //System.out.println("("+line_num+")"+String.valueOf(line)); //その行は読み込む行か? if(line_num == game_buffer[5]){ //そうであった場合、読み込んで解析 next_flag = AnalyzeScript(line); game_buffer[5]++; //マップ移動、会話イベント、ダイアログなら抜ける if(!next_flag){ done_flag = false; break; } //そうでないならそのまま読み込み続ける line_num++; }else{ //違うなら、改行数増やして探索続行 line_num++; } x=0; } } is.close(); }catch(IOException e){} //最後まで読み切った場合は、フラグ解除 if(done_flag){ System.out.println("Script("+filename+"):End"); game_flags[2] = false; game_buffer[5] = 0; //テーブル更新予約があればテーブル更新 if(game_flags[8]){ Load_Event_Table(); game_flags[8] = false; } } } //指定の行を読み込んで解析(戻り値がある時はそれを実行し次の行へ続く) public boolean AnalyzeScript(char line[]){ int i,x,y; String command; String value; String buffer; boolean next_flag=true; //改行コード以降切り捨て(改行含む) String sline = Harulib.HaruChop(line); //コマンド取得 command = Harulib.HaruSplit(sline,":",0); //値取得 value = Harulib.HaruSplit(sline,":",1); System.out.println("("+game_buffer[5]+")Script -- > com="+command+",value="+value); //ラベル確認 if(command.equals("IF_SCENE1")){ //そのラベル以降は実行すべきか? if(game_buffer[7] == 0){ game_flags[10] = false;//スキップ解除してそのまま実行 } else{ game_flags[10] = true; } }else if(command.equals("IF_SCENE2")){ //そのラベル以降は実行すべきか? if(game_buffer[7] == 1){ game_flags[10] = false;//スキップ解除してそのまま実行 } else{ game_flags[10] = true; } }else if(command.equals("IF_SCENE3")){ //そのラベル以降は実行すべきか? if(game_buffer[7] == 2){ game_flags[10] = false;//スキップ解除してそのまま実行 } else{ game_flags[10] = true; } }else if(command.equals("END_SCENE")){ //スキップ終了 game_flags[10] = false; } //スキップ実行の時 if(game_flags[10]){ return true;//抜ける } //コマンドによってイベント実行 //マップ移動コマンド if(command.equals("move")){ System.out.println("Do:Move"); //移動イベント開始 game_flags[0] = true; //値を解析 buffer = Harulib.HaruSplit(value,"=",0); game_buffer[1] = Integer.parseInt(buffer);//移動先マップNO buffer = Harulib.HaruSplit(value,"=",1); game_buffer[2] = Integer.parseInt(buffer);//X buffer = Harulib.HaruSplit(value,"=",2); game_buffer[3] = Integer.parseInt(buffer);//Y buffer = Harulib.HaruSplit(value,"=",3); game_buffer[4] = Integer.parseInt(buffer);//方向 next_flag=false; } //会話コマンド else if(command.equals("talk")){ System.out.println("Do:Talk"); //会話イベント開始 game_flags[3] = true; //流れ始める。 game_flags[4] = true; //会話 game_strings[1] = value; //char配列にコピー game_strings[1].getChars(0,game_strings[1].length(),game_talks,0); //文字の位置 game_buffer[6] = 1;//1文字目 next_flag=false; } //ゲーム進行スイッチオンコマンド else if(command.equals("switch_on")){ System.out.println("Do:switch_on"); game_switch[ Integer.parseInt(value) ] = true; //テーブル更新予約 game_flags[8] = true; } //分岐1 else if(command.equals("SCENE1")){ System.out.println("Do:SCENE1"); game_strings[2] = value; } //分岐2 else if(command.equals("SCENE2")){ System.out.println("Do:SCENE2"); game_strings[3] = value; game_buffer[7] = 0; game_buffer[8] = 2;//選択肢の数 } //分岐3 else if(command.equals("SCENE3")){ System.out.println("Do:SCENE3"); game_strings[4] = value; game_buffer[7] = 0; game_buffer[8] = 3;//選択肢の数 } //ダイアログを出す else if(command.equals("DIALOG")){ System.out.println("Do:DIALOG"); game_flags[9] = true; next_flag=false; } return next_flag; } //キーが押された瞬間(使わない) public void keyTyped(KeyEvent e){} //キーを押している時 public void keyPressed(KeyEvent e){ int key; key=e.getKeyCode(); switch(key){ //上キー case KeyEvent.VK_UP: //最初に押した時に2を入れる if(key_states[0] == 0){ key_states[0] = 2; } break; //下キー case KeyEvent.VK_DOWN: //最初に押した時に2を入れる if(key_states[1] == 0){ key_states[1] = 2; } break; //左キー case KeyEvent.VK_LEFT: key_states[2] = 1; break; //右キー case KeyEvent.VK_RIGHT: key_states[3] = 1; break; //Zキー case KeyEvent.VK_Z: //最初に押した時に2を入れる if(key_states[4] == 0){ key_states[4] = 2; } break; } } //キーが放された瞬間 public void keyReleased(KeyEvent e){ int key; key=e.getKeyCode(); switch(key){ //上キー case KeyEvent.VK_UP: key_states[0] = 0; break; //下キー case KeyEvent.VK_DOWN: key_states[1] = 0; break; //左キー case KeyEvent.VK_LEFT: key_states[2] = 0; break; //右キー case KeyEvent.VK_RIGHT: key_states[3] = 0; break; //Zキー case KeyEvent.VK_Z: key_states[4] = 0; break; } } }