4つそろったら消えるプログラム(再)

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

4つそろったら消えるプログラム(再)

#1

投稿記事 by icon01 » 11年前

先日、4つ並べて消すプログラムについてご質問させていただいたものですが、解決したと思っていたのが不十分だったので、改めてトピックを立てさせていただきました。

※言葉では伝わりにくいかもしれませんがご容赦を

◆▲◆▲☆◯
◆◯▲☆◯▲
◯◆◆◯▲☆

実際は12*12マス

とまあ、適当に図を書きましたが、これを同じ形のブロックを縦か、横に4つ以上そろうと消えるプログラムを組もうとしているところです。しかし、デバック用に、消す代わりに揃えたブロックを別のブロックに変えるように組んでみたところ、加算ブレンドして気づいたのですが、元の4つのブロックと、変えた後のブロックが二重に表示されるようになってしまうのです。これでは、その次の消えたところを埋める作業に移れません。どなたか助言をよろしくお願いいたします。

コード:

int g_Block[16];	// 画像を入れる変数 
int g_Panel[PANEL_SIZE][PANEL_SIZE];	//パネルの大きさ12*12マス
int g_DelCountW,g_DelCountH;
int g_DeletePanelW[PANEL_SIZE][PANEL_SIZE],g_DeletePanelH[PANEL_SIZE][PANEL_SIZE]; // 1なら消える
int g_CheckPanelW[PANEL_SIZE][PANEL_SIZE],g_CheckPanelH[PANEL_SIZE][PANEL_SIZE]; // 1ならチェック済み
whire文の外で初期化
void InitializePlay(void){
int h,w;
for( h = 0; h < PANEL_SIZE ; h++)
{
    for( w = 0; w < PANEL_SIZE; w++)
    {
        g_Panel[h][w] = GetRand(12);
    }
}
}
以下while文の中での処理
/==============================================================================================
// 消えるブロックの検索
//==============================================================================================
void SearchDelBlock(void){
int h,w;
for( h = 0; h < PANEL_SIZE; h++)
{
    for( w = 0; w < PANEL_SIZE; w++)
    {
        if(g_DeletePanelW[h][w] == 0)
        { // まだ消えていないブロックなら…
            SearchDelBlockW(h, w); // 再帰ルーチン(横)スタート
            if(g_DelCountW >= DEL_MIN)
            { // 消えるなら…
                for(int h2 = 0; h2 < PANEL_SIZE; h2++)
                {
                    for(int w2 = 0; w2 < PANEL_SIZE; w2++)
                    {
                        if(g_CheckPanelW[h2][w2] == 1)
                        {
                            g_DeletePanelW[h2][w2] = 1; // チェックしたブロック→消える
                        }
                    }
                }
            }
            // 次の処理に備えて初期化
            ZeroMemory(g_CheckPanelW, sizeof(g_CheckPanelW));
            g_DelCountW = 0;
        }
    }
}
for( h = 0; h < PANEL_SIZE; h++)
{
    for( w = 0; w < PANEL_SIZE; w++)
    {
        if(g_DeletePanelH[h][w] == 0)
        { // まだ消えていないブロックなら…  
            SearchDelBlockH(h, w); // 再帰ルーチン(縦)スタート
            if(g_DelCountH >= DEL_MIN)
            { // 消えるなら…
                for(int h2 = 0; h2 < PANEL_SIZE; h2++)
                {
                    for(int w2 = 0; w2 < PANEL_SIZE; w2++)
                    {
                         if(g_CheckPanelH[h2][w2] == 1)
                         {
                              g_DeletePanelH[h2][w2] = 1; // チェックしたブロック→消える
                         }
                    }
                }
            }
            // 次の処理に備えて初期化
            ZeroMemory(g_CheckPanelH, sizeof(g_CheckPanelH));
            g_DelCountH = 0;
        }
    }
}
}
//==============================================================================================
// 再帰ルーチン(横)
//==============================================================================================
void SearchDelBlockW(int h, int w){
g_CheckPanelW[h][w] = 1; // チェックしました。
g_DelCountW++;    
if(w + 1 < PANEL_SIZE)
{ //→
    if(g_CheckPanelW[h][w + 1] == 0 && g_Block[g_Panel[h][w]] == g_Block[g_Panel[h][w + 1]])
    {
        SearchDelBlockW(h, w + 1);
    }
}
if(w - 1 >= 0)
{ //←
    if(g_CheckPanelW[h][w - 1] == 0 && g_Block[g_Panel[h][w]] == g_Block[g_Panel[h][w - 1]])
    {
        SearchDelBlockW(h, w - 1);
    }
}
}
//==============================================================================================
// 再帰ルーチン(縦)
//==============================================================================================
void SearchDelBlockH(int h, int w){
g_CheckPanelH[h][w] = 1; // チェックしました。
g_DelCountH++;
if(h + 1 < PANEL_SIZE)
{ //↓
    if(g_CheckPanelH[h + 1][w] == 0 && g_Block[g_Panel[h][w]] == g_Block[g_Panel[h + 1][w]])
    {
        SearchDelBlockH(h + 1, w);
    }
}    
if(h - 1 >= 0)
{ //↑
    if(g_CheckPanelH[h - 1][w] == 0 && g_Block[g_Panel[h][w]] == g_Block[g_Panel[h - 1][w]])
    {
        SearchDelBlockH(h - 1, w);
    }
}
}
//----------------------------
        ステージ描画
//----------------------------
void DrawStage(void){
int h,w;	
for( h = 0; h < PANEL_SIZE ; h++)
{
    for( w = 0; w < PANEL_SIZE; w++)
    {
        if(g_DeletePanelW[h][w] == 0 && g_DeletePanelH[h][w] == 0)
        {
            SetDrawBlendMode( DX_BLENDMODE_ALPHA,  224 );
            DrawGraph( w*32, h*32 , g_Block[g_Panel[h][w]], TRUE );
            SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
        }
        if(g_DeletePanelW[h][w] == 1)
        {
            SetDrawBlendMode( DX_BLENDMODE_ALPHA,  224 );
            DrawGraph( w*32, h*32 , g_Block[9] , TRUE);
            SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
        }
        if(g_DeletePanelH[h][w] == 1)
        {
            SetDrawBlendMode( DX_BLENDMODE_ALPHA,  224 );
            DrawGraph( w*32, h*32 , g_Block[9], TRUE);
            SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
        }		
    }
}
}

アバター
バグ
記事: 130
登録日時: 13年前
住所: 愛媛県
連絡を取る:

Re: 4つそろったら消えるプログラム(再)

#2

投稿記事 by バグ » 11年前

横方向に並んで消える、縦方向に並んで消えるという情報は必要なのでしょうか?
それとも消えるか消えないかの情報だけでも構わないのでしょうか?

icon01

Re: 4つそろったら消えるプログラム(再)

#3

投稿記事 by icon01 » 11年前

バグさん返信ありがとうございます。
バグ さんが書きました:横方向に並んで消える、縦方向に並んで消えるという情報は必要なのでしょうか?
それとも消えるか消えないかの情報だけでも構わないのでしょうか?
質問の意図がわかりかねますが、私のプログラムは「とりあえず4つ塊があったら消える」のを防ぐために、横と縦のルーチンに分けているだけです。(横に4つまたは縦に4つ並ばなければ消えない)

問題としているのは、消した後の処理の描画方法に問題があるのかないのか、消す前の描画情報が残ったまま、その上に新しく消した後の処理が重ねて表示されてしまう原因を知りたいのです。

やはり、文章だけではわかりにくいようですね、至らなくて申し訳ございません。

あと、タイトルに4つそろったら消えるプログラム(再)とありますが、正しくは再帰関数の実装について(再)といったほうが正しかったです。重ね重ね申し訳ございません。

アバター
バグ
記事: 130
登録日時: 13年前
住所: 愛媛県
連絡を取る:

Re: 4つそろったら消えるプログラム(再)

#4

投稿記事 by バグ » 11年前

縦もしくは横に4つ並んだ箇所にチェックを入れる関数のサンプルです。
SearchDeleteBlock関数を呼び出してやることで、g_Vanish配列の消去箇所に対応する箇所が0から1に変化します。あとは、1になった箇所に対して消去処理をおこなってやればOKのはずです。

コード:

//==============================================================================================
// 定数
//==============================================================================================
#define PANEL_SIZE	12
#define DEL_MIN		4

//==============================================================================================
// グローバル変数
//==============================================================================================
int g_Panel[PANEL_SIZE][PANEL_SIZE];			// パネルの大きさ12*12マス
int g_Vanish[PANEL_SIZE][PANEL_SIZE];			// 1なら消える


//==============================================================================================
// 同色で並んでいる個数をカウントして、消去フラグを立てる(再帰関数)
// int posX			= 検査X座標
// int posY			= 検査Y座標
// int moveX		= 横方向移動量
// int moveY		= 縦方向移動量
// int block		= 検査開始箇所の色情報
// int panel[][]	= パネル情報配列
// int vanish[][]	= 消去フラグ配列
// int *count		= 同色で並んでいる個数
//==============================================================================================
void SearchBlock (int posX, int posY, int moveX, int moveY, int block, int panel[PANEL_SIZE][PANEL_SIZE], int vanish[PANEL_SIZE][PANEL_SIZE], int* count)
{
	// 検査座標がパネル外?もしくは違う色が見つかった?
	if (posX < 0 || posX >= PANEL_SIZE ||
		posY < 0 || posY >= PANEL_SIZE ||
		block != panel[posY][posX])
	{
		// 再帰処理終了
		return;
	}
	else
	{
		// カウンタをインクリメント
		++(*count);

		// 次の検査箇所へ移動(再帰処理)
		SearchBlock (posX + moveX, posY + moveY, moveX, moveY, block, panel, vanish, count);
	}

	// 同じ色が指定回数以上続いた?
	if (*count >= DEL_MIN)
	{
		// 消去フラグを立てる
		vanish[posY][posX] = 1;
	}
}

//==============================================================================================
// 消えるブロックの検索
//==============================================================================================
void SearchDeleteBlock (void)
{
	int x;
	int y;
	int count;

	// 消去フラグを初期化
	for (y = 0; y < PANEL_SIZE; ++y)
	{
		for (x = 0; x < PANEL_SIZE; ++x)
		{
			g_Vanish[y][x] = 0;
		}
	}
	
	// 消去箇所の探索
	for (y = 0; y < PANEL_SIZE; ++y)
	{
		for (x = 0; x < PANEL_SIZE; ++x)
		{
			// 縦方向サーチ
			count = 0;
			SearchBlock (x, y, 0, 1, g_Panel[y][x], g_Panel, g_Vanish, &count);

			// 横方向サーチ
			count = 0;
			SearchBlock (x, y, 1, 0, g_Panel[y][x], g_Panel, g_Vanish, &count);
		}
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	//
	// ここに到達した時点で、g_Vanishの縦もしくは横に4つ以上並んでいる箇所が1になっています。
	//
	///////////////////////////////////////////////////////////////////////////////////////////////
}

icon01

Re: 4つそろったら消えるプログラム(再)

#5

投稿記事 by icon01 » 11年前

 私とバグさんの間には、何か齟齬があるようです。私が全面的に間違っている可能性も否定できませんが。

私は、ブロックの検索をする関数の実装はできている(つもり)です。

◆▲◆▲☆◯           ◆▲◆▲☆◯         ◆▲◆▲☆◯ 
◆◯▲☆◆▲           ◆◯▲☆◆▲         ◆◯▲☆◆▲
◯◆◆◯◆☆      ⇒    ◯◆◆◆◆☆   ⇒     ◯★★★★☆     
☆☆◯◆▲◯           ☆☆◯◯▲◯         ☆☆◯◯▲◯
◆▲◆▲☆◯           ◆▲◆▲☆◯         ◆▲◆▲☆◯

上記のように◯と◆を入れ替えると(便宜的に)★に代わるようにプログラムを組んでみました。しかし、実際は

◆◆◆◆の上に★★★★が重ねて表示されてしまうのです。

と、ここまで書いてから冷静になって考えてみたのですが、バグさんはルーチンの書き方に間違いがあるとにらんでいるのでしょうか?私は描画処理のほうにばかり意識が行ってしまっていたので。もしバグさんのにらんだ通りなら、その通りに書けば、重ねて表示されることもなくなるのでしょうか?

icon01

Re: 4つそろったら消えるプログラム(再)

#6

投稿記事 by icon01 » 11年前

 フォーラムに違反していたらすみませんが、埋もれさせたくない質問なので改めてお聞きしたいと思います。

上にも書いた通り、
icon01 さんが書きました: 

私は、ブロックの検索をする関数の実装はできている(つもり)です。

◆▲◆▲☆◯           ◆▲◆▲☆◯         ◆▲◆▲☆◯ 
◆◯▲☆◆▲           ◆◯▲☆◆▲         ◆◯▲☆◆▲
◯◆◆◯◆☆      ⇒    ◯◆◆◆◆☆   ⇒     ◯★★★★☆     
☆☆◯◆▲◯           ☆☆◯◯▲◯         ☆☆◯◯▲◯
◆▲◆▲☆◯           ◆▲◆▲☆◯         ◆▲◆▲☆◯

上記のように◯と◆を入れ替えると(便宜的に)★に代わるようにプログラムを組んでみました。しかし、実際は

◆◆◆◆の上に★★★★が重ねて表示されてしまうのです。

と、ここまで書いてから冷静になって考えてみたのですが、バグさんはルーチンの書き方に間違いがあるとにらんでいるのでしょうか?私は描画処理のほうにばかり意識が行ってしまっていたので。もしバグさんのにらんだ通りなら、その通りに書けば、重ねて表示されることもなくなるのでしょうか?
どなたか返信お願いできないでしょうか。

Poco
記事: 161
登録日時: 13年前

Re: 4つそろったら消えるプログラム(再)

#7

投稿記事 by Poco » 11年前

早く回答が欲しいのであれば、現象を再現可能なソースコード/リソース一式を提示されてみてはどうでしょうか?
机上デバッグしかできない現状では、回答者のゲスパー能力頼みになってしまいます。

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#8

投稿記事 by icon01 » 11年前

pocoさんの言葉を聞き、ファイルの添付を行おうと思ったのですが、

参照してファイルの追加のボタンを押したところ
しばらく読み込んだ後、
IEではこのページを開けませんと言われてしまいました。

どうすれば、正しくファイルの添付が行えるのでしょうか。

アバター
バグ
記事: 130
登録日時: 13年前
住所: 愛媛県
連絡を取る:

Re: 4つそろったら消えるプログラム(再)

#9

投稿記事 by バグ » 11年前

1:4つ以上同じブロックが並んでいる箇所を見つける ・・・ おそらく出来ているだろう。

2:1で検出された箇所へ、「空白のブロック」を描画する(ようするに今描画されているブロックを消してください) ・・・ 出来ていますか?

3:1で検出された箇所へ、「新しいブロック(今回だと★?)」を描画する ・・・ 出来ていますか?


全体の流れを追いかけるほどは読み込んでいないので、なんとなくで書いてますが、重ねて描画されるとしたら、2が抜けてるような気がします。


※パネポンみたいなゲームを目指しているのでしょうか?

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

Re: 4つそろったら消えるプログラム(再)

#10

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

ファイル添付は、zipファイルの場合8MB程度に納めて下さい。
なので、ソースコードだけとか画像だけとかファイルを分ける必要があるかも知れません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#11

投稿記事 by icon01 » 11年前

バグさんsoftyaさん返信ありがとうございます。

一応ファイルの添付ができましたのでよかったら見てください。

タイトルでは上下キーでスタートを選び押してプレイ画面へ、ゲーム終了で終了。他はまだ作っていないので押さないでください。
操作方法としては、薄緑色のカーソルを方向キーで動かして任意の画像の上に持っていき、spaceで二枚の画像の入れ替えができます。縦か横に4つ以上揃うと鉄?のブロックに変化しますが、元のブロックが下に透けて見えると思います。
プレイ画面からタイトル画面へはxキーで戻れます。

>バグさん

コード:

void DrawStage(void){
int h,w;    
for( h = 0; h < PANEL_SIZE ; h++)
{
    for( w = 0; w < PANEL_SIZE; w++)
    {
        if(g_DeletePanelW[h][w] == 0 && g_DeletePanelH[h][w] == 0)
        {
            SetDrawBlendMode( DX_BLENDMODE_ALPHA,  224 );
            DrawGraph( w*32, h*32 , g_Block[g_Panel[h][w]], TRUE );
            SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
        }
        if(g_DeletePanelW[h][w] == 1)
        {
            SetDrawBlendMode( DX_BLENDMODE_ALPHA,  224 );
            DrawGraph( w*32, h*32 , g_Block[9] , TRUE);
            SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
        }
        if(g_DeletePanelH[h][w] == 1)
        {
            SetDrawBlendMode( DX_BLENDMODE_ALPHA,  224 );
            DrawGraph( w*32, h*32 , g_Block[9], TRUE);
            SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
        }       
    }
}
}
上記の書き方がそもそも自分でも腑に落ちなくて、何度も書き換えたりしているのですが、if文でブロックの種類を違えるだけでなく、一度消す処理を入れなければならないということでしょうか。その場合、InitGraph()を使ったりするのでしょうか?
添付ファイル
CG・BGM.zip
(5.02 MiB) ダウンロード数: 92 回
ソースファイル.zip
(5.56 KiB) ダウンロード数: 94 回

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#12

投稿記事 by icon01 » 11年前

追記

コード:

void DrawStage(void){
int h,w;    
for( h = 0; h < PANEL_SIZE ; h++)
{
    for( w = 0; w < PANEL_SIZE; w++)
    {
        if(g_DeletePanelW[h][w] == 0 && g_DeletePanelH[h][w] == 0)
        {
            SetDrawBlendMode( DX_BLENDMODE_ALPHA,  224 );
            DrawGraph( w*32, h*32 , g_Block[g_Panel[h][w]], TRUE );
            SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
        }
        if(g_DeletePanelW[h][w] == 1)
        {
            SetDrawBlendMode( DX_BLENDMODE_ALPHA,  160 );
            DrawGraph( w*32, h*32 , g_Block[9] , TRUE);
            SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
        }
        if(g_DeletePanelH[h][w] == 1)
        {
            SetDrawBlendMode( DX_BLENDMODE_ALPHA,  160 );
            DrawGraph( w*32, h*32 , g_Block[9], TRUE);
            SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
        }       
    }
}
}
このように書き換えてみたところ、下の画像は見えなくなりました。が、
ずっと言い忘れていましたが、
鉄のブロックが初期化(Xキーでタイトルに戻っても)消えずに残るんです。・・・なんで?

アバター
バグ
記事: 130
登録日時: 13年前
住所: 愛媛県
連絡を取る:

Re: 4つそろったら消えるプログラム(再)

#13

投稿記事 by バグ » 11年前

WinMain関数のwhileループの条件を

while (ProcessMessage() == 0 && g_flag == 0 && ClearDrawScreen() == 0)

としてみてください。

あと、DrawStage関数のループ内も下記でいいと思います。

コード:


if (g_DeletePanelW[h][w] == 0 && g_DeletePanelH[h][w] == 0)
{
	SetDrawBlendMode(DX_BLENDMODE_ALPHA, 224);
	DrawGraph(w * 32, h * 32, g_Block[g_Panel[h][w]], TRUE);
	SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
}
else
{
	SetDrawBlendMode(DX_BLENDMODE_ALPHA, 160);
	DrawGraph(w * 32, h * 32, g_Block[9], TRUE);
	SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
}

パっと見て気付いたのはこんなとこかな?

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#14

投稿記事 by icon01 » 11年前

バグさんの通りに組んでみましたが、変化はありませんでした。

そもそも、ClearDrawScreen() == 0をwhileループの条件に入れる意味はないように思えるのですが・・・。相変わらず鉄のブロックは出現した後初期化しても消えてくれません。

それと、鉄のブロックはBlock[9]ではなくBlock[7]ですね、今気づきました。

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

Re: 4つそろったら消えるプログラム(再)

#15

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

icon01 さんが書きました:バグさんの通りに組んでみましたが、変化はありませんでした。

そもそも、ClearDrawScreen() == 0をwhileループの条件に入れる意味はないように思えるのですが・・・。相変わらず鉄のブロックは出現した後初期化しても消えてくれません。

それと、鉄のブロックはBlock[9]ではなくBlock[7]ですね、今気づきました。
DXライブラリでは、特に初心者はClearDrawScreen()は毎フレーム行う必要があると思ってもらったほうが良いと思います。
※ すごく特殊なエフェクトでも行わない限り毎フレーム行う事は必須です。そのようなエフェクトを初心者が使うとは思えません。
ScreenFlip()とセットですので見て分かる位置関係にある必要がありますので、whileの中にある必然は無いですがwhileループ中の適切な位置にある事は必須です。

「Block[9]ではなくBlock[7]ですね」と言う点も間違えやすいので#defineでBLOCK_NOとか定義して使って下さい。Block[BLOCK_NO]とします。

それと動かしてみたのですが問題点が再現あるいは理解できませんでした。
もう一度再現手順を説明して下さい。

【補足】
ClearDrawScreen(); がDrawSceneにあるみたいですが、それはプログラムを大変わかりづらくしバグのもとになります。
そのせいでバグさんも勘違いされたのです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
バグ
記事: 130
登録日時: 13年前
住所: 愛媛県
連絡を取る:

Re: 4つそろったら消えるプログラム(再)

#16

投稿記事 by バグ » 11年前

>>そもそも、ClearDrawScreen() == 0をwhileループの条件に入れる意味はないように思えるのですが・・・。

こちらのプロジェクトでは重ならずに普通に描画されていますが・・・?

>>相変わらず鉄のブロックは出現した後初期化しても消えてくれません。
>>それと、鉄のブロックはBlock[9]ではなくBlock[7]ですね、今気づきました。

すみませんが、どう動いて、どう描画されたら正しいのかをもう一度、細かく、具体的に書いていただけませんか?

icon01さんの頭の中の完成図は私には見えませんので・・・

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#17

投稿記事 by icon01 » 11年前

バグさん、softyaさん返信ありがとうございます。

まず、私が問題としているのは、4つ揃えて鉄のブロックを出現させた後、その上でもう一度spaceを押すと、下に描画されている画像は左右入れ替わるが、鉄のブロックは微動だにせず、また、初期化(Xキーでタイトルに戻る)しても鉄のブロックが残ったままになるということです。(重ならずに鉄ブロックだけ表示できていても、試していただけると分かると思います)

 ▲▲▲◯▲ を▲▲▲▲◯にして ★★★★◯
                             ↑
                     ここにカーソルを合わせてspace
すると、★★★★▲
     ▲▲▲◯▲(下に透けて見える)


下の画像が変化しないことには、パズルとして成立しないと思うのですが・・・

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#18

投稿記事 by icon01 » 11年前

間違えて送信してしまったので追記。

私は下の画像そのものを鉄のブロック(最終的に描画しない)に変化させたいのですが、今のプログラムでは下のデータはそのままで、上に新たに別のデータが重ねて描画されてしまうのを良しとしないのです。

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

Re: 4つそろったら消えるプログラム(再)

#19

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

少なくとも下に透けては見えませんね。
あとg_Panelを鉄ブロックに書き換えていない様ですから鉄ブロックになっているはずはないと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#20

投稿記事 by icon01 » 11年前

if文をいじりすぎたせいで今の自分のプログラムとsoftoyaさんに渡したものが違うのでしょうね。

おそらくsoftoyaさんに渡したものは4つ揃えると何も表示されなくなると思うのですが、
icon01 さんが書きました:バグさん、softyaさん返信ありがとうございます。

まず、私が問題としているのは、4つ揃えて鉄のブロックを出現させた後、その上でもう一度spaceを押すと、下に描画されている画像は左右入れ替わるが、鉄のブロックは微動だにせず、また、初期化(Xキーでタイトルに戻る)しても鉄のブロックが残ったままになるということです。(重ならずに鉄ブロックだけ表示できていても、試していただけると分かると思います)

 ▲▲▲◯▲ を▲▲▲▲◯にして ★★★★◯
                             ↑
                     ここにカーソルを合わせてspace
すると、★★★★▲
     ▲▲▲◯▲(下に透けて見える)


下の画像が変化しないことには、パズルとして成立しないと思うのですが・・・
以上のことを試していただけると、同じ現象が起こると思います。

ちなみに今の私のプログラムは

コード:


if (g_DeletePanelW[h][w] == 0 && g_DeletePanelH[h][w] == 0)
{
    SetDrawBlendMode(DX_BLENDMODE_ALPHA, 224);
    DrawGraph(w * 32, h * 32, g_Block[g_Panel[h][w]], TRUE);
    SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
}
else
{
    SetDrawBlendMode(DX_BLENDMODE_ALPHA, 160);
    DrawGraph(w * 32, h * 32, g_Block[9], TRUE);
    SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
}
バグさんに倣いこのようにしています。

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

Re: 4つそろったら消えるプログラム(再)

#21

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

[7]のことろ[9]になっている間違いがあると言うことなので[7]に修正してあります。
同じか分からないプログラムで論じていても意味が無いので最新のソースを全部添付して下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#22

投稿記事 by icon01 » 11年前

softoyaさん、何度も申し訳ございません。

添付したファイルでは、下のブロックは描画されず、上のブロックだけ描画されるようになっているはずです。

その上で、spaceキーを押して確かめていただけると、下の画像だけが入れ替わり、鉄のブロックは微動だにしないことがわかっていただけるかと思います。
添付ファイル
ソースファイル.zip
(5.57 KiB) ダウンロード数: 89 回

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

Re: 4つそろったら消えるプログラム(再)

#23

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

icon01 さんが書きました:softoyaさん、何度も申し訳ございません。

添付したファイルでは、下のブロックは描画されず、上のブロックだけ描画されるようになっているはずです。

その上で、spaceキーを押して確かめていただけると、下の画像だけが入れ替わり、鉄のブロックは微動だにしないことがわかっていただけるかと思います。
ごめんなさい。
問題点は何なのでしょうか?
g_Panelを鉄ブロックに書き換えていないと指摘したはずですから、この状態で当たり前だと思います。
どうしたいのでしょうか?

1)下の画像を鉄ブロックしたい。 → g_Panelの該当ブロックを鉄ブロックに書き換えて下さい。それとg_DeletePanelW[h][w] == 0 && g_DeletePanelH[h][w] == 0で判定するのを止めて下さい。これで鉄ブロックにした上で交換可能になります。
2) 鉄ブロックなら画像を交換できないようにしたい  → 交換をガードする判定処理を入れて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#24

投稿記事 by icon01 » 11年前

softyaさん、バグさん、無事解決することができました。ありがとうございます。
コード載せておきます。

コード:

//==============================================================================================
// 消えるブロックの検索
//==============================================================================================
void SearchDelBlock(void){
int h,w;
for( h = 0; h < PANEL_SIZE; h++)
{
    for( w = 0; w < PANEL_SIZE; w++)	
    {
        if(g_DeletePanelW[h][w] == 0)
        { // まだ消えていないブロックなら…
            SearchDelBlockW(h, w); // 再帰ルーチン(横)スタート
            if(g_DelCountW >= DEL_MIN)
            { // 消えるなら…
                for(int h2 = 0; h2 < PANEL_SIZE; h2++)
                {
                    for(int w2 = 0; w2 < PANEL_SIZE; w2++)
                    {
                        if(g_CheckPanelW[h2][w2] == 1)
                        {
                            g_DeletePanelW[h2][w2] = 1; // チェックしたブロック→消える

                            g_Panel[h2][w2] = 7;    //ここに追加

                        }
                    }
                }
            }
            // 次の処理に備えて初期化
            ZeroMemory(g_CheckPanelW, sizeof(g_CheckPanelW));
            g_DelCountW = 0;
        }
    }
}
for( h = 0; h < PANEL_SIZE; h++)
{
    for( w = 0; w < PANEL_SIZE; w++)
    {
        if(g_DeletePanelH[h][w] == 0)
        { // まだ消えていないブロックなら…
            SearchDelBlockH(h, w); // 再帰ルーチン(縦)スタート
            if(g_DelCountH >= DEL_MIN)
            { // 消えるなら…
                for(int h2 = 0; h2 < PANEL_SIZE; h2++)
                {
                    for(int w2 = 0; w2 < PANEL_SIZE; w2++)
                    {
                        if(g_CheckPanelH[h2][w2] == 1)
                        {
                            g_DeletePanelH[h2][w2] = 1; // チェックしたブロック→消える

                            g_Panel[h2][w2] = 7;//此処も追加

                        }
                    }
                }
            }
            // 次の処理に備えて初期化
            ZeroMemory(g_CheckPanelH, sizeof(g_CheckPanelH));
            g_DelCountH = 0;
        }
    }
}
}
void DrawStage(void){
int h,w;
for( h = 0; h < PANEL_SIZE ; h++)
{
    for( w = 0; w < PANEL_SIZE; w++)
    {
        SetDrawBlendMode( DX_BLENDMODE_ALPHA,  224 );
        DrawGraph( w*32, h*32 , g_Block[g_Panel[h][w]], TRUE );
        SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );
    }
}
}
これをもって解決とさせていただきます。
2日にわたり私ごときに付き合ってくださり大変ありがとうございました。

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

Re: 4つそろったら消えるプログラム(再)

#25

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

これ直ってませんが?

>「Block[9]ではなくBlock[7]ですね」と言う点も間違えやすいので#defineでBLOCK_NOとか定義して使って下さい。Block[BLOCK_NO]とします。

#define IRON_BLOCK_NO (7)
としてはどうでしょう?
g_Panel[h2][w2] = IRON_BLOCK_NO; //ここに追加
こんな感じで使います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

icon01
記事: 25
登録日時: 11年前

Re: 4つそろったら消えるプログラム(再)

#26

投稿記事 by icon01 » 11年前

ご指摘ありがとうございます。

#define BLOCK_NO 7

g_Panel[h2][w2] = BLOCK_NO;

という書き方に直していたのを、投稿用に書き直したときなぜか元に戻っていたようです。申し訳ありませんでした。

閉鎖

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