DXライブラリ

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

DXライブラリ

#1

投稿記事 by LOL » 8年前

Windows 8
VS Express 2010 for Desktop
を使用していて
http://akaguro.jp/tetris_dx/tetris_dx_index.shtml
↑のサイトを参考にテトリスを作っています。そこで、ホールド機能を追加したいのですが、どうやって作ればいいのでしょうか?わかる方教えてください

akaguro
記事: 4
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ

#2

投稿記事 by akaguro » 8年前

僭越ながら当該サイト(akaguro.jp)の管理人をやっております者です。
参考にしていただき誠にありがとうございます。
質問にありました「ホールド機能の追加」につきまして回答させていただきます。
いちようホールド機能というのはゲームの動きをストップさせる機能の事でよろしいでしょうか?
そうだとして話を進めさせていただきます。
ホールド機能の事は考えていなかったので現状のソースをあまり崩さない形での
簡易な方法になります。
まずは前準備として例えばspaceキーによってホールドの切り替えを行うとして、
ホールド中かどうかのフラグを別に用意します。
そして押されるたびに「true」「false」を切り替えられる状態にしておきます。
そして当該ソースの動きをつかさどる部分ですが、基本的には「gamecount」というグローバル変数の増加によって
全体的な動きを変化させているのでそこをさきほどのフラグで
<code>
if(hold_flag){
gamecount++;
}
</code>
などのようにすればひとまず動きは止まります。
あとはキー入力受付の「my_move_block」の中身
<code>
if (key[KEY_INPUT_LEFT] % 5 == 1){
}
if (key[KEY_INPUT_RIGHT] % 5 == 1){
}
if (key[KEY_INPUT_DOWN] % 5 == 1){
}
if (key[KEY_INPUT_UP] == 1){
}
if (key[KEY_INPUT_Z] == 1){
}
</code>
このへんのキー入力を受け付けるところもまとめて
同じようにすればとりあえずのホールド機能は実現されると思われます。
あくまでも暫定的な方法になりますのでご了承ください。

LOL

Re: DXライブラリ

#3

投稿記事 by LOL » 8年前

返信いただきありがとうございます。
最後のほうのプログラムでNEXT BLOCKなどを表示させる黒枠を左側にも作り、そこにホールドしたのを表示できるようにしたいと思っています。
その場合は
/*次回ブロック・変数・スコアボックス表示*/
ここのなかに追加でDrawBoxを書いたほうがいいでしょうか?それとも新しく
/*ホールドブロック*/としてDrawBoxを書いたほうがいいですか?
一応同じ中に書いてみたのですが、NEXT BLOCKが表示されなくなってしまったので、後者でしょうか・・・

アバター
amehirune
記事: 181
登録日時: 11年前
住所: どっか
連絡を取る:

Re: DXライブラリ

#4

投稿記事 by amehirune » 8年前

横から失礼します。
ここでいうホールド機能というものは、テトリミノを1つだけ保持することができるというモノでしょうか?
私はぷよぷよテトリスでの感覚が強いので、そういった機能であるという前提で話を進めます。

提示されたサイトは見ていませんが、まず、NEXT表示があるということは、
テトリミノのタイプはIDか何かで管理されている、と考えてよろしいでしょうか?
テトリミノは全部で7種類あるため、IDも0~6の7つだけふられていると仮定します。

まず最初に、ホールド用の変数を定義します。int holdNoなど、適当な変数をintで宣言してください。
この変数に入るのは、ホールドされたテトリミノのIDです。-1、0~6のどれかが入ります。
ここで、ゲームを初期化する際に、holdNoには-1を代入しておいてください。
-1は、「どのテトリミノもホールドされていない」状態を指すことにします。

2つ目に、ホールドボタンが押されたときの処理をかいていきます。
まず、if文でholdNoが-1かどうかを判定します。
-1でなければ、drop中のテトリミノIDとholdNoの値を入れ替えて、テトリミノの位置を初期位置にセットしなおすだけです。
-1であれば、holdNo = dropNoと代入、drop中のテトリミノの処理はスキップして、
通常通り次のテトリミノのセットを行えばいいでしょう。
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

akaguro
記事: 4
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ

#5

投稿記事 by akaguro » 8年前

ホールド機能とはテトリミノを1つだけ保持する機能の事だったのですね。
勘違いしておりました。
上の方が回答してくれております通りなのですが、
当該ソースがあまり簡素な良いコードとはいい難いのでもう少し具体的に
こちらからも再度回答させて頂きます。
http://akaguro.jp/tetris_dx/tetris_dx_index.shtml
の完成ソースに加えるカタチでのホールド機能の実装になります。
まずホールドされたブロックを保存する為の変数、
その時のブロックの種類、回転状態を保存する為の変数をそれぞれ用意します。

コード:

int hold_block[4][4];//ホールドされたブロック
int hold_ran2;//ブロックの種類
int hold_turn_point;//回転状態
あとは最初のホールドなのか2回目以降のホールドなのかのフラグを用意します。

コード:

int hold_block_flag;
あとは上の方も言っている通りに初回はテトリミノをそのまま
ホールドブロックの方に回転状態などと共に保存して次回ブロックを発生させる処理を行い、
2回目以降はそのホールドされたブロックと現在のブロックを入れ替える
作業を行い位置を初期位置に戻すだけです。

コード:

void my_hold_block(){
        //ループ用変数
	int x, y;
        //入れ替え用変数
	int tmp_block[4][4] = { 0 };
	int tmp_ran2;
	int tmp_turn_point;

	if (hold_block_flag == 0){//初回ホールド

                //その時のブロックを「hold_block[4][4]」に移して
               //ブロックの種類・回転状態を保存
               //「my_init_var2();」で次のブロックを発生
               //「hold_block_flag = 1;」フラグをオンにする。

		for (y = 0; y<4; y++){
			for (x = 0; x<4; x++){
				hold_block[y][x] = block[y][x];
			}
		}
		hold_ran2 = ran2;
		hold_turn_point = turn_point;
		my_init_var2();
		hold_block_flag = 1;
	}
	else{//2回目以降ホールド

                //初回にホールドしたブロックとの入れ替えをして
                //次のブロックは発生させないでただ位置を初期に戻す

		for (y = 0; y<4; y++){
			for (x = 0; x<4; x++){
				tmp_block[y][x] = block[y][x];
				block[y][x] = hold_block[y][x];
				hold_block[y][x] = tmp_block[y][x];
				
			}
		}
		tmp_ran2 = ran2;
		tmp_turn_point = turn_point;
		ran2 = hold_ran2;
		turn_point = hold_turn_point;
		hold_ran2 = tmp_ran2;
		hold_turn_point = tmp_turn_point;

		fall = 0;
		side = 6;
		gamecount = 0;
	}
}
こんな感じの処理をすれば良いと思われます。

LOL

Re: DXライブラリ

#6

投稿記事 by LOL » 8年前

お二人とも返信していただきありがとうございました!
akaguroさんのプログラムで試してみますね!本当に助かりました。

LOL

Re: DXライブラリ

#7

投稿記事 by LOL » 8年前

コード:

/*ホールド*/
void my_draw_variable2(){
	int x, y;

	DrawBox(70, 0, 170, 100, Color_Black, TRUE);
	DrawFormatString(100, 0, Color_White, "HOLD");

	for (y = 0; y < BLOCK_HEIGHT; y++){
		for (x = 0; x < BLOCK_WIDTH; x++){
			if (hold_block[y][x] == 1)DrawFormatString(HOLD_BLOCK_X + x * 20, HOLD_BLOCK_Y + y * 20, Color_Yellow, "■");
			else if (hold_block[y][x] == 2)DrawFormatString(HOLD_BLOCK_X + x * 20, HOLD_BLOCK_Y + y * 20, Color_Orange, "■");
			else if (hold_block[y][x] == 3)DrawFormatString(HOLD_BLOCK_X + x * 20, HOLD_BLOCK_Y + y * 20, Color_Blue, "■");
			else if (hold_block[y][x] == 4)DrawFormatString(HOLD_BLOCK_X + x * 20, HOLD_BLOCK_Y + y * 20, Color_Red, "■");
			else if (hold_block[y][x] == 5)DrawFormatString(HOLD_BLOCK_X + x * 20, HOLD_BLOCK_Y + y * 20, Color_Green, "■");
			else if (hold_block[y][x] == 6)DrawFormatString(HOLD_BLOCK_X + x * 20, HOLD_BLOCK_Y + y * 20, Color_Fuchsia, "■");
			else if (hold_block[y][x] == 7)DrawFormatString(HOLD_BLOCK_X + x * 20, HOLD_BLOCK_Y + y * 20, Color_Aqua, "■");
		}
	}
}
void my_hold_block(){
	//ループ用変数
	int x, y;
	//入れ替え用変数
	int tmp_block[4][4] = { 0 };
	int tmp_ran2;
	int tmp_turn_point;

	


	if (hold_block_flag == 0){//初回ホールド

		//その時のブロックを「hold_block[4][4]」に移して
		//ブロックの種類・回転状態を保存
		//「my_init_var2();」で次のブロックを発生
		//「hold_block_flag = 1;」フラグをオンにする。

		for (y = 0; y<4; y++){
			for (x = 0; x<4; x++){
				hold_block[y][x] = block[y][x];
			}
		}
		hold_ran2 = ran2;
		hold_turn_point = turn_point;
		my_init_var2();
		hold_block_flag = 1;
	}
	else{//2回目以降ホールド

		//初回にホールドしたブロックとの入れ替えをして
		//次のブロックは発生させないでただ位置を初期に戻す

		for (y = 0; y < 4; y++){
			for (x = 0; x < 4; x++){
				tmp_block[y][x] = block[y][x];
				block[y][x] = hold_block[y][x];
				hold_block[y][x] = tmp_block[y][x];

			}
		}
		if (key[KEY_INPUT_TAB] == 1){
			hold_block_flag = 1;
		}
		
		tmp_ran2 = ran2;
		tmp_turn_point = turn_point;
		ran2 = hold_ran2;
		turn_point = hold_turn_point;
		hold_ran2 = tmp_ran2;
		hold_turn_point = tmp_turn_point;

		fall = 0;
		side = 6;
		gamecount = 0;
	}
}
これでできないんですけど、どこを変えればいいですか?

akaguro
記事: 4
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ

#8

投稿記事 by akaguro » 8年前

手順としては、
グローバル域にさきほどの変数

コード:

int hold_block[4][4];//ホールドされたブロック
int hold_ran2;//ブロックの種類
int hold_turn_point;//回転状態
int hold_block_flag;
こちらを加えて、
ホールド用に作った関数「my_hold_block()」もどこか適当な場所に加えて、
その「my_hold_block()」を呼び出す為のキーを「my_move_block()」内などに

コード:

if (key[KEY_INPUT_H] == 1){
	my_hold_block();
}
のように設定して最後にその「hold_block[4][4]」を表示すべく、
「my_draw_variable2()」などに「next_block」表示と同じような処理で表示すれば
とりあえずのホールドブロックは実装されると思われます。
http://akaguro.jp/tetris_dx/tetris_dx_index.shtml
こちらの完成ソースに実装したものを改めてアップしておきましたので
もしわからなければ参考にしていただければと思います。
「h」キーでホールドです。

LOL

Re: DXライブラリ

#9

投稿記事 by LOL » 8年前

たびたび申し訳ありません、ブロックの色をランダムで変えることってできるでしょうか?
それと、テトリス風の音楽を入れたいのですが、ループで再生させることもできますか?

hide

Re: DXライブラリ

#10

投稿記事 by hide » 8年前

DXライブラリにランダムに値を生成する関数があります。
DXライブラリに値から色(コード)を作り出す関数があります。
DXライブラリに音楽をループさせるためのフラグがあります。

まず、聞く前に調べました?
http://dxlib.o.oo7.jp/dxfunc.html

akaguro
記事: 4
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ

#11

投稿記事 by akaguro » 8年前

ただいまホームページ(akaguro.jp)改装中の為、
一部ページが閲覧できない状態になっております。
もし閲覧途中でしたら大変ご迷惑をおかけします。
では質問にありました
「ブロックの色をランダムに」についてですが、
その場しのぎの実装になりますが、
まずブロックを作る「my_make_block()」内で
ランダムに色を発生、

コード:

int color;
color = rand % 7 + 1;
//1~7までの数字がcolorに入ります
そして発生させた色で現在のブロックを塗り替える

コード:

for(y=0;y<BLOCK_HEIGHT;y++){
    for(x=0;x<BLOCK_WIDTH;x++){
        if(block[y][x] != 0)block[y][x] = color;
    }
}
みたいな処理を書けばおそらくブロックの色がランダムに発生されると
思われます。
音楽の再生は

コード:

int bgm = LoadSoundMem("音楽ファイルのパス");
で変数「bgm」に音楽ファイル読み込み

コード:

PlaySoundMem(bgm, DX_PLAYTYPE_LOOP);
で繰り返し再生

コード:

StopSoundMem(bgm);
でストップです。
注意点としては音楽ファイル読み込みは画像ファイル読み込みなどと同じように
基本は初期化時に一回読み込めば大丈夫です。
(グローバル変数のように実行中に破棄されない変数の場合)
詳しくは上の方もおっしゃってるとおり
リファレンスをご覧になってみてください。

LOL

Re: DXライブラリ

#12

投稿記事 by LOL » 8年前

返信いただきありがとうございます。
ランダム関数とりあえず試してみます。
また何かあったらよろしくお願いします

閉鎖

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