前回の質問では大変お世話になりました。
今回も宜しくお願い致します。
以下のコードでは、テキストファイルにマップのサイズ、マップチップ配列、
そして移動先のマップの書かれたテキストファイル名を記述し、
特定のマップチップに接触した場合、あらかじめポインタに設定しておいた、
移動先のマップの書かれたテキストファイル名を呼び出し、
そのマップデータを描画するというものです。
使用するテキストファイルの内容は一番下に記載させていただきました。
ビルドは通りますが、デバッグ中に移動するためのチップに接触すると
致命的なエラー、またはハンドルされていない例外が発生してしまいます。
原因としては、80行目のstrtokで、移動先のマップが書かれたテキストファイル名を
読み込めていないのではないかと思います。
また、293行目で文字列を表示させようとすると文字化けが起きてしまうため、
そもそものポインタの扱いが間違っているのかもしれません。
そこで質問なのですが、ポインタで文字列を扱う場合、配列を使用すると思うのですが、
strtokで分割したトークンをさらに1文字ずつに分けて、配列に格納していくことは可能なのでしょうか。
それともそこまでややこしいことをする必要はなく、単にポインタの扱いを間違っているだけなのでしょうか。
また文字化けの原因についてもご教授いただけたらと思います。
宜しくお願い致します。
#include "DxLib.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
//ウインドウの横と縦の大きさ
#define GAME_WINDOW_WIDTH 640//32*20
#define GAME_WINDOW_HEIGHT 480//32*15
#define MAPCHIP_SIZE 32//マップチップサイズ
#define LINE_1 256//動的擬似に次元配列の実験用定数
int mapSizeY,mapSizeX;//読み取ったマップのサイズ
int make_sure_of_memori;//メモリ確保の可否
//メモリ確保のための変数
int **MapData;//ダブルポインタの宣言
int i,j;//LoadMapFile内で使用、forのカウント用、メモリの確保用
int l,k;//Mapchipdraw内で使用、forのカウント用
int pox,poy;//配列を代入するときのカウント用
//マップデータ読み込み許可の有無
int load;//0:on,1:off
//マップデータ変更許可の有無
int MapChengAct;//0:on,1:off
int x,y;//マップチップ描画の際のカウント用
int tate,yoko;//プレイヤーの座標
int Direction;//移動ボタンの方向別適用動作
int MFC;//メモリ開放の際のカウント用
//どの出口から出たかを決める
//これによりどのマップへ移動するか(どのマップを読み込むか)を決める
int InChip;
//マップチップ描画時のプレイヤー座標の再設定の可否
int PlayerPositionFirstSetting;//0:on,1:off
//各出口の行き先を格納する変数の実体の宣言
//マップデータの読み込みと割り当て時に使用
char *P_ExitChip[1];//ポインタ。[1]を追加
//マップデータを入れる場所
char *P_DataFilePointer[1];//ポインタ。[1]を追加
char *SCRIPT_FILENAME;
//****************************関数一覧*********************
//プレイヤーの描画
void PlayerDraw()
{
DrawBox(yoko,
tate,
yoko+MAPCHIP_SIZE,
tate+MAPCHIP_SIZE,
GetColor(100,100,100),
TRUE);
}
//ファイルの読み込み、振り分け、メモリの確保
void ReadMapDataFile( char* Filename)
{
char line[LINE_1];
poy = 0;//DATAの行数
int make_sure_of_memori;//メモリの確保の可否
make_sure_of_memori= 0;
FILE*mapFile;
mapFile = fopen(Filename,"r");
while (fgets(line,LINE_1,mapFile))
{
char*words =strtok(line,",");
if(strcmp("MAP_SIZE",words) == 0 )//マップサイズの読み込み
{
mapSizeY = atoi(strtok(NULL,","));
mapSizeX = atoi(strtok(NULL,","));
}
else if(strcmp("ExitChip",words) == 0 )//出入り口の行き先
{
P_ExitChip[0] = strtok(NULL,",");//[0]を追加
}
else if(strcmp("DATA",words) == 0 )//マップチップ配列の読み込み
{
if(make_sure_of_memori == 0)
{
//y軸のメモリの確保
MapData = new int *[mapSizeY];
//x軸のメモリの確保
for(i = 0; i < mapSizeY; i++)
{
MapData[i] = new int[mapSizeX];
//値の設定
for (j = 0;j < mapSizeX; j++)
{
MapData[i][j] = 0;
}
}
//二回目以降はメモリの確保を繰り返さない
make_sure_of_memori = 1;
}
//x軸に列の内容をstrtokで読み込ませる
for(pox = 0; pox < mapSizeX; pox++)
{
MapData[poy][pox] = atoi(strtok(NULL,","));
}
poy++;
}
}
//ファイルを閉じる
fclose(mapFile);
}
//プレイヤーの移動・上下のみ
void Player_Act()
{
int idou;//プレイヤーの移動距離は1
idou = 1;xn--u9ja4nvhmc2b4gv462a8g1a8n0b2yqgr8cwrya
int idou_count;
int P_Idou_Stetus;
Direction = 0;//プレイヤーを静止状態にする
if(CheckHitKey( KEY_INPUT_UP ) == 1 )//上ボタン
{
Direction = 3;
P_Idou_Stetus = 8;//歩数
}
else if(CheckHitKey( KEY_INPUT_DOWN ) == 1 )//下ボタン
{
Direction = 4;
P_Idou_Stetus = 8;//歩数
}
//////////////////////////////////////////////////////////////
//上ボタンが押されたら
if( Direction == 3 )//if( CheckHitKey( KEY_INPUT_UP ) == 1 )
{
for(idou_count = 0;idou_count<P_Idou_Stetus;idou_count++)
{
//ここから移動チップに対する記述
//上は北、チップは4
if(MapData[(tate-idou)/32][yoko/32] == 4 ||MapData[(tate-idou)/32][(yoko + 31)/32] == 4 )
{
//マップ移動先に北側のマップデータを設定する
//どの出口から出たか
InChip = 1;
//マップ変更関数を許可
MapChengAct = 0;//0:on,1:off
//マップ移動後の初期座標の設定の許可
PlayerPositionFirstSetting= 0;//0:on,1:off
}
//マップチップ0以外の場合
else if(MapData[(tate - idou)/32][yoko/32] != 0 && MapData[(tate - idou)/32][(yoko + 31)/32] != 0)
{
tate -= idou;
}
}
}
////////////////////////////////////////////////////////
////下ボタンが押されたら
if( Direction == 4 )//if( CheckHitKey( KEY_INPUT_DOWN ) == 1 )
{
for(idou_count = 0;idou_count<P_Idou_Stetus;idou_count++)
{
//ここから移動チップに対する記述
//下は南、チップ5
if(MapData[(tate+31+idou)/32][yoko/32] == 5 ||MapData[(tate+31+idou)/32][(yoko + 31)/32] == 5 )
{
InChip = 2;//どこの出口から出たか
//マップ変更の許可
MapChengAct = 0;//0:on,1:off
//マップ移動後の初期座標の設定の許可
PlayerPositionFirstSetting= 0;//0:on,1:off
}
//////////////////////////////////////////////////
//進む先の座標が0、または2ではないか && となりの座標にかぶってないか
else if(MapData[(tate + 31 + idou)/32][yoko/32] !=0 && MapData[(tate + 31 + idou)/32][(yoko + 31)/32] != 0)
{
tate += idou;
}
}
}
///////////////////////////////////////////////////////////
}//
//マップチップの描画
void MapChipDraw()
{
for(y = 0; y < mapSizeY; y++)
{
for(x = 0; x < mapSizeX;x++)
{
if(MapData[y][x]==0)
{
DrawBox(x*MAPCHIP_SIZE,
y*MAPCHIP_SIZE,
x*MAPCHIP_SIZE+MAPCHIP_SIZE,
y*MAPCHIP_SIZE+MAPCHIP_SIZE,
GetColor(255,255,255),
TRUE);
}
//マップ移動時のプレイヤーの初期座標設定
//ここでのマップごとの初期座標(出口)の設定はデータを読み込んだ初回のみとする
if(PlayerPositionFirstSetting == 0)
{
//どこから入ったか、そしてどこから出るか
if( InChip == 2 && MapData[y][x]==5)//南口、北マップからの移動、移動先は北口
{
tate = y*MAPCHIP_SIZE-MAPCHIP_SIZE;
yoko = x*MAPCHIP_SIZE;
}
//InChip == 2(北口から)
else if( InChip == 1 && MapData[y][x]==4)//北口、南マップからの移動、出口は南口
{
tate = y*MAPCHIP_SIZE+MAPCHIP_SIZE;
yoko = x*MAPCHIP_SIZE;
}
//スイッチをoffにする
PlayerPositionFirstSetting = 1;
}
}
}
}
//確保したメモリの開放
void MapMemorieClear()
{
for(MFC=0;MFC<mapSizeY; MFC++)
{
delete[]MapData[MFC];
}
delete[]MapData;
}
//メイン
int WINAPI WinMain( HINSTANCE hInstace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
//**********************セッティング***********************
ChangeWindowMode( TRUE );//ウィンドウモードで起動
//画面の大きさは800 * 600
SetGraphMode( GAME_WINDOW_WIDTH, GAME_WINDOW_HEIGHT, 16 ) ;
//DxLib初期化
if( DxLib_Init() == -1 )
{
return -1;
}
SetDrawScreen( DX_SCREEN_BACK );
//*********************************************************
//**********************初期設定***************************
tate = 64;
yoko = 64;
load = 0;//0:on,1:off
MapChengAct=1;//0:on,1:off
Direction = 0;
SCRIPT_FILENAME = "map.txt";
P_DataFilePointer[0] = SCRIPT_FILENAME;//アドレスの格納、[0]を追加
//*********************************************************
while(CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
ClearDrawScreen();
//1-******************マップデータの読み込みと設定******************
if(load == 0)
{
ReadMapDataFile(P_DataFilePointer[0]);//[0]を追加
load = 1;
}
//2-*****************データ内容の描画*********************
//マップチップの描画
MapChipDraw();//マップ変更時のプレイヤーの初期座標設定
Player_Act();//プレイヤーの移動、および座標計算
PlayerDraw();//プレイヤーの描画
DrawFormatString(0,80,GetColor(255,100,255),"Now%s",P_DataFilePointer[0]);
DrawFormatString(0,100,GetColor(255,150,255),"Next%s",P_ExitChip[0]);
//P_ExitChipが文字化け
//3-*****************読み込むマップデータの差し替え******************
if(MapChengAct==0)
{
MapMemorieClear();//メモリのクリア
*P_DataFilePointer[0] = *P_ExitChip[0];//訂正した
/*
致命的なエラーが検出される
*/
//strcpy(P_DataFilePointer[0],P_ExitChip[0]);
/*
こちらのstrcpyを使うとハンドルされていない例外が発生する
*/
MapChengAct=1;//差し替えスイッチのオフ
load = 0;//マップデータの読み込みを許可
}
ScreenFlip();
WaitTimer(20);
}
DxLib_End();
return 0;
}
***********map.txt***********
MAP_SIZE,5,5,
ExitChip,map2,
DATA,0,0,4,0,0,
DATA,0,1,1,1,0,
DATA,0,1,1,1,0,
DATA,0,1,1,1,0,
DATA,0,0,0,0,0,
***********map2.txt**********
MAP_SIZE,10,10,
ExitChip,map,
DATA,0,0,0,0,0, 0,0,0,0,0,
DATA,0,1,1,1,1, 1,1,1,1,0,
DATA,0,1,1,1,1, 1,1,1,1,0,
DATA,0,1,1,1,1, 1,1,1,1,0,
DATA,0,0,5,0,0, 0,0,0,0,0,
*/