初心者です

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

初心者です

#1

投稿記事 by banan » 8年前

今DXライブラリとBox2Dを使ってゲームを作っているのですが、画像をうまく表示させたいところに別の画像が表示されてしまったりして困っています。
ゲームとしては上のほうにいる自分のキャラクターを左右に動かしてそこからボールを落として下にあるいろいろなゴールに入れることを予想しています。
でも床の壁などの画像が正しいものが表示されたり別のものが表示されたりしてしまいます。
以下に必要そうだと思われる部分のソース乗せて起きます。初心者なものでどなたかよろしくお願いしますm(_ _)m
これだけじゃわからないなどでもお願いします。

コード:


//ファイルの読み込み
int LoadFiles(){
if( LoadDivGraph("media\\chara_hero_l.png", 
6, 6, 1, 46, 96, g_images.hero) == -1)
{
return -1;
}
//壁床
g_images.wall[WALL_568]=LoadGraph("media\\wall_s.png");
if(g_images.wall[568]==-1)return -1;
g_images.wall[WALL_48]=DerivationGraph(0,0,48,48,g_images.wall[WALL_568]);
g_images.wall[WALL_192]=DerivationGraph(0,0,192,48,g_images.wall[WALL_568]);
g_images.wall[WALL_284]=DerivationGraph(0,0,284,48,g_images.wall[WALL_568]);
g_images.wall[EASY]=DerivationGraph(0,0,192,12,g_images.wall[WALL_568]);//難易度はゴールに入れる難しさ。これで得点を変える
g_images.wall[MEDIUM]=DerivationGraph(0,0,96,12,g_images.wall[WALL_568]);
g_images.wall[DIFFICULT]=DerivationGraph(0,0,48,12,g_images.wall[WALL_568]);
//玉
g_images.ball[3] = LoadGraph("media\\ball_s.png");
if(g_images.ball[3] == -1) return -1;
g_images.ball[BALL_24] = DerivationGraph(0, 0, 24, 24,
g_images.ball[3]);//これしか使いません
g_images.ball[BALL_48] = DerivationGraph(24, 0, 48, 48,
g_images.ball[3]);
g_images.ball[BALL_96] = DerivationGraph(0, 48, 96, 96,
g_images.ball[3]);
//読み込み成功
return 1;

//マップの読み込み
int LoadMapData(char *filepath){
int f; //ファイルハンドル
char buf[1024]; //テキスト読み込みバッファ

f = FileRead_open(filepath);
if (f==0) return -1; //読み込みエラー

//マップサイズと主人公初期位置読み込み
if(FileRead_gets( buf, 1023, f ) == -1) return -1;
float w, h, sx, sy;
sscanf_s(buf, "%f, %f, %f, %f", &w, &h, &sx, &sy);
g_stage.mapsize_w = w;
g_stage.mapsize_h = h;

//主人公キャラクター
g_stage.hero = CreateBox(PHS(sx), PHS(sy), 
PHS(23), PHS(48), 0, true);

//地形オブジェクト読み込み
if(FileRead_gets( buf, 1023, f ) == -1) return -1;
int imax;
sscanf_s(buf, "%d" , &imax); //行数取得
float x, y, angle; 
int id;

for(int i=0; i<imax; i++){
if(FileRead_gets( buf, 1023, f ) == -1) return -1;
sscanf_s( buf, "%f, %f, %f, %f, %f, %d", 
&x, &y, &w, &h, &angle, &id);
//ボディ作成
Character ch;
ch.body=CreateBox(PHS(x), PHS(y),PHS(w/2), PHS(h/2), angle, false);
switch(id){
case 0:
if((int)w == 48) ch.ID = WALL_48;//この部分(たぶん)に別の画像が入ってしまう。Box2Dの枠は正しい
if((int)w == 192) ch.ID = WALL_192;
if((int)w == 284) ch.ID = WALL_284;
if((int)w == 568) ch.ID = WALL_568;
break;
case 1:
ch.ID=EASY;
ch.type=EASY;//当たり判定用
g_stage.flagbody=ch.body;
ch.body->SetUserData(&g_images.wall[g_stage.num_mapchara]);
break;
case 2:
ch.ID=MEDIUM;
ch.type=MEDIUM;
g_stage.flagbody=ch.body;
ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
break;
case 3:
ch.ID=DIFFICULT;
ch.type=DIFFICULT;
g_stage.flagbody=ch.body;
ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
break;
}
ch.used = true;
g_stage.wall[g_stage.num_mapchara] = ch;
g_stage.num_mapchara++; 
}
FileRead_close(f);
return 0;
}
}

//地形などの描画
void DrawEnemyAndMap(){
int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
//地形の描画
for(int i=0; i<g_stage.num_mapchara; i++){
if(g_stage.wall[i].used == false) continue;
b2Vec2 pos = g_stage.wall[i].body->GetPosition();
float angle = g_stage.wall[i].body->GetAngle();
int id = g_stage.wall[i].ID;
DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,g_images.wall[id], TRUE);//仮
}
//玉の描画
for(int i=0; i<MAXBALLCHARA; i++){
if(g_stage.ball[i].used == false) continue;
b2Vec2 pos = g_stage.ball[i].body->GetPosition();
float angle = g_stage.ball[i].body->GetAngle();
//int id = g_stage.ball[i].ID;
DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,g_images.ball[0], TRUE);
//画面外に出たら消去
if(IsOutScreen(pos.x, pos.y)==true){
//g_world.DestroyBody(g_stage.ball[i].body);
//g_stage.ball[i].used = false;
}
}
//出現
if(IsAKeyTrigger(key)==true){
FallSnow(1);
}
}

Suikaba
記事: 194
登録日時: 9年前

Re: 初心者です

#2

投稿記事 by Suikaba » 8年前

コードは、インデントをつけてくださると、ほかの方も大変読みやすくなります。

コード:


//ファイルの読み込み
int LoadFiles(){
	if( LoadDivGraph("media\\chara_hero_l.png", 
		6, 6, 1, 46, 96, g_images.hero) == -1)
	{
		return -1;
	}
	//壁床
	g_images.wall[WALL_568] = LoadGraph("media\\wall_s.png");
	if(g_images.wall[568] == -1) return -1;
	g_images.wall[WALL_48] = DerivationGraph(0,0,48,48,g_images.wall[WALL_568]);
	g_images.wall[WALL_192] = DerivationGraph(0,0,192,48,g_images.wall[WALL_568]);
	g_images.wall[WALL_284] = DerivationGraph(0,0,284,48,g_images.wall[WALL_568]);
	g_images.wall[EASY] = DerivationGraph(0,0,192,12,g_images.wall[WALL_568]);//難易度はゴールに入れる難しさ。これで得点を変える
	g_images.wall[MEDIUM] = DerivationGraph(0,0,96,12,g_images.wall[WALL_568]);
	g_images.wall[DIFFICULT] = DerivationGraph(0,0,48,12,g_images.wall[WALL_568]);
	//玉
	g_images.ball[3] = LoadGraph("media\\ball_s.png");
	if(g_images.ball[3] == -1) return -1;
	g_images.ball[BALL_24] = DerivationGraph(0, 0, 24, 24,
		g_images.ball[3]);//これしか使いません
	g_images.ball[BALL_48] = DerivationGraph(24, 0, 48, 48,
		g_images.ball[3]);
	g_images.ball[BALL_96] = DerivationGraph(0, 48, 96, 96,
		g_images.ball[3]);
	//読み込み成功
	return 1;

	//マップの読み込み
	int LoadMapData(char *filepath){
		int f; //ファイルハンドル
		char buf[1024]; //テキスト読み込みバッファ

		f = FileRead_open(filepath);
		if (f == 0) return -1; //読み込みエラー

		//マップサイズと主人公初期位置読み込み
		if(FileRead_gets( buf, 1023, f ) == -1) return -1;
		float w, h, sx, sy;
		sscanf_s(buf, "%f, %f, %f, %f", &w, &h, &sx, &sy);
		g_stage.mapsize_w = w;
		g_stage.mapsize_h = h;

		//主人公キャラクター
		g_stage.hero = CreateBox(PHS(sx), PHS(sy), 
			PHS(23), PHS(48), 0, true);

		//地形オブジェクト読み込み
		if(FileRead_gets( buf, 1023, f ) == -1) return -1;
		int imax;
		sscanf_s(buf, "%d" , &imax); //行数取得
		float x, y, angle; 
		int id;

		for(int i=0; i<imax; i++){
			if(FileRead_gets( buf, 1023, f ) == -1) return -1;
			sscanf_s( buf, "%f, %f, %f, %f, %f, %d", 
				&x, &y, &w, &h, &angle, &id);
			//ボディ作成
			Character ch;
			ch.body = CreateBox(PHS(x), PHS(y),PHS(w/2), PHS(h/2), angle, false);
			switch(id){
				case 0:
					if((int)w == 48) ch.ID = WALL_48;//この部分(たぶん)に別の画像が入ってしまう。Box2Dの枠は正しい
					if((int)w == 192) ch.ID = WALL_192;
					if((int)w == 284) ch.ID = WALL_284;
					if((int)w == 568) ch.ID = WALL_568;
					break;
				case 1:
					ch.ID=EASY;
					ch.type=EASY;//当たり判定用
					g_stage.flagbody=ch.body;
					ch.body->SetUserData(&g_images.wall[g_stage.num_mapchara]);
					break;
				case 2:
					ch.ID=MEDIUM;
					ch.type=MEDIUM;
					g_stage.flagbody=ch.body;
					ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
					break;
				case 3:
					ch.ID=DIFFICULT;
					ch.type=DIFFICULT;
					g_stage.flagbody=ch.body;
					ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
					break;
			}
			ch.used = true;
			g_stage.wall[g_stage.num_mapchara] = ch;
			g_stage.num_mapchara++; 
		}
		FileRead_close(f);
	}
	return 0;
}

//地形などの描画
void DrawEnemyAndMap(){
	int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
	//地形の描画
	for(int i=0; i<g_stage.num_mapchara; i++){
		if(g_stage.wall[i].used == false) continue;
		b2Vec2 pos = g_stage.wall[i].body->GetPosition();
		float angle = g_stage.wall[i].body->GetAngle();
		int id = g_stage.wall[i].ID;
		DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,g_images.wall[id], TRUE);//仮
	}
	//玉の描画
	for(int i=0; i<MAXBALLCHARA; i++){
		if(g_stage.ball[i].used == false) continue;
		b2Vec2 pos = g_stage.ball[i].body->GetPosition();
		float angle = g_stage.ball[i].body->GetAngle();
		//int id = g_stage.ball[i].ID;
		DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,g_images.ball[0], TRUE);
		//画面外に出たら消去
		if(IsOutScreen(pos.x, pos.y) == true){
			//g_world.DestroyBody(g_stage.ball[i].body);
			//g_stage.ball[i].used = false;
		}
	}
	//出現
	if(IsAKeyTrigger(key) == true){
		FallSnow(1);
	}
}

アバター
パコネコ
記事: 139
登録日時: 9年前
住所: 大阪

Re: 初心者です

#3

投稿記事 by パコネコ » 8年前

コード:

    //読み込み成功
    return 1;
 
    //マップの読み込み
    int LoadMapData(char *filepath){
となっていますが、
このままでは下まで行きませんよ?
そもそも「マップの読み込み」が「ファイルの読み込み」の中にあるのは仕様でしょうか?
ニャン!!\(゜ロ\)(/ロ゜)/

banan

Re: 初心者です

#4

投稿記事 by banan » 8年前

すいません
抜いた部分の閉じ括弧を付け忘れていたみたいで。
これがメインのプログラムです。

コード:



#include "main.h"

//グローバル変数
GameState g_gamestate = GAME_TITLE;

//box2d関連
b2Vec2 gravity(0.0f, GRAVITY_Y);	//重力加速度
b2World g_world(gravity, true);		//Box2DWorld

//ゲームデータ
Images g_images;		//画像データ
Sounds g_sounds;		//音声データ
StageInfo g_stage;		//ステージデータ



//メインループ
void MyMain(){
	//ゲーム開始からの時間を計る
	g_stage.gametime = g_lasttime - g_stage.gamestarttime;
	//b2bの時間を進める
	g_world.Step(g_frametime, VELOCITYITE, POSITIONITE);
	//各画面の描画
	switch(g_gamestate){
	case GAME_TITLE:
		DrawGameTitle();
		break;
	case GAME_MAIN:
		DrawGameMain();
		break;
	case GAME_CLEAR:
		DrawGameClear();
		break;
	case GAME_OVER:
		DrawGameOver();
		break;
	}
}

//ファイルの読み込み
int LoadFiles(){
	//ファイル読み込み処理をここに書く
	if(	LoadDivGraph("media\\chara_hero_l.png", 
		6, 6, 1, 46, 96, g_images.hero) == -1)
	{
		return -1;
	}
	//壁床
	g_images.wall[WALL_568]=LoadGraph("media\\wall_s.png");
	if(g_images.wall[568]==-1)return -1;
	g_images.wall[WALL_48]=DerivationGraph(0,0,48,48,g_images.wall[WALL_568]);
	g_images.wall[WALL_192]=DerivationGraph(0,0,192,48,g_images.wall[WALL_568]);
	g_images.wall[WALL_284]=DerivationGraph(0,0,284,48,g_images.wall[WALL_568]);
	g_images.wall[EASY]=DerivationGraph(0,0,192,12,g_images.wall[WALL_568]);
	g_images.wall[MEDIUM]=DerivationGraph(0,0,96,12,g_images.wall[WALL_568]);
	g_images.wall[DIFFICULT]=DerivationGraph(0,0,48,12,g_images.wall[WALL_568]);
	//g_images.wall[EASY]=LoadGraph("media\\goalflag.png");
	//if(g_images.wall[EASY]==-1)return -1;
	//玉
	g_images.ball[3] = LoadGraph("media\\ball_s.png");
	if(g_images.ball[3] == -1) return -1;
	g_images.ball[BALL_24] = DerivationGraph(0, 0, 24, 24,
		g_images.ball[3]);
	g_images.ball[BALL_48] = DerivationGraph(24, 0, 48, 48,
		g_images.ball[3]);
	g_images.ball[BALL_96] = DerivationGraph(0, 48, 96, 96,
		g_images.ball[3]);
	//読み込み成功
	return 1;
}




//タイトル画面描画
void GoGameTitle(){
	g_gamestate = GAME_TITLE;
}
void DrawGameTitle(){
	//テキスト表示
	DrawStringToHandle(100, 340, "Zキーでゲームスタート", 
		0x666666, g_middlefont);
	//キーをチェックして画面切り替え
	int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
	if(IsAKeyTrigger(key)==true) GoGameMain();
}
//ゲーム本編描画
void GoGameMain(){
	g_gamestate = GAME_MAIN;
	InitStage();	//ステージデータの初期化
}
void DrawGameMain(){
	//スクロール座標調整
	b2Vec2 pos=g_stage.hero->GetPosition();
	int hx=(int)(pos.x*WLDSC);
	if(hx-SCROLL_LIMIT<g_stage.screen_x){
		g_stage.screen_x=hx-SCROLL_LIMIT-640;
	}
	if(640-SCROLL_LIMIT<hx-g_stage.screen_x){
		g_stage.screen_x=hx+SCROLL_LIMIT-640;
	}
	int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
	//ボールあたり判定
	for(int i=0;i<30;i++){
		if(g_stage.ball[i].used == false) continue;
	    b2Vec2 pos1 = g_stage.ball[i].body->GetPosition();
	    if(pos1.x>887&&pos.x<935){
		    if(pos1.y>360&&pos.y<408){
			    GoGameOver();
			}
		}
	}
	//衝突判定
	Collision();
	//画面外チェック
	if(IsOutScreen(pos.x,pos.y)==true)GoGameOver();
	DrawEnemyAndMap();//地形描画
	//主人公の足下確認
	g_stage.isontheground = true;
	HeroState hstate = HERO_STANDING;
	
	//主人公の位置と移動ベクトル
	b2Vec2 vec = g_stage.hero->GetLinearVelocity();
	float angle = g_stage.hero->GetAngle();
	//キーチェック
		//左右移動
		if(key & PAD_INPUT_LEFT) {
			vec.x += -PHS(4.0f);
			g_stage.hero->SetLinearVelocity(vec);
			hstate = HERO_RUNNING;
			g_stage.isheroleft = true;
			if(angle>-0.2f){
			angle=-0.2f;
			g_stage.hero->SetAngularVelocity(angle);
			}
		}
		if(key & PAD_INPUT_RIGHT) {
			vec.x += PHS(4.0f);
		    g_stage.hero->SetLinearVelocity(vec);
			hstate = HERO_RUNNING;
			g_stage.isheroleft = false;
			if(fabs(angle)<0.2f){
			angle=0.2f;
			g_stage.hero->SetAngularVelocity(angle);
			}
		}
	//転倒対策
	if( fabs(angle) > 0.2f||fabs(angle) < -0.2f ){
    g_stage.hero->SetAngularVelocity(-angle);
	}
	if( fabs(angle) < 0.01f&&fabs(angle) > -0.01f ){
    g_stage.hero->SetAngularVelocity(0);
	}
	//主人公移動制限
	if( vec.x > PHS(1000.0f)||vec.x < PHS(-1000.0f) ){
	vec.x=(float)(vec.x*0.9);
    g_stage.hero->SetLinearVelocity(vec);
	}
	vec.x=(float)(vec.x*0.995);
	g_stage.hero->SetLinearVelocity(vec);
	if( vec.x < PHS(1.5f)&&vec.x > PHS(-1.5f) ){
	vec.x=0;
    g_stage.hero->SetLinearVelocity(vec);
	}
	//スコア表示
	DrawFormatStringToHandle(0, 0, 0xFF0000, g_middlefont,
		"SCORE: %d", g_stage.score);
}
void DrawHero(int hstate){
	b2Vec2 pos = g_stage.hero->GetPosition();
	float angle = g_stage.hero->GetAngle();
	//キャラクター描画
	int animpat = (g_lasttime / (1000 / 12)) % 4;
	switch(hstate){
	case HERO_STANDING:
		DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,
			g_images.hero[0], TRUE, g_stage.isheroleft);
		break;
	case HERO_RUNNING:
		DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,
			g_images.hero[1 + animpat], TRUE, 
			g_stage.isheroleft);
		break;
	case HERO_JUMP:
		DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,
			g_images.hero[5], TRUE, g_stage.isheroleft);
		break;
	}
}
//衝突判定
void Collision(){
	//接触確認ループ
	for(b2Contact* c = g_world.GetContactList(); c!=NULL;
		c = c->GetNext())
	{
		for(int i=0;i<30;i++){
		if(c->IsTouching() == false) continue;
		//接触しているボディを取り出す
		b2Body* b1 = c->GetFixtureA()->GetBody();
		b2Body* b2 = c->GetFixtureB()->GetBody();
		//主人公のチェック
		b2Body* hb = NULL;
		b2Body* ob = NULL;
		if(b1 == g_stage.ball[i].body) {hb = b1; ob = b2;}
		if(b2 == g_stage.ball[i].body) {hb = b2; ob = b1;}
		if(hb != NULL){
			Character *ch = (Character *)ob->GetUserData();
			if(ch != NULL){
				b2Vec2 vec = g_stage.ball[i].body->GetLinearVelocity();
				if(vec.x!=0){
				if(ch->type==EASY){
					if(vec.x<0){
					vec.x=-1*vec.x;
					g_stage.score+=(int)(10*vec.x);//仮
					}
					if(vec.x>0){
					g_stage.score+=(int)(10*vec.x);
					}
				}
			    if(ch->type==MEDIUM){
					if(vec.x<0){
					vec.x=-1*vec.x;
					g_stage.score+=(int)(10*vec.x);
					}
					if(vec.x>0){
					g_stage.score+=(int)(10*vec.x);
					}
				}
				if(ch->type==DIFFICULT){
					if(vec.x<0){
					vec.x=-1*vec.x;
					g_stage.score+=(int)(10*vec.x);
					}
					if(vec.x>0){
					g_stage.score+=(int)(10*vec.x);
					}
				}
				}
			}
		}
		}
	}	
}

//ステージ初期化
void InitStage(){
	//ゲームデータ全体のゼロ初期化
	ZeroMemory(&g_stage, sizeof(g_stage));
	//全ボディ・ジョイント削除
	DeleteAllBody();
	//地形読み込み
	if(LoadMapData("media\\stage01.txt")==-1){
		MessageBox(NULL, "マップデータ読み込み失敗", 
			"DXライブラリ", MB_OK);
	}
	//g_stage.hero = CreateBox(PHS(140),PHS(40),
		//PHS(23), PHS(48), true);
	//ゲーム開始時刻の記録
	g_stage.gamestarttime = g_lasttime;
}


//ゲームクリア画面描画
void GoGameClear(){
	g_gamestate = GAME_CLEAR;
	g_stage.timerstart = g_lasttime;
}
void DrawGameClear(){
	//5秒経ったらタイトル画面へ
	if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle();
}
//ゲームオーバー画面描画
void GoGameOver(){
	g_gamestate = GAME_OVER;
	g_stage.timerstart = g_lasttime;
}
void DrawGameOver(){
	//5秒経ったらタイトル画面へ
	if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle();
}

//マップの読み込み
int LoadMapData(char *filepath){
	int f;	//ファイルハンドル
	char buf[1024];	//テキスト読み込みバッファ

	f = FileRead_open(filepath);
	if (f==0) return -1;	//読み込みエラー

	//マップサイズと主人公初期位置読み込み
	if(FileRead_gets( buf, 1023, f ) == -1) return -1;
	float w, h, sx, sy;
	sscanf_s(buf, "%f, %f, %f, %f", &w, &h, &sx, &sy);
	g_stage.mapsize_w = w;
	g_stage.mapsize_h = h;

	//主人公キャラクター
	g_stage.hero = CreateBox(PHS(sx), PHS(sy), 
		PHS(23), PHS(48), 0, true);

	//地形オブジェクト読み込み
	if(FileRead_gets( buf, 1023, f ) == -1) return -1;
	int imax;
	sscanf_s(buf, "%d" , &imax);	//行数取得
	float x, y, angle; 
	int id;
	
	for(int i=0; i<imax; i++){
		if(FileRead_gets( buf, 1023, f ) == -1) return -1;
		sscanf_s( buf, "%f, %f, %f, %f, %f, %d", 
			&x, &y, &w, &h, &angle, &id);
		//ボディ作成
		Character ch;
		ch.body=CreateBox(PHS(x), PHS(y),PHS(w/2), PHS(h/2), angle, false);
		switch(id){
		case 0:
		    if((int)w == 48) ch.ID = WALL_48;
		    if((int)w == 192) ch.ID = WALL_192;
		    if((int)w == 284) ch.ID = WALL_284;
		    if((int)w == 568) ch.ID = WALL_568;
		    break;
		case 1:
			ch.ID=EASY;
			ch.type=EASY;
			g_stage.flagbody=ch.body;
			ch.body->SetUserData(&g_images.wall[g_stage.num_mapchara]);
			break;
		case 2:
		//if(id==2)
			ch.ID=MEDIUM;
			ch.type=MEDIUM;
			g_stage.flagbody=ch.body;
			ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
			break;
		case 3:
		//if(id==3)
			ch.ID=DIFFICULT;
			ch.type=DIFFICULT;
			g_stage.flagbody=ch.body;
			ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
			break;
		}
		ch.used = true;
		g_stage.wall[g_stage.num_mapchara] = ch;
		g_stage.num_mapchara++;		
	}
	
	FileRead_close(f);
	return 0;
}

b2Body* CreateDynamicBall(float x, float y, float radius){
	//ボディ定義
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;	//動的ボディ
	bodyDef.position.Set(x, y);
	//ボディ作成
	b2Body* body = g_world.CreateBody(&bodyDef);
	//シェイプ作成
	b2CircleShape dynamicBall;
	dynamicBall.m_radius = radius;
	//フィクスチャ定義
	b2FixtureDef fixtureDef;
	fixtureDef.shape = &dynamicBall;
	fixtureDef.density = 4.0f;		//密度
	fixtureDef.restitution = 0.7f;	//反発力
	body->CreateFixture(&fixtureDef);
	return body;
}

b2Body* CreateBox(float x, float y, float w, float h,float angle, bool dynamic){
	//ボディ定義
	b2BodyDef bodyDef;
	if(dynamic) bodyDef.type = b2_kinematicBody;	//動的ボディ 
	else bodyDef.type = b2_staticBody;	//静的ボディ
	bodyDef.position.Set(x, y);
	bodyDef.angle=angle;
	///bodyDef.angle = 0.1f;
	//ボディ作成
	b2Body* body = g_world.CreateBody(&bodyDef);
	//シェイプ作成
	b2PolygonShape staticBox;
	staticBox.SetAsBox(w, h);
	//フィクスチャ定義
	b2FixtureDef fixtureDef;
	fixtureDef.shape = &staticBox;
	fixtureDef.density = 4.0f;		//密度
	fixtureDef.restitution = 0.2f;	//反発力
	fixtureDef.friction = 0.2f;		//摩擦係数
	body->CreateFixture(&fixtureDef);
	return body;
}
//地形などの描画
void DrawEnemyAndMap(){
	int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
	//地形の描画
	for(int i=0; i<g_stage.num_mapchara; i++){
		if(g_stage.wall[i].used == false) continue;
		b2Vec2 pos = g_stage.wall[i].body->GetPosition();
		float angle = g_stage.wall[i].body->GetAngle();
		int id = g_stage.wall[i].ID;
		DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,g_images.wall[id], TRUE);//仮
	}
		//雪玉の描画
	for(int i=0; i<MAXBALLCHARA; i++){
		if(g_stage.ball[i].used == false) continue;
		b2Vec2 pos = g_stage.ball[i].body->GetPosition();
		float angle = g_stage.ball[i].body->GetAngle();
		//int id = g_stage.ball[i].ID;
		DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,g_images.ball[0], TRUE);
		//画面外に出たら消去
		if(IsOutScreen(pos.x, pos.y)==true){
			//g_world.DestroyBody(g_stage.ball[i].body);
			//g_stage.ball[i].used = false;
		}
	}
	//出現
	if(IsAKeyTrigger(key)==true){
		FallSnow(1);
	}
}
//配列から空きキャラクターを探す
int FindBlankChara(Character *arr, int arraymax){
	for(int i=0; i<arraymax; i++){
		if(arr[i].used == false){
			return i;
		}
	}
	//空きが見つからない場合
	return -1;
}
void FallSnow(int num){
	    b2Vec2 pos = g_stage.hero->GetPosition();
	    b2Vec2 vec = g_stage.hero->GetLinearVelocity();
	    int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
		Character ch2;
		for(int i=0;i<num;i++){
		//空きキャラクターを探す
		int blank = FindBlankChara(g_stage.ball, MAXBALLCHARA);
		if(blank >= 0){
			//種類を決める
			float sz=24.0f; int ID=24;
			//ボディ作成
			ch2.body = CreateDynamicBall(pos.x,pos.y+2, PHS(sz/2));
			b2Vec2 vec2 = ch2.body->GetLinearVelocity();
			vec2.x=vec.x;
			ch2.body->SetLinearVelocity(vec2);
			ch2.used = true;
			ch2.ID = ID;
			g_stage.ball[blank] = ch2;
			blank-=1;
			}
		}
}

アバター
ookami
記事: 214
登録日時: 9年前
住所: 東京都

Re: 初心者です

#5

投稿記事 by ookami » 8年前

各クラスの構造が示されていないのでわかりませんが、

g_images.wall[WALL_568]=LoadGraph("media\\wall_s.png");
if(g_images.wall[568]==-1)return -1;
g_images.wall[WALL_48]=DerivationGraph(0,0,48,48,g_images.wall[WALL_568]);
g_images.wall[WALL_192]=DerivationGraph(0,0,192,48,g_images.wall[WALL_568]);
g_images.wall[WALL_284]=DerivationGraph(0,0,284,48,g_images.wall[WALL_568]);
g_images.wall[EASY]=DerivationGraph(0,0,192,12,g_images.wall[WALL_568]);
g_images.wall[MEDIUM]=DerivationGraph(0,0,96,12,g_images.wall[WALL_568]);
g_images.wall[DIFFICULT]=DerivationGraph(0,0,48,12,g_images.wall[WALL_568]);
//g_images.wall[EASY]=LoadGraph("media\\goalflag.png");
//if(g_images.wall[EASY]==-1)return -1;

この部分は正しいのでしょうか?
全部画像の左上(0,0)から取っているようですが...

banan

Re: 初心者です

#6

投稿記事 by banan » 8年前

たぶん正しいです。
ひとつの横幅568縦幅48の灰色の画像を分割して使っています。
easy,medium,difficultの部分に当てることで点数を入れるようにしています。
main.hものせておきますm(_ _)m

コード:

#include <DxLib.h>
#include <Box2D/Box2D.h>
#ifdef _DEBUG
	#pragma comment(lib, "Box2D_d.lib")
#endif
#ifndef _DEBUG
	#pragma comment(lib, "Box2D.lib")
#endif
#include "_dxdebugdraw.h"

//定数
#define B2D_DEBUG_DRAW
const int VELOCITYITE = 6;		//速度計算精度
const int POSITIONITE = 2;		//位置計算精度
const float GRAVITY_Y = 10.0f;	//重力加速度
const float WLDSC = 50.0f;		//世界倍率
const float SCREENAREA = 300.0f;//スクリーン範囲
const int SCROLL_LIMIT=321;//スクロール限界

//画像読み込み用構造体
struct Images{
	int back[2];	//背景画像
	int logo[3];	//ロゴ(タイトル、オーバー、クリア)
	int titleback;
	int hero[6];	//主人公キャラクター
	int wall[4];    //壁
	int ball[4];       //玉
};
//音声読み込み用構造体
struct Sounds{
};
//ゲームステート
enum GameState{
	GAME_TITLE, GAME_MAIN, GAME_OVER, GAME_CLEAR
};
//キャラクター構造体
struct Character{
	b2Body *body;	//ボディ
	bool used;		//使用中フラグ
	int type;		//種類
	int ID;			//細かい種類
};
const int MAXMAPCHARA = 1024;	//地形の最大数
const int MAXBALLCHARA=30;

//ゲームデータ記録用構造体
struct StageInfo{
	int timerstart;			//待機タイマーの開始時刻
	int gamestarttime;		//ゲームの開始時間
	int gametime;			//ゲーム開始からの経過ミリ秒
	float mapsize_w, mapsize_h;	//マップサイズ
	int screen_x, screen_y;	//表示原点(スクロール用)
	Character wall[MAXMAPCHARA];//床壁
	int num_mapchara;//読み込んだ地形の数
	b2Body *hero;	//主人公
	//b2Body *ball[MAXBALLCHARA]; //ボール
	bool isheroleft;	//主人公の向き
	bool isontheground;	//乗っている?
	Character ball[MAXBALLCHARA];
	b2Body *flagbody;
	int score;
};
//HEROステート(アニメーション表示に使う列挙体)
enum HeroState{
	//立つ、走る、ジャンプ
	HERO_STANDING, HERO_RUNNING, HERO_JUMP
};
//WALL
enum WallID{
	WALL_48,WALL_192,WALL_284,WALL_568
};
enum CharacterType{
	EASY,MEDIUM,DIFFICULT
};
//BALL
enum BallID{
	BALL_24, BALL_48, BALL_96
};
//関数プロトタイプ宣言
void MyMain();
int LoadFiles();
int LoadMapData(TCHAR *filepath);
void InitStage();
void GoGameTitle();
void DrawGameTitle();
void GoGameMain();
void DrawGameMain();
void GoGameClear();
void DrawGameClear();
void GoGameOver();
void DrawGameOver();
b2Body* CreateDynamicBall(float x, float y, float radius);
b2Body* CreateBox(float x, float y, float w, float h,float angle, bool dynamic);
void Collision();
void DrawHero(int hstate);
void DrawEnemyAndMap();
int FindBlankChara(Character*arr,int arraymax);
void FallSnow(int num);

//ユーティリティ関数
bool IsAKeyTrigger(int key);
bool IsBKeyTrigger(int key);
bool IsCKeyTrigger(int key);
void DeleteAllBody();
int VIWX(float v);
int VIWY(float v);
float PHS(float v);
bool IsOutScreen(float x, float y);

//グローバル変数のエクスターン宣言
extern int g_lasttime;
extern float g_frametime;
extern bool g_exitflag;
extern b2World g_world;
#ifdef  B2D_DEBUG_DRAW
extern DxDebugDraw g_debugdraw;
#endif
extern int g_middlefont;
extern StageInfo g_stage;

アバター
ookami
記事: 214
登録日時: 9年前
住所: 東京都

Re: 初心者です

#7

投稿記事 by ookami » 8年前

あー...
てっきり、(いわゆるRPGのマップチップみたいな感じで、)
「同じ大きさの画像がたくさん並んでいる」と思ったんですが、違うんですね?

念のため、wall_s.pngを添付してもらっていいですか?

--追記
ステージの読み込み部分も確認したいので、
stage01.txt
も添付をお願いします^^;

banan

Re: 初心者です

#8

投稿記事 by banan » 8年前

http://www.dotup.org/uploda/www.dotup.o ... 5.rar.html
pass:game

こちらにすべてまとめてアップロードしました。
よろしくお願いしますm(_ _)m

アバター
ookami
記事: 214
登録日時: 9年前
住所: 東京都

Re: 初心者です

#9

投稿記事 by ookami » 8年前

ダウンロードしてみました。
wall_s.pngを見てみましたが、これは分割して使う画像なんですか...?

すみませんが、もう一度、
> でも床の壁などの画像が正しいものが表示されたり別のものが表示されたりしてしまいます。

という部分について、詳しく説明していただけますか?
実行してみたところ、壁以外の画像が表示されなかったのですが...

banan

Re: 初心者です

#10

投稿記事 by banan » 8年前

画像は分割してそれでステージの壁をそれぞれ使って作成します
EASY、MEDIUM、DIFFICULTは画像がないのでとりあえずこれを使っています。変えるかもしれません。
DrawGameMain関数の//転倒防止の前にDrawHero(hstate);を追加していただくと、キャラが表示されます。
実行すると画面真ん中より少し右下に黄色い正方形があると思うのですが、そこにWALL_48の画像を表示させるつもりがEASY(とても横長の四角)がはみ出して表示されてしまっています。
矢印で左右に移動でき、Zキーを押すとボールを30個まで落とすことができます、
当たり判定は画像でなく、黄色い四角の部分であると思います。
一番下の床や横の大きな壁はきちんと黄色い枠どおりに表示されているのですが、、
説明下手ですみません

アバター
ookami
記事: 214
登録日時: 9年前
住所: 東京都

Re: 初心者です

#11

投稿記事 by ookami » 8年前

あー たぶん分かりました。
enumの使い方について確認しますね?

enum { A,B,C };
enum { D,E,F };
と書くと、次の意味になります。
const int A=0;
const int B=1;
const int C=2;
const int D=0; // ←ここに注目
const int E=1;
const int F=2;

enumで列挙するたびに、ゼロから始まっているところに注意してください。
すると、bananさんの

コード:

enum WallID{
    WALL_48,WALL_192,WALL_284,WALL_568
};
enum CharacterType{
    EASY,MEDIUM,DIFFICULT
};
このコードでは、
WALL_48 も EASY も 0 ということになります。ここまでは良いでしょうか。

つまり、画像をロードしている、
g_images.wall[WALL_48]=DerivationGraph(0,0,48,48,g_images.wall[WALL_568]);

g_images.wall[EASY]=DerivationGraph(0,0,192,12,g_images.wall[WALL_568]);
の部分で、
g_images.wall[WALL_48] にロードした画像を、g_images.wall[EASY]で上書きしてしまっている、ということになります。
両方 g_images.wall[0] なので。

同じwall配列に入れるなら、

コード:

enum WallID{
    WALL_48,WALL_192,WALL_284,WALL_568,
    EASY,MEDIUM,DIFFICULT
};
のようにくっつけるか、別配列にするか、などでどうでしょう。

banan

Re: 初心者です

#12

投稿記事 by banan » 8年前

できました!本当にありがとうございました。
enumについてよくわかってなかったので、とても参考になりました。
あともうひとつもし時間があればでいいのですが、
当たり判定がボールとMEDIUM、DIFFICULTにだけでて、ボールとEASYには適用されてないようなのですが、どうしてかわかりますしょうか?

アバター
ookami
記事: 214
登録日時: 9年前
住所: 東京都

Re: 初心者です

#13

投稿記事 by ookami » 8年前

画像の方は解決したようで、よかったです!

さて、新たに、
DIFFICULTだけ当たり判定しない、とのことですが、

コード:

void Collision(){
    //接触確認ループ
    for(b2Contact* c = g_world.GetContactList(); c!=NULL;c = c->GetNext())
    {
        for(int i=0;i<30;i++){
            if(c->IsTouching() == false) continue;
            //接触しているボディを取り出す
            b2Body* b1 = c->GetFixtureA()->GetBody();
            b2Body* b2 = c->GetFixtureB()->GetBody();
            //主人公のチェック
            b2Body* hb = NULL;
            b2Body* ob = NULL;
            if(b1 == g_stage.ball[i].body) {hb = b1; ob = b2;}
            if(b2 == g_stage.ball[i].body) {hb = b2; ob = b1;}
            if(hb != NULL){
                Character *ch = (Character *)ob->GetUserData();
                if(ch != NULL){
                    b2Vec2 vec = g_stage.ball[i].body->GetLinearVelocity();
                    if(vec.x!=0){
                        if(ch->type==EASY){
                            if(vec.x<0){
                                vec.x=-1*vec.x;
                                g_stage.score+=(int)(10*vec.x);//仮
                            }
                            if(vec.x>0){
                                g_stage.score+=(int)(10*vec.x);
                            }
                        }
                        if(ch->type==MEDIUM){
                            if(vec.x<0){
                                vec.x=-1*vec.x;
                                g_stage.score+=(int)(10*vec.x);
                            }
                            if(vec.x>0){
                                g_stage.score+=(int)(10*vec.x);
                            }
                        }
                        if(ch->type==DIFFICULT){
                            if(vec.x<0){
                                vec.x=-1*vec.x;
                                g_stage.score+=(int)(10*vec.x);
                            }
                            if(vec.x>0){
                                g_stage.score+=(int)(10*vec.x);
                            }
                        }
                    }
                }
            }
        }
    }   
}
この中の何かだろうなぁと思うのですが、
まずは、
for(b2Contact* c = g_world.GetContactList(); c!=NULL;c = c->GetNext())
このループの中に
for(int i=0;i<30;i++)
このループが入っているのはなぜですか?


---
あと、ついでですが、
if(g_images.wall[568]==-1)return -1;
は、
if(g_images.wall[WALL_568]==-1)return -1;
ですね。

banan

Re: 初心者です

#14

投稿記事 by banan » 8年前

30個あるボールをそれぞれどこかと接触してないかというのをチェックしようと思ってやりました
if(b1 == g_stage.ball.body) {hb = b1; ob = b2;}
if(b2 == g_stage.ball.body) {hb = b2; ob = b1;}のiの部分の扱いに困ってそうしました。
実はこのあたり判定の部分がなんとなくしか理解できていないです(^_^;)

アバター
ookami
記事: 214
登録日時: 9年前
住所: 東京都

Re: 初心者です

#15

投稿記事 by ookami » 8年前

うーん、いまいち原因が分かりませんねぇf^^;
2重forループにしているのも、意図通りの動きかどうか...

まずは、
LoadMapData内のch.type=DIFFICULT;
や、
Collision内のif(ch->type==DIFFICULT)
あたりに、ブレークポイントを設定するなどして、
読み込みと当たり判定のどちらに問題があるか確認してみてはいかがでしょう。

閉鎖

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