壁に当たったら反射させたい

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

壁に当たったら反射させたい

#1

投稿記事 by yaegasi » 12年前

敵を壁に当たったら反射させたいんですがうまくいきません
すいませんが教えてください・・・・


// マップスクロール基本
#include "DxLib.h"

#define MAP_SIZE 32 // マップチップ一つのドットサイズ

#define MAP_WIDTH 20 // マップの幅
#define MAP_HEIGHT 16 // マップの縦長さ

// マップのデータ
int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
{ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 , 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 , 1, 1, 1, 1, 1, 1, 0, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 , 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 , 0, 0, 1, 1, 1, 1, 1, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 , 0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 , 0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,

{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 , 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 , 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 , 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 , 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 1 , 1, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
} ;


typedef struct{
int x,y,OldenemyX,OldenemyY,counter,img,muki,walking_flag;
}enemy_t;
enemy_t enemy;

// プレイヤーの位置
int PlayerX , PlayerY ;

int IsAbleToGo(int x,int y,int muki){//進めるかを判定する
if(muki==0)//上向きなら
if(MapData[y-1][x]==1)//進めるか判定
return 1;//エラー
if(muki==1)//左向きなら
if(MapData[y][x-1]==1)
return 1;
if(muki==2)//下向きなら
if(MapData[y+1][x]==1)
return 1;
if(muki==3)//右向きなら
if(MapData[y][x+1]==1)
return 1;
return 0;//正常
}

// マップとプレイヤーの描画関数
void GraphDraw( void )
{
int j , i ;
int MapDrawPointX , MapDrawPointY ; // 描画するマップ座標値
int DrawMapChipNumX , DrawMapChipNumY ; // 描画するマップチップの数

// 描画するマップチップの数をセット
DrawMapChipNumX = 640 / MAP_SIZE + 1 ;
DrawMapChipNumY = 480 / MAP_SIZE + 1 ;

// 画面左上に描画するマップ座標をセット
MapDrawPointX = PlayerX - DrawMapChipNumX / 2 ;
MapDrawPointY = PlayerY - DrawMapChipNumY / 2 ;

// マップを描く
for( i = 0 ; i < DrawMapChipNumY ; i ++ )
{
for( j = 0 ; 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 , i * MAP_SIZE ,
j * MAP_SIZE + MAP_SIZE , i * MAP_SIZE + MAP_SIZE ,
GetColor( 255 , 0 , 0 ) , TRUE ) ;
}
}
}

// プレイヤーの描画
DrawBox( ( enemy.x - MapDrawPointX ) * MAP_SIZE , ( enemy.y - MapDrawPointY ) * MAP_SIZE ,
( enemy.x - MapDrawPointX + 1 ) * MAP_SIZE , ( enemy.y - MapDrawPointY + 1 ) * MAP_SIZE ,
GetColor( 255 , 255 , 25 ) , TRUE ) ;
DrawBox( ( PlayerX - MapDrawPointX ) * MAP_SIZE , ( PlayerY - MapDrawPointY ) * MAP_SIZE ,
( PlayerX - MapDrawPointX + 1 ) * MAP_SIZE , ( PlayerY - MapDrawPointY + 1 ) * MAP_SIZE ,
GetColor( 255 , 255 , 255 ) , TRUE ) ;
}

// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
int Key ;
int OldX , OldY ; // 移動する前のプレイヤーの位置を保存する変数

SetGraphMode( 640 , 480 , 16 ) ;
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}

// 描画先画面を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;

// プレイヤーの初期位置をセット
PlayerX = 2 ;
PlayerY = 2 ;

enemy.muki=3 ;
enemy.x=3 , enemy.y=4 ;
// ループ
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
{
// 画面を初期化
ClearDrawScreen() ;

// キー入力を得る
Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;

// 移動する前のプレイヤーの位置を保存
OldX = PlayerX ;
OldY = PlayerY ;
enemy.OldenemyX = enemy.x ;
enemy.OldenemyY = enemy.y ;
// キー入力に応じてプレイヤーの座標を移動
if( Key & PAD_INPUT_LEFT ) PlayerX -= 1 ;
if( Key & PAD_INPUT_RIGHT ) PlayerX += 1 ;
if( Key & PAD_INPUT_UP ) PlayerY -= 1 ;
if( Key & PAD_INPUT_DOWN ) PlayerY += 1 ;

// 進入不可能なマップだった場合は移動できない
if( MapData[ PlayerY ][ PlayerX ] == 0 )
{
PlayerX = OldX ;
PlayerY = OldY ;
}

enemy.counter++;
if(enemy.counter%10==0){enemy.walking_flag=1;}


if(enemy.walking_flag==1){ //もし歩くなら
if(IsAbleToGo(enemy.x,enemy.y,enemy.muki)==1){//行き先が歩けないなら
for(int i=0;i<=3;i++){//も一回いける方向探す
if(IsAbleToGo(enemy.x,enemy.y,i)==0){enemy.muki=i;break;}
}}}
if(enemy.walking_flag==1){
if(enemy.muki==0)
enemy.y--;
else if(enemy.muki==1) //左向きならch.x座標を減らす
enemy.x--;
else if(enemy.muki==2) //下向きならch.y座標を増やす
enemy.y++;
else if(enemy.muki==3) //右向きならch.x座標を増やす
enemy.x++;
}
// マップとプレイヤーを描画
GraphDraw() ;

// 裏画面の内容を表画面に映す
ScreenFlip() ;

// ウエイト
WaitTimer( 100 ) ;
}

DxLib_End() ; // DXライブラリ使用の終了処理

return 0 ; // ソフトの終了
}

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: 壁に当たったら反射させたい

#2

投稿記事 by みけCAT » 12年前

まず、コードはcodeタグで囲んでいただけるとありがたいです。
どこがどううまくいかないのか、具体的に書けますか?
(こうなってほしいが、動かすとこうなってしまう、など)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

yaegasi

Re: 壁に当たったら反射させたい

#3

投稿記事 by yaegasi » 12年前

if(enemy.walking_flag==1){ //もし歩くなら
if(IsAbleToGo(enemy.x,enemy.y,enemy.muki)==0){//行き先が歩けないなら
for(int i=0;i<=3;i++){//も一回いける方向探す
if(IsAbleToGo(enemy.x,enemy.y,i)==1){enemy.muki=i;break;}
}}}
と逆にしたらえきました
0=行ける1=いけないと思ってたんですが

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: 壁に当たったら反射させたい

#4

投稿記事 by みけCAT » 12年前

関数名がIsAbleToGoなのに、0なら行けるというのは矛盾を感じます。
(好みの問題です。このままでもかまいません)

このマップは、1が通路、0が壁として作っているのではないのですか?
だとしたら、

コード:

int IsAbleToGo(int x,int y,int muki){//進めるかを判定する
	if(muki==0)//上向きなら
		if(MapData[y-1][x]==1)//進めるか判定
		return 1;//エラー
	if(muki==1)//左向きなら
		if(MapData[y][x-1]==1)
			return 1;
	if(muki==2)//下向きなら
		if(MapData[y+1][x]==1)
			return 1;
	if(muki==3)//右向きなら
		if(MapData[y][x+1]==1)
			return 1;
	return 0;//正常
}
この関数のMapData[][]==1の1は全て0であるべきだと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

yaegasi

Re: 壁に当たったら反射させたい

#5

投稿記事 by yaegasi » 12年前

壁と通路が逆でしたか・・・
見落としていましたorz
どうもありがとうございました。

yaegasi

Re: 壁に当たったら反射させたい

#6

投稿記事 by yaegasi » 12年前

何度もすいません
数を増やしたらまた反射しなくなりました

コード:


// マップスクロール基本
#include "DxLib.h"

#define MAP_SIZE	32			// マップチップ一つのドットサイズ

#define MAP_WIDTH	20			// マップの幅
#define MAP_HEIGHT	16			// マップの縦長さ

// マップのデータ
int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] =
{
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
	{ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 ,  1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  1, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  1, 1, 1, 1, 1, 1, 0, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 ,  0, 0, 0, 0, 0, 1, 0, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 1, 1, 1, 1, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 ,  0, 0, 1, 0, 0, 1, 1, 0, 1, 0 } ,

	{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 0, 0, 1, 1, 0, 0, 1, 0, 0 ,  0, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 1 ,  1, 1, 1, 0, 0, 1, 1, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
	{ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } ,
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
} ;


typedef struct{
        int x,y,counter,img,muki,speed,walking_flag,flag;
}enemy_t;
     enemy_t enemy[50] = {
		{ 3,2,7,2,1,2,0 },
		{ 4,3,7,2,1,2,0 },
		{ 5,4,7,2,2,2,0},
		{ 4,4,7,2,2,2,0 },
		{ 12,13,7,2,2,2,0 },
		{ 21,2,7,2,2,2,0 },
		{ 4,3,7,2,3,2,0 },
		{ 5,4,7,2,0,2,0},
		{ 4,4,7,2,2,2,0 },
		{ 12,13,7,2,2,2,0 },
		{ 3,2,7,2,2,2,0 },
		{ 4,3,7,2,2,2,0 },
		{ 5,4,7,2,2,2,0},
		{ 4,4,7,2,2,2,0 },
		{ 12,13,7,2,2,2,0 },
		{ 13,2,7,2,1,2,0 },
		{ 14,3,7,2,2,2,0 },
		{ 15,4,7,2,3,2,0},
		{ 5,4,7,2,2,3,0 },
		{ 12,13,7,2,0,2,0 },};
// プレイヤーの位置
int PlayerX , PlayerY ;

	// 描画するマップチップの数をセット
	int DrawMapChipNumX = 640 / MAP_SIZE + 1 ;
	int DrawMapChipNumY = 480 / MAP_SIZE + 1 ;

	// 画面左上に描画するマップ座標をセット
	int MapDrawPointX = PlayerX - DrawMapChipNumX / 2 ;
	int MapDrawPointY = PlayerY - DrawMapChipNumY / 2 ;
int IsAbleToGo(int x,int y,int muki){//進めるかを判定する
        if(muki==0)//上向きなら
                if(MapData[y-1][x]==0)//進めるか判定
                        return 1;//エラー
        if(muki==1)//左向きなら
                if(MapData[y][x-1]==0)
                        return 1;
        if(muki==2)//下向きなら
                if(MapData[y+1][x]==0)
                        return 1;
        if(muki==3)//右向きなら
                if(MapData[y][x+1]==0)
                        return 1;
        return 0;//正常
}

// マップとプレイヤーの描画関数
void GraphDraw( void )
{
	int j , i ;
	int MapDrawPointX , MapDrawPointY ;		// 描画するマップ座標値
	int DrawMapChipNumX , DrawMapChipNumY ;	// 描画するマップチップの数
	
	// 描画するマップチップの数をセット
	DrawMapChipNumX = 640 / MAP_SIZE + 1 ;
	DrawMapChipNumY = 480 / MAP_SIZE + 1 ;

	// 画面左上に描画するマップ座標をセット
	MapDrawPointX = PlayerX - DrawMapChipNumX / 2 ;
	MapDrawPointY = PlayerY - DrawMapChipNumY / 2 ;

	// マップを描く
	for( i = 0 ; i < DrawMapChipNumY ; i ++ )
	{
		for( j = 0 ; 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 , i * MAP_SIZE ,
					j * MAP_SIZE + MAP_SIZE , i * MAP_SIZE + MAP_SIZE ,
							GetColor( 255 , 0 , 0 ) , TRUE ) ;
			}
		}
	}
	// プレイヤーの描画	
		for( i = 0 ; i < 50 ; i ++ )
		{
	if(enemy[i].flag==1){  
	DrawBox( ( enemy[i].x - MapDrawPointX ) * MAP_SIZE , ( enemy[i].y - MapDrawPointY ) * MAP_SIZE ,
		 ( enemy[i].x - MapDrawPointX + 1 ) * MAP_SIZE , ( enemy[i].y - MapDrawPointY + 1 ) * MAP_SIZE ,
			 GetColor( 255 , 255 , 25 ) , TRUE ) ;
		}}
	DrawBox( ( PlayerX - MapDrawPointX ) * MAP_SIZE , ( PlayerY - MapDrawPointY ) * MAP_SIZE ,
		 ( PlayerX - MapDrawPointX + 1 ) * MAP_SIZE , ( PlayerY - MapDrawPointY + 1 ) * MAP_SIZE ,
			 GetColor( 255 , 255 , 255 ) , TRUE ) ;
}

// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						 LPSTR lpCmdLine, int nCmdShow )
{
 ChangeWindowMode(TRUE);
	int Key ;
	int OldX , OldY ;	// 移動する前のプレイヤーの位置を保存する変数

	SetGraphMode( 640 , 480 , 16 ) ;
	if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
	{
		 return -1;				// エラーが起きたら直ちに終了
	}
	// 描画先画面を裏画面にする
	SetDrawScreen( DX_SCREEN_BACK ) ;

	// プレイヤーの初期位置をセット
	PlayerX = 2 ;
	PlayerY = 2 ;
        int MouseX, MouseY;

	// ループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
	{
		// 画面を初期化
		ClearDrawScreen() ;

		// キー入力を得る
		Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;

		// 移動する前のプレイヤーの位置を保存
		OldX = PlayerX ; 
		OldY = PlayerY ;
		// キー入力に応じてプレイヤーの座標を移動
		if( Key & PAD_INPUT_LEFT ) PlayerX -= 1 ;
		if( Key & PAD_INPUT_RIGHT ) PlayerX += 1 ;
		if( Key & PAD_INPUT_UP ) PlayerY -= 1 ;
		if( Key & PAD_INPUT_DOWN ) PlayerY += 1 ;

		// 進入不可能なマップだった場合は移動できない
		if( MapData[ PlayerY ][ PlayerX ] == 0 )
		{
			PlayerX = OldX ;
			PlayerY = OldY ;
		}

		for(int i = 0 ; i < 50 ; i ++ )
		{
			// 画面からはみ出た位置なら描画しない
                if(enemy[i].x<-20 || MapDrawPointX+20<enemy[i].x || enemy[i].y<-20 || MapDrawPointY+20<enemy[i].y)
                    enemy[i].flag=0;else enemy[i].flag=1; 
}

		for(int i = 0 ; i < 50 ; i ++ )
		{
            if(enemy[i].flag==1){    //もし歩くなら
                if(IsAbleToGo(enemy[i].x,enemy[i].y,enemy[i].muki)==1){//行き先が歩けないなら(このマップは0が壁で1が通路であるから注意)
        for(int i=0;i<=3;i++){//も一回いける方向探す
			if(IsAbleToGo(enemy[i].x,enemy[i].y,i)==0){enemy[i].muki=i;break;}
		}}}}

	for(int i = 0 ; i < 50 ; i ++ )
		{		
	if(enemy[i].flag==1){  
	if(enemy[i].muki==0) {  
	enemy[i].y--;}
	        else if(enemy[i].muki==1)        //左向きならch.x座標を減らす
                    enemy[i].x--;
            else if(enemy[i].muki==2)        //下向きならch.y座標を増やす
                    enemy[i].y++;
            else if(enemy[i].muki==3)        //右向きならch.x座標を増やす
                    enemy[i].x++;
}}
		// マップとプレイヤーを描画
		GraphDraw() ;

            GetMousePoint( &MouseX, &MouseY );
            DrawFormatString( 0, 0, GetColor(255,255,255), "%d,%d", MouseX, MouseY );
		DrawFormatString( 0, 80, GetColor(0,0,255), "enemy.x%d",enemy[0].x);
		DrawFormatString( 0, 100, GetColor(0,0,255), "enemy.muki%d",enemy[0].muki);  
		DrawFormatString( 0, 120, GetColor(0,0,255), "enemy.x%d",enemy[0].x);
		DrawFormatString( 0, 140, GetColor(0,0,255), "enemy.y%d",enemy[0].y);  
		// 裏画面の内容を表画面に映す
		ScreenFlip() ;

		// ウエイト
		WaitTimer( 100 ) ;
	}

	DxLib_End() ;				// DXライブラリ使用の終了処理

	return 0 ;					// ソフトの終了
}

アバター
Tatu
記事: 445
登録日時: 15年前
住所: 北海道

Re: 壁に当たったら反射させたい

#7

投稿記事 by Tatu » 12年前

182行目からの

コード:

        for(int i = 0 ; i < 50 ; i ++ )
        {
            if(enemy[i].flag==1){    //もし歩くなら
                if(IsAbleToGo(enemy[i].x,enemy[i].y,enemy[i].muki)==1){//行き先が歩けないなら(このマップは0が壁で1が通路であるから注意)
        for(int i=0;i<=3;i++){//も一回いける方向探す
            if(IsAbleToGo(enemy[i].x,enemy[i].y,i)==0){enemy[i].muki=i;break;}
        }}}}
で敵の添え字と方向を探す時のカウンタ変数の両方でiが使われています。
敵の添え字はiとし、方向を探す時はjとするというように別の変数を使ってください。

コードを読みやすいようにインデントを見直してください。

}}}}のように}を同じ行に複数書くのは見づらいです。

yaegasi

Re: 壁に当たったら反射させたい

#8

投稿記事 by yaegasi » 12年前

for(int i = 0 ; i < 50 ; i ++ )
{
if(enemy.flag==1){ //もし歩くなら
if(IsAbleToGo(enemy.x,enemy.y,enemy.muki)==1){//行き先が歩けないなら(このマップは0が壁で1が通路であるから注意)
for(int j=0;j<=3;j++){//も一回いける方向探す
if(IsAbleToGo(enemy.x,enemy.y,j)==0){enemy.muki=j;break;}
}}}}

こうでしょうか?壁抜けは治ったのですが
途中で変なところで消えるやつがいます

アバター
Tatu
記事: 445
登録日時: 15年前
住所: 北海道

Re: 壁に当たったら反射させたい

#9

投稿記事 by Tatu » 12年前

codeタグを忘れていますね。
あと、インデントを見直すことと}を同じ行に何個も書くと見づらいということを書いたはずですが。

いくつかあるfor(int i=0;i<50;i++){については
一つにまとめたほうが見やすくなりそうです。

「途中で変なところで消える」とはどういう意味でしょうか?
このような自分の思った通りに動かない現象について
今の状態と理想の状態の両方がわかる説明をできるようにすることは
問題の解決に役立つ可能性があります。


「変なところで消える」というのが左上に敵が出現し、
上に向かって移動して消えるということであるという場合

原因は

175行目から

コード:

        for(int i = 0 ; i < 50 ; i ++ )
        {
            // 画面からはみ出た位置なら描画しない
                if(enemy[i].x<-20 || MapDrawPointX+20<enemy[i].x || enemy[i].y<-20 || MapDrawPointY+20<enemy[i].y)
                    enemy[i].flag=0;else enemy[i].flag=1; 
}
の部分で初期化されていない敵(座標が(0,0)でmukiが0(上向き)になっている)について
(0,0)は画面内(ウィンドウに表示される範囲)に存在するのでenemy[*].flagが1になってしまう。これにより、敵が勝手に左上に出現する。
その後、移動できるかどうかを調べるとき、移動できるという判定になってしまい、
そのまま移動、消失となる。

また、画面外に消えた時にenemy.flag=0としていますが
画面外に消えた時でも敵はステージ中に存在しているのでこの処理は行わない方がよいでしょう。

解決策としては

enemy[]の初期化を行うときにflagも代入されるようにする
もし、画面外の敵を描画するということが気になるのならば、敵を描画するときに敵が画面内にいるかどうかを調べるようにする
上で示した原因の処理をコメントアウトして動作を確認し、問題がなければ削除する

というようにするのがよいと思います。


もし、消滅するというのが
敵とプレイヤーもしくは敵同士が重なったために消えているように見えるということであれば
移動できるかどうかを調べる時にプレイヤーと他の敵がそこに存在するかを調べる処理を追加すればよいでしょう。

► スポイラーを表示

yaegasi

Re: 壁に当たったら反射させたい

#10

投稿記事 by yaegasi » 12年前

なるほど
敵は存在してるから画面外に出ても座標計算部分はif(enemy.flag==1){と書いてはいけないということですね
描画部分だけに書くとうまくいきました
あと初期化にflagの値も入れたほうがいいということですね
参考になりました
インデントや書き方にも注意したいと思います
ありがとうございました

アバター
Tatu
記事: 445
登録日時: 15年前
住所: 北海道

Re: 壁に当たったら反射させたい

#11

投稿記事 by Tatu » 12年前

敵の計算や描画でif(enemy.flag==1){と書くのは問題ありません。
存在する敵のみ処理すればよく、存在しない敵について意味がなかったり、
やると不都合になったりする処理をわざわざすることはないからです。

今回は敵の座標が表示される範囲にあるかどうかで
flagを1にしたり、0にしたりするという処理によって
配置していない敵を勝手に発生(flagが1になる)させられていたり、
消すつもりのない敵が消されたり(flagが0になる)していたのが問題なのです。

閉鎖

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