640×480の画面に対し、800×480のマップ画面を用意して
キャラクタが動いたら横スクロールさせていきたいです。
試しに画面の中央320からキャラクタの移動した距離でスクロール量を算出してみたのですが
スクロール+キャラクタの移動で2歩ずつ歩いてしまいます。
スクロール量が1以上の時は、キャラクタの位置を補正すればいいのか?と考えましたが
キャラクタの位置からスクロール量を算出しているため上手くいきませんでした。
最初はx方向のスクロールを行い次にy方向のスクロールも実施してみたいです。
マップスクロールの考え方についてご指導をお願いします
► スポイラーを表示
#include "DxLib.h"
#include<string>
#include<sstream>
#define WindowSize 640
using namespace std;
//キャラクターデータ
typedef struct Character{
int x;
int y;
int image[16];
bool bWalkFlag;
int nCharDirection;//向き
int nCharDrawHandle;//画像
}CharData;
//マップ定義
int Block[15][25] ={4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,
7,0,2,3,0,2,0,2,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,
7,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,
7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,
10,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9};
int CheckWalk(CharData cd,int nScroll){
//上向き
if(cd.nCharDirection == 0){
if(Block[(cd.y / 32 - 1)][cd.x / 32 + nScroll] != 0)return 1;
}
//下向き
if(cd.nCharDirection == 2){
if(Block[(cd.y / 32 + 1)][cd.x / 32 + nScroll] != 0)return 1;
}
//右向き
if(cd.nCharDirection == 3){
if(Block[(cd.y / 32)][(cd.x/32+1)+nScroll] != 0) return 1;
}
//左向き
if(cd.nCharDirection == 1){
if(Block[(cd.y / 32)][(cd.x/32-1)+nScroll] != 0 ) return 1;
}
return 0;
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
CharData player;
char Key[256];
const char *lpCharImage ="画像/char01.png";
const char *lpMapImage ="画像/maptip.png";
const char *lpMapImage2 ="画像/map2.png";
const char *lpMapImage3 ="画像/map3.png";
int nMapHandle[9];
int nMapHandle2 = LoadGraph(lpMapImage2,true);
int nMapHandle3 = LoadGraph(lpMapImage3,true);
LoadDivGraph(lpMapImage,9,3,3,32,32,nMapHandle,true);
LoadDivGraph(lpCharImage,16,4,4,32,32,player.image,0);
player.x=320;
player.y=32;
player.nCharDirection = 0;
int nBlock_x,nBlock_y;
int nScroll =0;
nBlock_y = sizeof(Block)/sizeof(Block[0]);//行数の取得
nBlock_x = sizeof(Block[0]) / sizeof(Block[0][0]);//列数の取得
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
GetHitKeyStateAll( Key ) ;
//スクロールデータの計算(仮定義)//
int nChar = WindowSize / 2;//キャラ中央位置
if((player.x - nChar) / 32 == 1) nScroll = 1;
else if((player.x - nChar) / 32 == 2) nScroll = 2;
else if((player.x - nChar) / 32 == 3) nScroll = 3;
else if((player.x - nChar) / 32 == 4) nScroll = 4;
else if((player.x - nChar) / 32 == 5) nScroll = 5;
else if((player.x - nChar) /32 == 0) nScroll = 0;
//マップの描写
for(int x = 0;x < (nBlock_x * 32) / 32;++x){
for(int n = 0;n < (nBlock_y * 32) / 32;++n){
DrawGraph(x*32 - 32 * nScroll,n*32,nMapHandle[4],true);
if(Block[n][x] == 2) DrawGraph(x*32 - 32 * nScroll,n*32,nMapHandle2,true);
else if(Block[n][x] == 3) DrawGraph(x*32 - 32*nScroll,n*32,nMapHandle3,true);
else if(Block[n][x] == 4) DrawGraph(x*32 - 32*nScroll,n*32,nMapHandle[0],true);
else if(Block[n][x] == 5) DrawGraph(x*32 - 32*nScroll,n*32,nMapHandle[1],true);
else if(Block[n][x] == 6) DrawGraph(x*32 - 32*nScroll,n*32,nMapHandle[2],true);
else if(Block[n][x] == 7) DrawGraph(x*32 - 32*nScroll,n*32,nMapHandle[3],true);
else if(Block[n][x] == 8) DrawGraph(x*32 - 32*nScroll,n*32,nMapHandle[7],true);
else if(Block[n][x] == 9) DrawGraph(x*32 - 32 * nScroll,n*32,nMapHandle[8],true);
else if(Block[n][x] == 10) DrawGraph(x*32 - 32 * nScroll,n*32,nMapHandle[6],true);
else if(Block[n][x] == 11) DrawGraph(x*32 - 32 * nScroll,n*32,nMapHandle[5],true);
}
}
//キャラ移動入力
if(player.x % 32 == 0 && player.y %32 == 0){
if(Key[KEY_INPUT_UP] == 1){//上
player.nCharDirection = 0;
player.bWalkFlag = true;
}
else if(Key[KEY_INPUT_DOWN] == 1){
player.nCharDirection = 2;//下
player.bWalkFlag = true;
}
else if(Key[KEY_INPUT_RIGHT] == 1){
player.nCharDirection = 3;//右
player.bWalkFlag = true;
}
else if(Key[KEY_INPUT_LEFT] == 1){
player.nCharDirection = 1;//左
player.bWalkFlag = true;
}else{
player.bWalkFlag = false;
}
if(player.bWalkFlag == true){
if(CheckWalk(player,nScroll) == 1) player.bWalkFlag = false;
}
}
if(player.bWalkFlag == true){
if(player.nCharDirection == 0) player.y--;//上
else if(player.nCharDirection == 2) player.y++;//下
else if(player.nCharDirection == 3) player.x++;//右
else if(player.nCharDirection == 1) player.x--;//左
}
string str,str2,str3;
stringstream ss,ss2,ss3;
ss << "座標 X = " << player.x << "座標 Y = " << player.y;
str = ss.str();
DrawString(0,0,str.c_str(),RGB(255,255,255),true);
player.nCharDrawHandle = player.image[(player.x % 32 + player.y % 32) / 8 + player.nCharDirection * 4];
ss2 << "画像データ = " << (player.x % 32 + player.y % 32) / 8 + player.nCharDirection * 4;
str2 = ss2.str();
DrawString(300,0,str2.c_str(),RGB(255,255,255),true);
ss3 << "スクロール量 = " << nScroll;
str3 = ss3.str();
DrawString(500,0,str3.c_str(),RGB(255,255,255),true);
DrawGraph(player.x,player.y,player.nCharDrawHandle,true);
}
DxLib_End(); // DXライブラリ終了処理
return 0;
}