DXライブラリ置き場 http://homepage2.nifty.com/natupaji/DxL ... am.html#N4
こちらの「マップスクロール」(スクロールが滑らかになる方)でマップを作りました。
質問なのですが、マップ上に敵がいます。
移動処理、当たり判定はなんとなく検討がついているので多分大丈夫なのですが、
自キャラが移動すると、モンスターもその方向に動き、また初期位置に戻る行動を繰り返してしまいます。
画面スクロールしても、敵をその場所に記憶させる事はできました。
例:自キャラが左へ移動→敵も一瞬左へ移動→すぐに初期位置に戻る
それと、マップスクロールを使っているため、ch.x、ch.yが機能しておらず、
キャラクターのアニメーションが向きしか機能していません。
(キャラの動きは旧ゲームプログラミング館19~22章)
どうすればマップスクロールに対応したアニメーションを行えるでしょうか。
ちなみに226~232行がキャラ、モンスター画像処理です。
コード張ります。
#include "DxLib.h"
#include "def.h"
#include "Hit.h"
#include "Key.h"
// モンスター、プレイヤーの位置
int PlayerX , PlayerY;
int MonsterX,MonsterY;
// 移動しているかどうかのフラグ( 0:停止中 1:移動中 )
int Move;
// 各方向に移動する量
int MoveX, MoveY;
// 移動し始めてから何フレーム経過したかを保持する変数
int MoveCounter;
int hp = 1000,hp_max = 1000; //初期HP
int ep = 0,ep_max = 1000; //初期MP
int exp = 0,exp_max = 1000; //初期EXP
int lvl = 1;
int MapDrawPointX , MapDrawPointY , MapDrawPointMonsX; // 描画するマップ座標値
int DrawMapChipNumX , DrawMapChipNumY ; // 描画するマップチップの数
int idou = 0; //移動中の向きフラグ防止
int Key[256]; // キーが押されているフレーム数を格納する
int Stats_1 = OFF; //Item画面スイッチ処理
int ItemBox = OFF; //Item画面処理
int GameTime = 0;
ch_t ch;
mons_t mons;
extern int MapData[ MAP_HEIGHT ][ MAP_WIDTH ];
// マップとプレイヤーの描画関数
void GraphDraw( int ScrollX, int ScrollY )
{
int j , i ;
// 描画するマップチップの数をセット
DrawMapChipNumX = 800 / MAP_SIZE + 2 ;
DrawMapChipNumY = 600 / MAP_SIZE + 2 ;
// 画面左上に描画するマップ座標をセット
MapDrawPointX = PlayerX - ( DrawMapChipNumX / 2 - 1 ) ;
MapDrawPointY = PlayerY - ( DrawMapChipNumY / 2 - 1 ) ;
MapDrawPointMonsX = MonsterX - ( DrawMapChipNumX / 2 - 1 ) ;
// マップを描く
for( i = -1 ; i < DrawMapChipNumY ; i ++ )
{
for( j = -1 ; j < DrawMapChipNumX ; j ++ )
{
// 画面からはみ出た位置なら描画しない
if( j + MapDrawPointX < 0 || i + MapDrawPointY < 0 ||
j + MapDrawPointX >= MAP_WIDTH || i + MapDrawPointY >= MAP_HEIGHT ) continue ;
// マップデータが0だったら四角を描画する
if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 0 )
{
DrawBox(j * MAP_SIZE + ScrollX, i * MAP_SIZE + ScrollY,
j * MAP_SIZE + MAP_SIZE + ScrollX, i * MAP_SIZE + MAP_SIZE + ScrollY,
GetColor( 0 , 200 , 200 ) , TRUE ) ;
}
// マップデータが0だったら四角を描画する
if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 1 )
{
DrawBox(j * MAP_SIZE + ScrollX, i * MAP_SIZE + ScrollY,
j * MAP_SIZE + MAP_SIZE + ScrollX, i * MAP_SIZE + MAP_SIZE + ScrollY,
GetColor( 0 , 100 , 0 ) , TRUE ) ;
}
}
}
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int image[16];
int ScrollX, ScrollY ;
//画面サイズ
SetGraphMode( 800 , 600 , 32 ) ;
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
ch.x =320;
ch.y =160;
ch.walking_flag=0;
ch.muki=3;
// プレイヤーの初期位置をセット
PlayerX = 5 ;
PlayerY = 5 ;
MonsterX = 2;
MonsterY = 2;
// 最初は停止中(0)にしておく
Move = 0 ;
SetDrawScreen( DX_SCREEN_BACK ) ; //描画先を裏画面に設定
//画像読み込み
LoadDivGraph( "画像/char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
while(!ProcessMessage() && !ClearDrawScreen() && gpUpdateKey()==0 && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されると終了
// 移動中ではない場合キー入力を受け付ける
if( Move == 0 )
{
// キー入力を得る
// Key[0] = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;
// キー入力に応じてプレイヤーの座標を移動
if( (Key[ KEY_INPUT_LEFT] >= 1) && PAD_INPUT_LEFT && ch.muki == 1)
{
Move = 1 ;
MoveX = -1 ;
MoveY = 0 ;
}
if( (Key[ KEY_INPUT_RIGHT] >= 1) && PAD_INPUT_RIGHT && ch.muki == 3)
{
Move = 1 ;
MoveX = 1 ;
MoveY = 0 ;
}
if( (Key[ KEY_INPUT_UP] >= 1) && PAD_INPUT_UP && ch.muki == 0)
{
Move = 1 ;
MoveX = 0 ;
MoveY = -1 ;
}
if( (Key[ KEY_INPUT_DOWN] >= 1) && PAD_INPUT_DOWN && ch.muki == 2)
{
Move = 1 ;
MoveX = 0 ;
MoveY = 1 ;
}
// 進入不可能なマップだった場合は移動できない
if( Move == 1 )
{
if( MapData[ PlayerY + MoveY ][ PlayerX + MoveX ] == 0 ||
MapData[ PlayerY + MoveY ][ PlayerX + MoveX ] == 2)
{
Move = 0 ;
}
else
{
MoveCounter = 0 ;
}
}
// 停止中は画面のスクロールは行わない
ScrollX = 0 ;
ScrollY = 0 ;
}
// 移動中の場合は移動処理を行う
if( Move == 1 )
{
MoveCounter +=4 ;
idou = 1;
// 移動処理が終了したら停止中にする
if( MoveCounter == MOVE_FRAME )
{
Move = 0 ;
idou = 0;
// プレイヤーの位置を変更する
PlayerX += MoveX ;
PlayerY += MoveY ;
// 停止中は画面のスクロールは行わない
ScrollX = 0 ;
ScrollY = 0 ;
}
else
{
// 経過時間からスクロール量を算出する
ScrollX = -( MoveX * MAP_SIZE * MoveCounter / MOVE_FRAME ) ;
ScrollY = -( MoveY * MAP_SIZE * MoveCounter / MOVE_FRAME ) ;
}
}
// マップとプレイヤーを描画
GraphDraw( ScrollX, ScrollY ) ;
if(ch.x%32==0 && ch.y%32==0){ //座標が32で割り切れたら入力可能
ch.walking_flag=1; //歩くフラグを立てる。
if ( (Key[ KEY_INPUT_UP ] >= 1)
&& Key[ KEY_INPUT_LEFT ] == 0
&& Key[ KEY_INPUT_DOWN ] == 0
&& Key[ KEY_INPUT_RIGHT] == 0
&& idou == 0) //上ボタンが押されたら(それ以外を押されていなかったら)
ch.muki=0; //上向きフラグを立てる
else if( Key[ KEY_INPUT_LEFT ] >= 1
&& Key[ KEY_INPUT_UP ] == 0
&& Key[ KEY_INPUT_DOWN ] == 0
&& Key[ KEY_INPUT_RIGHT] == 0
&& idou == 0) //左ボタンが押されたら
ch.muki=1; //左向きフラグを立てる
else if( Key[ KEY_INPUT_DOWN ] >= 1
&& Key[ KEY_INPUT_UP ] == 0
&& Key[ KEY_INPUT_LEFT ] == 0
&& Key[ KEY_INPUT_RIGHT] == 0
&& idou == 0) //下ボタンが押されたら
ch.muki=2; //下向きフラグを立てる
else if( Key[ KEY_INPUT_RIGHT] >= 1
&& Key[ KEY_INPUT_UP ] == 0
&& Key[ KEY_INPUT_LEFT ] == 0
&& Key[ KEY_INPUT_DOWN] == 0
&& idou == 0) //右ボタンが押されたら
ch.muki=3; //右向きフラグを立てる
else //何のボタンも押されてなかったら
ch.walking_flag=0; //歩かないフラグを立てる
}
//当たり判定
MonsterHit();
//描画処理
//キャラクター
ch.img=image[ch.muki*4]; //画像をセット
DrawGraph( ( PlayerX - MapDrawPointX ) * MAP_SIZE , ( PlayerY - MapDrawPointY ) * MAP_SIZE, ch.img , TRUE ) ;//画像を描画
//モンスター
mons.img=image[(mons.x%32+mons.y%32)/8 + mons.muki*4]; //画像をセット
DrawGraph( ( MonsterX - MapDrawPointMonsX ) * MAP_SIZE , ( MonsterY - MapDrawPointY ) * MAP_SIZE, mons.img , TRUE ) ;//画像を描画
//ステータス背景
DrawBox(0,544,800,600,GetColor(0,125,120),TRUE );
//HP表示
DrawBox(89,555,91+WD ,571,GetColor(0,0,0),FALSE);//メーターの枠を描画
DrawBox(90,556,90+WD*hp/hp_max,570,GetColor(255,0,0),TRUE );//メーターの中身を描画
//EP表示
DrawBox(89,575,91+WD ,591,GetColor(0,0,0),FALSE);//メーターの枠を描画
DrawBox(90,576,90+WD*ep/ep_max,590,GetColor(0,200,120),TRUE );//メーターの中身を描画
if(ep<ep_max) ep+=1;
//EXP表示
DrawBox(249,555,351+WD ,591,GetColor(0,0,0),FALSE);//メーターの枠を描画
DrawBox(250,556,250+(WD+100)*exp/exp_max,590,GetColor(0,255,0),TRUE );//メーターの中身を描画
//文字表示
DrawString(65,555,"HP",GetColor(0,0,0));
DrawString(65,575,"EP",GetColor(0,0,0));
DrawString(215,565,"EXP",GetColor(0,0,0));
DrawFormatString(15,565, GetColor(0,0,0), "LV %d",lvl);
DrawString(475,565,"Equip",GetColor(0,0,0));
if(Key[ KEY_INPUT_A] == 1 && ItemBox == OFF){
ItemBox = ON;
Stats_1 = OFF;
} else if(Key[ KEY_INPUT_A] == 2 && Stats_1 == ON){
ItemBox = OFF;
}
if(ItemBox == ON){
DrawBox(20,50,120,200,GetColor(0,125,120),TRUE );
DrawString(30,60,"Item",GetColor(0,0,0));
if(Key[ KEY_INPUT_A] == 0)Stats_1 = ON;
}
ScreenFlip();
}
DxLib_End();
return 0;
}