ほぼ初心者です。テトリスのステージとフィールドについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
taka_taka
記事: 79
登録日時: 11年前

ほぼ初心者です。テトリスのステージとフィールドについて

#1

投稿記事 by taka_taka » 11年前

前、15パズルを作成しまして、現在、テトリスを作成しようとしています。

1.下記、main.cpp、Stage.cpp、Stage.hを作成しましたが、いかがなのでしょうか。
 0を何もない場所、9を壁としましたが、壁の表示には使っていません。

色々と情報はありますが、下記wikiのプレイフィールドは、壁以外の0の場所とはことなるのでしょうか。

壁とブロックの計算は、必要だと思っていますが、よくわかってないです。
http://wiki.game-develop.com/index.php? ... C#l8e30baf

2.また、Stage.cppとは別にBlocs.cppを作ろうと思っているのですが、いかがなのでしょうか。
分ける必要はないのでしょうか。
メリットデメリット等がよくわかっていません。

コード:

//インクルード_dxライブラリ
#include "DxLib.h"

//インクルード_ローカル
#include "Stage.h"

//グローバル変数

/* ************************************** *
 * 関数名 :WINAPI WinMain                *
 * 概要   :ここからプログラムが動き出す  *
 * 戻り値 :0                             *
 * ************************************** */
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

	//MessageBoxの戻り値用変数
	int flag;

	//ウィンドウモードに変更	
	ChangeWindowMode(true); 

	//DXライブラリ初期化
	if (DxLib_Init() != 0)
	{
		//エラーメッセージを表示
		flag = MessageBox(
                NULL ,
                TEXT("DxLib_Init() err") ,
                TEXT("Err") , 
                MB_OK);
		return -1;
	}

	//ステージの初期化
	Stage_Initialize();

	while( 1 ){

		// 裏画面の内容を表画面に表示
		if( ScreenFlip() != 0 ){
			//エラーメッセージを表示
			flag = MessageBox(
					NULL ,
					TEXT("ScreenFlip err") ,
					TEXT("Err") , 
					MB_OK);

				break;
		}
		
		//メッセージ処理
		if( ProcessMessage() != 0 ){
			//エラーメッセージを表示
			/*flag = MessageBox(
					NULL ,
					TEXT("ProcessMessage err(End)") ,
					TEXT("Err") , 
					MB_OK);
			*/
				break;
		}

		// 画面を初期化
		if( ClearDrawScreen() != 0 ){
			//エラーメッセージを表示
			flag = MessageBox(
					NULL ,
					TEXT("ClearDrawScreen err") ,
					TEXT("Err") , 
					MB_OK);
	
			break;
		}

		//ステージの描画
		Stage_Draw();
	}

	//ステージの終了処理
	void Stage_Finalize();

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

	//ソフトの終了
	return 0;

}

コード:

//インクルード_dxライブラリ
#include "DxLib.h"

//インクルード_ローカル
#include "Stage.h"

//グローバル変数
static const int MAX_WIDTH = 12;	//壁を含めたステージの横幅
static const int MAX_HEIGHT = 21;	//壁を含めたステージの高さ
static const int Block_Size = 20;
static Stage_t Stage;

/*********************************************************
宣言	:	Stage_Initialize()
概略	:	Stage.Stage[width][height]の値の初期化とステージ画像の初期化
引数	:	なし
戻り値	:	なし
*}********************************************************/
void Stage_Initialize(){

	int width;
	int height;

	//Stageの壁を9に、それ以外を0に初期化
	for(width = 0; width < MAX_WIDTH; width++)
	{
		for(height = 0; height < MAX_HEIGHT; height++)
		{
			if (width == 0 || width == MAX_WIDTH - 1 || height == 0)
			{
				Stage.Stage[width][height] = 9;

			} else {
				Stage.Stage[width][height] = 0;
			}
		}
	}
	
	Stage.Handle_stage = LoadGraph(TEXT("C:/Documents and Settings/All Users/Documents/My Pictures/Sample Pictures/block_kabe.png"));

}

/************************************************
宣言 : Stage_Draw()
概略 : ステージの描画処理
引数 : なし
戻り値:  なし
*}*********************************************/
void Stage_Draw(){

	int width;
	int height;
	int x = 0;
	int y = 0;
	
	DrawGraph( 0, 0, Stage.Handle_stage, FALSE);

	for(height = 0; height < MAX_HEIGHT; height++)
	{
		DrawGraph( 0, y, Stage.Handle_stage, TRUE );
		DrawGraph( (MAX_WIDTH - 1) * Block_Size, y, Stage.Handle_stage, TRUE );
		y += Block_Size;
	}
	
	for(width = 0; width < MAX_WIDTH; width++)
	{
		DrawGraph( x, (MAX_HEIGHT - 1) * Block_Size, Stage.Handle_stage, TRUE );
		x += 20;
	}
	
}

/************************************************
宣言 : Stage_Finalize()
概略 : ステージの終了処理
引数 : なし
戻り値:  なし
*}*********************************************/
void Stage_Finalize(){
	
	DeleteGraph(Stage.Handle_stage);

}

コード:

#ifndef DEF_Stage_H //二重include防止

#define DEF_Stage_H

typedef struct{
	int Handle_stage;	//壁の画像の格納用変数(画像の読み込み用変数)
	int Stage[12][21];		//Stage情報の格納用変数
} Stage_t;

// 初期化をする
void Stage_Initialize();

// 描画する
void Stage_Draw();

// 終了処理をする
void Stage_Finalize();

#endif 

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#2

投稿記事 by h2so5 » 11年前

結局のところ現状、何が問題となっているのでしょうか。
それがよく分からないのですが。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#3

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

一度作って、リファインすることで見てくることもあります。
最初からコードの分割を決めて作るのは慣れてからで良いのでは?
それとmainとか前回の注意点が全然生かされていません、出ても困るエラーメッセージに意味は無いのです。
やり過ぎはコードの可読性を下げてバグの原因となります。

あと、テトリスの仕様を出来るだけ日本語で細かく書き出して見ることをオススメします。
詳細設計の作業です。ここが出来ていないからファイルや関数の構造が見えてこないのでは?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

お答えを頂きまして、ありがとうございます。

#4

投稿記事 by taka_taka » 11年前

>h2so5様
わかりずらくて、申し訳ございません。

>softya(ソフト屋)様
おっしゃるように、設計段階で、不明瞭な点が多いので、迷いが多いのだと思います。
仕様も含めて、詳細設計を考えて見ます。多分、ここも難しいかもしれませんが、
がんばってみます。
ちなみに、このレベルは、詳細設計を考えずにできるレベルは最低でも必要な感じでしょうか。
softya(ソフト屋) さんが書きました: 一度作って、リファインすることで見てくることもあります。
最初からコードの分割を決めて作るのは慣れてからで良いのでは?
それとmainとか前回の注意点が全然生かされていません。
出ても困るエラーメッセージに意味は無いのです。やり過ぎはコードの可読性を下げてバグの原因となります。
ありがとうございます。一度、最後まで作ってみます。
前回のエラーメッセージの処理が生かされておりませんでした。
気をつけます。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#5

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

プログラムを設計する上で大事なのは、物事を整理することだと思います。
で、前回の16パズルのトピックで色んな意見が出ていたはずですが、それを整理できていないのは問題かと思います。
まず読み直して、みなさんの意見を整理して書きだしてみましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#6

投稿記事 by Dixq (管理人) » 11年前

# のんびり書いてる内にコメントが古くなりました・・。

他の方もかかれていますが、コードに冗長性の高い記述が多くて少々読みにくいです。
このレベルなら関数ヘッダすら不要に感じます。
例えば

コード:

/************************************************
宣言 : Stage_Finalize()
概略 : ステージの終了処理
引数 : なし
戻り値:  なし
*}*********************************************/
void Stage_Finalize(){
    
    DeleteGraph(Stage.Handle_stage);
 
}
これは関数ヘッダの意味を成しているでしょうか。
私には以下のようなコメントと同じように見えます。

if( a == 0 ){ // もしaが0なら

変数名、関数名は説明なしで分かるように命名すべきであり、説明なしで分かるのなら不要かと思います。
現在書かれている関数ヘッダはどれも必要に思いませんし、色々シンプルに書けばかなり短くすっきりすると思いますよ。

もしゲームプログラミングの経験があまりないのであれば最初は試行錯誤でがむしゃらにコーディングし、後からじっくりリファクタリングするという手順が良いかもしれません。
一通りコーディングが終わってから、ここはこういう分担、あそこはあぁいう分担・・とカテゴライズしていけば、機能分割やクラス化が見えてくるかもしれません。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#7

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

確かに16パズルより冗長なコメントになっていますね。
ちなみに、関数ヘッダの書き方は業務アプリを参考にしたようです。

私的にも
宣言 : Stage_Finalize()
引数 : なし
戻り値: なし
は不要だと思います。

私が気になるのは、「Stage.Stage[width][height]の値の初期化とステージ画像の初期化」とかですね。
見れば分かることですので、要点だけ書いてもらえばOKです。
「ステージの初期化と画像のロード」で十分でしょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#8

投稿記事 by Dixq (管理人) » 11年前

逆に説明して欲しい部分に説明が無い状態になっているように思います。
例えば

Stage.Stage[width][height] = 9;

このコードを初めて見た人は「?」となるでしょう。
マジックナンバーはなるべくコードに埋め込まず、定義するなりして定義値を入れるようにすることをお勧めします。
誰が初めて読んでも文章を読むようにスッと読めるようなコーディングをするのが理想です。

taka_taka
記事: 79
登録日時: 11年前

アドバイスを頂きまして、ありがとうございます。

#9

投稿記事 by taka_taka » 11年前

>Dixq (管理人)様
Dixq (管理人) さんが書きました:もしゲームプログラミングの経験があまりないのであれば最初は試行錯誤でがむしゃらにコーディングし、
後からじっくりリファクタリングするという手順が良いかもしれません。
一通りコーディングが終わってから、ここはこういう分担、あそこはあぁいう分担・・
とカテゴライズしていけば、機能分割やクラス化が見えてくるかもしれません。
ありがとうございます。
ゲームプログラミングとC言語は、ほぼ初心者です。
プログラミングも、業務用アプリケーションの改良がメインで、ほぼテンプレート化したコーディングをしています。
普段は、既存のデータ量とコード量、システムのバグの損害が大きすぎるため、ミスができないためです。
コメントはほぼ定型的に書いていたためよくない感じだったかもしれません。
後は自分の力量不足かもしれません。

冗長性は、なかなか抜けきれないかもしれませんが、がんばってみます。
Dixq (管理人) さんが書きました: Stage.Stage[width][height] = 9;このコードを初めて見た人は「?」となるでしょう。マジックナンバーはなるべくコードに埋め込まず、定義するなりして定義値を入れるようにすることをお勧めします。
誰が初めて読んでも文章を読むようにスッと読めるようなコーディングをするのが理想です。
ありがとうございます。マジックナンバーは無いように気をつけます。
テトリスの作成を進めてみます。

taka_taka
記事: 79
登録日時: 11年前

すいません。コードを追記しましたので、よろしくお願いします。

#10

投稿記事 by taka_taka » 11年前

下記のサイトを参考に、dxライブラリで、壁と一番上に四角いボックス
□               ■■          □    
□               ■■          □       
□                            □
□                            □


としたいのですが、うまくいきません。
http://www.nhk.or.tv/kow/program/program_124.php
コードの悪い部分を、デバックで探そうとしましたが、drawのifの箇所かと思いますが、
他にございますでしょうか。

※コードは、追記してあります。申し訳ございません。

コード:

//インクルード_dxライブラリ
#include "DxLib.h"

//インクルード_ローカル


//グローバル変数
static const int STAGE_ZERO = 0;	//ステージの左壁と壁の底を表す数字
static const int MAX_WIDTH = 12;	//ステージの横幅の最大値
static const int MAX_HEIGHT = 21;	//ステージの高さの最大値
static const int Block_Size = 20;	//1ブロックの辺の大きさ
static const int Data_Size = 4;		//1ブロックのデータサイズ

static int Handle_Stage;
static int Handle_Block;
static int block[Data_Size][Data_Size] = {{0, 0, 0, 0},{0, 1, 1, 0},{0, 1, 1, 0},{0, 0, 0, 0}};
static int field[MAX_HEIGHT][MAX_WIDTH] = {0};
static int stage[MAX_HEIGHT][MAX_WIDTH] = {0};

//関数
void Stage_Initialize(){

	int i,j;

	for(i = 0; i < MAX_HEIGHT; i++)
	{
		stage[STAGE_ZERO][i] = 9;
		stage[MAX_WIDTH - 1][i] = 9;
	}

	for(i = 0; i < MAX_WIDTH; i++)
	{
		stage[i][MAX_HEIGHT - 1] = 9;
	}

	for(i = 0; i<Data_Size; i++)
	{
		for(j = 0; j<Data_Size; j++)
		{
			field[i][j] = stage[i][j] + block[i][j];
		}
	}
	
	Handle_Stage = LoadGraph(TEXT("C:/Documents and Settings/All Users/Documents/My Pictures/Sample Pictures/テトリス/block_kabe.png"));
	Handle_Block = LoadGraph(TEXT("C:/Documents and Settings/All Users/Documents/My Pictures/Sample Pictures/テトリス/block_white.png"));
}

void Stage_Draw(){

	int i;
	int j;

	for(i = 0; i<MAX_WIDTH; i++)
	{
		for(j = 0; j < MAX_HEIGHT; j++)
		{
			if (field[i][j] == 1)
			{
				DrawGraph( i * 20, j * 20, Handle_Block, TRUE );
			
			} else if (field[i][j] >= 9){
			
				DrawGraph( i * 20, j * 20, Handle_Stage, TRUE );
			}		}
	}
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

	//ウィンドウモードに変更	
	ChangeWindowMode(true), DxLib_Init() != 0, SetDrawScreen( DX_SCREEN_BACK );

	//ステージの初期化
	Stage_Initialize();

	while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0){

		//ステージの描画
		Stage_Draw();
	}

	//ステージの終了処理
	void Stage_Finalize();

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

	//ソフトの終了
	return 0;

}
最後に編集したユーザー taka_taka on 2013年2月06日(水) 18:25 [ 編集 2 回目 ]

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#11

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

前にロードでフルパスは辞めたほうが良いと注意されてませんでした?
上にも書きましたが、注意されたことを整理されたほうが良いと思いますよ。

それと、WinMainのヘッダコメントが一番無駄だと思います。みんながわかっていることで、今後も変更されるとも思えません。
ソースを見た時の区切りとしては意味があるんですけどね。

気になる所。
・1や9や20の即値
・上にも書いたフルパス
・HEIGHTとWIDTHが混乱しています。i,jを使わずにw,hと分かりやすく書きなおしてみてください。
問題に気づけると思います。
・同じ座標に2度書いているんですが?

コード:

                    DrawGraph( i * 20, j * 20, Handle_Stage, TRUE );
                    DrawGraph( i * 20, j * 20, Handle_Stage, TRUE );
・転送しているところが意図とズレていると思います。

コード:

    for(i = 0; i<Data_Size; i++)
    {
        for(j = 0; j<Data_Size; j++)
        {
            field[i][j] = stage[i][j] + block[i][j];
        }
    }
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

大変失礼しました。

#12

投稿記事 by taka_taka » 11年前

直すべきところが他にもございましたら、おっしゃってください。

配列の行と列、xとyを混同しておりました。
書き直します。

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

Re: 大変失礼しました。

#13

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

taka_taka さんが書きました:直すべきところが他にもございましたら、おっしゃってください。

配列の行と列、xとyを混同しておりました。
書き直します。
とりあえず、前回のトピックで言われた事は網羅して下さい。
テキストファイルに書き出す。紙に書き出す。なんでも方法は良いので、再チェックできる仕組みを自分で考え出すんです。
仕事なら余計にですが、一度言われたことは整理して自分のものとすることが大事なんですよ。
※ 確か前のトピックで後で直すとか書かれていたはずですが、後回しにするとダメな理由はこういう事になるからです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

先のコードを書き直しましたが、いかがでしょうか。

#14

投稿記事 by taka_taka » 11年前

1点ご質問がございます。
マジックナンバーは、たとえば、forループの0や転送用数値4等にも
用いたほうがよいでしょうか。
あと、何かございましたら、アドバイスをお願いします。

コード:

//インクルード_dxライブラリ
#include "DxLib.h"

//グローバル変数
static const int ZERO = 0;	//ステージの左壁と壁の底を表す数字
static const int One = 1;
static const int MAX_WIDTH = 12;	//ステージの横幅の最大値
static const int MAX_HEIGHT = 21;	//ステージの高さの最大値
static const int Block_Size = 20;	//1ブロックの辺の大きさ
static const int Data_Size = 4;		//1ブロックのデータサイズ
static const int Stage_Round = 9;	//ステージの周囲を表す数値

static int Handle_Stage;
static int Handle_Block;

static int block[Data_Size][Data_Size] = {{0, 0, 0, 0},{0, 1, 1, 0},{0, 1, 1, 0},{0, 0, 0, 0}};
static int field[MAX_HEIGHT][MAX_WIDTH] = {0};
static int stage[MAX_HEIGHT][MAX_WIDTH] = {0};

//関数
void Stage_Initialize(){

	int i,j;

	for(i = 0; i < MAX_HEIGHT; i++)
	{
		stage[i][ZERO] = Stage_Round;
		stage[i][MAX_WIDTH - One] = Stage_Round;
	}

	for(i = 0; i < MAX_WIDTH; i++)
	{
		stage[MAX_HEIGHT - One][i] = Stage_Round;
	}

	for(i = 0; i<Data_Size; i++)
	{
		for(j = 0; j<Data_Size; j++)
		{
			field[i][j + 4] = stage[i][j + 4] + block[i][j];
		}
	}
	
	Handle_Stage = LoadGraph(TEXT("../../../../../../All Users/Documents/My Pictures/Sample Pictures/テトリス/block_kabe.png"));
	Handle_Block = LoadGraph(TEXT("../../../../../../All Users/Documents/My Pictures/Sample Pictures/テトリス/block_white.png"));
}

void Stage_Draw(){

	int w;
	int h;

	for(h = 0; h < MAX_HEIGHT; h++)
	{
		for(w = 0; w <MAX_WIDTH; w++)
		{
			if (field[h][w] == One)
			{
				DrawGraph( w * Block_Size, h * Block_Size, Handle_Block, TRUE );
			
			} 
			if (stage[h][w] >= Stage_Round){
			
				DrawGraph( w * Block_Size, h * Block_Size, Handle_Stage, TRUE );
			}
		}
	}
}

//WinMain
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

	//ウィンドウモードに変更	
	ChangeWindowMode(true), DxLib_Init() != 0, SetDrawScreen( DX_SCREEN_BACK );

	//ステージの初期化
	Stage_Initialize();

	while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0){

		//ステージの描画
		Stage_Draw();
	}

	//ステージの終了処理
	void Stage_Finalize();

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

	//ソフトの終了
	return 0;

}

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#15

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

即値が悪いわけではなく、メンテナンス性や意味が分かり辛くなるので置き換えるのです。
0を置き換えると逆に分かり辛くなります。
4は置き換えたほうが分かりやすくないですか?
それと変更時に容易になるし、同じ4でも違う意味のところがあったら区別がつきやすくなります。

Stage_Initializeもi,jは止めたほうが良いと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#16

投稿記事 by Dixq (管理人) » 11年前

1.
画像はマイピクチャに置くべきではありません。
もしゲームを配布する時、ユーザーに「このファイルはここに、このファイルはここに置いて下さい」とお願いするのでしょうか。
素材はプロジェクトがあるフォルダにすべて置くべきです。

2.
>たとえば、forループの0や転送用数値4等にも用いたほうがよいでしょうか。
0や1は良いですが、それ以外については定義を用いるべきでしょう。
4と聞いてもパっと見よく分かりませんでした。
また、グローバル領域の定義にData_Sizeという名前を用いるのはよくないかと思います。
何のデータサイズか分かりません。
せっかく定義を作っても一か所でしか使わないといったことがあるのであれば

コード:

{
    const static int HOGE = 4;
    for(int i=0; i<HOGE; i++){
        //
    }
}
このように書くと良いでしょう。

3.
i,jはx,yなどに置き換えた方が誤解が無いでしょう。

taka_taka
記事: 79
登録日時: 11年前

確かに可読性とメンテナンス性は高まります。

#17

投稿記事 by taka_taka » 11年前

ただ、今回のことではなくて、
基本的に、マジックナンバーの扱いは、結構、センスや解釈の違いが出る気がします。
自分はまだまだセンスも経験も足りないと実感しています。

逆に、同じ4で違う意味でしたら、違う文字で置き換えるべきでしょうか。

ブロックの4×4と、転送用の4は意味は違いますが、別の文字に置き換えたほうが
よろしいでしょうか。
最後に編集したユーザー taka_taka on 2013年2月06日(水) 20:07 [ 編集 1 回目 ]

taka_taka
記事: 79
登録日時: 11年前

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#18

投稿記事 by taka_taka » 11年前

>Dixq (管理人)様

アドバイスをありがとうございます。
Dixq (管理人) さんが書きました:1.
画像はマイピクチャに置くべきではありません。
もしゲームを配布する時、ユーザーに「このファイルはここに、このファイルはここに置いて下さい」とお願いするのでしょうか。
素材はプロジェクトがあるフォルダにすべて置くべきです。
1.環境はVC2008++なのですが、素材は、cppと一緒のフォルダに置けばよろしいでしょうか?
Dixq (管理人) さんが書きました: また、グローバル領域の定義にData_Sizeという名前を用いるのはよくないかと思います。
何のデータサイズか分かりません。
せっかく定義を作っても一か所でしか使わないといったことがあるのであれば

コード:

{
    const static int HOGE = 4;
    for(int i=0; i<HOGE; i++){
        //
    }
}
このように書くと良いでしょう。
言われてみると、Data_Sizeはよくないです。Block_Pixel_Size等にすべきでした。
一か所でしか使わない場合は、グローバルではなく、ローカルで定数定義をします。

2.作成途中で、一箇所かどうか判断がつかない場合は、普通はどうすべきなのでしょうか。
Dixq (管理人) さんが書きました: 3.
i,jはx,yなどに置き換えた方が誤解が無いでしょう。
x,yやw,hどちらかにしようと思っています。

色々とご指導、アドバイスありがとうございます。
助かりますので、またよろしくお願いします。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#19

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

taka_taka さんが書きました:ブロックの4×4と、転送用の4は意味は違いますが、別の文字に置き換えたほうが
よろしいでしょうか。
どちらがメンテナンス性が高いか考えれば、自ずと答えになると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#20

投稿記事 by Dixq (管理人) » 11年前

> 1.環境はVC2008++なのですが、素材は、cppと一緒のフォルダに置けばよろしいでしょうか?

cppがあるフォルダではなく、プロジェクトがあるフォルダから見た相対パスで指定するのが普通です。
http://dixq.net/g/
ゲームプログラミングの館のプロジェクトを落としてもらえれば参考になるかと思います。

> 2.作成途中で、一箇所かどうか判断がつかない場合は、普通はどうすべきなのでしょうか。

普通グローバル領域に定義を書く方が良いでしょう。
「どうしても一か所でしか使わないのに定義を書くのは無駄が・・」と思ったらローカルに書けばよいかと思います。
そのような場合は定義でなくても変数でも良いです。

コード:

XX( true, true );
これは引数を見て何を渡したいのか分かるでしょうか。さっぱり分かりませんね。
そんな時以下のように書いてみたらどうでしょう。

コード:

bool isClickable = true;
bool isRunnable = true;
XX( isClickable, isRunnable );
いくらか何を渡したいのか分かるようになったのではないかと思います。
このようにコメントなしで知らない人がコードを読めるようにするとよろしいかと思います。

> x,yやw,hどちらかにしようと思っています。

幅と高さではないのですからx,yが自然でしょうね。

taka_taka
記事: 79
登録日時: 11年前

お返事ありがとうございます。

#21

投稿記事 by taka_taka » 11年前

>softya(ソフト屋) 様

別々にしようと思いました。
メンテナンス性を考えると、変更があった場合、別々だと直しやすいと思いました。
ありがとうございます。

>Dixq (管理人) 様

素材は、プロジェクトがあるフォルダから見た相対パスで指定するのが普通なのですね。
知りませんでしたので、試してみます。
Dixq (管理人) さんが書きました:普通グローバル領域に定義を書く方が良いでしょう。
「どうしても一か所でしか使わないのに定義を書くのは無駄が・・」と思ったらローカルに書けばよいかと思います。
そうですね、読みやすいです。自分でも気をつけたいです。

お忙しいところ、お返事ありがとうございます。

今、やっと、y方向に、真四角のブロックが動くようになりました。
次に、壁で止まる処理、止まったブロックに重なっていく処理、
さらに、x方向へも動く処理、横の壁で止まる処理、全体的に重なる処理
、扱うブロックを増やす処理等、やることだらけですが、がんばってみます。

taka_taka
記事: 79
登録日時: 11年前

どうしても、ブロックが積み重なりません。

#22

投稿記事 by taka_taka » 11年前

ほぼ初心者です。
ブロックが落ちて、壁では停止するのですが、
2つ目のブロックが落ちてきたときに、また同じように壁まで行ってしまいます。

処理全体を見直したほうがいいのでしょうか。
それとも、特定の箇所を変えれば直る感じでしょうか。

コード:

//インクルード_dxライブラリ
#include "DxLib.h"

//インクルード_ローカル


//グローバル変数
static const int Zero = 0;	//ステージの左壁と壁の底を表す数字
static const int One = 1;	//ブロック箇所の数値
static const int MAX_WIDTH = 12;	//ステージの横幅(列)の最大値
static const int MAX_HEIGHT = 21;	//ステージの高さ(行)の最大値
static const int Block_Size = 20;	//1ブロックの辺のピクセルサイズ
static const int Block_Data_Size = 4;		//1ブロックのデータサイズ
static const int Stage_Round = 9;	//ステージの周囲を表す数値
static const int Middle = 4;	//4×4ブロックを中央に移動するための数値

static int Handle_Stage;
static int Handle_Block;

static int block[Block_Data_Size][Block_Data_Size] = {{0, 0, 0, 0},{0, 1, 1, 0},{0, 1, 1, 0},{0, 0, 0, 0}};
static int field[MAX_HEIGHT][MAX_WIDTH] = {0};
static int stage[MAX_HEIGHT][MAX_WIDTH] = {0};

static int g_x = 0;
static int g_y = 0;

//関数
void Stage_Initialize(){

	int w;
	int h;

	for(h = 0; h < MAX_HEIGHT; h++)
	{
		stage[h][Zero] = Stage_Round;
		stage[h][MAX_WIDTH - One] = Stage_Round;
		field[h][Zero] = Stage_Round;
		field[h][MAX_WIDTH - One] = Stage_Round;
	}

	for(w= 0; w < MAX_WIDTH; w++)
	{
		stage[MAX_HEIGHT - One][w] = Stage_Round;
		field[MAX_HEIGHT - One][w] = Stage_Round;
	}

	for(h = 0; h < Block_Data_Size; h++)
	{
		for(w = 0; w < Block_Data_Size; w++)
		{
			field[h][w + Middle] = stage[h][w + Middle] + block[h][w];
		}
	}
	
	Handle_Stage = LoadGraph(TEXT("./block_kabe.png"));
	Handle_Block = LoadGraph(TEXT("./block_white.png"));
}

void Block_Move(int y2){

	int w;
	int h;

	//今までのブロックを消して
	for(h = 0; h < Block_Data_Size; h++)
	{
		for(w = 0; w < Block_Data_Size; w++)
		{
			field[h + g_y][w + Middle] -= block[h][w];
		}
	}
	
	g_y = y2;

	for(h = 0; h < Block_Data_Size; h++)
	{
		for(w = 0; w < Block_Data_Size; w++)
		{
			field[h + g_y][w + Middle] += block[h][w];
		}
	}
}

int CheckOverlap(int y2){

	int w;
	int h;

	//ブロックが向かう位置に固定ブロックもしくは壁があるかどうかを検査
	for(h = 0; h < Block_Data_Size; h++)
	{
		for(w = 0; w < Block_Data_Size; w++)
		{
			if(block[h][w])
			{
				if(stage[y2 + h][w] != 0)
				{
					return 1;
				}
			}
		}
	}
	return 0;
}

void LockBlock(){
	
	int w;
	int h;

	//ブロックを壁に加える
	for(h = 0; h < MAX_HEIGHT; h++)
	{
		for(w = 0; w < MAX_WIDTH; w++)
		{
			stage[h][w] = field[h][w];
		}
	}
}

void Stage_Draw(){

	int w;
	int h;

	for(h = 0; h < MAX_HEIGHT; h++)
	{
		for(w = 0; w <MAX_WIDTH; w++)
		{
			if (field[h][w] == One)
			{
				DrawGraph( w * Block_Size, h * Block_Size, Handle_Block, TRUE );
			
			} 
			//if (stage[y][x] >= Stage_Round)
			if (field[h][w] >= Stage_Round)
			{
				DrawGraph( w * Block_Size, h * Block_Size, Handle_Stage, TRUE );
			}
			if (stage[h][w] == One)
			{
				DrawGraph( w * Block_Size, h * Block_Size, Handle_Block, TRUE );
			}
		}
	}
}


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

	int y = 0;
	int count = 0;
	
	//ウィンドウモードに変更	
	ChangeWindowMode(true), DxLib_Init() != 0, SetDrawScreen( DX_SCREEN_BACK );

	//ステージの初期化
	Stage_Initialize();

	while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0){

		if (count % 30 == 0)
		{
			if(CheckOverlap(y) != 1)
			{
				Block_Move(y);
				y++;
			} else {
				LockBlock();
				y = 0;
			}
			
		}
		//ステージの描画
		Stage_Draw();
		count++;
	}

	//ステージの終了処理
	void Stage_Finalize();

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

	//ソフトの終了
	return 0;

}

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#23

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

ズバリの回答をするより、なぜこうなるかを調べる方法を教えます。

printfとデバッガを使って2つ目のブロックがちゃんと衝突判定しているか確認してみて下さい。
「簡単RPG講座 番外編。 デバッグ入門 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&b=982&c=2
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

貴重なお返事ありがとうございます。

#24

投稿記事 by taka_taka » 11年前

とりあえず、正方形のブロックが積み重なるところまでできました。

CheckOverlapでインデックスが間違っていました。
CreatBlockを加えました。

コード:

//インクルード_dxライブラリ
#include "DxLib.h"

//インクルード_ローカル

//グローバル変数
static const int Zero = 0;	//ステージの左壁と壁の底を表す数字
static const int One = 1;	//ブロック箇所の数値
static const int MAX_WIDTH = 12;	//ステージの横幅(列)の最大値
static const int MAX_HEIGHT = 21;	//ステージの高さ(行)の最大値
static const int Block_Size = 20;	//1ブロックの辺のピクセルサイズ
static const int Block_Data_Size = 4;		//1ブロックのデータサイズ
static const int Stage_Round = 9;	//ステージの周囲を表す数値
static const int Middle = 4;	//4×4ブロックを中央に移動するための数値

static int Handle_Stage;
static int Handle_Block;

static int block[Block_Data_Size][Block_Data_Size] = {{0, 0, 0, 0},{0, 1, 1, 0},{0, 1, 1, 0},{0, 0, 0, 0}};
static int field[MAX_HEIGHT][MAX_WIDTH] = {0};
static int stage[MAX_HEIGHT][MAX_WIDTH] = {0};

static int g_x = 0;
static int g_y = 0;
static int gameover = 0;
//プロトタイプ宣言
int CreateBlock();
void Stage_Draw();
//関数
void Stage_Initialize(){

	int w;
	int h;

	for(h = 0; h < MAX_HEIGHT; h++)
	{
		stage[h][Zero] = Stage_Round;
		stage[h][MAX_WIDTH - One] = Stage_Round;
		field[h][Zero] = Stage_Round;
		field[h][MAX_WIDTH - One] = Stage_Round;
	}

	for(w= 0; w < MAX_WIDTH; w++)
	{
		stage[MAX_HEIGHT - One][w] = Stage_Round;
		field[MAX_HEIGHT - One][w] = Stage_Round;
	}

	CreateBlock();

	Handle_Stage = LoadGraph(TEXT("./block_kabe.png"));
	Handle_Block = LoadGraph(TEXT("./block_white.png"));
}

int CreateBlock(){
	int w;
	int h;

	//ブロックの座標を最上段中央にセット
	g_x = 4;
	g_y = 0;

	for(h = 0; h < Block_Data_Size; h++)
	{
		for(w = 0; w < Block_Data_Size; w++)
		{
			field[h][w + g_x] = stage[h][w + g_x] + block[h][w];

			//初期位置に置いたブロックが既に固定ブロックに重なっていればゲームオーバー
			if(field[h][w+g_x] > 1)
			{
				gameover = 1;
				return 1;
			}
		}
	}
	return 0;
}

void Block_Move(int y2){

	int w;
	int h;

	//今までのブロックを消して
	for(h = 0; h < Block_Data_Size; h++)
	{
		for(w = 0; w < Block_Data_Size; w++)
		{
			field[h + g_y][w + Middle] -= block[h][w];
		}
	}
	
	g_y = y2;

	for(h = 0; h < Block_Data_Size; h++)
	{
		for(w = 0; w < Block_Data_Size; w++)
		{
			field[h + g_y][w + Middle] += block[h][w];
		}
	}
}

int CheckOverlap(int y2){

	int w;
	int h;

	//ブロックが向かう位置に固定ブロックもしくは壁があるかどうかを検査
	for(h = 0; h < Block_Data_Size; h++)
	{
		for(w = 0; w < Block_Data_Size; w++)
		{
			if(block[h][w])
			{
				if(stage[y2 + h][w + Middle] != 0)
				{
					return 1;
				}
			}
		}
	}
	return 0;
}

void LockBlock(){
	
	int w;
	int h;

	//ブロックを壁に加える
	for(h = 0; h < MAX_HEIGHT; h++)
	{
		for(w = 0; w < MAX_WIDTH; w++)
		{
			stage[h][w] = field[h][w];
		}
	}
}

void Stage_Draw(){

	int w;
	int h;

	for(h = 0; h < MAX_HEIGHT; h++)
	{
		for(w = 0; w <MAX_WIDTH; w++)
		{
			if (field[h][w] == One)
			{
				DrawGraph( w * Block_Size, h * Block_Size, Handle_Block, TRUE );
			
			}
			if (field[h][w] >= Stage_Round)
			{
				DrawGraph( w * Block_Size, h * Block_Size, Handle_Stage, TRUE );
			}
			if (stage[h][w] == One)
			{
				DrawGraph( w * Block_Size, h * Block_Size, Handle_Block, TRUE );
			}
		}
	}
}


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

	int y = 0;
	int count = 0;
	
	//ウィンドウモードに変更	
	ChangeWindowMode(true), DxLib_Init() != 0, SetDrawScreen( DX_SCREEN_BACK );

	//ステージの初期化
	Stage_Initialize();

	while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0){

		if (count % 30 == 0)
		{
			if(CheckOverlap(g_y + 1) != 1)
			{
				Block_Move(g_y + 1);
			} else {
				LockBlock();
				CreateBlock();
				if(gameover == 1) break; 
			}
			
		}
		//ステージの描画
		Stage_Draw();
		count++;
	}

	//ステージの終了処理
	void Stage_Finalize();

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

	//ソフトの終了
	return 0;

}

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#25

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

気になることですが、すごく細かくてすいません。
すごく不注意な使い方が多いでので気をつけていただきたくて。

・Oneは冗長です。1で分かります。あと2つの意味で使われているような?
ブロック種類はenum定義したほうが良いでしょうね。
・Zeroは意味を表していません。
・MAX_WIDTH/MAX_HEIGHTよりは、STAGE_BLOCK_WIDTH/STAGE_BLOCK_HEIGHTですかね。何のサイズか明確になります。
・Block_Sizeよりは、Block_Pixel_Sizeでしょうか。単位が明確になります。
・Middle/Stage_Roundも単位やら基準を明確な名前に。
・Handle_Stage/Handle_Blockもグラフィックであることは明確にしたほうが良いです。
・g_x/g_yもブロックの座標であると明確な名前に。
・CreateBlock()からのゲームオーバー情報の伝達方法が直感的ではありません。
g_x = 4;はg_x = Middle;なのでは?
・Block_Move()でグローバル変数g_yとy2の関係性が分かりづらいです。
この関数だけ_があるのはBlock系で非統一なのでは?
それとMiddleじゃなくg_xでは? これはCheckOverlap()もですが。
・CheckOverlap()の戻り値がfalse/trueの方がよさそうです。そうすると分かりやすくなりませんか?
あとこの関数だけBlockが名前にないです。
・Stage_Draw()で不要なのでは? 勘違いだったらすいません。

コード:

            if (stage[h][w] == One)
            {
                DrawGraph( w * Block_Size, h * Block_Size, Handle_Block, TRUE );
            }
と長くなりましが以上です。
抜けが多い気がするので、1つ1つ、どう対応したかを教えて下さい。
そういえば、Dixq(管理人)さんにx,yにしたほうが良いと言われてませんでしたっけ?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

アドバイスを頂きまして、ありがとうございます。

#26

投稿記事 by taka_taka » 11年前

http://www.nhk.or.tv/kow/program/program_124.php

上記のサイトを参考にしましたが、g_x, g_yを定義したので、
ループがx, yだと行列の行と列を自分が混乱したので、
あえてh , wにしましたが、x, yのほうがよろしければ、直します。

アドバイス一つ一つ対応しようと思いますので、
よろしくお願いします。

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

Re: アドバイスを頂きまして、ありがとうございます。

#27

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

taka_taka さんが書きました:http://www.nhk.or.tv/kow/program/program_124.php

上記のサイトを参考にしましたが、g_x, g_yを定義したので、
ループがx, yだと行列の行と列を自分が混乱したので、
あえてh , wにしましたが、x, yのほうがよろしければ、直します。

アドバイス一つ一つ対応しようと思いますので、
よろしくお願いします。
参考サイトはあくまで参考サイトなので、頼り過ぎたら自分でプログラムが書けない事になります。
概念的な情報の勉強用と考え、コード自体は参考にしないほうが良いでしょう。
今見なおしてみましたが、基本的構造まで同じなんですね。

【補足】
どうしても分からないのなら仕方ない部分もありますが、それならもっと簡単なモノからやるべきだとは思います。
出来なければアプローチを変えて簡単な部分から理解を始めるのは業務プログラムでも有用な方法です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

アドバイスありがとうございます。

#28

投稿記事 by taka_taka » 11年前

どうしても難しく感じるので、もう少し簡単なゲームに取り組もうと思います。

ただ、じゃんけんゲームなどならいいのですが、他にいいレベルのゲームが少なそうというところが

やりずらい部分でもあります。

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

Re: アドバイスありがとうございます。

#29

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

taka_taka さんが書きました:どうしても難しく感じるので、もう少し簡単なゲームに取り組もうと思います。

ただ、じゃんけんゲームなどならいいのですが、他にいいレベルのゲームが少なそうというところが

やりずらい部分でもあります。
ゲームの完成形に囚われずに、ブロック崩しのボールの反射だけとか基礎的な動き・アルゴリズムの部分を重点的にやってみてはどうでしょうか?

【補足】
プロの方だと思って、ソースコードの書き方について細かく厳し目に書いてますので、ソースコードの綺麗な書き方にが足かせになっているのなら、とりあえず綺麗に書くのを止めてみるのも方法です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#30

投稿記事 by taka_taka » 11年前

softya(ソフト屋) さんが書きました:ゲームの完成形に囚われずに、
ブロック崩しのボールの反射だけとか基礎的な動き・アルゴリズムの部分を重点的にやってみてはどうでしょうか?
アドバイス、ありがとうございます。
基礎的な部分を重点的にやってみます。
ちなみに、ライブラリを使用するときは、理解したうえでサンプルをコピー&ペーストしたほうがいいのか、
サンプルを見ずに自分で書いたほうがいいのか、どちらがいいのでしょうか。
ライブラリを使用した経験があまり無い前提でお答えをお願いします。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#31

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

taka_taka さんが書きました:
softya(ソフト屋) さんが書きました:ゲームの完成形に囚われずに、
ブロック崩しのボールの反射だけとか基礎的な動き・アルゴリズムの部分を重点的にやってみてはどうでしょうか?
アドバイス、ありがとうございます。
基礎的な部分を重点的にやってみます。
ちなみに、ライブラリを使用するときは、理解したうえでサンプルをコピー&ペーストしたほうがいいのか、
サンプルを見ずに自分で書いたほうがいいのか、どちらがいいのでしょうか。
ライブラリを使用した経験があまり無い前提でお答えをお願いします。
サンプルを理解した上で、最終的に見ずに書くでしょうね。
理解するためにはサンプルを一度コピペして動かしてデバッガで解析するなども必要だと思いますけどね。
最終的に見ずに書かない時が、一番理解しているかが自分でもわかるからです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#32

投稿記事 by taka_taka » 11年前

softya(ソフト屋) さんが書きました:理解するためにはサンプルを一度コピペして動かしてデバッガで解析するなども必要だと思いますけどね。
最終的に見ずに書かない時が、一番理解しているかが自分でもわかるからです。
見ずに書くのは、できるものですか?
自分のレベルだと、つづりを間違えるのが怖くて、コピーを利用する感じです。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#33

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

DXLIBのリファレンスを見て関数名ぐらいコピーしても もちろんOKですよ。
それ以上は見ないで書くということです。これなら関数名でエラーにはなりませんよね?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

変なご質問をしてしまいまして、申し訳ございません。

#34

投稿記事 by taka_taka » 11年前

意図としては、関数名以外で、ゲームプログラミングでは、
どういうイメージを持つとよろしいでしょうか。

数字や文字処理のプログラミングは、データを処理するので、
式や探索をイメージしやすいのですが、
典型的なのはデータベース周りやHTMLのコーディングです。

ゲームプログラミングでは、どのあたりをイメージして、
コーディングする感じでしょうか。
(箇所によって、何をイメージするのか大きく変わるのが、
ゲームプログラミングの特徴であったり、難しさなのでしょうか。)

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#35

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

それは特に意識したことがない質問ですね。
あえて言うなら、実際に画面で動いているイメージぐらいしか無いでしょうか。
実際に動いてるモノ=オブジェクトがどんな情報をもって動いているかって感じですかね。

作っている人によって、頭の中のイメージは違うんじゃないかと思うんですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: 変なご質問をしてしまいまして、申し訳ございません。

#36

投稿記事 by h2so5 » 11年前

taka_taka さんが書きました: 数字や文字処理のプログラミングは、データを処理するので、
式や探索をイメージしやすいのですが、
典型的なのはデータベース周りやHTMLのコーディングです。

ゲームプログラミングでは、どのあたりをイメージして、
コーディングする感じでしょうか。
(箇所によって、何をイメージするのか大きく変わるのが、
ゲームプログラミングの特徴であったり、難しさなのでしょうか。)
そもそもソフトウェアの目的はデータの処理です。ゲームプログラムも例外ではありません。
ゲームプログラムをデータ処理に落とし込むことができないと難しいのかもしれません。

taka_taka
記事: 79
登録日時: 11年前

ありがとうございます。

#37

投稿記事 by taka_taka » 11年前

softya(ソフト屋) さんが書きました:あえて言うなら、実際に画面で動いているイメージぐらいしか無いでしょうか。
実際に動いてるモノ=オブジェクトがどんな情報をもって動いているかって感じですかね。
ありがとうございます。ご参考になります。
ゲームは色々と、目で見て動くものが多いで、混乱します。
目でこうしたいというときに、単純にデータだけだとイメージしずらいので、
実際に動いているオブジェクトとしてのデータ情報に着目すると、よさそうな感じがしました。
言われると当たり前なのですが、ゲームプログラミングは、
draw系で表示されるので、何か結びつけるのが難しい部分が個人的にはしていました。

h2so5 さんが書きました:そもそもソフトウェアの目的はデータの処理です。
ゲームプログラムも例外ではありません。
ゲームプログラムをデータ処理に落とし込むことができないと難しいのかもしれません。
変な質問に、ご回答ありがとうございます。
これが結構難しい部分の気がしました。

ゲームのパーツや動きに、データ処理(ソース)を落とし込むときに、
ポイントというか、つなぐ何か意識が足りない気がしまして、
自分にとって難しい感じがしていました。

データベースなどだと、データそのものをデータベースから抜き出すという
イメージがしやすいです。
(業務系だと、フローチャートとの対応が明確な感じがしています。)
HTMLなど表示系は、文章変換や画像処理のような対応が基礎的な部分で明確な気がしています。

ゲーム表示と、データ処理(ソース)を、どうつないだらいいのかと、自問自答していました。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#38

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

ここのテーマのテトリスだとサンプルコードのやつは盤面の変化をパズルの落下に錯覚させているわけですが、実際には紙と手作業で同じようなコマ撮りアニメも作れますよね?
紙に縦20行 × 横10列のマス目を引いて、色紙で作ったマス目サイズの四角形をマス目に合わせてテトリミノの形に置くとテトリスの1コマが完成です。
これをマス目をずらしながら撮影していけば、テトリスのアニメーションとなります。

まぁ、これをコンピューターの中でシミュレートしているわけです。そんなイメージは持てていましたか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#39

投稿記事 by taka_taka » 11年前

テトリスでは、消して再度表示するというソースを見たところで、
コマ送りはイメージできた気がします。

ただ、ブロック固定で、fieldとstage, blockの三つのデータと
対応が混乱してしまっていました。
stageにfieldを代入する、それを表示するとなると、blockとの
関連がうまくできなかった気がします。
drawのとき、どのデータを使うのか、どうなるのか、対応できているようで、
適当にやっていた気がします。

blockを表示させる処理で、やっとだったので、
2つ以上の処理、コマ送りと回転、
2つ以上のデータ、stage,field,block
さらに、それらのデータと座標の対応、
になると混乱していました。

あと、配列とコマ送りの対応がしっかりとイメージできていなかった気がします。
最後に編集したユーザー taka_taka on 2013年2月12日(火) 19:02 [ 編集 1 回目 ]

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#40

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

まぁ、別にあのような形にする必然は無くてですね。私ならstageとblockだけで済ませる可能性が高いと思います。
この場合はロックするまでstageは書き換えません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#41

投稿記事 by taka_taka » 11年前

アドバイスをありがとうございます。
この時点で、なんとなくでも、全体的なデータの扱いは
イメージできている感じでしょうか?

自分のレベルだと、確かにfieldがいらないとして、stageを書き換えないとして、
blockの定義は変えられないので、draw時の座標をうんぬんするのかなくらい
間でしかイメージできません。
この先までイメージができる感じでしょうか。

補足

ゲームプログラミング全般は、draw系で表示ということで、
表示に際して、ピクセル単位なのか、画像単位なのか、
そのあたりの区別があいまいだったというのも、
テトリスを作成する上で混乱した原因だった気がします。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#42

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

blockを回転させるためにはblockの大きさのworkが必要ですが、それは一時的な保存用のワークですね。
そのworkから直接Drawとか当たり判定を行います。
って感じのイメージは出来ています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#43

投稿記事 by taka_taka » 11年前

貴重なご考え方をありがとうございます。
ちなみに、そういったコーディング前段階でのイメージの広がりの範囲は、
経験で広がるものなのでしょうか。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#44

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

taka_taka さんが書きました:貴重なご考え方をありがとうございます。
ちなみに、そういったコーディング前段階でのイメージの広がりの範囲は、
経験で広がるものなのでしょうか。
さて?どうなんでしょう。
大雑把にこんな風にしているって話だけでだいたいイメージが掴めるんですよ。
※ 複雑な昨今のAIアルゴリズムなどは除く。
もちろん、経験値の部分もあるんですけどね。大半は自分で培った経験値でしょうね。

N88BASIC時代から組んでいますが見た目移植とか普通にやっていたので、ソースコード自体を参考にしたことは殆ど無いです。
※ 見た目移植 = 動いている動画・実物 だけを資料に同じゲームを作ること。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#45

投稿記事 by taka_taka » 11年前

お返事ありがとうございます。
softya(ソフト屋) さんが書きました:もちろん、経験値の部分もあるんですけどね。大半は自分で培った経験値でしょうね。
自分で培うというのは、プログラムを組んだり、書籍を読んだりでしょうか?

今の自分の初心者レベルでできることと言ったら、基礎的な動き・アルゴリズムの部分を重点的にやる、
その後、全体的にできるようにするということに当てはまりますでしょうか。
レベルはまったく異なりますが。
softya(ソフト屋) さんが書きました:N88BASIC時代から組んでいますが見た目移植とか普通にやっていたので、ソースコード自体を参考にしたことは殆ど無いです
これは、自分からすると、相当すごい感じがします。

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

Re: ほぼ初心者です。テトリスのステージとフィールドについて

#46

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

ほぼ、プログラム組んだりしただけです。
ただ、楽しんで遊んでいただけなので勉強していたという自覚はありません。
参考にしたのは、3Dワイヤーフレームのライブラリぐらいで、あとはゲーム画面だけでしょうね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

お世話になります。話題とずれますが、

#47

投稿記事 by taka_taka » 11年前

ゲームプログラミングのおすすめの学習方法はありますでしょうか?
簡単なゲームの部分的なアルゴリズムやプログラミングをすることから
スタートがいい感じでしょうか?
よくありがちな質問で、場違いでしたら、申し訳ございません。

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

Re: お世話になります。話題とずれますが、

#48

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

taka_taka さんが書きました:ゲームプログラミングのおすすめの学習方法はありますか?
簡単なゲームの部分的なアルゴリズムやプログラミングをすることから
スタートがいい感じですか?
この話題は別トピックにすることをオススメします。多くの意見が得られるとおもいますよ。
ただ、誰にでも通用する方法は無いと思うんですけどね。そういう意味では集められるのは私はこうだったとかでしょうね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taka_taka
記事: 79
登録日時: 11年前

ありがとうございます。

#49

投稿記事 by taka_taka » 11年前

別のトピックにします。

ご意見で十分だと思っています。

閉鎖

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