マップスクロール時、敵の行動について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
amuku

マップスクロール時、敵の行動について

#1

投稿記事 by amuku » 13年前

初投稿です。

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;
}
よろしくお願いします。

amuku

Re: マップスクロール時、敵の行動について

#2

投稿記事 by amuku » 13年前

追記ですが、マップ等のデータは他にまとめてあり、
この後も張ったコード内は整理する予定です。
色々試してMapDrawPointMonsX等加えてますがすべて失敗に終わっています。
(張ってあるコードの状況は、敵と自キャラのX座標が同じになり、動いてもX座標のみ同じでずっとついてくる状況、
Y座標は上記のとおり、動いた後に初期値に戻る状況。)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: マップスクロール時、敵の行動について

#3

投稿記事 by softya(ソフト屋) » 13年前

すいません見逃していました。

【少し修正】
実行できるコードではないのでざっと見ての感想ですが、座標の管理が変にややこしくなっています。
MapDrawPointXとMapDrawPointYは必要ですが、MapDrawPointMonsXなんてものは必要ないはずです。
基本的には、すべてのキャラクタ等はMap座標で処理・管理して表示するときだけ表示座標に変換して表示する方式にしたほうが物事がシンプルになりますので、自キャラもモンスターも表示座標はMapDrawPointXとMapDrawPointYを全て基準にするべきです。

↓ こんなイメージです。
画面イメージ.png
画面イメージ.png (25.28 KiB) 閲覧数: 2154 回
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

amuku

Re: マップスクロール時、敵の行動について

#4

投稿記事 by amuku » 13年前

返答遅れました、ありがとうございます。
座標については理解しました。
描画処理については未だ解決していませんが、がんばってみます。

amuku

Re: マップスクロール時、敵の行動について

#5

投稿記事 by amuku » 13年前

自己解決しました、ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る