今回もいまいちうまくできないところがありますので,アドバイスをいただきたいと思います。
(他の方による似たような質問が存在しますが,それとは別の問題と思われます)
マップスクロールのループを実装したかったので,このプログラム
を改変したのですが,
マップスクロール自体はループするのですが,右と下は滑らかに動くのに対し,
左と上に動かした場合は画面の左端および上端が「カクカクッ」といった感じの動きをしてしまいます。
ウィンドウ外の部分も描画するようにすれば良いのでしょうか?
(x:1~15,y:1~11をウィンドウに表示するとして,x:0~16,y:0~12を描画するようにする感じです)
先週に引き続いて質問をしてすみませんが,アドバイスをいただけるとありがたいです。
どうかよろしくお願いいたします。
ソース:(後でC#用に書き直します。)
#include "DxLib.h"
#define MAP_SIZE 48 // マップチップ一つのドットサイズ
#define MAP_WIDTH 20 // マップの幅
#define MAP_HEIGHT 16 // マップの縦長さ
#define MOVE_FRAME 6 // 移動にかけるフレーム数
// マップのデータ
int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 , 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 } ,
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ,
{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 , 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 } ,
{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 , 1, 1, 1, 1, 1, 1, 0, 0, 1, 0 } ,
{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0 , 0, 1, 0, 0, 0, 1, 0, 0, 1, 0 } ,
{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 , 0, 1, 1, 1, 1, 1, 1, 0, 1, 0 } ,
{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 , 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 , 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 1 , 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 , 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 } ,
} ;
int View[13][17]={
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,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 X=7,Y=5; //
bool loop=true;
// 移動しているかどうかのフラグ( 0:停止中 1:移動中 )
int Move ;
// 各方向に移動する量
int MoveX, MoveY ;
// 移動し始めてから何フレーム経過したかを保持する変数
int MoveCounter ;
// マップとプレイヤーの描画関数
void GraphDraw( int ScrollX, int ScrollY )
{
int j , i ;
int MapDrawPointX , MapDrawPointY ; // 描画するマップ座標値
int DrawMapChipNumX , DrawMapChipNumY ; // 描画するマップチップの数
// 描画するマップチップの数をセット
DrawMapChipNumX = 17 ;
DrawMapChipNumY = 13 ;
// 画面左上に描画するマップ座標をセット
MapDrawPointX = PlayerX - ( DrawMapChipNumX / 2 - 1 ) ;
MapDrawPointY = PlayerY - ( DrawMapChipNumY / 2 - 1 ) ;
// マップを描く
for( i = -1 ; i < 12 ; i ++ ){
for( j =-1 ; j < 16 ; j ++ ){
// 画面からはみ出た位置なら描画しない
// マップデータが0だったら四角を描画する
if( View[i][j] == 0 ){
DrawBox(j * MAP_SIZE + ScrollX,i * MAP_SIZE + ScrollY,
j * MAP_SIZE + MAP_SIZE + ScrollX, i * MAP_SIZE + MAP_SIZE + ScrollY,
GetColor( 255 , 0 , 0 ) , TRUE ) ;
}
}
}
// プレイヤーの描画
DrawBox( ( PlayerX - MapDrawPointX ) * MAP_SIZE , ( PlayerY - MapDrawPointY ) * MAP_SIZE ,
( PlayerX - MapDrawPointX + 1 ) * MAP_SIZE , ( PlayerY - MapDrawPointY + 1 ) * MAP_SIZE ,
GetColor( 255 , 255 , 255 ) , TRUE ) ;
for(int b=0;b<13;b++){
for(int a=0;a<17;a++){ View[b][a]=MapData[(PlayerY+MAP_HEIGHT+(b-5))%MAP_HEIGHT][(PlayerX+MAP_WIDTH+(a-7))%MAP_WIDTH];
DrawFormatString(23+a*48,23+b*48,GetColor(0,255,255), "%d", View[b][a]);}
}
}
// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
int Key ;
int a,b;
int ScrollX, ScrollY ;
SetGraphMode( 720 ,524, 16 ) ;
ChangeWindowMode(TRUE);
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
// 描画先画面を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// プレイヤーの初期位置をセット
PlayerX = 2 ;
PlayerY = 2 ;
// 最初は停止中(0)にしておく
Move = 0 ;
for(b=0;b<11;b++){
for(a=0;a<=15;a++){ View[b][a]=MapData[(PlayerY+MAP_HEIGHT+(b-5))%MAP_HEIGHT][(PlayerY+MAP_WIDTH+(a-7))%MAP_WIDTH];
DrawFormatString(a*64,b*64,GetColor(0,0,255), "[%d]", View[b][a]);}
}
// ループ
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
{
// 画面を初期化
ClearDrawScreen() ;
// 移動中ではない場合キー入力を受け付ける
if( Move == 0 ){
// キー入力を得る
Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;
// キー入力に応じてプレイヤーの座標を移動
if( Key & PAD_INPUT_LEFT ) { Move = 1 ; MoveX = -1 ; MoveY = 0 ; }
if( Key & PAD_INPUT_RIGHT ){ Move = 1 ; MoveX = 1 ; MoveY = 0 ; }
if( Key & PAD_INPUT_UP ) { Move = 1 ; MoveX = 0 ; MoveY = -1 ; }
if( Key & PAD_INPUT_DOWN ) { Move = 1 ; MoveX = 0 ; MoveY = 1 ; }
// 進入不可能なマップだった場合は移動できない
if( Move == 1 ){
if( View[ 5 + MoveY ][ 7+ MoveX ] == 0 ){Move = 0 ; }
else{ MoveCounter = 0 ;}
}
// 停止中は画面のスクロールは行わない
ScrollX = 0 ;
ScrollY = 0 ;
}
// 移動中の場合は移動処理を行う
if( Move == 1 ){
MoveCounter ++ ;
// 移動処理が終了したら停止中にする
if( MoveCounter == MOVE_FRAME )
{
Move = 0 ;
// プレイヤーの位置を変更する
PlayerX =(PlayerX+(MAP_WIDTH+MoveX))% MAP_WIDTH ;
PlayerY =(PlayerY+(MAP_HEIGHT+MoveY))% MAP_HEIGHT ;
// 停止中は画面のスクロールは行わない
ScrollX = 0 ;
ScrollY = 0 ;
}
else
{
// 経過時間からスクロール量を算出する
ScrollX = -( MoveX * MAP_SIZE * MoveCounter / MOVE_FRAME ) ;
ScrollY = -( MoveY * MAP_SIZE * MoveCounter / MOVE_FRAME ) ;
}
}
//ウィンドウ
for(b=0;b<11;b++){
for(a=0;a<=15;a++){ View[b][a]=MapData[(PlayerY+MAP_HEIGHT+(b-5))%MAP_HEIGHT][(PlayerX+MAP_WIDTH+(a-7))%MAP_WIDTH]; }
}
// マップとプレイヤーを描画
GraphDraw( ScrollX, ScrollY ) ;
// 裏画面の内容を表画面に映す
ScreenFlip() ;
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}