import java.awt.*; import java.applet.*; import java.io.*; import java.net.URL; import java.net.URLConnection; import java.awt.image.*; // マップ管理クラス class MapManage extends BasicManage{ // 画面サイズ static final short WIDTH = 256; static final short HEIGHT = 224; // 半分サイズ static final short HALF_WIDTH = WIDTH >> 1; static final short HALF_HEIGHT = HEIGHT >> 1; // 画面横幅をシフトで表す static final short WIDTH_SHIFT = 8; // チップサイズ static final byte CHIP_SIZE = 16; // チップサイズシフト用 final byte CHIP_SIZE_SHIFT = 4; // マップ最大のサイズ final int MAX_SIZE = 256; // チップ最大数 final int MAX_CHIP_NUM = 256; // 海の海岸線種類 static final int SEA_NUM = 16 + 2; // ゲームモード static final int LOOK_ONLY_MODE = 1; // 閲覧モード static final int EDIT_MODE = 0; // 編集モード static final int GAME_MODE = 2; // ゲームモード int GameMode = EDIT_MODE; void SetGameMode( int mode ){ GameMode = mode; } int GetGameMode(){ return GameMode; } // マップモード static final int DOWN_LAYER_MODE = 0; static final int UP_LAYER_MODE = 1; int map_window_mode = DOWN_LAYER_MODE; //-------------------------------------------------- // マップモードを返す //-------------------------------------------------- int GetMapWindowMode(){return map_window_mode;} //-------------------------------------------------- // マップモードをセット //-------------------------------------------------- void SetChipMode( int mode ){ map_window_mode = mode; } // ピクセル処理モード int PixAction = 0; final byte NORMAL_PIX = 0; //通常 final byte NIGHT_PIX = 1; //夜 final byte GRAY_PIX = 2; //グレー final byte SEPI_PIX = 3; //セピア void SetPixAction( int mode ){ PixAction = mode; } // チップの個数 int ChipNum; // 下層レイヤー用 int ChipUpNum; // 上層レイヤー用 // マップデータ配列(下層レイヤー) byte MapData[][]; // マップデータ配列(上層レイヤー) byte MapUpData[][]; // 透過色 int AlphaColor; // でかマップピクセル int BigPixels[]; // 上層レイヤー用 マップセル MapCell MapUpCell[]; // 下層レイヤー用 マップセル(画像と通過可能か) MapCell MapDownCell[]; // でかいマップ画像 Image BigMapImage; // 横幅(チップ数) int width; // 縦幅 int height; // チップ数×チップサイズの横幅縦幅 int m_total_width; int m_total_height; // 作業中の左上のインデックス private Point now_index = new Point(); Point GetNowIndex(){ return now_index; } // 選択しているパーツ byte selected_part = 0; // セーブフラグ int save_flag = 0; // デバッグ用 初期化にかかった時間 long initTime = 0; // スケール float m_scale_per = 1.0f; float GetScalePer(){ return m_scale_per; } // インスタンス static MapManage m_instance; static MapManage GetInstance(){ return m_instance; } static void NewInstance( MapEdit applet ){ m_instance = new MapManage( applet ); } //-------------------------------------------------- // コンストラクタ //-------------------------------------------------- MapManage( MapEdit applet ){ this.applet = applet; } MapCell GetMapCell( int x, int y ){ return MapDownCell[ ToUnsignedByte( MapData[ x ][ y ] ) ]; } //-------------------------------------------------- // チップ数を返す //-------------------------------------------------- int GetChipNum(){ if( map_window_mode == DOWN_LAYER_MODE ){ return ChipNum; }else{ return ChipUpNum; } } //-------------------------------------------------- // 選択しているパーツを返す //-------------------------------------------------- byte GetSelectedPart(){ return selected_part; } //-------------------------------------------------- // インデックスセット(スクロールバーから操作) //-------------------------------------------------- void SetIndex( int x, int y ){ if( x >= 0 && x < width ){ this.now_index.x = x; } if( y >= 0 && y < height ){ this.now_index.y = y; } applet.SetCamera( CHIP_SIZE * this.now_index.x + MapManage.WIDTH/2, CHIP_SIZE * this.now_index.y + MapManage.HEIGHT/2 ); } //-------------------------------------------------- // 初期化 //-------------------------------------------------- void Initialize(){ this.width = 0; this.height = 0; now_index.x = 0; now_index.y = 0; // マップデータ配列初期化 MapData = new byte[ MAX_SIZE ][ MAX_SIZE ]; MapUpData = new byte[ MAX_SIZE ][ MAX_SIZE ]; MapDownCell = new MapCell[ MAX_CHIP_NUM ]; MapUpCell = new MapCell[ MAX_CHIP_NUM ]; // マップセル初期化 for( int i = 0; i < MAX_CHIP_NUM; i++ ){ MapDownCell[i] = new MapCell(); MapUpCell[i] = new MapCell(); } } //-------------------------------------------------- // マップリセット //-------------------------------------------------- void Reset( int width, int height ){ int i,j; this.width = width; this.height = height; now_index.x = 0; now_index.y = 0; this.m_total_width = width * CHIP_SIZE; this.m_total_height = height * CHIP_SIZE; for( i = 0; i < MAX_SIZE; i++ ){ for( j = 0; j < MAX_SIZE; j++ ){ MapData[ i ][ j ] = 0; MapUpData[ i ][ j ] = 0; } } } //-------------------------------------------------- // マップ画像読み込み //-------------------------------------------------- void LoadMapImage( String file, MediaTracker mediaT ){ // でかい画像ロード BigMapImage = applet.getImage( applet.getDocumentBase(), file ); mediaT.addImage( BigMapImage, 0 ); } //-------------------------------------------------- // マップデータ読み込み //-------------------------------------------------- void LoadMapData( String file ){ DebugPrint( file ); try{ InputStream is = new URL( applet.getDocumentBase(), file ).openStream(); int i, x, y; x = y = 0; DebugPrint( "load_start" ); // 一気にロード byte[] buf = new byte[ this.width * this.height ]; is.read( buf, 0, this.width * this.height ); is.close(); for( i = 0; i < this.width * this.height; i++ ){ //DebugPrint( "("+x+","+y+", "+i+")" ); MapData[ x ][ y ] = buf[i]; if( ++x == this.width ){ ++y; x = 0; if( y == this.height ){ break; } } } }catch( IOException e ){ DebugPrint( "load_fail" ); } } //-------------------------------------------------- // マップデータ読み込み(上層レイヤー) //-------------------------------------------------- void LoadMapUpData( String file ){ DebugPrint( file ); try{ InputStream is = new URL( applet.getDocumentBase(), file ).openStream(); int i, x, y; x = y = 0; DebugPrint( "load_start" ); // 一気にロード byte[] buf = new byte[ this.width * this.height ]; is.read( buf, 0, this.width * this.height ); is.close(); for( i = 0; i < this.width * this.height; i++ ){ //DebugPrint( "("+x+","+y+", "+i+")" ); MapUpData[ x ][ y ] = buf[i]; if( ++x == this.width ){ ++y; x = 0; if( y == this.height ){ break; } } } }catch( IOException e ){ DebugPrint( "load_fail" ); } } //-------------------------------------------------- // データセーブ //-------------------------------------------------- void SaveData( String mapid ){ // CGIアクセス try{ System.out.println("SaveData()"); URL url = new URL( applet.getDocumentBase(),"check.cgi"); //POSTコマンドのデータ部分に突っ込むデータ StringBuffer poststr = new StringBuffer(); URLConnection conn = url.openConnection(); conn.setDoOutput(true); PrintStream pout = new PrintStream(conn.getOutputStream()); // 最初の1バイトはマップNO pout.print( mapid ); //pout.print(poststr); for( int i = 0; i < height; i++ ){ for( int j = 0; j < width; j++ ){ pout.write( MapData[j][i] ); } } pout.close(); //POSTコマンドを発行したので、次にその結果を読み込む。 BufferedReader reader = new BufferedReader( new InputStreamReader(conn.getInputStream() ) ); String line; while( (line = reader.readLine() ) != null){ System.out.println(line); } reader.close(); // 上層レイヤーも { url = new URL( applet.getDocumentBase(),"saveup.cgi"); //POSTコマンドのデータ部分に突っ込むデータ poststr = new StringBuffer(); conn = url.openConnection(); conn.setDoOutput(true); pout = new PrintStream(conn.getOutputStream()); // 最初の1バイトはマップNO pout.print( mapid ); //pout.print(poststr); for( int i = 0; i < height; i++ ){ for( int j = 0; j < width; j++ ){ pout.write( MapUpData[j][i] ); } } pout.close(); //POSTコマンドを発行したので、次にその結果を読み込む。 reader = new BufferedReader( new InputStreamReader(conn.getInputStream() ) ); while( (line = reader.readLine() ) != null){ System.out.println(line); } reader.close(); } // セーブフラグ save_flag = 1; }catch(Exception e){ System.out.println("POSTの実行に失敗しました"); // セーブフラグ save_flag = 2; } } //-------------------------------------------------- // グラフィックスセット //-------------------------------------------------- void SetGraphics( Graphics g ){ this.g = g; } //-------------------------------------------------- // マップバラバラ画像構築 //-------------------------------------------------- void MakeBaraMap(){ int i; int x, y; int count; // 処理にかかる時間を計測 long waitTime = System.currentTimeMillis(); // でかいマップ画像を解体 // ツクール素材互換 BigPixels = new int[ 480 * 256 ]; PixelGrabber pg = new PixelGrabber( BigMapImage, 0, 0, 480, 256, BigPixels, 0, 480 ); try{ pg.grabPixels(); }catch( InterruptedException e ){ System.err.println("Error"); } // まず上層レイヤーから作る count = 0; for( y = 8; y < 16; y++ ){ for( x = 18; x < 24; x++ ){ MapUpCell[ count++ ].SetChipImage( MakeImageByBigMap( x, y ) ); } } for( y = 0; y < 16; y++ ){ for( x = 24; x < 30; x++ ){ MapUpCell[ count++ ].SetChipImage( MakeImageByBigMap( x, y ) ); } } // 透過色の指定 上層レイヤの最初のチップの色 AlphaColor = MapUpCell[0].GetChipImage().pix[0]; ChipUpNum = count; // 下層レイヤー(海などの特殊チップ) // 海は左上、右上、右下、左下の組み合わせで行う MapDownCell[0].SetChipImage( MakeSeaPart( 3, 3, 3, 3 ) ); MapDownCell[1].SetChipImage( MakeSeaPart( 0, 2, 3, 1 ) ); MapDownCell[2].SetChipImage( MakeSeaPart( 2, 2, 3, 3 ) ); MapDownCell[3].SetChipImage( MakeSeaPart( 2, 0, 1, 3 ) ); MapDownCell[4].SetChipImage( MakeSeaPart( 3, 1, 1, 3 ) ); MapDownCell[5].SetChipImage( MakeSeaPart( 3, 1, 0, 2 ) ); MapDownCell[6].SetChipImage( MakeSeaPart( 3, 3, 2, 2 ) ); MapDownCell[7].SetChipImage( MakeSeaPart( 1, 3, 2, 0 ) ); MapDownCell[8].SetChipImage( MakeSeaPart( 1, 3, 3, 1 ) ); MapDownCell[9].SetChipImage( MakeSeaPart( 1, 1, 1, 1 ) ); MapDownCell[0xa].SetChipImage( MakeSeaPart( 2, 2, 2, 2 ) ); MapDownCell[0xb].SetChipImage( MakeSeaPart( 0, 2, 2, 0 ) ); MapDownCell[0xc].SetChipImage( MakeSeaPart( 0, 0, 1, 1 ) ); MapDownCell[0xd].SetChipImage( MakeSeaPart( 2, 0, 0, 2 ) ); MapDownCell[0xe].SetChipImage( MakeSeaPart( 1, 1, 0, 0 ) ); MapDownCell[0xf].SetChipImage( MakeSeaPart( 0, 0, 0, 0 ) ); MapDownCell[0x10].SetChipImage( MakeImageByBigMap( 23, 7 ) ); MapDownCell[0x11].SetChipImage( MakeImageByBigMap( 23, 7 ) ); // ここから飛び飛びの値でおk // 表示リスト int list_x[] = {0,3,0,3,4,5,0,3,0, 3 ,6+1,9+1,6+1,9+1,6,9,6, 9 }; //18個 int list_y[] = {0,0,4,4,4,4,8,8,12,12,0+2,0+2,4+2,4+2,8,8,12,12}; for( i = 0; i < list_x.length; i++){ MapDownCell[ i + SEA_NUM ].SetChipImage( MakeImageByBigMap( list_x[i], list_y[i] ) ); } // ここから連続 count = 18 + SEA_NUM; for( y = 0; y < 16; y++ ){ for( x = 12; x < 18; x++ ){ MapDownCell[ count++ ].SetChipImage( MakeImageByBigMap( x, y ) ); } } for( y = 0; y < 8; y++ ){ for( x = 18; x < 24; x++ ){ MapDownCell[ count++ ].SetChipImage( MakeImageByBigMap( x, y ) ); } } ChipNum = count; // 処理にかかった時間を表示 DebugPrint("bara="+( System.currentTimeMillis() - waitTime ) ); } //-------------------------------------------------- // 対応する場所のピクセルイメージ作成 //-------------------------------------------------- ChipImage MakeImageByBigMap( int x, int y ){ int[] rPixels = new int[ CHIP_SIZE * CHIP_SIZE ]; GetPixelByBigImage( rPixels, x*CHIP_SIZE, y*CHIP_SIZE, CHIP_SIZE, CHIP_SIZE, BigPixels ); return new ChipImage( rPixels, CHIP_SIZE, CHIP_SIZE ); } //-------------------------------------------------- // でか画像から指定のチップ採取 // 入力、開始x,y 幅、高さ、でか画像ピクセル //-------------------------------------------------- void GetPixelByBigImage( int pix[], int x, int y, int width, int height, int big_pixels[] ){ // でかマップから採取 int xx, yy; for( yy = 0; yy < width; yy++ ){ for( xx = 0; xx < height; xx++ ){ pix[ xx + yy * width ] = big_pixels[ ( x + xx ) + ( y + yy ) * 480 ]; } } } //-------------------------------------------------- // 海岸線付き海チップ作成 // 左上、右上、右下、左下の組み合わせで行う //-------------------------------------------------- ChipImage MakeSeaPart( int a, int b, int c, int d ){ final int list_x[] = {0,1,1,0};//左上、右上、右下、左下のオフセット final int list_y[] = {0,0,1,1}; final int plase_list[] = {0,1,2,4}; int order_list[] = {a,b,c,d}; int i, count = 0; final int CUT_SIZE = 8; int[][] pixels = new int[4][CUT_SIZE*CUT_SIZE]; // 作成 int[] total = new int[CHIP_SIZE*CHIP_SIZE]; for( count = 0; count < 4; count++ ){ GetPixelByBigImage( pixels[count], list_x[count]*CUT_SIZE, CHIP_SIZE*plase_list[ order_list[count] ] + list_y[count]*CUT_SIZE, CUT_SIZE, CUT_SIZE, BigPixels ); } int start = 0; int offset; for( i = 0; i < CUT_SIZE*CUT_SIZE; i++ ){ start = CHIP_SIZE*(i/CUT_SIZE); offset = i%CUT_SIZE; total[ offset + start] = pixels[0][i]; start = CUT_SIZE + CHIP_SIZE*(i/CUT_SIZE); total[ offset + start ] = pixels[1][i]; start = CUT_SIZE + CHIP_SIZE*(i/CUT_SIZE) + 0x80; total[ offset + start ] = pixels[2][i]; start = CHIP_SIZE*(i/CUT_SIZE) + 0x80; total[ offset + start ] = pixels[3][i]; } // チップイメージにする return new ChipImage( total, CHIP_SIZE, CHIP_SIZE ); } //-------------------------------------------------- // 左画面マップ描画 //-------------------------------------------------- void DspMap( int OffPix[] ){ int x, y; int map_x, map_y; byte index; // 描画にかかる時間を計測 long waitTime = System.currentTimeMillis(); // 描くチップ数 int dsp_width_num = WIDTH / CHIP_SIZE + 2; int dsp_height_num = HEIGHT / CHIP_SIZE + 2; // 描画用座標 int dsp_map_x, dsp_map_y; // 左上の座標(カメラ座標から求める) // 負の時があるので、小数切捨てはまずい。繰り下げにする。 // そんな計算するくらいなら1パーツ増やすの術 最後の-1 int left_up_x = ( (applet.GetCamera().x - HALF_WIDTH) / CHIP_SIZE ) - 1; int left_up_y = ( (applet.GetCamera().y - HALF_HEIGHT) / CHIP_SIZE ) - 1; // 縮小モード if( Game.GetInstance().GetMapScaleState() != Game.NORMAL_SCALE_MAP ){ // 発想の逆転 縮小サイズイメージから逆参照 int pixel; int s_point; // X方向のスケール //float x_scale = m_scale_per; //float y_scale = m_scale_per; //float gen = ( m_scale_per - 1.0f ) / 300.0f; // 固定小数 int x_scale_i = (int)(m_scale_per * ONE); int y_scale_i = (int)(m_scale_per * ONE); int yy; // 先計算用 // 空中モードの場合、遠近感を出すために縮小率を徐々に下げていく int gen_i = (int)( ( m_scale_per - 1.0f ) * ONE / 300.0f); for( y = 0; y < HEIGHT; y++ ){ yy = y << WIDTH_SHIFT; for( x = 0; x < WIDTH; x++ ){ s_point = yy + x; // 下層と上層を合わせて行う // 浮動小数ver //OffPix[ s_point ] = GetPixelByMap( (int)( (x-HALF_WIDTH) * x_scale) + 160, (int)( (y-HALF_HEIGHT) * y_scale ) + HALF_HEIGHT ); // 固定小数ver OffPix[ s_point ] = GetPixelByMap( ChangeOne( (x-HALF_WIDTH) * x_scale_i) + HALF_WIDTH, ChangeOne( (y-HALF_HEIGHT) * y_scale_i ) + HALF_HEIGHT ); OffPix[ s_point ] = ToNight( OffPix[ s_point ], Game.GetInstance().GetNightLevel() ); } //x_scale -= gen; //y_scale -= gen; // 空のとき if( Game.GetInstance().GetMapScaleState() == Game.SKY_SCALE_MAP ){ x_scale_i -= gen_i; y_scale_i -= gen_i; } } return; }else{ m_scale_per = 1.0f; } // 下層レイヤー for( y = 0; y < dsp_height_num; y++ ){ for( x = 0; x < dsp_width_num; x++ ){ // 左上(起点)を加算 map_x = left_up_x + x; map_y = left_up_y + y; // 描画用に記憶 dsp_map_x = map_x; dsp_map_y = map_y; // ループマップ構成 if( map_x < 0 ) map_x = width + map_x; if( map_y < 0 ) map_y = height + map_y; if( map_x >= width ) map_x = map_x - width; if( map_y >= height ) map_y = map_y - height; index = MapData[ map_x ][ map_y ]; // ↓初期バージョンとの互換で一応 if( ToUnsignedByte(index) < ChipNum ){ // オフスクリーンに直接描画 drawChipImageToMap( OffPix, MapDownCell[ ToUnsignedByte(index) ].GetChipImage(), ToScreenX( dsp_map_x*CHIP_SIZE ), ToScreenY( dsp_map_y*CHIP_SIZE ), WIDTH, HEIGHT ); } } } // 上層レイヤー for( y = 0; y < dsp_height_num; y++ ){ for( x = 0; x < dsp_width_num; x++ ){ // 左上(起点)を加算 map_x = left_up_x + x; map_y = left_up_y + y; // 描画用に記憶 dsp_map_x = map_x; dsp_map_y = map_y; // ループマップ構成 if( map_x < 0 ) map_x = width + map_x; if( map_y < 0 ) map_y = height + map_y; if( map_x >= width ) map_x = map_x - width; if( map_y >= height ) map_y = map_y - height; index = MapUpData[ map_x ][ map_y ]; if( index != 0 && ToUnsignedByte(index) < ChipUpNum ){ // 通過フラグ2は後で描画 if( MapUpCell[ ToUnsignedByte(index) ].GetWalkFlag() != 2 ){ // オフスクリーンに描画 drawChipImageToMap( OffPix, MapUpCell[ ToUnsignedByte(index) ].GetChipImage(), ToScreenX( dsp_map_x*CHIP_SIZE ), ToScreenY( dsp_map_y*CHIP_SIZE ), WIDTH, HEIGHT ); } } } } } //-------------------------------------------------- // 上層レイヤの通過フラグ2専用 //-------------------------------------------------- void DspMapUp2( int OffPix[] ){ int x, y; int map_x, map_y; byte index; // 描く数 int dsp_width_num = WIDTH / CHIP_SIZE + 2; int dsp_height_num = HEIGHT / CHIP_SIZE + 2; // 左上の座標(カメラ座標から求める) // 負の時があるので、小数切捨てはまずい。繰り下げにする。 // そんな計算するくらいなら1パーツ増やすの術 最後の-1 int left_up_x = ( (applet.GetCamera().x - HALF_WIDTH) / 16 ) - 1; int left_up_y = ( (applet.GetCamera().y - HALF_HEIGHT) / 16 ) - 1; // 描画用座標 int dsp_map_x, dsp_map_y; // 空モード if( Game.GetInstance().GetNowPhase() == Game.TO_SKY_PHASE ){ // 飛行船だけ表示 // 影の半径 int size = (int)(CHIP_SIZE / 2 / m_scale_per); // カメラの位置に影表示 //Game.GetInstance().fillRectToMemory( OffPix, HALF_WIDTH - size/2, HALF_HEIGHT - size/2, size, size, 0x80000000 ); Game.GetInstance().fillOvalToMemory( OffPix, HALF_WIDTH, HALF_HEIGHT, size, size, 0x80000000 ); // 乗り物描画 // 位置は影の上で。 Player player = PlayerManage.GetInstance().GetPlayerInstance( 10 ); player.SetDir( PlayerManage.GetInstance().GetPlayerInstance( 0 ).GetDir() ); int dsp_x = HALF_WIDTH - 8; int dsp_y = HALF_HEIGHT - 8 - (int)( ( m_scale_per - 1.0f ) * 32 ); dsp_x += CharaManage.CENTER_OFFSET_X; dsp_y += CharaManage.CENTER_OFFSET_Y; CharaManage.GetInstance().drawChipImageToMemory( OffPix, player.GetChipImage(), dsp_x, dsp_y, player.GetAlphaColor(), WIDTH, HEIGHT ); } // エンカウント else if( Game.GetInstance().GetNowPhase() == Game.ENCOUNT_PHASE ){ } // 通常 else{ // 上層レイヤー for( y = 0; y < dsp_height_num; y++ ){ for( x = 0; x < dsp_width_num; x++ ){ // 左上(起点)を加算 map_x = left_up_x + x; map_y = left_up_y + y; // 描画用に記憶 dsp_map_x = map_x; dsp_map_y = map_y; // ループマップ構成 if( map_x < 0 ) map_x = width + map_x; if( map_y < 0 ) map_y = height + map_y; if( map_x >= width ) map_x = map_x - width; if( map_y >= height ) map_y = map_y - height; index = MapUpData[ map_x ][ map_y ]; if( index != 0 && ToUnsignedByte(index) < ChipUpNum ){ // 通過フラグ2 if( MapUpCell[ ToUnsignedByte(index) ].GetWalkFlag() == 2 ){ // オフスクリーンに描画 drawChipImageToMap( OffPix, MapUpCell[ ToUnsignedByte(index) ].GetChipImage(), ToScreenX( dsp_map_x*CHIP_SIZE ), ToScreenY( dsp_map_y*CHIP_SIZE ), WIDTH, HEIGHT ); } } } } } } //-------------------------------------------------- // 文字列専用 //-------------------------------------------------- void DrawString(){ // 文字 g.setColor( Color.black ); g.drawString( "左上("+now_index.x+","+now_index.y+") 右下("+(now_index.x+WIDTH/CHIP_SIZE -1 )+","+(now_index.y+HEIGHT/CHIP_SIZE - 1)+") 全体サイズ("+width+","+height+")", 0, 276 ); g.drawString("初期化時間:"+initTime+"ミリ秒", 0, 296 ); if( save_flag == 1 ){ g.drawString( "データセーブに成功", 200, 312 ); } else if( save_flag == 2 ){ g.drawString( "データセーブに失敗", 200, 312 ); } g.drawString("選択チップ:"+ToUnsignedByte(selected_part), 0, 330 ); } //-------------------------------------------------- // キャラ描画 //-------------------------------------------------- void DrawChara(){ g.setColor( Color.black ); // 選択チップ画像の描画(拡大) if( GetMapWindowMode() == DOWN_LAYER_MODE ){ g.drawString("下層レイヤー", 40, 350 ); g.drawImage( MapDownCell[ ToUnsignedByte( selected_part ) ].GetChipImage().GetImage(), 4, 332, 4 + CHIP_SIZE*2, 330 + CHIP_SIZE*2, 0, 0, CHIP_SIZE, CHIP_SIZE, applet ); }else{ g.drawString("上層レイヤー", 40, 350 ); g.drawImage( MapUpCell[ ToUnsignedByte( selected_part ) ].GetChipImage().GetImage(), 4, 332, 4 + CHIP_SIZE*2, 330 + CHIP_SIZE*2, 0, 0, CHIP_SIZE, CHIP_SIZE, applet ); } } //-------------------------------------------------- // 正しいチップIDか //-------------------------------------------------- boolean IsCorrectID( byte id, int mode ){ if( mode == DOWN_LAYER_MODE ){ if( ToUnsignedByte( id ) < ChipNum ) return true; else return false; }else{ if( ToUnsignedByte( id ) < ChipUpNum ) return true; else return false; } } //-------------------------------------------------- // 右画面チップセレクトウィンドウ描画 //-------------------------------------------------- void DspMapWindow( int OffPix[], int mode ){ int x, y; int map_x, map_y; byte index; int i, j; // この個数配置して改行 final int BR_NUM = 6; // 海分オフセット final int SEA_OFFSET = (SEA_NUM / BR_NUM) * CHIP_SIZE; // 下層レイヤーモード if( mode == DOWN_LAYER_MODE ){ for( i = 0; i < ChipNum; i++){ // 海の海岸線複数は出したくないので隠す if( i < SEA_NUM ){continue;} x = (i%BR_NUM) * CHIP_SIZE; y = (int)(i/BR_NUM) * CHIP_SIZE; // オフスクリーンに描画 drawChipImage( OffPix, MapDownCell[ i ].GetChipImage(), x, y - SEA_OFFSET ); } } // 上層レイヤー else{ // 一覧 for( i = 0; i < ChipUpNum; i++ ){ x = (i%BR_NUM) * CHIP_SIZE; y = (int)(i/BR_NUM) * CHIP_SIZE; // オフスクリーンに描画 drawChipImage( OffPix, MapUpCell[ i ].GetChipImage(), x, y ); } } } //-------------------------------------------------- // 選択している枠描画 //-------------------------------------------------- void DrawRect( int mode ){ // この個数配置して改行 final int BR_NUM = 6; // 海分オフセット final int SEA_OFFSET = (SEA_NUM / BR_NUM) * CHIP_SIZE; int x = (ToUnsignedByte(selected_part)%BR_NUM) * CHIP_SIZE; int y = (int)(ToUnsignedByte(selected_part)/BR_NUM) * CHIP_SIZE; // 下層レイヤの場合 if( mode == DOWN_LAYER_MODE ){ g.setColor( Color.white ); // 海以上なら if( ToUnsignedByte(selected_part) >= SEA_NUM ){ g.drawRect( x, y - SEA_OFFSET, CHIP_SIZE - 1, CHIP_SIZE - 1 ); } // 海の場合なら左上を囲んでおく else if( ToUnsignedByte(selected_part) < SEA_NUM ){ g.drawRect( 0, 0, CHIP_SIZE - 1, CHIP_SIZE - 1 ); } } // 上層レイヤー else{ g.setColor( Color.cyan ); g.drawRect( x, y, CHIP_SIZE - 1, CHIP_SIZE - 1 ); } } //-------------------------------------------------- // チップをオフスクリーン(メモリイメージ)に描画(マップキャンバス用) // メモリイメージ配列 チップイメージ スクリーン座標 オフスクリーンの横幅 オフスクリーンの縦幅 //-------------------------------------------------- void drawChipImageToMap( int []off, ChipImage chip_image, int x, int y, int off_width, int off_height ){ int xx, yy; int draw_p; int new_x, new_y; int s_point; //ソースポイント for( yy = 0; yy < CHIP_SIZE; yy++ ){ for( xx = 0; xx < CHIP_SIZE; xx++ ){ // オフスクリーンに書き込む新座標 new_x = x + xx; new_y = y + yy; // 領域外なら抜ける if( new_x < 0 || new_x >= off_width ) continue; if( new_y < 0 || new_y >= off_height ) continue; // オフスクリーン配列上の描き込む位置 draw_p = new_x + new_y * off_width; if( draw_p < off_width * off_height ){ // 元チップ側のピクセル座標 s_point = xx + yy*CHIP_SIZE; // 透過色ならスキップ if( chip_image.pix[ s_point ] == AlphaColor ) continue; // (ゲームモード)ゲーム時間に応じて色変化 if( applet.GetGameMode() == MapEdit.GAME_MODE ){ // 夜 off[ draw_p ] = ToNight( chip_image.pix[ s_point ], Game.GetInstance().GetNightLevel() ); } // エディタモード else{ // 通常描画 if( PixAction == NORMAL_PIX ){ off[ draw_p ] = chip_image.pix[ s_point ]; } // 夜にしてみる else if( PixAction == NIGHT_PIX ){ off[ draw_p ] = ToNight( chip_image.pix[ s_point ], 50 ); } // グレー else if( PixAction == GRAY_PIX ){ off[ draw_p ] = ToGray( chip_image.pix[ s_point ] ); } } } } } } // 引数はスクリーン座標 int GetPixelByMap( int x, int y ){ int world_x, world_y; int map_x; int map_y; int pix_x, pix_y; // スクリーン座標からワールド座標へ world_x = ToWorldX( x ); world_y = ToWorldY( y ); // ループマップ構成 while( world_x < 0 ) world_x += m_total_width; while( world_y < 0 ) world_y += m_total_height; while( world_x >= m_total_width ) world_x -= m_total_width; while( world_y >= m_total_height ) world_y -= m_total_height; // マップ座標へ変換 map_x = world_x >> CHIP_SIZE_SHIFT; map_y = world_y >> CHIP_SIZE_SHIFT; // 位置 pix_x = world_x - ( map_x << CHIP_SIZE_SHIFT ); pix_y = world_y - ( map_y << CHIP_SIZE_SHIFT ); // そのマップのピクセルゲット // ピクセル配列上の位置 int pix_point = (pix_y<> 16 ) & 0xff; int g = ( pix >> 8 ) & 0xff; int b = pix & 0xff; r -= value; if( r <= 0 ){ r = 0; } g -= value; if( g <= 0 ){ g = 0; } return b | (g<<8) | (r<<16) | (0xff000000); } // グレー int ToGray( int pix ){ int r = ( pix >> 16 ) & 0xff; int g = ( pix >> 8 ) & 0xff; int b = pix & 0xff; // 3色の重み付き平均をとってみる int av = (int)(0.298912 * r + 0.586611 * g + 0.114478 * b); return av | (av<<8) | (av<<16) | (0xff000000); } //-------------------------------------------------- // チップをオフスクリーンに描画(セレクトキャンバス用) //-------------------------------------------------- void drawChipImage( int []off, ChipImage chip_image, int x, int y ){ int xx, yy; for( yy = 0; yy < CHIP_SIZE; yy++ ){ for( xx = 0; xx < CHIP_SIZE; xx++ ){ if( x + xx + (yy+y)*SelectChipCanvas.WIDTH < SelectChipCanvas.WIDTH * SelectChipCanvas.HEIGHT ){ off[ x + xx + y * SelectChipCanvas.WIDTH + yy*SelectChipCanvas.WIDTH ] = chip_image.pix[ xx + yy*CHIP_SIZE ]; } } } } //-------------------------------------------------- // 符号付バイトを符号無バイトへ //-------------------------------------------------- int ToUnsignedByte( byte b ){ if( b < 0 ){ return 256 + b; }else{ return b; } } //-------------------------------------------------- // 選択チップIDセット //-------------------------------------------------- void SetSelectedID( byte id ){ this.selected_part = id; } //-------------------------------------------------- // マップにチップセット //-------------------------------------------------- void SetChip( int x, int y ){ // 左上(起点)を加算 int map_x = now_index.x + x; int map_y = now_index.y + y; if( map_x >= 0 && map_x < width && map_y >= 0 && map_y < height ){} else return; // 下層レイヤーの場合 if( this.map_window_mode == DOWN_LAYER_MODE ){ this.MapData[ map_x ][ map_y ] = selected_part; // 海岸線処理 PutCoastline( map_x, map_y ); // 上下左右チェック PutCoastline( map_x, map_y - 1 ); PutCoastline( map_x, map_y + 1 ); PutCoastline( map_x - 1, map_y ); PutCoastline( map_x + 1, map_y ); }else{ this.MapUpData[ map_x ][ map_y ] = selected_part; } } //-------------------------------------------------- // 自動海岸線補完 //-------------------------------------------------- void PutCoastline( int x, int y ){ // 領域外 if( x < 0 || y < 0 || x >= width || y >= height ){ return; } // 海岸線を付けないID(これ未満) final int NOT_COAST = 24; // 海のID(これ未満) // 海じゃない場合 if( ToUnsignedByte( MapData[ x ][ y ] ) >= SEA_NUM ){ return; } final int UP = 0x1; final int DOWN = 0x2; final int LEFT = 0x4; final int RIGHT = 0x8; int flag = 0; // 上は海じゃない? if( y >= 1 ){ if( ToUnsignedByte( MapData[ x ][ y-1 ] ) >= NOT_COAST ){ flag |= UP; } } // 下は海じゃない? if( y < height-1 ){ if( ToUnsignedByte( MapData[ x ][ y+1 ] ) >= NOT_COAST ){ flag |= DOWN; } } // 左は海じゃない? if( x >= 1 ){ if( ToUnsignedByte( MapData[ x-1 ][ y ] ) >= NOT_COAST ){ flag |= LEFT; } } // 右は海じゃない? if( x < width-1 ){ if( ToUnsignedByte( MapData[ x+1 ][ y ] ) >= NOT_COAST ){ flag |= RIGHT; } } byte chip = 0; switch( flag ){ // 何もない case 0x00: chip = 0; break; // 左上 case LEFT|UP: chip = 0x01; break; // 上 case UP: chip = 0x02; break; // 右上 case RIGHT|UP: chip = 0x03; break; // 右 case RIGHT: chip = 0x04; break; // 右下 case RIGHT|DOWN: chip = 0x05; break; // 下 case DOWN: chip = 0x06; break; // 左下 case LEFT|DOWN: chip = 0x07; break; // 左 case LEFT: chip = 0x08; break; // 左右 case LEFT|RIGHT: chip = 0x09; break; // 上下 case UP|DOWN: chip = 0x0a; break; // 左上下 case LEFT|UP|DOWN: chip = 0x0b; break; // 上左右 case UP|LEFT|RIGHT: chip = 0x0c; break; // 上下右 case UP|DOWN|RIGHT: chip = 0x0d; break; // 下左右 case DOWN|LEFT|RIGHT: chip = 0x0e; break; // 上下左右 case UP|DOWN|LEFT|RIGHT: chip = 0x0f; break; } MapData[ x ][ y ] = chip; } //-------------------------------------------------- // 通過リスト読み込み 引数:ファイル名、下層=0 or 上層=1 //-------------------------------------------------- void LoadCanWalkList( String file, int mode ){ DebugPrint( file ); try{ InputStream is = new URL( applet.getDocumentBase(), file ).openStream(); // テキストだからリーダーを使う BufferedReader br = new BufferedReader( new InputStreamReader( is ) ); // ライン格納 String line; int i, j; DebugPrint( "walk_load_start" ); // 一行ずつ読み込む int line_num = 0; if( mode == DOWN_LAYER_MODE ){ // 海は通行不可 for( i = 0; i < 0x12; i++ ){ MapDownCell[ i ].SetWalkFlag( 0 ); } i = 0x12; }else{ i = 0; } while( ( line = br.readLine() ) != null ){ for( j = 0; j < line.length(); j++ ){ int value = 0; int element = 0; if( line.charAt( j ) == '1' ){ value = 1; }else if( line.charAt( j ) == '2' ){ value = 2; } // 3はとりあえず通れない設定 else if( line.charAt( j ) == '3' ){ value = 0; } // カウンター属性 else if( line.charAt( j ) == 'c' ){ element = 1; } if( mode == DOWN_LAYER_MODE ){ MapDownCell[ i ].SetWalkFlag( value ); MapDownCell[ i ].SetElement( element ); }else{ MapUpCell[ i ].SetWalkFlag( value ); MapUpCell[ i ].SetElement( element ); } i++; } } MapDownCell[ 33 ].SetElement( 1 ); is.close(); }catch( IOException e ){ DebugPrint( "load_fail" ); } } }