ページ 11

描画がうまくいきません

Posted: 2012年6月06日(水) 18:29
by NABE

コード:

// *******************************************************************
//
// アイテム
//
// *******************************************************************

//インクルード-------------------------------------------
#include <stdio.h>//c言語
#include "gs.h"//学内ライブラリィ
#include "Def.h"//共通定義

#include "Item.h"//アイテム

//グローバル変数宣言----------------------------------------
OBJ gItem[ITEM_MAX];//アイテム構造体


//グローバル変数参照----------------------------------------
//画像ーーーーーーーーーーーーーーーーーーー
extern gsTexture ggBox;//宝箱
extern gsTexture ggST_UP;//スタミナ回復
extern gsTexture ggST_DOWN;//スタミナ減少
extern gsTexture ggBT_UP;//弾数回復
extern gsTexture gglast_UP;//残機回復
extern gsTexture ggNeedle;//トゲ
//ーーーーーーーーーーーーーーーーーーーーー

extern float gMapX;//マップスクロール
extern OBJ gPlayer;//プレイヤーの構造体

//-------------------------------------------------------------
// 開始
//-------------------------------------------------------------
void ItemStart()
{
	for(int i=0; i<ITEM_MAX; i++)//アイテムの数
	{
		gItem[i].flg = ON;//存在する
	}
}


//-------------------------------------------------------------
// 処理
//-------------------------------------------------------------
void ItemMain()
{
}


//-------------------------------------------------------------
// 表示
//-------------------------------------------------------------
void ItemDraw()
{
	for(int i=0; i<ITEM_MAX; i++)//アイテムの数
	{
           //種類によって描画する絵を変える
		if(gItem[i].type == TYPE1)
		{
			//宝箱
			gsDraw2D(ggBox, (int)(PARTS_SIZE*6-gMapX), PARTS_SIZE*8);
			gsDraw2D(ggBox, (int)(PARTS_SIZE*15-gMapX), PARTS_SIZE*4);
		}

		if(gItem[i].type == TYPE2)
		{
			//スタミナ回復
			gsDraw2D(ggST_UP, (int)(PARTS_SIZE*8-gMapX), PARTS_SIZE*8);
		}
		if(gItem[i].type == TYPE3)
		{
			//スタミナ減少
			gsDraw2D(ggST_DOWN, (int)(PARTS_SIZE*15 -gMapX), PARTS_SIZE*8);
		}

		if(gItem[i].type == TYPE4)
		{
			//弾数回復
			gsDraw2D(ggBT_UP, (int)(PARTS_SIZE*20 -gMapX), PARTS_SIZE*8);
		}
		
		if(gItem[i].type == TYPE5)
		{
			//残機回復
			gsDraw2D(gglast_UP, (int)(PARTS_SIZE*25 -gMapX), PARTS_SIZE*8);
		}

		if(gItem[i].type == TYPE6)
		{
			//トゲ
			gsDraw2D(ggNeedle, (int)(PARTS_SIZE*20 -gMapX), PARTS2_SIZE*17);
		}
	}
}
アイテムの種類が多くなってきたのでタイプでまとめた見たのですがうまくいきません。
現状、宝箱の絵は指定した座標に描画されるのですが他のアイテム画面のどこにも描画されません。

#define PARTS_SIZE 64//ブロック64
#define PARTS2_SIZE 32//ブロック32
#define ITEM_MAX 10//アイテムの数
#define ITEM_SIZE 64//アイテムのサイズ

アイテムのサイズは縦横64です。
トゲのサイズのみ横64縦32です。

Re: 描画がうまくいきません

Posted: 2012年6月06日(水) 18:34
by h2so5
アイテムの種類はどこで設定しているんですか

Re: 描画がうまくいきません

Posted: 2012年6月06日(水) 18:42
by NABE
h2so5 さんが書きました:アイテムの種類はどこで設定しているんですか
Def.hの中でTYPE1からTYPE6までを用意しています。


ミスでトピックスを2つ立ててしまいました。
こちらの方で返信をお願いします。

Re: 描画がうまくいきません

Posted: 2012年6月06日(水) 18:49
by h2so5
NABE さんが書きました: Def.hの中でTYPE1からTYPE6までを用意しています。
用意していることと、設定していることの違いが分かりますか?

具体的に言うと、

コード:

gItem[i].flg = TYPE1;
[/s]

修正:

コード:

gItem[i].type = TYPE1;
のようにどこかで代入されている必要があります。

Re: 描画がうまくいきません

Posted: 2012年6月06日(水) 19:22
by NABE
勘違いしました。
そして設定していませんでした。

コード:

//-------------------------------------------------------------
// 設置
//-------------------------------------------------------------
void ItemSet()
{
	for(int i=0; i<ITEM_MAX; i++)
	{
		//それぞれのタイプを設定
		gItem[i].type = TYPE1;
		gItem[i].type = TYPE2;
		gItem[i].type = TYPE3;
		gItem[i].type = TYPE4;
		gItem[i].type = TYPE5;
		gItem[i].type = TYPE6;
	}
}
書き加えました。

Re: 描画がうまくいきません

Posted: 2012年6月06日(水) 19:23
by softya(ソフト屋)
それだと最後のTYPE6が全部に代入されますよ。
の添え字毎にタイプが違うのでは無いでしょうか?

Re: 描画がうまくいきません

Posted: 2012年6月06日(水) 19:59
by NABE
softya(ソフト屋) さんが書きました:それだと最後のTYPE6が全部に代入されますよ。
の添え字毎にタイプが違うのでは無いでしょうか?

コード:

void ItemSet()
{
	for(int i=0; i<ITEM_MAX; i++)
	{
		//それぞれのタイプを設定
		gItem[0].type = TYPE1;
		gItem[1].type = TYPE1;
		gItem[2].type = TYPE2;
		gItem[3].type = TYPE3;
		gItem[4].type = TYPE4;
		gItem[5].type = TYPE5;
		gItem[6].type = TYPE6;
	}
こういうことでしょうか?

Re: 描画がうまくいきません

Posted: 2012年6月06日(水) 20:14
by h2so5
それだとループさせている意味がないですよ

Re: 描画がうまくいきません

Posted: 2012年6月06日(水) 20:19
by softya(ソフト屋)
アイテムは7個あって6種類って事ですか?
あれ? ITEM_MAX が10個ですけど。

Re: 描画がうまくいきません

Posted: 2012年6月07日(木) 17:22
by NABE
ITEM_MAX 10はとりあえず各アイテムを1ずつ表示しようと思い適当に用意した数です。
アイテムによっては複数用意したのもありますが・・・。
最終的には各アイテムは複数用意する予定です。


ではどう書いたらいいんでしょうか?
すいません。C言語はじめて1ヶ月くらいしか経ってないので

Re: 描画がうまくいきません

Posted: 2012年6月07日(木) 17:43
by softya(ソフト屋)
アイテムというのは固定で最初から有るんじゃなくて動的に発生・取得されるんではないのですか?
どんなゲームかわからないのでアイテムは発生成条件が全く不明なんですが固定で代入しておけば良いのならここでfor文なんて必要ないです。

コード:

void ItemSet()
{
   //それぞれのタイプを設定
	gItem[0].type = TYPE1;
	gItem[1].type = TYPE1;
	gItem[2].type = TYPE2;
	gItem[3].type = TYPE3;
	gItem[4].type = TYPE4;
	gItem[5].type = TYPE5;
	gItem[6].type = TYPE6;
}
1ヶ月とはいえfor文は基礎の基礎ですので、調べて良く考えてみてください。

あとアイテムの表示位置は固定なんでしょうか?
今のコードだとTYPE1の宝箱が1個でもあると2個とも表示されてしますので今の仕組みだとTYPE1でもどっちなのか区別する必要が出てきます。
並んでいる順番で表示位置を変える方法もありますが、それだともっと工夫しないといけません。

Re: 描画がうまくいきません

Posted: 2012年6月07日(木) 18:59
by NABE
ゲームジャンルのアクションゲームでアイテムの設置場所は固定
アイテムの移動はなしです。

Re: 描画がうまくいきません

Posted: 2012年6月07日(木) 19:19
by softya(ソフト屋)
NABE さんが書きました:ゲームジャンルのアクションゲームでアイテムの設置場所は固定
アイテムの移動はなしです。
表示部分を簡単にしたかったら構造体に画像のハンドルと表示座標を追加してやって、初期化で全部代入すれば表示はループで回しながら画像のハンドルと表示座標を使って表示するだけでよくなります。あと表示するときにgItem.flgは見たほうが良いと思います。取得したら無くなるんですよね?
それとtypeは表示の時じゃなくて、アクション時の取得?処理で判定に使いましょう。

Re: 描画がうまくいきません

Posted: 2012年6月07日(木) 19:59
by NABE
すいません。
ハンドルってなんですか?


アイテムの種類を見てもらえばわかりますがトゲ意外は取ると消えます。
トゲはダメージになります。

Re: 描画がうまくいきません

Posted: 2012年6月07日(木) 21:01
by softya(ソフト屋)
あっとすいません。ハンドルと思われるgsTexture の事です。

Re: 描画がうまくいきません

Posted: 2012年6月07日(木) 21:08
by ookami
こんにちは。ookamiです。

NABEさんが示されているコードは描画部分だけだと思いますが、
値をセット(初期化?)する部分のコードも示してもらえますか?

また、アイテムの座標はどうやってセットしていますか?

Re: 描画がうまくいきません

Posted: 2012年6月07日(木) 21:10
by softya(ソフト屋)
ookami さんが書きました:こんにちは。ookamiです。

NABEさんが示されているコードは描画部分だけだと思いますが、
値をセット(初期化?)する部分のコードも示してもらえますか?

また、アイテムの座標はどうやってセットしていますか?
途中の部分を見るとわかりますが、ItemDraw()で座標を決め打ちで描画しているとおもいます。

Re: 描画がうまくいきません

Posted: 2012年6月07日(木) 21:35
by ookami
あぁ...なるほど。失礼しましたm(_ _)m
softyaさんの仰るとおり、gsTextureの部分に問題がありそうですね。

Re: 描画がうまくいきません

Posted: 2012年6月09日(土) 12:19
by NABE
昨日返信できなくてすいません。
皆さんのアドバイスのおかげで描画することができました。


描画できたので衝突判定を書いてみたのですが衝突判定が今うまくいかない。どうすればいいか?
衝突判定が2行でできる方法があると聞いたんですがその方法を教えていただければと思います。


コード:

// *******************************************************************
//
// アイテム
//
// *******************************************************************

//インクルード-------------------------------------------
#include <stdio.h>//c言語
#include "gs.h"//学内ライブラリィ
#include "Def.h"//共通定義

#include "Item.h"//アイテム

//グローバル変数宣言----------------------------------------
OBJ gItem[ITEM_MAX];



//グローバル変数参照----------------------------------------
extern gsTexture ggBox;//宝箱
extern gsTexture ggST_UP;//スタミナ回復
extern gsTexture ggST_DOWN;//スタミナ減少
extern gsTexture ggBT_UP;//弾数回復
extern gsTexture gglast_UP;//残機回復
extern gsTexture ggNeedle;//トゲ

extern float gMapX;

extern OBJ gPlayer;

//-------------------------------------------------------------
// 開始
//-------------------------------------------------------------
void ItemStart()
{
	for(int i=0; i<ITEM_MAX; i++)
	{
		gItem[i].flg = ON;
	}
}


//-------------------------------------------------------------
// 処理
//-------------------------------------------------------------
void ItemMain()
{
	ItemSet();
	ItemCollision();//アイテムの衝突判定
}


//-------------------------------------------------------------
// 表示
//-------------------------------------------------------------
void ItemDraw()
{
	for(int i=0; i<ITEM_MAX; i++)
	{
		if(gItem[i].type == TYPE1)
		{
			//宝箱仮
			gsDraw2D(ggBox, (int)(PARTS_SIZE*6-gMapX), PARTS_SIZE*8);
			gsDraw2D(ggBox, (int)(PARTS_SIZE*15-gMapX), PARTS_SIZE*4);
		}

		else if(gItem[i].type == TYPE2)
		{
			//スタミナ回復
			gsDraw2D(ggST_UP, (int)(PARTS_SIZE*8-gMapX), PARTS_SIZE*8);
		}
		else if(gItem[i].type == TYPE3)
		{
			//スタミナ減少
			gsDraw2D(ggST_DOWN, (int)(PARTS_SIZE*15 -gMapX), PARTS_SIZE*8);
		}

		else if(gItem[i].type == TYPE4)
		{
			//弾数回復
			gsDraw2D(ggBT_UP, (int)(PARTS_SIZE*20 -gMapX), PARTS_SIZE*8);
		}
		
		else if(gItem[i].type == TYPE5)
		{
			//残機アップ
			gsDraw2D(gglast_UP, (int)(PARTS_SIZE*23 -gMapX), PARTS_SIZE*8);
		}

		else if(gItem[i].type == TYPE6)
		{
			//トゲ
			gsDraw2D(ggNeedle, (int)(PARTS_SIZE*19 -gMapX), PARTS_SIZE*8 + PARTS2_SIZE);
		}
	}	
}


//----------------------------------------------------------------------------
// アイテムデバッグ表示
//----------------------------------------------------------------------------
void ItemDebugDraw()
{
	for(int i=0; i<ITEM_MAX; i++)
	{
		gsDrawNum(i*150,200,gItem[i].type);
	}
}

//----------------------------------------------------------------------
//設置
//----------------------------------------------------------------------
void ItemSet()
{
	//種類を設定
	gItem[0].type = TYPE1;//宝箱
	gItem[1].type = TYPE2;//スタミナ回復
	gItem[2].type = TYPE3;//スタミナ減少
	gItem[3].type = TYPE4;//弾数回復
	gItem[4].type = TYPE5;//残機アップ
	gItem[5].type = TYPE6;//トゲ

}



//-------------------------------------------------------------
// アイテムの衝突判定
//-------------------------------------------------------------
void ItemCollision()
{
	//アイテムの数
	for(int i=0; i<ITEM_MAX; i++)
	{
		//存在すれば
		if(gItem[i].flg == ON)
		{
			//衝突判定
			if(gPlayer.x + PLAYER_W_MAX > gItem[i].x &&          //プレイヤーの右 > アイテムの左
				gPlayer.x < gItem[i].x + ITEM_MAX &&    //プレイヤーの左 < アイテムの右   
				gPlayer.y + PLAYER_H_MAX > gItem[i].y && //プレイヤーの下 > アイテムの上
				gPlayer.y < gItem[i].y + ITEM_MAX )           //プレイヤーの上 < アイテムの下
			{
				//アイテムの存在を消す
				gItem[i].flg = OFF;

				//それぞれのアイテム効果
                         //(効果はまだ未定)
			}
		}
	}
}


Re: 描画がうまくいきません

Posted: 2012年6月09日(土) 12:29
by softya(ソフト屋)
全然指摘が生かされていません。
おかしいところを列挙します。
(1)ItemStartで10個のアイテムが有効であるとしている。
(2)ItemMainでItemSet()する意味が無い。ItemStartですべき。
(3)ItemDrawでif(gItem.type == TYPE1)なら2つの宝箱を無条件に描画。
(4)ItemSet()で設定しているアイテムは6個。(1)や(3)と矛盾。
(5)ItemCollisionで使うgItem.xが初期化された形跡がない。

Re: 描画がうまくいきません

Posted: 2012年6月09日(土) 12:32
by ookami
1.
ItemMainを呼び出しているところと、
gItem配列をセットしているところを、貼ってもらえませんか?
プログラムの全体像が見えず、アドバイスがむずかしい状態です。

2.
最初に投稿されたコードと、
2番目に投稿されたコードを比較しましたが、
描画関連で変更したところが分かりませんでした。
何を変えたら描画できるようになったのでしょうか?

Re: 描画がうまくいきません

Posted: 2012年6月12日(火) 19:57
by NABE
風邪を引き返信遅くなりました。

softya(ソフト屋) さんの指摘で分かるところは修正しました。

この状態で一様描画はできています。衝突判定しません。

コード:

// *******************************************************************
//
// アイテム
//
// *******************************************************************

//インクルード-------------------------------------------
#include <stdio.h>//c言語
#include "gs.h"//学内ライブラリィ
#include "Def.h"//共通定義

#include "Item.h"//アイテム

//グローバル変数宣言----------------------------------------
OBJ gItem[ITEM_MAX];


//グローバル変数参照----------------------------------------
extern gsTexture ggBox;//宝箱
extern gsTexture ggST_UP;//スタミナ回復
extern gsTexture ggST_DOWN;//スタミナ減少
extern gsTexture ggBT_UP;//弾数回復
extern gsTexture gglast_UP;//残機回復
extern gsTexture ggNeedle;//トゲ

extern float gMapX;

extern OBJ gPlayer;

//-------------------------------------------------------------
// 開始
//-------------------------------------------------------------
void ItemStart()
{
	ItemSet();
}

//-------------------------------------------------------------
// 処理
//-------------------------------------------------------------
void ItemMain()
{
	ItemCollision();//アイテムの衝突判定
}

//-------------------------------------------------------------
// 表示
//-------------------------------------------------------------
void ItemDraw()
{
	if(gItem[0].type == TYPE1)
	{
		//宝箱仮
		gsDraw2D(ggBox, (int)(PARTS_SIZE*6-gMapX), PARTS_SIZE*8);
		gsDraw2D(ggBox, (int)(PARTS_SIZE*15-gMapX), PARTS_SIZE*4);
	}

	if(gItem[1].type == TYPE2)
	{
		//スタミナ回復
		gsDraw2D(ggST_UP, (int)(PARTS_SIZE*8-gMapX), PARTS_SIZE*8);
	}
	if(gItem[2].type == TYPE3)
	{
		//スタミナ減少
		gsDraw2D(ggST_DOWN, (int)(PARTS_SIZE*15 -gMapX), PARTS_SIZE*8);
	}

	if(gItem[3].type == TYPE4)
	{
		//弾数回復
		gsDraw2D(ggBT_UP, (int)(PARTS_SIZE*20 -gMapX), PARTS_SIZE*8);
	}
	
	if(gItem[4].type == TYPE5)
	{
		//残機アップ
		gsDraw2D(gglast_UP, (int)(PARTS_SIZE*23 -gMapX), PARTS_SIZE*8);
	}

	if(gItem[5].type == TYPE6)
	{
		//トゲ
		gsDraw2D(ggNeedle, (int)(PARTS_SIZE*19 -gMapX), PARTS_SIZE*8 + PARTS2_SIZE);
	}
}


//----------------------------------------------------------------------------
// アイテムデバッグ表示
//----------------------------------------------------------------------------
void ItemDebugDraw()
{
	for(int i=0; i<ITEM_MAX; i++)
	{
		gsDrawNum(i*150,200,gItem[i].type);
	}
}

//----------------------------------------------------------------------
//設置
//----------------------------------------------------------------------
void ItemSet()
{
	//種類を設定
	gItem[0].type = TYPE1;//宝箱
	gItem[1].type = TYPE2;//スタミナ回復
	gItem[2].type = TYPE3;//スタミナ減少
	gItem[3].type = TYPE4;//弾数回復
	gItem[4].type = TYPE5;//残機アップ
	gItem[5].type = TYPE6;//トゲ
}



//-------------------------------------------------------------
// アイテムの衝突判定
//-------------------------------------------------------------
void ItemCollision()
{
	//アイテムの数
	for(int i=0; i<ITEM_MAX; i++)
	{
		//存在すれば
		if(gItem[i].flg == ON)
		{
			//衝突判定
			if(gPlayer.x + PLAYER_W_MAX > gItem[i].x &&
				gPlayer.x < gItem[i].x + ITEM_MAX &&
				gPlayer.y + PLAYER_H_MAX > gItem[i].y &&
				gPlayer.y < gItem[i].y + ITEM_MAX)
			{
				//アイテムの存在を消す
				gItem[i].flg = OFF;

				//それぞれのアイテム効果

			}
		}
	}
}


Re: 描画がうまくいきません

Posted: 2012年6月12日(火) 22:25
by softya(ソフト屋)
よく分からずに直しているようにしか見えませんので、私の書いた(1)から(5)まで対処した内容を個々に説明して頂けますか?

Re: 描画がうまくいきません

Posted: 2012年6月12日(火) 23:48
by NABE
softya(ソフト屋) さんが書きました:よく分からずに直しているようにしか見えませんので、私の書いた(1)から(5)まで対処した内容を個々に説明して頂けますか?

(1)ItemStartで10個のアイテムが有効であるとしている。     
 理由はよくわからない

(2)ItemMainでItemSet()する意味が無い。ItemStartですべき。 
 はじめから設定されているから

(3)ItemDrawでif(gItem.type == TYPE1)なら2つの宝箱を無条件に描画。  
 よくわからない。でも言われてみるとおかしい感じがする

(4)ItemSet()で設定しているアイテムは6個。(1)や(3)と矛盾。     
(1)の理由が分かればわかるかも

(5)ItemCollisionで使うgItem.xが初期化された形跡がない。     
初期化するんですか?ここは自信があったので驚いている。
前作ったシューティングゲームで衝突判定でそういうことしていなかったので。

Re: 描画がうまくいきません

Posted: 2012年6月13日(水) 00:15
by softya(ソフト屋)
変数の処理で参照するためには、初期化、変更は何処かでする必要があります。
もし初期化せずに参照していれば、その変数の値は不定ですのでプログラムは99%バグっています。稀に動く場合もありますが、それは単なる偶然です。
NABE さんが書きました:(1)ItemStartで10個のアイテムが有効であるとしている。     
 理由はよくわからない
gItemがITEM_MAX個あると定義していて、gItem.flg = ON;としてるのですから10個有効にしたいのではないですか?
NABE さんは、どういう同理由でgItem.flgってメンバ変数を準備して初期化したのでしょうか?

NABE さんが書きました: (2)ItemMainでItemSet()する意味が無い。ItemStartですべき。 
 はじめから設定されているから


誰が設定したのでしょうか?そして何が設定されていんでしょう。

NABE さんが書きました: (3)ItemDrawでif(gItem.type == TYPE1)なら2つの宝箱を無条件に描画。  
 よくわからない。でも言われてみるとおかしい感じがする


NABE さんはの考えではgItemってなんの情報を蓄える為にあって、宝箱1と宝箱2はどの情報で区別されるんでしょうか?

NABE さんが書きました: (5)ItemCollisionで使うgItem.xが初期化された形跡がない。     
初期化するんですか?ここは自信があったので驚いている。
前作ったシューティングゲームで衝突判定でそういうことしていなかったので。


前作のことはお聞きしませんが上にも書いた通り初期化されていない変数は値が不定です。
gItem.xやgItem.yなどの値が不定の変数は言うなれば出鱈目な数字が落書きされたノートです。
落書きされた数値が書かれたノートと大小比較して何の意味がありますか?

Re: 描画がうまくいきません

Posted: 2012年6月13日(水) 13:46
by ookami
開発環境はVisualStudioでしょうか?
そうだとして、ブレークポイントは使っていますか?
http://www.flow.cs.is.nagoya-u.ac.jp/ha ... g/vs3.html

ブレークポイントでブレークすると、
その瞬間々々での変数の値などが分かるので、デバッグが非常に効率的になります。
gItem.x あたりにブレークポイントをつけて、値を確認してください。
初期化を本当にしていないなら、デタラメな値になっているはずです。

Re: 描画がうまくいきません

Posted: 2012年6月13日(水) 14:03
by naohiro19
「理由はわからない」というのは答えになっていません。

Re: 描画がうまくいきません

Posted: 2012年6月13日(水) 15:48
by ISLe
外部変数なのでゼロ初期化されていると思いますけど、意図しない動作という点は変わらないですかね。