DXライブラリを使ってRPG作りに挑戦しています。
現在、キャラの移動に伴ってマップをスクロールさせる部分のコードを書いています。
キー入力とキャラの入力に関しては、ゲームプログラミングの館の「キャラを4方向に歩かせる」のところを参考にさせていただきました。
Char_Moveでキー入力に従ってキャラの向きを変えて、読み込むマップの左上座標を変更しています。
Char_Drawでキャラを描画しています。
本来はキー入力でキャラを動かす処理だったんですが、キャラは真ん中に固定して、変わりにマップを動かしてキャラが動いてるように見せてます。
「座標が32で割り切れたら入力可能」の部分はいらないかなと思ったんですが消してません・・・後々いじろうかなと思ってます。
#include "charmove.h"
#include "DxLib.h"
int image[16];
ch_t ch = {320,160,0,3};
char Key[256];
DWORD mapend_x = 0;
DWORD mapend_y = 0;
void Char_Move(void)
{
if(ch.x%32==0 && ch.y%32==0){ //座標が32で割り切れたら入力可能
ch.walking_flag=1; //歩くフラグを立てる。
if ( Key[ KEY_INPUT_UP ] == 1 ) //上ボタンが押されたら
ch.muki=0; //上向きフラグを立てる
else if( Key[ KEY_INPUT_LEFT ] == 1 ) //左ボタンが押されたら
ch.muki=1; //左向きフラグを立てる
else if( Key[ KEY_INPUT_DOWN ] == 1 ) //下ボタンが押されたら
ch.muki=2; //下向きフラグを立てる
else if( Key[ KEY_INPUT_RIGHT] == 1 ) //右ボタンが押されたら
ch.muki=3; //右向きフラグを立てる
else //何のボタンも押されてなかったら
ch.walking_flag=0; //歩かないフラグを立てる
}
if(ch.walking_flag==1){ //歩くフラグが立っていたら
if (ch.muki==0 && mapend_y!=0) //上向きなら
mapend_y--;
else if(ch.muki==1 && mapend_x!=0) //左向きなら
mapend_x--;
else if(ch.muki==2 && mapend_y!=480) //下向きなら
mapend_y++;
else if(ch.muki==3 && mapend_x!=640) //右向きなら
mapend_x++;
}
}
void Char_Draw(void)
{
ch.img=image[(ch.x%32+ch.y%32)/8 + ch.muki*4]; //画像をセット
DrawGraph( ch.x , ch.y , ch.img , TRUE ) ;//画像を描画
}
マップのデータはplatinumを使って作りました。
fmfファイルからのデータの読み込みとマップの描画の部分に関しては
softyaさんの簡単RPG講座
http://dixq.net/forum/blog.php?u=114&b= ... させていただきました。
Map_Loadでfmfファイルを開いてマップ情報を得ています。
Map_Drawでマップを描画します。
マップの端っこまで来たらマップを動かさずにキャラの位置を動かすようにしする処理とかはほったらかしにしてます。
まずはスクロールさせてみたかったので・・・。
#include "DxLib.h"
#include "fmfmap.h"
#include "map.h"
CFmfMap map;
void Map_Load(const char *MapName) //FMFファイルを開いてマップ情報を得る
{
map.Open(MapName);
}
void Map_Draw(int px , int py,int MTHandle) //マップを描画。引数は描画する範囲の左上座標。
{
int chipW = map.GetChipWidth(); //チップの横幅(ピクセル)
int chipH = map.GetChipHeight(); //チップの縦幅(ピクセル)
DWORD mapW = map.GetMapWidth(); //マップの横幅(チップ数)
DWORD mapH = map.GetMapHeight(); //マップの縦幅(チップ数)
// 縦横の最大表示マップチップ数。
// 1を足すのは、端のマップチップが画面に収まら無い座標にいたときのため。
int chipsX = 640 / chipW + 1;
int chipsY = 480 / chipH + 1;
// ピクセル位置からチップ位置に変換
int ctopX = px / chipW;
int ctopY = py / chipH;
// 描画するチップのオフセットを求める
int cofX = px % chipW;
int cofY = py % chipH;
// マップを描画
for( int x=0 ; x<chipsX ; x++ ) {
for( int y=0 ; y<chipsY ; y++ ) {
// マップチップの位置座標
DWORD cx = x + ctopX;
DWORD cy = y + ctopY;
// マップデータの範囲内か?
if( (cx<mapW) && (cy<mapH) ) {
// 描画する座標を求める。
DWORD dstX = (x * chipW) - cofX;
DWORD dstY = (y * chipH) - cofY;
// 描画するパーツの座標を求める。
int pno = map.GetValue(0,cx,cy);
DWORD srcX = (pno % 16) * chipW;
DWORD srcY = (pno / 16) * chipH;
// マップチップを描画する。
DrawRectGraph( dstX,dstY, srcX,srcY, chipW, chipH, MTHandle, TRUE, FALSE );
}
}
}
}
#include "DxLib.h"
#include "map.h"
#include "charmove.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ; // ウインドウモードに変更
if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了
SetDrawScreen( DX_SCREEN_BACK ) ; //描画先を裏画面に設定
LoadDivGraph( "char3.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
Map_Load("ipponmiti.fmf") ;
int sougen = LoadGraph("sougen.bmp");
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されると終了
Char_Move();
Map_Draw(mapend_x,mapend_y,sougen);
Char_Draw();
ScreenFlip();//裏画面を表画面に反映
}
WaitKey() ; // 結果を見るためにキー待ち(『WaitKey』を使用)
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
ですが、ちょっと速度が遅いかなぁと感じました。
RPGとかでよくある、ダッシュボタンを押さずに歩いた時の速度ぐらいでしょうか^^;
もう少しサクサク動けるようにしたいです。ダッシュ移動ぐらいの速度に。
無駄の多いコードだから重くなってしまってるのでしょうか?
それとも処理の過程でどこかで速度に制限をかけてしまっているのでしょうか?
読みにくいコードで申し訳ありませんが、どうかご教授下さい。