またご意見をいただきたく投稿いたしました。
現在マップチップをドット単位でスクロールさせようとしているのですが、うまく動作しません
以下の記述では MapData[ y + MapDrawPointY ][ x + MapDrawPointX ]という形で
マップをスクロールさせていますが、これだとチップ単位での移動になってしまいます。
その後に続く DrawGraphの記述をいろいろと試してみましたが、描画される位置が変わるだけで
マップチップ自体がピクセル単位で移動しているわけではありませんでした。
他に、1ピクセルにつきマップチップを1チップとして、マップデータをファイルから読み込むようにしようかとも
思いましたが、いくらなんでもデータを作る手間がかかり過ぎると思い実行しておりません。
以下の記述は製作途中のものです。
右キーを押していると、プレイヤーがマップの中心部へと移動するのですが、
少しずつ座標がずれていってしまい、マップの左側ではマップチップとの衝突判定が起きなくなっています。
また、プレイヤーの上下の移動に対してもまだ補正を記述しておりません。
ですが、今そこの帳尻を合わせても、マップチップがピクセル単位で動かなければ
結局書き直すことになるだろうと思い、失礼ですが中途半端な状態で投稿させていただきました。
最終的には聖○伝説2のような上下左右に動くアクションRPGのようにしたいと思っています。
何かヒントをいただければ幸いです。
よろしくお願いいたします。
#include "DxLib.h"
#define MAP_SIZE 64 // マップチップ一つのドットサイズ
#define WINDOW_WIDTH 960 //ウインドウの大きさ
#define WINDOW_HEIGHT 704
#define MAP_WIDTH 20 // マップの幅
#define MAP_HEIGHT 16 // マップの縦長さ
#define idou 16//プレイヤーの移動距離
// マップのデータ
int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
{ 0, 1, 1, 0, 0, 0, 1, 0, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 0, 0, 1, 1, 1, 0, 1, 0, 0, 0 , 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
{ 0, 0, 1, 0, 1, 0, 1, 0, 0, 0 , 1, 1, 1, 1, 1, 1, 0, 0, 1, 0 } ,
{ 0, 1, 1, 0, 1, 0, 1, 1, 1, 0 , 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 } ,
{ 0, 1, 0, 0, 1, 1, 1, 1, 1, 0 , 0, 0, 1, 1, 1, 1, 1, 0, 1, 0 } ,
{ 0, 1, 0, 0, 1, 0, 1, 1, 1, 1 , 1, 1, 1, 1, 1, 1, 1, 0, 1, 0 } ,
{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 , 0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 , 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 , 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 , 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 , 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 1 , 1, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
} ;
// プレイヤーの位置
int PlayerX , PlayerY ;
//プレイヤーのドット上の位置
int P_D_PointX,P_D_PointY;
// 描画するマップ座標値
int MapDrawPointX , MapDrawPointY ;
//プレイヤーのカメラ内の座標
//マップが動かないときはこれを用いてプレイヤー座標を動かす
int P_DrawX,P_DrawY;
//カメラ内でのマップチップに対しての座標
//またマップチップへの判定を判断する座標はこれに集約される
int coordinateX,coordinateY;
//方向キー入力の番号
int houkou;
//デバッグ文字列の色
int ty;
//プレイヤーがマップの中間を移動した分
//(カメラの移動分)
int Camera_Move_X,Camera_Move_Y;
// プレイヤーの描画関数
void P_Draw(void)
{
DrawBox( (( PlayerX - MapDrawPointX )+ P_DrawX ) ,
(( PlayerY - MapDrawPointY )+ P_DrawY ) ,
(( PlayerX - MapDrawPointX + MAP_SIZE ) + P_DrawX ) ,
(( PlayerY - MapDrawPointY + MAP_SIZE ) + P_DrawY ) ,
GetColor( 0 , 125 , 255 ) ,
TRUE ) ;//8,6
}
// マップの描画関数
void GraphDraw( void )
{
int x , y ;
int DrawMapChipNumX , DrawMapChipNumY ; // 描画するマップチップの数
DrawMapChipNumX = WINDOW_WIDTH + MAP_SIZE ;//1024
DrawMapChipNumY = WINDOW_HEIGHT+ MAP_SIZE ;//768
MapDrawPointX = PlayerX +(Camera_Move_X/MAP_SIZE)- DrawMapChipNumX / 2 ;//512-1024/2
MapDrawPointX = PlayerX +(Camera_Move_X/MAP_SIZE)- DrawMapChipNumX / 2 ;//512-1024/2
// マップを描く
for( y = 0 ; y < DrawMapChipNumY ; y ++ )
{
for( x = 0 ; x < DrawMapChipNumX ; x ++ )
{
// 画面からはみ出た位置なら描画しない
if( x + MapDrawPointX < 0 || y + MapDrawPointY < 0 ||
x + MapDrawPointX >= MAP_WIDTH || y + MapDrawPointY >= MAP_HEIGHT ) continue ;
// マップデータが0だったら四角を描画する
if( MapData[ y + MapDrawPointY ][ x + MapDrawPointX ] == 0 )
{
DrawBox( x * MAP_SIZE ,
y * MAP_SIZE ,
x * MAP_SIZE + MAP_SIZE ,
y * MAP_SIZE + MAP_SIZE ,
GetColor( 255 , 0 , 0 ) ,
TRUE ) ;
}
}
}
}
//描画されていないだけで、マップ自体は隣接している
//そしてマップ自体は無限ループしている
// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
int Key ;
int OldX , OldY ; // 移動する前のプレイヤーの位置を保存する変数
ty = GetColor(255,255,255);
//デスクトップの解像度にあわせると、自動で全画面になる
SetGraphMode( WINDOW_WIDTH , WINDOW_HEIGHT , 16 ) ;
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
// 描画先画面を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// プレイヤーの初期位置をセット
PlayerX = 8 *64;
PlayerY = 6 *64;
//プレイヤーのカメラ内での初期位置をセット
P_DrawX = 0;
P_DrawY = 0;
// ループ
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
{
// 画面を初期化
ClearDrawScreen() ;
// キー入力を得る
Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;
// 移動する前のプレイヤーの位置を保存
OldX = coordinateX ;
OldY = coordinateY ;
//左キーの記述
if( Key & PAD_INPUT_LEFT )
{
houkou =1;
//もしマップチップの座標Xが0で
//カメラ内でのX位置が0の場合
//左側
if( MapDrawPointX == 0
&& P_DrawX <1)
{
P_DrawX -= idou;
}
//中心
else if( MapDrawPointX > 0
&& P_DrawX ==0)
{
PlayerX -= idou;
}
//右側
else if(MapDrawPointX == 5
&& P_DrawX > 0)
{
P_DrawX -= idou;
}
}
//右キーの記述
else if( Key & PAD_INPUT_RIGHT )
{
houkou = 2;
//もしマップチップの座標が0,0で
//カメラ内での位置が0,0のばあい
//左側
if( MapDrawPointX == 0
&& P_DrawX < 0)
{
P_DrawX += idou;
}
//中心
else if( MapDrawPointX < 5
&& P_DrawX > -1)
{
Camera_Move_X+= idou ;
//PlayerX += idou ;
}
//右側
else if( MapDrawPointX == 5
&& P_DrawX > -1)
{
P_DrawX += idou;
}
}
//後に訂正
//上キーの記述
else if( Key & PAD_INPUT_UP )
{
houkou = 3;
//上側
if(MapDrawPointY == 0
&& P_DrawY < 1)
{
P_DrawY -= idou ;
}
//中心
else if(MapDrawPointY < 6
&& P_DrawY == 0)
{
PlayerY -= idou ;
}
//下側
else if(MapDrawPointY == 5
&& P_DrawY > 0)
{
P_DrawY -= idou;
}
}
//下キーの記述
else if( Key & PAD_INPUT_DOWN )
{
houkou = 4;
//上側
if( MapDrawPointY == 0
&& P_DrawY < 0)
{
P_DrawY += idou ;
}
//中心
else if( MapDrawPointY < 5
&& P_DrawY == 0)
{
PlayerY += idou;
}
//下側
else if(MapDrawPointY == 5
&& P_DrawY > -1)
{
P_DrawY += idou ;
}
}
//座標の確認1
coordinateX = (PlayerX + P_DrawX)/MAP_SIZE;
coordinateY = (PlayerY + P_DrawY)/MAP_SIZE;
// 進入不可能なマップだった場合は移動できない
if( MapData[ coordinateY ][ coordinateX ] == 0 )
{
if(houkou == 1)
{
P_DrawX += idou ;
}
else if(houkou == 2)
{
P_DrawX -= idou ;
}
else if(houkou == 3)
{
P_DrawY += idou ;
}
else if(houkou == 4)
{
P_DrawY -= idou ;
}
}
// マップを描画
GraphDraw() ;
//プレイヤーを描画
P_Draw();
//デバッグ用記述
//カメラ内でのプレイヤーのドット上での位置
P_D_PointX = (PlayerX + P_DrawX - MapDrawPointX) ;
P_D_PointY = (PlayerY + P_DrawY - MapDrawPointY);
//デバッグ文字列
//マップチップ上でのカメラの中心
DrawString(0,20,"マップチップ上でのカメラの中心",ty);
DrawFormatString(0,40,ty,"PlayerX%d",PlayerX);
DrawFormatString(0,60,ty,"PlayerY%d",PlayerY);
//カメラに移っているマップチップの描画ポイント
DrawString(0,100,"カメラに移っているマップチップの描画ポイント",ty);
DrawFormatString(0,120,ty,"MapDrawPointX%d",MapDrawPointX);
DrawFormatString(0,140,ty,"MapDrawPointY%d",MapDrawPointY);
//カメラが止まっているときのカメラの中心からのプレイヤーの描画位置位置
DrawString(0,180,"カメラが止まっているときのカメラの中心からのプレイヤーの描画位置位置",ty);
DrawFormatString(0,200,ty,"P_DrawX%d",P_DrawX);
DrawFormatString(0,220,ty,"P_DrawY%d",P_DrawY);
//マップチップ上でのプレイヤーの位置
DrawString(0,260,"マップチップ上でのプレイヤーの位置",ty);
DrawFormatString(0,280,ty,"coordinateX%d",coordinateX);
DrawFormatString(0,300,ty,"coordinateY%d",coordinateY);
//カメラ内でのプレイヤーのドット上での位置
DrawString(0,340,"カメラ内でのプレイヤーのドット上での位置",ty);
DrawFormatString(0,360,ty,"P_D_PointX%d",P_D_PointX);
DrawFormatString(0,380,ty,"P_D_PointY%d",P_D_PointY);
// 裏画面の内容を表画面に映す
ScreenFlip() ;
// ウエイト
WaitTimer( 100 ) ;
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}