表題の件ですが、
以下のプログラム( DXライブラリ + C++ )を実行して、上下左右キーで移動(スクロール)させると、
DrawDivGraph LoadDivGraphでロードした画像のつなぎ目が目に見える瞬間があります。
#include <DxLib.h>
#include <vector>
// スクリーンサイズ
static const unsigned int SCREEN_W = 640 ;
static const unsigned int SCREEN_H = 480 ;
// 画像サイズ
static const unsigned int GRAPH_W = 32 ;
static const unsigned int GRAPH_H = 32 ;
// 画像分割数
static const unsigned int DIV_X = 2 ;
static const unsigned int DIV_Y = 1 ;
// 移動速度
static const float SPEED = 4.3f ;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// ウィンドウモードで起動
DxLib::ChangeWindowMode( TRUE ) ;
// スクリーンサイズ指定
DxLib::SetGraphMode( SCREEN_W, SCREEN_H, 32 ) ;
// 非フォーカスでも処理します
DxLib::SetAlwaysRunFlag( TRUE ) ;
// ログ出力なし
DxLib::SetOutApplicationLogValidFlag( FALSE ) ;
// DXライブラリ初期化
if( DxLib::DxLib_Init() != 0 ){ return -1 ; }
// 背景色を白に
DxLib::SetBackgroundColor( 255, 255, 255 ) ;
// 描画先を裏画面に設定
DxLib::SetDrawScreen( DX_SCREEN_BACK ) ;
// 画像ハンドル配列
std::vector<int> graphList( DIV_X * DIV_Y, -1 ) ;
/* 【これは実験です】
// 乗算済みアルファにしてみる
DxLib::SetUsePremulAlphaConvertLoad( TRUE ) ;
*/
// 画像ロード(64*32の画像を32*32の画像として分割ロード)
if( DxLib::LoadDivGraph( "graph.png", graphList.size(), DIV_X, DIV_Y, GRAPH_W, GRAPH_H, &*graphList.begin() ) != 0 )
{
::MessageBox( NULL, TEXT( "画像ロード失敗だよ" ), TEXT( "エラー" ), MB_ICONEXCLAMATION | MB_OK ) ;
DxLib::DxLib_End() ;
return -1 ;
}
// 描画開始座標を初期化
float drawX = 0.0f ;
float drawY = 0.0f ;
// ESCキーで終了
while( DxLib::ProcessMessage() == 0 && DxLib::CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
{
// 上下左右で移動
if( DxLib::CheckHitKey( KEY_INPUT_UP ) != 0 )
{
drawY -= SPEED * 1.0f ;
}
else if( DxLib::CheckHitKey( KEY_INPUT_DOWN ) != 0 )
{
drawY += SPEED * 1.0f ;
}
if( DxLib::CheckHitKey( KEY_INPUT_RIGHT ) != 0 )
{
drawX += SPEED * 1.0f ;
}
else if( DxLib::CheckHitKey( KEY_INPUT_LEFT ) != 0 )
{
drawX -= SPEED * 1.0f ;
}
// バイリニアで補間する
DxLib::SetDrawMode( DX_DRAWMODE_BILINEAR ) ;
/* 【これは実験です】
// 乗算済みアルファのアルファブレンドで描画してみる
DxLib::SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ) ;
*/
// 画像を敷き詰める
for( unsigned int i=0, n=SCREEN_H / GRAPH_H; i<n; ++i )
{
const float y = drawY + (float)i * (float)GRAPH_H ;
for( unsigned int j=0, m=SCREEN_W / GRAPH_W; j<m; ++j )
{
const float x = drawX + (float)j * (float)GRAPH_W ;
// float指定で0番目だけを描画する
DxLib::DrawGraphF( x, y, *graphList.begin(), TRUE ) ;
}
}
/* 【これは実験です】
// 乗算済みアルファのアルファブレンドを解除する
DxLib::SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 ) ;
*/
// ニアレストに戻す
DxLib::SetDrawMode( DX_DRAWMODE_NEAREST ) ;
// フリップ
DxLib::ScreenFlip() ;
// 裏画面をクリア
DxLib::ClsDrawScreen() ;
// 適当なウェイト
Sleep( 10 ) ;
}
// DXライブラリの終了処理
DxLib::DxLib_End() ;
// プログラム終了
return 0 ;
}
また、以下を読んだ限りでは、どうにもならないのかもしれないと思っております。
参考URL
http://hpcgi2.nifty.com/natupaji/bbs/pa ... ast&no=899
そこで、私ならではの工夫を考えてみました。
1.敷き詰める際に、微妙に重なるように座標を小細工すれば・・・
⇒座標を変えても画像のつなぎ目部分が消えるわけではないので意味が無かったです。
2.乗算済みアルファを使えばきっと・・・
⇒変化なしでした。
3.Draw時のみ、バイリニア補間をやめる
⇒つなぎ目は見えなくなりますが、描画におけるfloatの恩恵が得られなくなります。
補足)Drawをfloat座標指定で行いかつ、バイリニア補間しないと、
見た目の小数ピクセルを表現できないからカクカクするように感じます。
4.画像ファイル自体を変更してつなぎ目を最も目立たない色に変える
⇒いまのところこれかな。
質問です。
この問題はみなさんどうやって解決されていますか?
質問させていただいた背景としては、
例えば、横スクロールアクションで、キャラクターの移動量がfloatである場合、
背景(に敷き詰めたマップチップ)のスクロール量もfloatだと思うので、
割と普通に立ちはだかる問題なのではないかな、と思ったからです。
移動量が整数(int)なら問題ないですが、
ゲームプログラムでは、移動量が(あるいはキャラクターの座標x,yが)floatであるというのは
特殊ではなく一般的だろう、と考えてのことです。
私の認識に誤りや思い込みがある場合もご指摘くださいm(__)m
【環境】
Visual C++2010 Express Edition
DXライブラリ ver.3.13d
Windows 7 Home Edition 64bit